The queue saves you picking a time for every post. Each profile has a weekly schedule of slots; a post sent with add_to_queue=true takes the first slot that still has room.
Add a post to the queue
Send any post with add_to_queue=true instead of a scheduled_date:
curl -X POST https://api.reelspan.com/v1/posts/video \
-H "Authorization: Bearer $REELSPAN_API_KEY" \
-F "user=my-brand" \
-F "platform[]=tiktok" \
-F "platform[]=instagram" \
-F "title=Behind the scenes" \
-F "add_to_queue=true" \
-F "[email protected]"import { Reelspan } from 'reelspan';
import { readFile } from 'node:fs/promises';
const reelspan = new Reelspan();
const post = await reelspan.posts.video({
user: 'my-brand',
platforms: ['tiktok', 'instagram'],
title: 'Behind the scenes',
addToQueue: true,
video: { data: await readFile('launch.mp4'), name: 'launch.mp4', type: 'video/mp4' },
});from reelspan import Reelspan
reelspan = Reelspan()
post = reelspan.posts.video("my-brand", ["tiktok", "instagram"], "launch.mp4", "Behind the scenes", add_to_queue=True){
"success": true,
"job_id": "sched_7a2c9e4b1d6f40a8c3e5b9d2",
"request_id": "6e3b9d1f7a2c4e8b0d5f3a1c9e7b2d4f",
"scheduled_date": "2026-12-01T12:00:00.000Z",
"queue_slot": "2026-12-01T12:00:00.000Z",
"message": "Post added to queue"
}The answer is 202, and from then on it is an ordinary scheduled post: edit or cancel it by job_id. Giving it a scheduled_date later takes it out of the queue.
add_to_queueandscheduled_datecan't be used together (400).max_posts_per_sloton the post overrides the profile's setting for this one post (1 to 100).- The queue looks 30 days ahead. With no free slot in that time the answer is 400
QUEUE_FULL. - Two posts sent at once never take the same last place in a slot.
The schedule
Until you set one, every profile has this schedule:
{
"timezone": "America/New_York",
"slots": [{ "hour": 9, "minute": 0 }, { "hour": 12, "minute": 0 }, { "hour": 17, "minute": 0 }],
"days_of_week": [0, 1, 2, 3, 4, 5, 6],
"max_posts_per_slot": 1,
"full_slots": []
}| Setting | What it is |
|---|---|
timezone |
The IANA zone the slots are in. |
slots |
Up to 24 times of day, as hour (0 to 23) and minute (0 to 59). |
days_of_week |
The days the slots run, 0 = Monday to 6 = Sunday. |
max_posts_per_slot |
How many posts one slot holds, 1 to 100. |
full_slots |
Slots you marked full by hand (see below). |
Read it with GET /v1/queue/settings?profile_username=my-brand. Change it with POST /v1/queue/settings; send only what changes, and the rest stays:
curl -X POST https://api.reelspan.com/v1/queue/settings \
-H "Authorization: Bearer $REELSPAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"profile_username": "my-brand",
"timezone": "Europe/London",
"slots": [{ "hour": 8, "minute": 30 }, { "hour": 18, "minute": 0 }],
"days_of_week": [0, 1, 2, 3, 4]
}'await reelspan.queue.setSettings('my-brand', {
timezone: 'Europe/London',
slots: [{ hour: 8, minute: 30 }, { hour: 18, minute: 0 }],
days_of_week: [0, 1, 2, 3, 4],
});reelspan.queue.set_settings(
"my-brand",
timezone="Europe/London",
slots=[{"hour": 8, "minute": 30}, {"hour": 18, "minute": 0}],
days_of_week=[0, 1, 2, 3, 4],
)Duplicate slots are dropped and the list is sorted. Posts already in the queue keep their times when the schedule changes.
How full is each slot
GET /v1/queue/preview lists the next slots (10 by default, count up to 50) and how many posts each holds:
curl "https://api.reelspan.com/v1/queue/preview?profile_username=my-brand&count=3" \
-H "Authorization: Bearer $REELSPAN_API_KEY"const preview = await reelspan.queue.preview('my-brand');preview = reelspan.queue.preview("my-brand"){
"success": true,
"timezone": "Europe/London",
"max_posts_per_slot": 1,
"slots": [
{ "datetime_utc": "2026-12-01T08:30:00.000Z", "datetime_local": "2026-12-01T08:30:00", "available": false, "post_count": 1, "max_posts_per_slot": 1, "is_full": true, "manually_full": false },
{ "datetime_utc": "2026-12-01T18:00:00.000Z", "datetime_local": "2026-12-01T18:00:00", "available": true, "post_count": 0, "max_posts_per_slot": 1, "is_full": false, "manually_full": false },
{ "datetime_utc": "2026-12-02T08:30:00.000Z", "datetime_local": "2026-12-02T08:30:00", "available": true, "post_count": 0, "max_posts_per_slot": 1, "is_full": false, "manually_full": false }
],
"next_available": "2026-12-01T18:00:00.000Z"
}post_count counts every post of the profile scheduled for exactly that time, queued or not. A slot less than a minute away isn't offered.
For just the next free slot, GET /v1/queue/next-slot answers { "next_slot": { "datetime_utc", "datetime_local", "timezone" } }, or "next_slot": null when nothing is free in the next 30 days.
Keep a slot free
Mark a slot full and the queue skips it, for example to keep a launch slot for one hand-picked post. slot_datetime is the slot's time with an offset, as datetime_utc shows it:
curl -X POST https://api.reelspan.com/v1/queue/slot-full \
-H "Authorization: Bearer $REELSPAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"profile_username": "my-brand", "slot_datetime": "2026-12-01T18:00:00Z"}'await reelspan.queue.markFull('my-brand', '2026-12-01T18:00:00Z');
await reelspan.queue.markOpen('my-brand', '2026-12-01T18:00:00Z'); // open it againreelspan.queue.mark_full("my-brand", "2026-12-01T18:00:00Z")
reelspan.queue.mark_open("my-brand", "2026-12-01T18:00:00Z") # open it againBoth answer with full_slots, the slots now marked. DELETE /v1/queue/slot-full with the same body opens a slot again. Past slots drop off the list on their own.
Keys and scopes
Reading the queue needs the read scope; changing the schedule or marking slots needs profiles; adding a post needs publish.