Scheduling
Hand over a time and close the session. The queue runs on our side, so nothing depends on your agent still being awake at nine on Saturday morning.
Queue a post
Add scheduled_time to the same create_post call you would use to publish immediately. Times are ISO 8601; a naive timestamp is read as UTC, so say what you mean:
create_post(
account_id="acct_x",
text="ship notes",
media_urls=["https://…/render.mp4"],
scheduled_time="2026-08-01T09:00:00Z",
)
→ { "schedule_id": "sch_7f2", "status": "scheduled" }See, move and cancel
list_schedules returns what is still queued, get_schedule a single entry, update_schedule moves it, and delete_schedule cancels it. A post that has already gone out is no longer a schedule — it is a post, and list_posts has it. Asking to cancel one returns schedule_not_found rather than pretending to unpublish something.
The calendar is the same queue in a month grid, if you would rather drag than call.
What a retry can and cannot duplicate
post_image and post_video are deduplicated on the pair of job and account. Retry one — a dropped connection, a loop that ran twice — and the first post comes back rather than a duplicate going out. Prefer this path whenever you are publishing something we rendered: hand over the job_id, not the URL of its asset.
create_post takes media_urls, so there is no job to deduplicate on and no key that makes two calls one. If it times out, check list_posts or list_schedules before sending it again. We would rather say this plainly than let you find out from your audience — a double post is public and cannot be taken back cleanly.
Scheduling is free
Queueing, moving, cancelling and the eventual publish cost no credits. Only the render did. See Credits & billing.
Publish only a finished job
post_image and post_video take a job id directly, and refuse with job_not_ready if that job has not succeeded yet — rather than scheduling a post whose media may never exist. Poll get_job first; polling is free.