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

Get post

Fetch a single post by ID. For published posts, this returns platformPostUrl for each platform.


GET
/v1/posts/{postId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key authentication - use your Zernio API key as a Bearer token

In: header

Path Parameters

postId*string

Response Body

application/json

application/json

application/json

application/json

application/json

{  "post": {    "_id": "65f1c0a9e2b5af0012ab34cd",    "title": "Launch post",    "content": "We just launched!",    "status": "scheduled",    "scheduledFor": "2024-11-01T10:00:00Z",    "platforms": [      {        "platform": "twitter",        "accountId": {          "_id": "64e1f0...",          "platform": "twitter",          "username": "@acme",          "displayName": "Acme Corp",          "isActive": true        },        "status": "pending"      }    ]  }}

Was this page helpful?

Create post

Create and optionally publish a post. Immediate posts (`publishNow: true`) include `platformPostUrl` in the response. Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or 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` (schedule), `publishNow: true` (publish synchronously) or `queuedFromProfile` (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. `isDraft: true` wins over `publishNow` and `scheduledFor` (the post is saved, never published); `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 — no new post is created. The official Zernio SDKs auto-generate a unique `x-request-id` per call. If you're using 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 simply omit the header — 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`. Returns `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) — 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.

Update post metadata

Updates metadata of a published video on the specified platform without re-uploading. Currently only supported for YouTube. At least one updatable field is required. Two modes: 1. Post-based (video published through Zernio): pass the Zernio postId in the URL and platform in the body. 2. Direct video ID (video uploaded outside Zernio, e.g. directly to YouTube): use _ as the postId, and pass videoId + accountId + platform in the body. The accountId is the Zernio social account ID for the connected YouTube channel.