Zernio
Zernio
API Reference

Posts

List postsGETCreate postPOSTGet postGETUpdate post metadataPOSTUpdate postPUTDelete postDELETEUnpublish postPOSTBulk upload from CSVPOSTRetry failed postPOSTEdit published postPOST
Dashboard
llms.txtOpenAPI
OverviewPlatformsAPI ReferenceResources
Posts

List posts

Returns a paginated list of posts. Published posts include platformPostUrl with the public URL on each platform.


GET
/v1/posts

Authorization

bearerAuth
AuthorizationBearer <token>

API key authentication: send your Zernio API key in the Authorization header, prefixed with Bearer.

In: header

Query Parameters

page?integer

Page number (1-based)

Range1 <= value
Default1
limit?integer

Page size. Values above the maximum return 400 rather than being clamped.

Range1 <= value <= 500
Default10
source?string

Which collection to read. zernio (default) returns posts authored through Zernio. external returns posts synced from the platform (existing/historical posts that were published outside Zernio). Combine with accountId and paginate via page/limit to walk the full synced history (we keep up to the last ~12 months per account).

Default"zernio"

Value in

  • "zernio"
  • "external"
status?string

Value in

  • "draft"
  • "scheduled"
  • "publishing"
  • "published"
  • "partial"
  • "failed"
  • "cancelled"
platform?string
profileId?string

Filter posts to a specific profile (24-char hex ObjectId). Omit it, or send all or an empty value, to list posts across every profile.

createdBy?string

Filter posts to those created by a specific team user (24-char hex ObjectId).

dateFrom?string

Zero-padded YYYY-MM-DD, or a full ISO 8601 datetime. An empty value means no date filter; any other malformed value returns 400.

Formatdate
dateTo?string

Zero-padded YYYY-MM-DD, or a full ISO 8601 datetime. An empty value means no date filter; any other malformed value returns 400.

Formatdate
includeHidden?boolean
Defaultfalse
search?string

Search posts by text content.

sortBy?string

Sort order for results.

Default"scheduled-desc"

Value in

  • "scheduled-desc"
  • "scheduled-asc"
  • "created-desc"
  • "created-asc"
  • "status"
  • "platform"
accountId?string

Filter posts to those published via a specific account (24-char hex ObjectId).

Response Body

application/json

application/json

application/json

{  "posts": [    {      "_id": "65f1c0a9e2b5af0012ab34cd",      "title": "Launch post",      "content": "We just launched!",      "status": "scheduled",      "scheduledFor": "2024-11-01T10:00:00Z",      "timezone": "UTC",      "platforms": [        {          "platform": "twitter",          "accountId": {            "_id": "64e1f0...",            "platform": "twitter",            "username": "@acme",            "displayName": "Acme Corp",            "isActive": true          },          "status": "pending"        }      ],      "tags": [        "launch"      ],      "createdAt": "2024-10-01T12:00:00Z",      "updatedAt": "2024-10-01T12:00:00Z"    }  ],  "pagination": {    "page": 1,    "limit": 10,    "total": 1,    "pages": 1  }}

Was this page helpful?

Re-subscribe a Facebook Page to Zernio's webhooks

Re-sends the full field set to Meta and returns the subscription read back afterwards. Meta only honours the field set sent at subscribe time, so a Page connected before a field existed stays without it until this runs. The response reflects what Meta actually granted, not what was requested.

Create post

Create a post, and optionally publish it in the same request. A post published immediately (`publishNow: true`) comes back with `platformPostUrl` in the response. `content` is optional in four cases: - media is attached - all platforms have `customContent` - every platform entry is an X Article (`platformSpecificData.article`) - every platform entry is a LinkedIn text-free reshare (`platformSpecificData.reshareUrl` with no text) See each platform's schema for media constraints. ## Scheduling Pick one of: - `scheduledFor`: publish at the scheduled time - `publishNow: true`: publish synchronously, inside this request - `queuedFromProfile`: publish in the profile's next queue slot With none of them and `isDraft` unset, the post is saved as a draft. `platforms` is required unless the post is a draft. Precedence: `isDraft: true` wins over `publishNow` and `scheduledFor` (the post is saved, never published), and `publishNow: true` wins over `scheduledFor`. A `scheduledFor` already in the past is not rejected: the post is published synchronously in the same request, exactly like `publishNow`. ## Idempotency Two layers of duplicate-protection apply, so safe-to-retry callers (network blips, n8n / Zapier retries, etc.) don't accidentally double-post. **1. Same-request idempotency (5-minute window).** Pass an `x-request-id` header to mark a logical request. If a second request arrives with the same `x-request-id` while the first is in-flight (or within ~5 minutes of completion), we return **HTTP 200** with the original post in the `existingPost` field, and no new post is created. The official Zernio SDKs auto-generate a unique `x-request-id` per call. On a generic HTTP client (curl, n8n's HTTP node, Zapier, custom code), either: - Set a unique `x-request-id` per logical call (recommended, UUIDv4 is fine) - Or omit the header, and we'll treat each request as new **Common pitfall**: if your workflow tool uses a single execution-level request ID and reuses it across multiple HTTP nodes (e.g. one ID for the whole run, shared across 6 different platform calls), every call after the first will look like a retry of the first and return its post. Generate a fresh ID per node. **2. Content-hash dedup (24-hour window).** Independently, we hash `(platform, accountId, content + media URLs)` and reject duplicates within 24 hours with **HTTP 409**. This catches genuine "same content posted twice to the same account" cases regardless of `x-request-id`. The response carries `error`, `accountId`, `platform`, and `existingPostId` so you can find the original. To intentionally re-post identical content within 24h, change something (the caption, the media, the account), because the dedup is keyed on the full content fingerprint. Order: same-`x-request-id` retries (200) are checked first; if no idempotency match, the content-hash dedup (409) runs.