Skip to content

Drafts and approvals API ​

Drafts hold a post that is not live. Approvals add a review step: a draft moves to pending_approval, and someone with approval rights either publishes it or sends it back. This is the safe path for AI agents, because a key with require-approval turned on can create and submit posts but cannot publish them.

All paths are under /api/content. Authentication and workspace selection work as described in the REST API overview.

What is the draft and approval lifecycle? ​

saveDraft: true  -->  draft  --submit-for-approval-->  pending_approval
                       ^                                   |
                       |------------- reject --------------|
                                                           |
                                      approve  -->  publishes (or schedules)
StatusMeaning
draftSaved, not live. Editable.
pending_approvalWaiting for a reviewer.
pendingScheduled for a future time, or just approved and dispatching.

How do I save a draft with the API? ​

Add "saveDraft": true to any create request. Media is still uploaded, and no job is queued.

bash
curl -X POST https://api.socifyr.com/api/content/text \
  -H "Authorization: Bearer sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "connections": ["linkedin-mybrand"],
    "text": "Draft: Q4 roadmap announcement",
    "saveDraft": true
  }'
json
{ "success": true, "data": { "success": true, "draftId": "6a05032a84584482ace13d52" } }

Saving a draft does not count against the monthly upload limit and does not use a key's daily post limit. Body parameters are listed in Content API. Edit a draft with PATCH /content/:id, and publish it with POST /content/:id/publish. See the drafts guide.

How do I submit a draft for approval? ​

POST /content/:id/submit-for-approval, no body. Needs post.create. A guarded key may call it, but only for drafts that key created.

bash
curl -X POST https://api.socifyr.com/api/content/6a05032a84584482ace13d52/submit-for-approval \
  -H "Authorization: Bearer sk_..."
json
{
  "success": true,
  "data": { "success": true, "id": "6a05032a84584482ace13d52", "status": "pending_approval" }
}
StatusCauseFix
404Content not foundCheck the ID and workspace.
409Only a draft can be submitted for approvalThe post is not in draft.
403A guardrail limit was reached when the key submittedSee guardrails.

When a key with a daily post limit or X spend cap submits a draft, that key's quota is reserved at submit time.

How do I approve a post? ​

POST /content/:id/approve, no body. Needs post.approve, which Editors, Admins and Owners have. It flips the post to draft and publishes it through the normal path, so the response is the same as publishing a draft (requestId, usage, message, scheduledAt, totalChannels). A post with a future scheduledAt is scheduled instead.

bash
curl -X POST https://api.socifyr.com/api/content/6a05032a84584482ace13d52/approve \
  -H "Authorization: Bearer sk_..."
json
{
  "success": true,
  "data": {
    "success": true,
    "requestId": "97005ec5-6361-4953-8a69-ce7292ad9f11",
    "usage": { "count": 8, "limit": 30, "remaining": 22 },
    "message": "Upload processing started",
    "scheduledAt": null,
    "totalChannels": 1
  }
}
StatusCause
404Content not found
409Content is not pending approval
403This API key requires approval and cannot approve posts — ... when a require-approval key calls it
403Your role does not have the 'post.approve' permission

How do I reject a post? ​

POST /content/:id/reject, no body. Needs post.approve. The post goes back to draft so the author can revise and resubmit.

json
{ "success": true, "data": { "success": true, "id": "6a05032a84584482ace13d52", "status": "draft" } }

Errors match approve: 404 Content not found, 409 Content is not pending approval.

Which routes can a require-approval key call? ​

A key with require-approval can create posts, but every post it creates (without saveDraft) lands in pending_approval and the create response says so. It is blocked from skipping review:

RouteRequire-approval key
POST /content/* (create)Allowed. Result is pending_approval.
POST /content/:id/submit-for-approvalAllowed.
PATCH /content/:idAllowed, drafts only.
POST /content/:id/publish403 ...cannot publish drafts directly...
POST /content/:id/publish-now403 ...cannot publish immediately...
POST /content/:id/approve403, and the route is not available to guarded keys.
POST /content/:id/reject403, and the route is not available to guarded keys.

How do I find posts waiting for approval? ​

GET /content/:id returns status: "pending_approval". The list endpoint's status filter does not accept pending_approval (it returns 400), so list posts without that filter and look for the status in each item.

Frequently asked questions ​

Can an agent approve its own post? No. A key with guardrails cannot call approve, and approve needs the post.approve permission from a member. Use a dashboard session or an unrestricted key.

Does rejecting delete the post? No. It returns to draft with its content intact.

Next steps ​