Docs › API reference › Queue

Queue API: weekly times and next free slots

Set your weekly posting times, read the next free ones, and send a post to the queue with queue true.

Updated

The queue is a weekly list of posting times, such as "Monday 09:30" and "Thursday 18:00", in one time zone. A post sent to the queue takes the next time in the list that is still free. For the idea behind it, see Calendar and queue.

GET /v1/queue

Read the queue

GET /v1/queue returns your schedule and the next free times.

Field Meaning
timezone An IANA time zone name, such as Europe/London. A new organization has no times and the zone is UTC until you set one
slots The weekly times. day is mon, tue, wed, thu, fri, sat or sun. time is local time as HH:MM in 24-hour time
upcoming The next free times as UTC instants, earliest first. At most 5. A time already taken by a queued post is skipped
curl https://omniposts.dev/v1/queue \
  -H "Authorization: Bearer omniposts_..."
{
  "timezone": "Asia/Kolkata",
  "slots": [
    { "day": "mon", "time": "09:30" },
    { "day": "thu", "time": "18:00" }
  ],
  "upcoming": [
    "2026-10-15T12:30:00Z",
    "2026-10-19T04:00:00Z"
  ]
}

PUT /v1/queue

Set the queue

PUT /v1/queue replaces the whole schedule. Send both fields every time; the list you send is the new schedule.

The answer is 200 with the schedule as stored, in the same shape as GET /v1/queue.

  • slots is required. Send [] to clear the schedule. Leaving it out is 400 invalid_request, so that a mistake cannot empty your queue.
  • timezone must be a valid IANA name. An unknown or empty one is 400 invalid_request.
  • Each slot needs a valid day and a time like 09:30. A bad value is 400 invalid_request with a message that says what is wrong.
  • A schedule holds at most 56 times. Duplicate times count once.
  • A key can set the queue. You do not need a signed-in person.

Changing the schedule does not move posts already in the queue. They keep the time they were given.

curl -X PUT https://omniposts.dev/v1/queue \
  -H "Authorization: Bearer omniposts_..." \
  -H "Content-Type: application/json" \
  -d '{
    "timezone": "Asia/Kolkata",
    "slots": [ { "day": "mon", "time": "09:30" }, { "day": "thu", "time": "18:00" } ]
  }'

Time zones and daylight saving

Slots are local times, so a 09:30 slot stays 09:30 on the clock when your clocks change. A time that does not exist on the day clocks go forward (for example 02:30 when 02:00 jumps to 03:00) moves later by the length of the gap. When clocks go back and a time happens twice, the first one is used.

Send a post to the queue

Create a post with "queue": true instead of scheduledFor. See Posts for the full request.

How the slot is picked:

  • OmniPosts takes the earliest slot that is at least one minute from now and that no other live queued post holds.
  • It looks up to 12 weeks ahead.
  • One post holds one slot. Two queued posts never share a time.
  • A post holds its slot until it can no longer be sent. Cancelling a post frees its slot. So does a post that failed before its time because every channel was cancelled or rejected.

The response has queued: true and scheduledFor set to the slot. You can also queue a draft: POST /v1/ideas/{id}/promote accepts queue: true too.

curl https://omniposts.dev/v1/groups \
  -H "Authorization: Bearer omniposts_..." \
  -H "Idempotency-Key: queued-post-2" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Next slot, please.", "queue": true, "targets": [{ "channelId": "CHANNEL_ID" }] }'

Errors

Status and code Meaning
422 queue_empty You have no posting times. Set some with PUT /v1/queue, or send a scheduledFor
422 queue_full Every posting time in the next 12 weeks is taken. Add more times or send a scheduledFor
400 invalid_request queue: true together with scheduledFor

Setting a time by hand leaves the queue

If you edit a queued post and set a new scheduledFor, the post leaves the queue: queued becomes false and its slot is free for another post. The time you set is used exactly as given and does not have to match any slot.