Content Calendar

Approval workflow

How to use the optional draft → review → approved → scheduled workflow.

The Content Engine includes an optional approval workflow that lets a reviewer check content before it goes live. This is useful for teams where a junior member creates posts and a senior member approves them, or for brand compliance review.

Overview

draft ──[submit]──► pending_review ──[approve]──► approved ──► scheduled

                         └──[reject]──► draft

The workflow is optional. You can bypass it by creating a slot with status: "scheduled" directly (requires content:slots.write permission).

Step 1: Create as draft

Create a slot without setting a status (it defaults to draft) or explicitly set status: "draft":

POST /content/slots
Content-Type: application/json
 
{
  "caption": "New feature announcement",
  "contentType": "text",
  "scheduledAt": "2026-07-15T09:00:00Z",
  "timezone": "Asia/Kolkata",
  "targets": [{ "connectionId": "conn_twitter_abc123" }],
  "status": "draft"
}

The slot exists in the system but no alarm is armed yet.

Step 2: Submit for review

When the content is ready for a reviewer:

POST /content/slots/:slotId/submit-review

No body required. The slot transitions to pending_review. Reviewers can now see it in the Pending review queue.

Step 3: Approve or reject

A user with the content:slots.approve permission can approve or reject.

Approve:

POST /content/slots/:slotId/approve

The slot transitions:
pending_review → approved → scheduled

Both transitions happen immediately in one call. The Durable Object alarm is armed at scheduledAt. The slot will publish automatically at that time without any further action.

Reject:

POST /content/slots/:slotId/reject
Content-Type: application/json
 
{ "approvalNote": "Caption is too long for LinkedIn — please shorten to 3000 chars" }

The slot returns to draft. The rejection note is stored on the slot and visible to the content creator.

Permissions

Action Required permission
Create slot (draft) content:slots.write
Submit for review content:slots.write
Approve content:slots.approve
Reject content:slots.approve
Create slot as scheduled (bypass workflow) content:slots.write

Skipping the workflow

Not all organizations need approval. If everyone on your team should be able to schedule directly:

  • Create slots with status: "scheduled" in the body — the workflow steps are skipped entirely
  • The slot goes directly to scheduled and the alarm is armed immediately

Notes

  • A pending_review slot can still be edited — but only by returning it to draft first (reject, then edit, then re-submit)
  • A scheduled slot can be rescheduled to a different time without re-approval
  • Approved slots that pass their scheduledAt without being cancelled will fire regardless of whether they were ever reviewed — the approval is recorded as a past event, not a gate at fire time
Content Engine · Content CalendarEdit on GitHub