Approvals Workflow
Approval queues, state transitions, batch vs item actions, and webhook events.
The Approvals API manages content review workflows. Use it to list pending approvals, take actions (approve/reject/reschedule), and track audit trails.
Approval Batches
Approval batches group generated content for team review. Each batch has:
- status:
pending,approved,rejected,partially_approved - priority:
low,medium,high - scheduled_for: when the content is scheduled to publish
- created_at: when the batch was created
Endpoints
List Approval Batches
List all approval batches awaiting action:
curl "$AIDELLY_API_BASE/approvals" \
-H "Authorization: Bearer $AIDELLY_API_KEY" \
-H "x-aidelly-workspace-id: $WORKSPACE_ID"Query Parameters:
status— filter by batch status (comma-separated:pending,rejected)priority— filter by priority (low,medium,high)automation_rule_id— filter by automation rulescheduled_after— batches scheduled after this ISO 8601 datescheduled_before— batches scheduled before this ISO 8601 datecreated_after— batches created after this ISO 8601 datecreated_before— batches created before this ISO 8601 datesort_by— field to sort by (default:created_at)sort_order—ascordesc(default:desc)page— pagination page (default: 1)limit— items per page, max 50 (default: 10)
Response:
{
"success": true,
"data": {
"batches": [
{
"id": "batch_uuid",
"status": "pending",
"priority": "high",
"automation_rule_id": "rule_uuid",
"scheduled_for": "2026-02-20T14:00:00Z",
"created_at": "2026-02-18T10:00:00Z",
"updated_at": "2026-02-18T10:00:00Z",
"generated_content": [
{
"id": "content_uuid",
"content_text": "Check out our new feature...",
"approval_status": "pending",
"created_at": "2026-02-18T10:00:00Z"
}
]
}
],
"summary": {
"total_batches": 42,
"pending_batches": 5,
"approved_batches": 30,
"rejected_batches": 5,
"partially_approved_batches": 2,
"total_content_items": 120
},
"pagination": {
"page": 1,
"limit": 10,
"total": 42,
"hasNext": true,
"hasPrev": false
}
},
"request_id": "uuid"
}Approval Actions
Two endpoint families handle approval actions: batch-level and item-level.
Batch-Level Action (Approve/Reject Entire Batch)
Act on an entire approval batch at once:
curl -X POST "$AIDELLY_API_BASE/approvals/$BATCH_ID/action" \
-H "Authorization: Bearer $AIDELLY_API_KEY" \
-H "x-aidelly-workspace-id: $WORKSPACE_ID" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: approval-batch-$BATCH_ID-001" \
-d '{
"action": "approve_all",
"force": false
}'Batch Actions:
approve_all— approve all pending items in the batchreject_all— reject all pending items in the batchreset_all— reset batch status back to pending (clear approvals/rejections)schedule_all— schedule all approved items for publishing
Body Parameters:
action(required) — one of the batch actions aboverejection_reason(optional) — reason when rejecting (max 500 chars)schedule_time(optional) — custom schedule time forschedule_all(ISO 8601)force(optional) — bypass confirmation checks (default: false)
Item-Level Action (Approve/Reject Individual Items)
Act on individual content items within a batch:
curl -X POST "$AIDELLY_API_BASE/approvals/items/action" \
-H "Authorization: Bearer $AIDELLY_API_KEY" \
-H "x-aidelly-workspace-id: $WORKSPACE_ID" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: approval-items-001" \
-d '{
"action": "approve",
"content_ids": ["content_uuid_1", "content_uuid_2"],
"account_id": "account_uuid"
}'Item Actions:
approve— approve specific itemsreject— reject specific itemsreschedule— reschedule items to a new timeedit— update content before approvingedit_approve— update and immediately approve
Body Parameters:
action(required) — one of the item actions abovecontent_ids(required) — array of content UUIDs to act on (min 1)account_id(optional) — social account to publish fromrejection_reason(optional) — reason when rejectingedited_content(optional) — map of content_id → updated fieldsreschedule_to(optional) — new schedule time (ISO 8601)schedule_all_approved(optional) — immediately schedule after approval
Edit Field Structure:
{
"action": "edit",
"content_ids": ["content_uuid"],
"edited_content": {
"content_uuid": {
"content_text": "Updated post text...",
"hashtags": ["tag1", "tag2"],
"media_urls": ["https://example.com/image.jpg"],
"suggested_post_time": "2026-02-20T15:00:00Z"
}
}
}State Transitions
Approval statuses follow this state machine:
pending
├─→ approve_all → approved → publish (via schedule_all)
├─→ reject_all → rejected
├─→ partial actions → partially_approved
└─→ reset_all → pending (from any state)Batch Status Rules:
- pending — at least one item has no action
- approved — all items approved
- rejected — all items rejected
- partially_approved — mix of approved, rejected, and pending
Webhooks
Approval actions trigger webhook events. Subscribe to:
approval.batch_created— new approval batch createdapproval.batch_approved— entire batch approvedapproval.batch_rejected— entire batch rejectedapproval.item_approved— individual item approvedapproval.item_rejected— individual item rejected
Example Webhook Payload:
{
"event": "approval.item_approved",
"workspace_id": "workspace_uuid",
"brand_id": "brand_uuid",
"data": {
"batch_id": "batch_uuid",
"content_id": "content_uuid",
"approval_status": "approved",
"approved_by_user_id": "user_uuid",
"approved_at": "2026-02-18T14:30:00Z"
},
"created_at": "2026-02-18T14:30:02Z"
}See Webhooks to subscribe.
Error Handling
Common approval errors:
| Code | Status | Meaning |
|---|---|---|
PUBLIC_API_APPROVALS_BATCH_NOT_FOUND | 404 | Batch ID doesn't exist or you don't have access |
PUBLIC_API_APPROVALS_CONTENT_NOT_FOUND | 404 | Content ID in action doesn't exist |
PUBLIC_API_APPROVALS_INVALID_TRANSITION | 409 | Action not allowed in current batch state |
PUBLIC_API_APPROVALS_CONFLICT | 409 | Idempotency key reused with different action |
Examples
Approve All Pending
curl -X POST "$AIDELLY_API_BASE/approvals/$BATCH_ID/action" \
-H "Authorization: Bearer $AIDELLY_API_KEY" \
-H "x-aidelly-workspace-id: $WORKSPACE_ID" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: batch-approve-$(date +%s)" \
-d '{ "action": "approve_all" }'Reject with Reason
curl -X POST "$AIDELLY_API_BASE/approvals/items/action" \
-H "Authorization: Bearer $AIDELLY_API_KEY" \
-H "x-aidelly-workspace-id: $WORKSPACE_ID" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: item-reject-001" \
-d '{
"action": "reject",
"content_ids": ["content_uuid"],
"rejection_reason": "Tone doesn't match brand voice. Please revise."
}'Edit and Approve
curl -X POST "$AIDELLY_API_BASE/approvals/items/action" \
-H "Authorization: Bearer $AIDELLY_API_KEY" \
-H "x-aidelly-workspace-id: $WORKSPACE_ID" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: item-edit-approve-001" \
-d '{
"action": "edit_approve",
"content_ids": ["content_uuid"],
"edited_content": {
"content_uuid": {
"content_text": "Updated version of the post..."
}
},
"account_id": "account_uuid",
"schedule_all_approved": true
}'