---
title: "List posts"
method: GET
path: "/v1/posts"
tags: ["Posts"]
---

# List posts

`GET /v1/posts`

## Request

- Base URL: `https://api.postzen.dev`
- URL: `https://api.postzen.dev/v1/posts`
- Auth: HTTP bearer

Returns posts the API key can access, newest first. A post's profiles are the profiles of its target accounts, and a key limited to selected profiles only sees posts whose accounts all sit in profiles it can access. Read-only and read-write API keys are accepted. Published posts include a `platformPostId` and `platformPostUrl` for each published platform target. Results are capped to the 1000 most recent matching posts.

## Query parameters

- `profileId` string
- `accountId` string
- `platform` 'twitter' | 'x' | 'instagram' | 'tiktok' | 'linkedin' | 'facebook' | 'youtube' | 'threads' | 'pinterest' | 'bluesky' | 'telegram'
- `status` 'draft' | 'scheduled' | 'queued' | 'publishing' | 'published' | 'partially_failed' | 'failed' | 'canceled'
- `dateFrom` string, date-time
- `dateTo` string, date-time
- `sortBy` 'createdAt' | 'scheduledFor'
- `page` integer
- `limit` integer

## Response `200`

Posts returned.

- PostsListResponse
  - `posts` ApiPost[], required
    - `_id` string, required
    - `title` string, nullable, required
    - `content` string, required
    - `status` string, required
    - `scheduledFor` string, date-time, nullable, required
    - `queueId` string, nullable: Queue that placed this post, or null when the post was not queued.
    - `timezone` string, required
    - `platforms` ApiPostPlatformResult[], required
      - `platform` 'twitter' | 'x' | 'instagram' | 'tiktok' | 'linkedin' | 'facebook' | 'youtube' | 'threads' | 'pinterest' | 'bluesky' | 'telegram', required
      - `accountId` ApiPostAccount, required
        - `_id` string, required
        - `platform` 'twitter' | 'x' | 'instagram' | 'tiktok' | 'linkedin' | 'facebook' | 'youtube' | 'threads' | 'pinterest' | 'bluesky' | 'telegram', required
        - `username` string, required
        - `displayName` string, required
        - `isActive` boolean, required
      - `status` 'draft' | 'scheduled' | 'pending' | 'publishing' | 'published' | 'failed' | 'canceled', required
      - `platformPostId` string: The platform's own id for the published post. Present as soon as this target is published, so it can be used right away with the inbox and analytics endpoints. For a thread, this is the root post's id.
      - `platformPostIds` string[]: X and Threads thread targets only: the platform id of every post in the thread, root first.
      - `platformPostUrl` string, uri
      - `error` string
      - `platformError` object: The platform's own error envelope for this failure, present only when the platform returned one (today: Instagram, Facebook, and Threads). Fields the platform did not send are absent. When PostZen stops retrying (`error` begins with "Publishing failed after too many attempts"), this is the last attempt's envelope.
        - `code` integer: The platform's error code, for example Meta's `36003`.
        - `subcode` integer: The platform's error subcode, for example Meta's `2207009`.
        - `fbtraceId` string: Meta's trace id for the failed call. Quote it to Meta support; Meta expires it after a short time.
        - `type` string: The platform's error type, for example `OAuthException`.
      - `customContent` string: The per-platform content override this target was created with, if any.
      - `settings` union: Platform-specific publishing options. Unknown keys are ignored.
        - InstagramSettings: Instagram target settings. `postType` selects the format: `feed` and `story` take exactly one media item, `reel` takes exactly one video, and `carousel` takes 2–10 media items (images and videos may be mixed). Captions are limited to 2,200 characters.
          - `postType` 'feed' | 'story' | 'reel' | 'carousel': Instagram post format. `feed` (default) and `story` publish a single media item; `reel` publishes a single video; `carousel` publishes 2–10 ordered media items and may mix images and videos. Sending multiple media items with `feed` returns a validation error directing you to `carousel`.
          - `collaborators` string[]: Up to three Instagram usernames to invite as collaborators. Supported on feed, reel, and carousel posts.
          - `userTags` object[]: Photo tags with relative `x`/`y` coordinates from 0 to 1. Feed posts only — user tags are not supported on carousels, reels, or stories.
            - `username` string, required
            - `x` number, required
            - `y` number, required
          - `firstComment` string: Posts a first comment after publishing. Supported on feed, reel, and carousel posts. Maximum 2,200 characters.
          - `shareToFeed` boolean: Reels only. Defaults to `true`. Set to `false` to keep the reel off the profile feed.
          - `trialParams` object: Reels only. Publishes the reel as a trial reel, which Instagram shows to non-followers first. Sending it with any other `postType` returns a validation error. Trial reels are available only on public professional accounts that Instagram has made eligible; an ineligible account fails at publish time.
            - `graduationStrategy` 'MANUAL' | 'SS_PERFORMANCE', required: How the trial reel graduates to followers. `MANUAL`: the creator graduates it in the Instagram app. `SS_PERFORMANCE`: Instagram graduates it automatically when it performs well with non-followers. Case-sensitive.
        - FacebookSettings
          - `link` string, uri
          - `firstComment` string
        - ThreadsSettings: Threads target settings. Set `threadItems` to publish a chain of 1–25 posts, each with up to 500 characters and 10 images/videos. The first item is the root and each later item replies to the previous one. When set, the target's `content`/`customContent` and the post's top-level `mediaItems` are not published to Threads; they still apply to other targets. `replyControl` applies only to the first post.
          - `replyControl` 'everyone' | 'accountsYouFollow' | 'mentionedOnly': Who can reply. Omit to let everyone reply. When threadItems is set, applies only to the first post.
          - `threadItems` ThreadsThreadItem[]: Publish this target as a thread of 1–25 posts, in order. The first item is the root post and each later item is published as a reply to the previous one. When set, the target's `content`/`customContent` and the post's top-level `mediaItems` are not published to Threads; they still apply to the post's other targets. `platformPostUrl` on the result is the root post's URL. A one-item thread publishes like a plain post. Each item supports up to 500 characters and 10 images/videos. `replyControl` applies only to the first post.
            - `content` string, required: Text of this post in the thread, up to 500 characters. May be empty only when the item has `mediaItems`.
            - `mediaItems` PostMediaItem[]: Up to 10 images/videos attached to this post, in the same format as the post's top-level `mediaItems`. Images (including GIF media) and videos can be mixed within an item.
              - …
        - TikTokSettings
          - `privacyLevel` 'publicToEveryone' | 'mutualFollowFriends' | 'followerOfCreator' | 'selfOnly'
          - `allowComments` boolean
          - `allowDuet` boolean
          - `allowStitch` boolean
          - `disableComment` boolean
          - `disableDuet` boolean
          - `disableStitch` boolean
          - `videoCoverTimestampMs` number
          - `uploadAsDraft` boolean
          - `brandContentToggle` boolean
          - `brandOrganicToggle` boolean
        - LinkedInSettings: LinkedIn target settings. A LinkedIn post carries exactly one media kind: no media (text only), 1–10 images (LinkedIn itself allows 20, but `mediaItems` caps at 10 items on every platform), one MP4 video, or one PDF document uploaded through `POST /v1/media/presign` with `contentType: "application/pdf"` (external document URLs are not ingested, and DOC/DOCX/PPT/PPTX cannot be published through the API). Commentary is limited to 3,000 characters. Every key below is also accepted in `snake_case` (for example `first_comment` and `organization_urn`).
          - `visibility` 'PUBLIC' | 'CONNECTIONS': Who can see the post. Matched case-insensitively; an empty string or `null` counts as unset (defaults to `PUBLIC`), and any other non-empty value returns `400` with `settings.visibility must be PUBLIC or CONNECTIONS`. `CONNECTIONS` is only valid for a member (personal profile) post — combining it with `organizationUrn` is a validation error, because a company page has no connections.
          - `videoTitle` string: Optional title for video posts, shown on the LinkedIn video player. Ignored for non-video posts.
          - `documentTitle` string: Title for a document (PDF carousel) post. LinkedIn requires a title on document posts; when this is omitted PostZen falls back to the uploaded file's name. Ignored for non-document posts.
          - `organizationUrn` string: Not available yet: company-page posting is waiting on LinkedIn's approval of PostZen's Community Management API access. Setting this (or an alias) today fails validation with `400` and a message prefixed with the target account's display name, for example `Jane Doe: LinkedIn company-page posting is not available yet, pending LinkedIn's approval. Remove settings.organizationUrn to publish to the connected member's profile.`, before anything is stored. On `PATCH /v1/posts/{postId}` the check applies to the `platforms` you send; omitting `platforms` leaves stored targets unchecked, and a stored company-page target fails at publish time instead. Once available, this publishes as a LinkedIn company page instead of the connected member. Accepts either the full URN (`urn:li:organization:12345`) or the bare numeric page id (`12345`), which PostZen expands to the URN. The connection must hold `w_organization_social`; one that does not gets `400` with `<account name>: Reconnect this LinkedIn account to post as a company page.`. Also accepted as `organizationId` / `organization_id`.
          - `firstComment` string: Comment posted by the same author immediately after the post goes live. LinkedIn's comment composer caps this at 1,250 characters, tighter than the 3,000-character post body. Best-effort: a failure here is logged and never fails the post, and the post is never retried because of it. Not available yet on LinkedIn: first comments wait on the same LinkedIn approval as company-page posting. Today the comment is dropped before the post is stored (the 1,250-character limit is not applied to it), the post still publishes, and the response carries a top-level `warnings` entry prefixed with the target account's display name, for example `Jane Doe: LinkedIn first comments are not available yet; this post publishes without the comment.`
          - `disableLinkPreview` boolean: LinkedIn's Posts API never scrapes URLs, so a bare link renders as plain text. When this is `false` or omitted and the text contains a URL, PostZen attaches a link card for the first URL; because no scraped metadata is available, the card is titled with the URL's hostname (for example `example.com`). Set to `true` to keep the post as plain text with no card. Also accepted as `disableLinkCard`.
          - `reshareUrl` string: LinkedIn post to quote-reshare. Accepts a public post permalink or a `urn:li:activity:` / `urn:li:share:` / `urn:li:ugcPost:` URN. Mutually exclusive with uploaded media.
          - `geoRestrictionCountries` string[]: Restrict who sees the post to these countries, as uppercase ISO 3166-1 alpha-2 codes (for example `["US", "CA"]`). Up to 25 countries, and organization posts only — supplying this without `organizationUrn` is a validation error. Not available yet, because it requires `organizationUrn`.
        - XSettings: X target settings. A single X post carries up to 280 characters and 1–4 images, one video, or one GIF. Set `threadItems` to publish a thread instead: the first item is the root post and each later item is published as a reply to the one before it. When `threadItems` is set, this target's `content`/`customContent` and the post's top-level `mediaItems` are not published to X — each item carries its own text and media — but they still apply to the post's other targets.
          - `replySettings` 'following' | 'mentionedUsers': Who can reply to the post. Omit to let everyone reply. On a thread this applies to the root post, which is where X enforces reply restrictions for the whole conversation.
          - `threadItems` XThreadItem[]: Publish this target as a thread of 1–25 posts, in order. The first item is the root post and each later item is published as a reply to the previous one. When set, the target's `content`/`customContent` and the post's top-level `mediaItems` are not published to X; they still apply to the post's other targets. `platformPostUrl` on the result is the root post's URL. A one-item thread publishes like a plain post.
            - `content` string, required: Text of this post in the thread, up to 280 characters. May be empty only when the item has `mediaItems`.
            - `mediaItems` PostMediaItem[]: Media attached to this post in the thread, in the same format as the post's top-level `mediaItems`: 1–4 images, or one video, or one GIF. Images and videos cannot be mixed within an item.
              - …
        - YouTubeSettings
          - `title` string
          - `privacyStatus` 'public' | 'unlisted' | 'private'
          - `tags` union
            - string[]
            - string: Comma-separated tags.
          - `categoryId` string
          - `madeForKids` boolean
          - `notifySubscribers` boolean
        - PinterestSettings
          - `boardId` string, required: Pinterest board to publish the pin to.
          - `title` string: Pin title.
          - `link` string, uri: Destination link for the pin.
          - `altText` string
          - `coverImageUrl` string, uri: Cover or thumbnail image URL for video pins.
          - `coverImageKeyFrameTime` number: Cover keyframe time in seconds for video pins, as an alternative to coverImageUrl.
        - BlueskySettings
          - `altTexts` string[]: Alt text for each image, matched to the media by order. Each entry is limited to 2000 characters.
          - `languages` string[]: Up to 3 BCP-47 language codes (e.g. `en`, `pt-BR`) declaring the languages of the post text.
          - `disableLinkCard` boolean: When true, PostZen skips generating an external link preview card for the first URL in the post.
        - TelegramSettings: Telegram target settings. Text-only posts allow 4,096 characters; attaching any media caps the text at 1,024 characters as a caption. A post carries 1-10 media items and may mix photos and videos in one album, but a GIF must be posted on its own. Telegram reports no post analytics.
          - `parseMode` 'html' | 'markdownv2': Formatting mode for the message or caption. Omit to send plain text, which is the default. `html` is recommended: it only requires escaping `<`, `>`, and `&`, whereas `markdownv2` requires escaping every one of `_ * [ ] ( ) ~ ` > # + - = | { } . !` and rejects the whole message otherwise.
          - `disableNotification` boolean: When true, members receive the post silently, with no sound or vibration.
          - `disableLinkPreview` boolean: When true, suppresses the link preview card for URLs in the text. Applies to text-only posts; a post with media has no link preview.
          - `protectContent` boolean: When true, Telegram blocks forwarding and saving of the post.
    - `mediaItems` object[], required: Attached media in stored order, with resolved hosted URLs and optional titles (alt text). Always present; empty when there is no available media.
      - `url` string, uri, required
      - `title` string
  - `pagination` Pagination, required
    - `page` integer, required
    - `limit` integer, required
    - `total` integer, required
    - `totalPages` integer, required

## Other responses

- `400`: Invalid request.
- `401`: Missing or invalid API key.
- `403`: The API key does not have sufficient permission or profile access.
- `404`: Resource not found.
- `429`: Rate limit exceeded. Retry after the interval indicated by the `Retry-After` header.

---

[API](https://skmtc.dev/postzen/apis/postzen-public-api.md) · [All operations](https://skmtc.dev/postzen/apis/postzen-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/postzen/apis/postzen-public-api/revisions/40863e3710ec?raw)
