Topolo Docs Topolo Platform
Open workspace

List Socialize posts

Read posts in one verified brand, interpret filter/status semantics and paginate with offsets.

Read posts in one verified brand, interpret filter/status semantics and paginate with offsets.

Access

  • Verify the original credential, production environment and intended organization. Discover the actual authorized Socialize workspace and bind it separately from action input; a post or campaign id is not a workspace id.
  • Published permission: app_topolo_socialize.posts:read. The published action is a read, but workspace authorization can synchronize the local brand mirror; do not infer a zero-SQL-write full request.
  • The request must use its intended named workspace or an explicitly understood verified default. A named inaccessible resource is denied, without silent default fallback. API-key bindings further narrow actual grants; do not forge identity headers or substitute another principal.

Find the workspace and filters

  • Resolve the brand/workspace through supported workspace discovery or the accessible brands guide, then preserve that scope across pages. Do not add brandId or organizationId to the strict action body.
  • Optional campaignId is an actual discovered campaign id in the intended workspace; threadId is the intended stored thread identifier. authorId is a post author filter, never a replacement authenticated caller.

Request

GET /api/posts

Action: app_topolo_socialize.posts.list.

Optional inputs: authorId, status, platform, campaignId, threadId, limit and offset. Use current action discovery for the exact schema; selection of a workspace stays in separate resource context.

Response and pagination

  • The handler returns {data:[post,...],meta:{count,limit,offset}}. count is this page’s length, not the total matching count. Default limit50/offset0; published schema restricts limit1–100 and non-negative integer offsets. No cursor or hasMore flag is supplied.
  • Rows are ordered by created_at descending with no secondary id sort. Concurrent inserts/deletes or tied timestamps can shift offset pages; retain/deduplicate ids and do not claim a stable snapshot. Stop when the page is shorter than the selected limit, recognizing concurrent changes can alter later pages.
  • platform=x is normalized to stored twitter. Other supported platforms are linkedin, linkedin_company, facebook, instagram, threads, tiktok and youtube. status supports draft, scheduled, published, failed, cancelled and archived.
  • status=failed selects failed_at IS NOT NULL; draft selects stored draft with no failed_at. Other status filters compare stored status. Mapping labels any row with failed_at as failed, so a different stored-status filter can still return a displayed failed status; inspect failure fields rather than assuming all returned statuses equal the requested string.
  • With campaignId, a distinct join includes both reusable content variants and concrete campaign occurrence posts. It does not restrict results to future queue occurrences or prove A/B distribution. The verified workspace and other filters remain applied.
  • threadId matches metadata JSON’s threadId only when the stored metadata is valid JSON. Returned metadata itself remains a JSON string or null; it is not automatically expanded into an object.
  • Each post exposes its actual owning brandId, content/author/platform/status, schedule/publication/failure/provider-record fields, mediaItems, normalized placement/publishMode and timestamps. Null provider/permalink fields are possible. A recorded published status or link is not a live provider availability/delivery test.
  • mediaItems is parsed from stored JSON. A malformed stored media_items value can fail the page through the generic error path; this handler does not silently drop that row or return a partial-success page.

Effects

  • resolveBrandId verifies the canonical workspace and may insert/reactivate/synchronize the local brand mirror before the post SELECT. Permission and API-key scope come from the original verified request.
  • PostService.getPosts reads stored rows and maps them; this path does not create posts, queue publishing, hydrate provider data, generate copy/images or call a model. No scheduling or provider delivery follows from reading a page.

Examples

Every example is source-derived, synthetic and unrun. Placeholder ids and stored times confer no authority; nothing was posted, generated or delivered.

List draft posts using the X alias

Source-derived synthetic and unrun. Assumes the illustrated row belongs to the verified workspace, has stored twitter/draft and no failure timestamp.

{
  "platform": "x",
  "status": "draft",
  "limit": 10,
  "offset": 0
}

Illustrative response:

