Layers

GET /v1/scheduled-posts/:scheduledPostId

Read one scheduled post's status. Polling or webhooks - either works.

View as Markdown
GET/v1/scheduled-posts/:scheduledPostId
Phase 1stable
Auth
Bearer
Scope
publish:read

Read a scheduled post's current state - whether it's queued, publishing right now, already published (with the external URL), or failed (with an error).

Poll until the post reaches a terminal state (published, failed, or canceled). Or subscribe to webhooks to skip polling.

Path
  • scheduledPostId
    stringrequired
    Id returned by schedule or publish.

Example request

curl https://api.layers.com/v1/scheduled-posts/sp_4c8e7d2f-9a1b-4c3d-8e7f-2a1b3c4d5e60 \
  -H "Authorization: Bearer lp_..."
async function waitUntilPublished(id: string) {
  for (;;) {
    const post = await layers.publishing.getScheduledPost({ id });
    if (post.status === "published") return post;
    if (post.status === "failed") throw new Error(post.lastError?.message ?? "publish failed");
    if (post.status === "canceled") throw new Error("canceled");
    await waitBeforeNextPoll();
  }
}
def wait_until_published(post_id: str) -> dict:
    while True:
        post = layers.publishing.get_scheduled_post(id=post_id)
        if post["status"] == "published":
            return post
        if post["status"] in ("failed", "canceled"):
            raise RuntimeError(post.get("lastError", {}).get("message", post["status"]))
        wait_before_next_poll()

Response

200Published
{
  "id": "sp_4c8e7d2f-9a1b-4c3d-8e7f-2a1b3c4d5e60",
  "containerId": "cnt_8f1d6c3e-4b2a-4a18-9e4f-c2d7a1b0e999",
  "socialAccountId": "sa_71b2a4e5-8c3f-4d1a-9e7b-2c5d8f0a1b22",
  "platform": "tiktok",
  "mode": "publish",
  "status": "published",
  "externalId": "7385912341234567890",
  "externalUrl": "https://www.tiktok.com/@acmecoffee/video/7385912341234567890",
  "scheduledFor": "2026-04-19T14:00:00Z",
  "attemptedAt": "2026-04-19T14:00:12Z",
  "publishedAt": "2026-04-19T14:00:18Z",
  "canceledAt": null,
  "lastError": null,
  "createdAt": "2026-04-19T13:55:01Z",
  "updatedAt": "2026-04-19T14:00:18Z"
}
200Failed - read lastError
{
  "id": "sp_d6e8f3a1-7b2c-4d5e-9a8b-3c4d5e6f7080",
  "status": "failed",
  "attemptedAt": "2026-04-19T14:00:12Z",
  "publishedAt": null,
  "canceledAt": null,
  "lastError": {
    "code": "CREDENTIAL_INVALID",
    "message": "The social account's token was revoked upstream.",
    "data": { "platform": "instagram", "platformCode": "OAuthException" }
  },
  "createdAt": "2026-04-19T13:55:01Z",
  "updatedAt": "2026-04-19T14:00:25Z"
}

Status values

statusTerminal?Meaning
queuednoWaiting for scheduledFor, or waiting on approval.
publishingnoLayers is actively uploading media and calling the platform API.
draftyesmode: draft — draft landed in the user's mobile app (TikTok inbox / IG SMS); they finish posting by hand. Terminal from Layers' side. The write-side mode and read-side status share the same string — no translation table needed.
publishedyesexternalId is populated. externalUrl is populated on TikTok unconditionally and on Instagram when the publisher captured a permalink from the Graph API (see Instagram callout below).
failedyeslastError is populated.
canceledyesYou or a token revocation canceled it.

externalUrl for Instagram. Instagram permalinks use an opaque shortcode (/p/<shortcode> or /reel/<shortcode>) that can't be derived from the numeric externalId. The publisher fetches the permalink from the Graph API's ?fields=permalink follow-up after a successful publish and surfaces it as externalUrl. In rare network-blip cases that fetch fails — the post is still live and externalId + publishedAt populate normally, but externalUrl stays null. Open the IG mobile app for the connected account to view the post manually. TikTok is always populated when externalId is — no equivalent edge case.

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing or invalid key.
403FORBIDDEN_SCOPEKey lacks publish:read.
404NOT_FOUNDPost not in your organization.

See also

On this page