---
title: "Start scheduling posts"
method: POST
path: "/api/apps/{app_id}/social-calendar/posts/schedule"
---

# Start scheduling posts

`POST /api/apps/{app_id}/social-calendar/posts/schedule`

<Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

Hands the app's approved posts to the publisher, so each one goes out at its own scheduled time.

The work runs in the background. Poll [Get scheduling job](/api-reference/get-scheduling-job) with the returned `job_id` to see how it went. Starting a second run for the same app while the first one is still starting is refused.

Calling it again for the same window normally returns the job already in flight instead of starting a second one, but treat that as best-effort rather than a guarantee. A retry sent in the moment before the job starts running can come back with a new `job_id`. Nothing is published twice when that happens, because both runs resolve the same automation for a given post.

It takes the posts whose `scheduled_at` falls in `[scheduled_from, scheduled_until)` and that aren't handed over yet, which means the posts you approved plus the ones an earlier run couldn't place. A post still in [`proposal`](/developers/references/apps-api/sections/virality#scheduled-posts) isn't taken at all, so approve it first.

Placing a post can fail for reasons this endpoint can't check up front, and each one is counted in the job's `result` rather than failing the request:

- The workspace is on the free plan. Publishing scheduled posts needs a paid workspace plan, and those posts are counted in `plan_limited`.
- The app has no connected account for the post's platform with publishing permission, or it has more than one. Those posts move to `needs_reconnect` and are counted there, and a later run picks them up once you fix the connection.
- The post's platform can't be published to at all, or its scheduled time has already passed. Those posts move to `failed`, which is final.

## Path parameters

- `app_id` string, required — ID of the app whose social calendar you want.

## Request body

- SchedulePostsRequest
  - `scheduled_from` string, date-time, required — Start of the range to schedule, inclusive, as an ISO 8601 timestamp carrying an offset.
  - `scheduled_until` string, date-time, required — End of the range, exclusive, as an ISO 8601 timestamp carrying an offset. It has to be later than `scheduled_from`.

## Response `202`

The scheduling job that is now running, or the one already in flight for this range.

- SchedulePostsResponse
  - `job_id` string, required — ID of the scheduling job. Pass it as `job_id` to [Get scheduling job](/api-reference/get-scheduling-job).
  - `status` string, required — State of the job. Either `pending`, `running`, `completed`, or `failed`. See [Scheduling jobs](/developers/references/apps-api/sections/virality#scheduling-jobs) for what each value means. A range holding nothing to schedule comes back `completed` straight away.

## Other responses

- `401` — Missing or invalid credentials.
- `403` — You don't have editor access to this app, or you used a workspace API key.
- `404` — App not found, or the social calendar is not enabled for your account.
- `409` — Scheduling is already starting for this app. Retry the request.
- `422` — The request body is missing `scheduled_from` or `scheduled_until`, sends a field this endpoint doesn't accept, sends a timestamp with no offset, sends `scheduled_from` on or after `scheduled_until`, or the range holds more than 100 posts to schedule.
- `429` — Rate limit exceeded (40 requests per minute), shared across every social calendar endpoint except the ones that create, edit, delete, or approve posts. See [Rate limits](/developers/references/apps-api/get-started/rate-limits).

---

[API](https://skmtc.dev/base44/apis/base44-app-management-api.md) · [All operations](https://skmtc.dev/base44/apis/base44-app-management-api/llms.txt) · [OpenAPI document](https://skmtc.dev/base44/apis/base44-app-management-api/revisions/cf164639a9bf?raw)
