---
title: "Approve scheduled posts"
method: POST
path: "/api/apps/{app_id}/social-calendar/posts/approve"
---

# Approve scheduled posts

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

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

Approves calendar posts, moving each one from `proposal` to `scheduled`.

Approving doesn't publish anything and doesn't reserve anything. It marks which posts you want sent, and [Start scheduling posts](/api-reference/start-scheduling-posts) is what hands them to the publisher.

Approval is a selection, so one unusable id never discards the rest. The request succeeds with a 200 even when no id could be approved, and the response reports each one: `approved` for the posts that are now `scheduled`, `not_found` for ids that name no live post of this app, and `rejected` for posts past the point of approval, each with the status that blocked it. Repeated ids are collapsed, and re-approving a post that's already `scheduled` reports it under `approved` without changing anything, so calling twice returns the same body.

Send between 1 and 50 ids.

The social calendar endpoints share two rate limits: 20 requests per minute across creating, editing, deleting and approving posts, and 40 requests per minute across the rest. This endpoint counts against the 20.

<Note>This endpoint accepts a personal API key. Workspace API keys are not authorized for it and are rejected with a 403.</Note>

## Path parameters

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

## Request body

- ApprovePostsPayload
  - `post_ids` string[], required — IDs of the posts to approve, 1 to 50 of them, as returned by [List scheduled posts](/api-reference/list-scheduled-posts). Repeated ids are collapsed.

## Response `200`

The outcome of each id you sent.

- ApprovePostsResult — Per-id outcome of an approve call. Approval is a selection, so one unusable id must not discard the rest: valid rows transition and the others are reported. Re-approving a row that is already `scheduled` lands in ``approved`` without a write, which makes a repeated call return the same body as the first.
  - `approved` string[] — IDs of the posts that are now `scheduled`, including any that already were.
  - `not_found` string[] — IDs that name no live post of this app, because the post never existed or was deleted.
  - `rejected` RejectedPost[] — Posts that are past the point of approval, each with the status that refused it.
    - `id` string, required — ID of the post that couldn't be approved.
    - `status` 'proposal' | 'scheduled' | 'publishing' | 'publish_outcome_unknown' | 'needs_reconnect' | 'not_materialized_plan_limit' | 'paused' | 'posted' | 'failed' | 'deleted', required

## 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.
- `422` — Validation Error
- `429` — Rate limit exceeded (20 requests per minute).

---

[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-service-production.skmtc.workers.dev/v1/apis/base44/base44-app-management-api/revisions/173e4e9c63c2/schema)