{
  "data": [
    {
      "id": "post_example",
      "content": "Example editorial draft.",
      "authorId": "user_example",
      "brandId": "ws_socialize_example",
      "platform": "twitter",
      "status": "draft",
      "scheduledFor": null,
      "publishedAt": null,
      "failedAt": null,
      "failureCode": null,
      "failureMessage": null,
      "lastPublishAttemptAt": null,
      "lastPublishResultAt": null,
      "permalink": null,
      "platformPostId": null,
      "mediaUrl": null,
      "mediaType": null,
      "mediaThumbnailUrl": null,
      "mediaItems": [],
      "placement": "feed",
      "publishMode": "auto",
      "metadata": null,
      "createdAt": "2026-10-21 00:00:00",
      "updatedAt": "2026-10-21 00:00:00"
    }
  ],
  "meta": {
    "count": 1,
    "limit": 10,
    "offset": 0
  }
}

Read data[0].brandId and normalized platform; count1 is the returned page length.

An empty later page

Source-derived synthetic and unrun. Assumes this authorized page has no matching rows; no Auth/storage failure is being simulated as an empty list.

{
  "limit": 10,
  "offset": 10
}

Illustrative response:

{
  "data": [],
  "meta": {
    "count": 0,
    "limit": 10,
    "offset": 10
  }
}

Treat it as an empty page of this scoped query, not evidence about another workspace or a fixed total.

Inspect stored failure information

Source-derived synthetic and unrun. Assumes existing persisted failure fields and valid stored empty media-array JSON; no provider call or failed delivery was executed.

{
  "status": "failed",
  "limit": 10,
  "offset": 0
}

Illustrative response:

{
  "data": [
    {
      "id": "post_failed_example",
      "content": "Example editorial draft.",
      "authorId": "user_example",
      "brandId": "ws_socialize_example",
      "platform": "twitter",
      "status": "failed",
      "scheduledFor": "2026-10-21T01:00:00.000Z",
      "publishedAt": null,
      "failedAt": "2026-10-21T01:00:02.000Z",
      "failureCode": "example_failure",
      "failureMessage": "Illustrative stored failure.",
      "lastPublishAttemptAt": "2026-10-21T01:00:00.000Z",
      "lastPublishResultAt": "2026-10-21T01:00:02.000Z",
      "permalink": null,
      "platformPostId": null,
      "mediaUrl": null,
      "mediaType": null,
      "mediaThumbnailUrl": null,
      "mediaItems": [],
      "placement": "feed",
      "publishMode": "auto",
      "metadata": null,
      "createdAt": "2026-10-21 00:00:00",
      "updatedAt": "2026-10-21 00:00:00"
    }
  ],
  "meta": {
    "count": 1,
    "limit": 10,
    "offset": 0
  }
}

Inspect the stored failure details and original workspace; this read does not retry publishing or certify provider state.

Refusals and recovery

StatusSource condition/codeNext step
400/problems/validation-errorUse valid query/context inputs and the current strict schema; local validation rejects undeclared fields or out-of-range limits before the action call. A raw handler validation failure has problem-detail form, not a successful empty page.
403workspace_forbiddenDiscover and bind an actually granted canonical workspace with the original credential; never guess another workspace or silently use a default for a refused named resource.
503workspace_unresolvedAuth could not verify workspace access. Preserve the refusal; this is not evidence of zero matching posts.
500/problems/internal-server-errorPreserve request evidence and inspect data/dependencies with the existing owner. Malformed stored media JSON can fail response mapping; no repair or post mutation is implied.

Outer credential/permission/rate-limit responses can differ from handler problem details. Deliberately invalid inputs such as limit101 are local validation failures, not captured HTTP responses.

Verify the result

  • Compare every returned brandId to the intended verified workspace before relying on its content. Check optional filters, the page’s meta count/limit/offset and deduplicated ids; count is not a total.
  • Inspect failedAt/failureCode/failureMessage alongside status and raw scheduling/publication fields. Do not treat campaign membership, schedule time, returned link or a successful list response as proof of provider execution.
  • After a dependency or malformed-storage error, retain the exact scope/input/request evidence and ask the existing owner to diagnose it. Do not mutate a post or substitute a workspace to make a read succeed.

Change log

2026-10-21: Added source-qualified post listing with explicit workspace selection, x/twitter mapping, offset limitations, stored failure-status semantics, full returned post fields and three synthetic unrun worked examples. Reviewed source9ff70e66954dc0275c604e827a8fae682de007b7; current published action markerbc22ce7a2ceaa4396388794c4d42895c777bed76. Source-to-serving association remains unverified.