GET /v1/scheduled-posts/:scheduledPostId
Read one scheduled post's status. Polling or webhooks — either works.
GET
/v1/scheduled-posts/:scheduledPostIdPhase 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).
Polling cadence: every 30 seconds while the status is queued, every 5 seconds while publishing, then stop once it reaches a terminal state (published, failed, or canceled). Or subscribe to webhooks to skip polling.
Path
scheduledPostIdstringrequiredId returned by schedule or publish.
Example request
curl https://api.layers.com/v1/scheduled-posts/sp_01HXZN4K5M6P7QRS8TUV9WXYZA \
-H "Authorization: Bearer lp_live_01HX9Y6K7EJ4T2_4QZpN..."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 new Promise((r) => setTimeout(r, post.status === "publishing" ? 5000 : 30000));
}
}import time
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"]))
time.sleep(5 if post["status"] == "publishing" else 30)Response
200Published
{
"id": "sp_01HXZN4K5M6P7QRS8TUV9WXYZA",
"containerId": "cnt_01HXZM3K4N5P6QRS7TUV8WXYZ9",
"socialAccountId": "sa_01HXZ9P2M4N5KLM6TUV7WXYZ9A",
"platform": "tiktok",
"mode": "direct_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_01HXZN4K5M6P7QRS8TUV9WXYZB",
"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
status | Terminal? | Meaning |
|---|---|---|
queued | no | Waiting for scheduledFor, or waiting on approval. |
publishing | no | Layers is actively uploading media and calling the platform API. |
draft_in_inbox | yes | mode: draft_to_device — draft landed in the user's mobile app; they finish by tapping post. Terminal from Layers' side. |
published | yes | externalId and externalUrl are populated. |
failed | yes | lastError is populated. |
canceled | yes | You or a token revocation canceled it. |
Errors
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHENTICATED | Missing or invalid key. |
| 403 | FORBIDDEN_SCOPE | Key lacks publish:write. |
| 404 | NOT_FOUND | Post not in your organization. |
See also
GET /v1/projects/:id/scheduled-posts— batch pollPOST /v1/scheduled-posts/:id/reschedule— changescheduledForDELETE /v1/scheduled-posts/:id— cancel while queued