logo
Schedulin Developers

Queue a post

Each channel can have a weekly posting schedule (its queue), set up in the dashboard or through the API. Instead of picking a time yourself, let Schedulin put the post in the next free slot.

Set the queue schedule

GET /v0/social-accounts/{id}/queue-schedule returns the channel's schedule. PUT /v0/social-accounts/{id}/queue-schedule replaces all of it — send every slot you want to keep, or "times": [] to clear the queue. Each slot is a weekday (0 = Sunday … 6 = Saturday), a wall-clock time (HH:MM, 24h) in the channel's timezone, and an optional capacity (how many posts the slot holds, 1-10, default 1) and label. Posts that are already scheduled keep their times.

curl -X PUT https://api.schedulin.app/v0/social-accounts/acc_123/queue-schedule \
  -H "x-api-key: $SCHEDULIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "times": [
      { "weekday": 2, "time": "09:00" },
      { "weekday": 2, "time": "13:00", "capacity": 2 },
      { "weekday": 4, "time": "09:00", "label": "Thursday tips" }
    ]
  }'
{
  "timezone": "America/New_York",
  "times": [
    { "weekday": 2, "time": "09:00", "capacity": 1, "label": null },
    { "weekday": 2, "time": "13:00", "capacity": 2, "label": null },
    { "weekday": 4, "time": "09:00", "capacity": 1, "label": "Thursday tips" }
  ]
}
const schedule = await client.socialAccounts.getQueueSchedule({ id: "acc_123" });
await client.socialAccounts.replaceQueueSchedule({
  id: "acc_123",
  times: [...schedule.times, { weekday: 5, time: "17:30" }],
});
schedule = client.social_accounts.get_queue_schedule("acc_123")
client.social_accounts.replace_queue_schedule(
    "acc_123",
    times=[*schedule.times, {"weekday": 5, "time": "17:30"}],
)

A repeated weekday + time pair, a malformed time, or an out-of-range value is rejected with 422 and the existing schedule is left as it was.

Preview the next slots

GET /v0/social-accounts/{id}/next-slots returns upcoming free slot times in UTC, computed from the channel's queue schedule, per-slot capacity, and timezone. limit (default 5, max 50) controls how many; after (ISO 8601) starts the search from a later time.

The channel's timezone (which the schedule's times are read in) can be changed with PUT /v0/social-accounts/{id}/timezone ({ "timezone": "America/New_York" }). It must be a valid IANA time zone name; anything else (Eastern Time, GMT+2, a typo) is rejected with 422.

curl "https://api.schedulin.app/v0/social-accounts/acc_123/next-slots?limit=3" \
  -H "x-api-key: $SCHEDULIN_API_KEY"
{
  "slots": [
    "2026-06-02T09:00:00.000Z",
    "2026-06-02T13:00:00.000Z",
    "2026-06-03T09:00:00.000Z"
  ]
}
const { slots } = await client.socialAccounts.nextSlots({ id: "acc_123", limit: 3 });
slots = client.social_accounts.next_slots("acc_123", limit=3).slots

slots is empty when the channel has no queue times configured.

Add a post to the queue

Create the post with action: "queue" and no scheduledAt. It's scheduled for the next free slot:

curl -X POST https://api.schedulin.app/v0/posts \
  -H "x-api-key: $SCHEDULIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "socialAccountId": "acc_123",
    "caption": "Tip of the day: batch your content on Mondays.",
    "action": "queue"
  }'
const post = await client.posts.create({
  socialAccountId: "acc_123",
  caption: "Tip of the day: batch your content on Mondays.",
  action: "queue",
});
post = client.posts.create(
    social_account_id="acc_123",
    caption="Tip of the day: batch your content on Mondays.",
    action="queue",
)

The response has status: "SCHEDULED" and the chosen scheduledAt. If the channel has no free slot, the request fails with 400 ("No available queue slot found for this social account.") — fall back to action: "schedule" with an explicit scheduledAt, such as one of the slots above.