Scheduling publishes a post at a time you choose. Send scheduled_at with POST /v1/posts, and SocialAPI holds the post and sends it to each target when the time arrives. Every platform accepts scheduled_at: SocialAPI does the waiting, not the platform.
A scheduled post costs 1 post credit when you create it, whatever the number of targets. Editing and cancelling cost nothing. See Plans and usage.
Endpoints
Schedule a post
Set scheduled_at to an RFC 3339 time in the future and name at least one target:
Response (HTTP 201):
The post is scheduled and each target is pending. SocialAPI sends post.scheduled when the post is created.
- Time: with at least one target, a
scheduled_at in the past returns 400 validation.field_invalid. With no targets, the post is saved as a draft. A value that is not RFC 3339 returns 400 validation.field_invalid. Include the UTC offset or Z.
- One time per target: a target can set its own
scheduled_at, which overrides the post’s. The post’s scheduled_at is the earliest of them.
- Without targets: a post with no targets is saved as a draft, even with
scheduled_at.
- Both flags: when you send
publish_now and scheduled_at together, the post is scheduled.
- Validation: SocialAPI validates the post when you schedule it, so a violation returns
400 publishing.validation_failed immediately, and validates the post again when its time arrives.
- Allowance: at the post allowance, scheduling returns
429 validation.post_limit_exhausted and creates nothing.
Stagger targets
Add stagger to publish the targets one after another, with a random gap between them, instead of all at the same time. Set min_seconds and max_seconds in whole seconds:
The first target publishes at scheduled_at. Each next target publishes a random delay between min_seconds and max_seconds after the previous one, in the order the targets are listed. With 4 targets and a 60 to 300 second gap, the times are, for example, 10:00:00, 10:02:41, 10:03:52, and 10:08:30. Read each target’s planned time from targets[].scheduled_at with GET /v1/posts/{pid}.
- Immediate start: with
publish_now: true and no scheduled_at, the first target publishes now and the others follow. The response still has status: "scheduled", because the later targets are still waiting.
- Fixed gap: set
min_seconds equal to max_seconds.
- Explicit target times: a target that sets its own
scheduled_at keeps that time and is left out of the sequence. It does not move the targets after it.
- Required: a post that would be saved as a draft (no
scheduled_at and no publish_now) cannot use stagger. It returns 400 validation.field_invalid with meta.field set to stagger.
- Bounds:
0 <= min_seconds <= max_seconds <= 86400. A value outside them returns 400 validation.field_invalid.
- Cost: 1 post credit for the whole post.
- Results: the post settles through the usual
post.published, post.partial, and post.failed events.
- Rescheduling:
PATCH /v1/posts/{pid} with a post-level scheduled_at moves every target to that single time and removes the spread. To keep a spread, send a scheduled_at on each target.
- Where it applies:
stagger applies only to POST /v1/posts. PATCH /v1/posts/{pid}, POST /v1/posts/{pid}/publish, and POST /v1/posts/validate ignore it, and CSV import has no column for it.
How a scheduled post moves through statuses
A scheduled post keeps the status scheduled while it waits for its time and while SocialAPI sends it, until every target has settled. While SocialAPI sends it, each target shows publishing. The post then becomes published, partial, or failed, and SocialAPI sends one post.published, post.partial, or post.failed event. The statuses and the per-target fields are in Track post delivery.
Edit or reschedule
PATCH /v1/posts/{pid} changes a scheduled post. A new time or target list takes effect at once.
The response is HTTP 200 with the updated post. SocialAPI sends post.updated with changed_fields. An edit to the content or targets runs validation again. A post in any status other than draft, scheduled, or failed returns 409 post.state_invalid. Publish a post lists every editable field.
Publish now
POST /v1/posts/{pid}/publish sends a scheduled post immediately. It costs 1 post credit again, on top of the credit the scheduling cost. The response is HTTP 201 and the post is publishing. A post that is published, partial, or failed returns 409 post.state_invalid.
Cancel a scheduled post
DELETE /v1/posts/{pid} cancels a scheduled post: SocialAPI removes the post and sends nothing. The response is HTTP 200 with {"success": true, "deleted": true}, and SocialAPI sends post.deleted. The post credit is not returned. Deleting a post that is already publishing returns 409 post.state_invalid. See Delete a post.
Posting caps can delay a scheduled post
SocialAPI caps how many posts one account publishes per hour and per 24 hours, by platform. A scheduled post that reaches a cap is not failed. The target stays pending, and SocialAPI publishes it when the cap window clears, so the post goes out later than scheduled_at. The caps and their values are in Rate limits. Immediate publishes that reach a cap return 429 publishing.velocity_limit instead.
When a scheduled post fails
SocialAPI makes one delivery attempt per target at the scheduled time. A failed attempt is final: the target becomes failed with its error, the post becomes failed or partial, and SocialAPI sends one post.failed or post.partial event. Nothing is re-sent automatically. A scheduled post’s credit is not returned when it fails.
Common causes are a disconnected account (publishing.delivery.account_load_failed), an account that lost the posts.write permission (account.permission_missing), content that stopped passing validation (validation.publish), and a platform refusal (platform.{platform}.*). The causes are in Track post delivery.
To send a failed post again, fix the cause, optionally edit the post, and call POST /v1/posts/{pid}/retry. It re-sends only the failed targets and costs 1 post credit.
A scheduled post still publishes when your SocialAPI account is past due. See Past-due accounts.
YouTube has 2 schedulers
On YouTube, scheduled_at makes SocialAPI upload the video at that time, and platform_data.youtube.publish_at uploads it now and lets YouTube make it public later. See Schedule a YouTube post.
Read scheduling support from the API
GET /v1/posts/validate returns scheduling.supported for each platform it covers. It is true for each of them. See Publish a post.
Scopes
Use from an AI agent
Last modified on October 19, 2026