Every post gets a request_id, and a scheduled one a job_id too. Pass either to see the post's overall state and each network's result. Use it after a post moved to the background, after a scheduled time, or after a retry.
Check a post
curl "https://api.reelspan.com/v1/posts/status?request_id=9b1f6c2e8a3d4f50b7e1c9a2d6f3e8b1" \
-H "Authorization: Bearer $REELSPAN_API_KEY"import { Reelspan } from 'reelspan';
const reelspan = new Reelspan();
const status = await reelspan.posts.status({ requestId: '9b1f6c2e8a3d4f50b7e1c9a2d6f3e8b1' });from reelspan import Reelspan
reelspan = Reelspan()
status = reelspan.posts.status(request_id="9b1f6c2e8a3d4f50b7e1c9a2d6f3e8b1")For a scheduled post, send job_id=sched_… instead ({ jobId } in Node, job_id= in Python). Without either, the answer is 400; an id that doesn't exist, or belongs to a profile your key can't use, is 404 with "status": "not_found".
{
"success": true,
"request_id": "9b1f6c2e8a3d4f50b7e1c9a2d6f3e8b1",
"job_id": null,
"external_id": "campaign-42",
"status": "in_progress",
"completed": 2,
"total": 3,
"results": [
{
"platform": "tiktok",
"success": true,
"status": "completed",
"message": "Published",
"upload_timestamp": "2026-12-01T09:00:41.000Z",
"platform_post_id": "7441…",
"post_url": "https://www.tiktok.com/@mybrand/video/7441…",
"error_message": null,
"error_code": null,
"warnings": [],
"post_id_resolved_late": false
},
{
"platform": "instagram",
"success": false,
"status": "skipped",
"message": "Profile my-brand has no Instagram account configured",
"upload_timestamp": "2026-12-01T09:00:02.000Z",
"platform_post_id": null,
"post_url": null,
"error_message": "Profile my-brand has no Instagram account configured",
"error_code": "profile_platform_mapping_invalid",
"warnings": [],
"post_id_resolved_late": false,
"skipped": true,
"skip_reason": "profile_platform_not_configured"
}
],
"last_update": "2026-12-01T09:00:41.000Z"
}Overall status
status |
Meaning |
|---|---|
pending |
Waiting: scheduled for later, or not started yet. |
in_progress |
At least one network has started or finished, and at least one hasn't. |
completed |
Every network has finished and at least one went live. |
failed |
Every network has finished and none went live. |
cancelled |
A scheduled post that was cancelled. |
completeddoesn't mean every network succeeded. Read each result'ssuccess, or compare the count of successes withtotal.
completed and total count networks: how many have finished, and how many the post has. A post made with a test key also carries "test": true.
Each network's result
results lists only the networks that have finished, so it grows as the post goes out. A network finishes in one of three ways:
completed: live.post_urlandplatform_post_idsay where.failed: the network refused it, or kept failing.error_messageanderror_codesay why; see Errors.skipped: never tried, with askip_reason. Most often the profile has no account on that network, or it needs reconnecting. A skipped network isn't charged.
warnings lists what changed on the way, such as links removed on X or a first comment that couldn't be posted. post_id_resolved_late is kept for Upload-Post compatibility and is always false.
While a network is still working it isn't in results. A temporary error (a network timing out, a rate limit) is retried on its own a few times, about 15, 30 and 60 seconds apart, before it counts as failed. History shows networks still working under in_progress.
Polling
Poll every 5 seconds or more, and stop once status is completed, failed or cancelled. The SDKs do it for you:
const done = await reelspan.posts.wait(requestId, { intervalMs: 5000, timeoutMs: 600_000 });done = reelspan.posts.wait(request_id, timeout=600, interval=5)Both return the last status they saw, finished or not, when the timeout passes.
Rather than polling, set a webhook: Reelspan sends an
upload_completedevent as each network finishes.
Lost the answer?
If the network dropped before you got a request_id, you can still find the post:
- Send your own
request_id(8 to 100 letters, digits,_or-) with the post, and poll that. - Or send an
external_idand look it up in History with?external_id=. - Or send an
Idempotency-Keyand repeat the request: it returns the first one's state instead of posting again. See Retrying safely.