Skip to content

Scheduling

Scheduling is one field. Set schedule_at on create or patch, and MissLess publishes the post at that time from its own scheduler. Your servers do not need to be up.

  • ISO-8601 with a timezone designator. Use UTC: "2026-09-01T09:00:00Z". An offset such as +02:00 is accepted and converted.
  • Must be in the future at the time of the call, otherwise validation_error on field: "schedule_at".
  • The workspace timezone does not change how schedule_at is read. It is used by the widget to show and pick times in the customer’s local time. Convert in your own UI before sending.

Scheduled posts go out within a minute of the requested time.

POST /posts
|
+------------+------------+
| | |
status:draft schedule_at neither
| | |
v v |
draft ----> scheduled |
| | |
| publish | due |
+-----+------+------------+
|
v
publishing <-- wait=true holds here for up to 25 s
|
+--------+--------+
| | |
published partial failed
|
| PATCH, then POST /posts/:id/publish
v
publishing (attempts + 1)
scheduled --DELETE--> canceled
Status Meaning
draft Saved. Nothing will happen on its own
scheduled Will publish at schedule_at
publishing A publish run is in progress. Targets are pending until the network answers
published Every target succeeded. published_at is the time of the last target
partial At least one target succeeded and at least one failed
failed Every target failed. last_error has the most recent reason
canceled You deleted it while it was scheduled

published and canceled are final. failed and partial can be patched and published again: a publish run only sends the targets that are not yet published, so a retry never posts twice.

A post with two targets is two publish calls to Meta. When one succeeds and the other fails you get partial, a post.partial webhook, and the detail per target:

{
"status": "partial",
"targets": [
{ "account": "acig4h2k5m7p9r1", "network": "instagram", "status": "published", "permalink": "https://www.instagram.com/p/C_abc123/", "error": null },
{ "account": "acfb8n2c4v6b1m3", "network": "facebook", "status": "failed", "permalink": null, "error": "(#200) The user hasn't authorized the application to perform this action" }
]
}

Store the result per target on your side, not per post. To retry, call POST /v1/posts/:id/publish (after a PATCH if something needs fixing): only the failed target is sent again, the target that is already published is skipped, so nothing is posted twice. attempts goes up by one per run.

PATCH /v1/posts/:id works while the post is scheduled. Move it by patching schedule_at, change the caption, media, targets or options. The scheduler picks up the new values at the new time. Patching after the post entered publishing returns conflict (409).

DELETE /v1/posts/:id on a scheduled post cancels it. The post stays readable with status: "canceled" so your calendar can show what was cancelled. Delete a draft and it is gone.

  1. Read last_error and the failing targets[].error.
  2. Fix the cause: reconnect the account, replace the media, shorten the caption.
  3. PATCH what changed, if anything.
  4. POST /v1/posts/:id/publish, with ?wait=true if you want the answer inline.

attempts increments on every run. There is no automatic retry after a failed outcome; the decision is yours.

Keep the workspace timezone correct. Set it on POST /v1/workspaces and patch it when the customer moves. The widget’s calendar and composer show times in that zone, and your own calendar should too, so the two never disagree about when a post goes out.