# Posting queues

Weekly posting times per profile, and posts that take the next free one.

## The week [#the-week]

Each profile has its own posting times, such as Monday, Wednesday and Friday at 09:00, read in the profile's time zone. 09:00 stays 09:00 across summer time. Set the whole week in one call (`set_queue` in MCP, scope `accounts:write`):

```bash
curl -X PUT https://api.rizamo.com/v1/profiles/prof_.../queue \
  -H "Authorization: Bearer $RIZAMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "slots": [
      { "weekday": "mon", "time": "09:00" },
      { "weekday": "wed", "time": "09:00" },
      { "weekday": "fri", "time": "09:00" }
    ]
  }'
```

- Days are `mon` to `sun`, times `HH:mm`. At most 24 times a day, each once. An empty list empties the queue.
- Changing the week, or the profile's time zone, moves no post already queued.

## Queue a post [#queue-a-post]

Create or update a post with `"queue": true` instead of a `scheduledAt`. It takes the soonest posting time when none of its accounts has a post at that minute, and none would go over its network's daily cap. The answer's `scheduledAt` is the time it took, and `queued` is `true`.

```bash
curl https://api.rizamo.com/v1/posts \
  -H "Authorization: Bearer $RIZAMO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "profileId": "prof_...",
    "targets": [{ "accountId": "acc_..." }],
    "text": "Fresh bread at 9.",
    "mediaIds": ["med_..."],
    "queue": true
  }'
```

The image is media you added first, as in the [Quickstart](/quickstart): Instagram and TikTok take no post without an image or a video. A TikTok target also needs the person's own choices in its `options.tiktok`.

- Times are taken per account: an Instagram-only post and a TikTok-only post can share Monday 09:00, and a post to both takes it for both.
- Every scheduled post takes its accounts' minute, queued or not.
- Posts queued at once each take a different time.
- A deleted or rescheduled post frees its time for the next one. Nothing else moves.
- With no posting times the answer is `queue_empty`; with none free in the next 90 days, `queue_full`. Both are 409.
- A queued post goes out like any scheduled one, with a `post.scheduled` event and webhook that carry `queued: true`. Queued again later, or given a time of its own, it writes `post.updated` with its `scheduledAt` and `queued`.
- `POST /v1/posts/validate` with `"queue": true` answers the `scheduledAt` the post would take now, without taking it.

## Read the queue [#read-the-queue]

`GET /v1/profiles/{id}/queue?count=10` (`get_queue`, scope `accounts:read`) gives the time zone, the week, the next free times with the accounts free at each, and the next 100 queued posts still to go out. A key or agent sees those posts only with `posts:read` too. The free times are for showing: to take one, create the post with `"queue": true`, never by copying a time into `scheduledAt`.

## With an agent [#with-an-agent]

Agents use the queue unless you name a time. Ask Claude, ChatGPT or n8n's AI Agent:

> Draft three posts from our latest blog article for Café Lisboa and add them to the queue.

It calls `create_post` with `queue: true` for each, and tells you when each one goes out.
