Content API
REST endpoints for the Content module — content items, categories, publishing integrations.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | /api/content | List content items. Filters: status, content_type, category_id. |
| POST | /api/content | Create. Emits content.post.created. |
| GET/PATCH/DELETE | /api/content/{id} | CRUD. |
| POST | /api/content/{id}/publish | Publish to a connected platform via a publishing_integration. Emits content.post.published on success. |
| GET | /api/content/scheduling-queue | List scheduled items (status='scheduled' with a future publish_date). |
| GET | /api/content/categories | List categories. |
| POST | /api/content/categories | Create. |
Key entity shapes
Content item
{
"id": "uuid",
"title": "string",
"slug": "string",
"content_type": "article | blog_post | social_post | email | landing_page | ad_copy | video_script",
"status": "draft | review | approved | scheduled | published | archived",
"body": "string?",
"excerpt": "string?",
"publish_date": "iso-8601?",
"platforms": ["wordpress", "medium", "..."],
"tags": ["string"],
"seo_title": "string?",
"seo_description": "string?",
"metadata": {}
}
Permissions
Seeded slugs: content.posts.read|create|update|delete|publish,
content.approvals.read|update. There are no separate seeded
slugs for content.items.* or content.categories.* — the
endpoint table refers to "content items" but the underlying table
- permission namespace is
content_posts.
Events
content.post.created|updated|published|deletedcontent.approval.updated
Scheduled publishing
Items with status='scheduled' and publish_date <= now() are
picked up by the content-scheduler cron (*/5 * * * *) which calls
the same publishing pipeline as the manual publish route. Status
flips scheduled → publishing → published via compare-and-set
so two ticks can't double-publish.
OpenAPI
Full schema at /api/openapi.json.