CMS
Sellable product
This capability is granted by an API key scoped to the `` product (product face). See the product reference below.
Shared GENERIC CMS engine. Threaded article comments with moderation + a store-authoritative collaborative-edit lock/session engine (multi-worker coherent — the correctness fix over the platform's per-process lock dict) + a user-submission submit/review FSM. All state is keyed by a caller-supplied (article_id, user_id) and org-scoped (organization_id, I6); the engine NEVER fetches or owns the per-vertical content documents (I4/I5 — those stay platform domain).
- Group: Content & media
- Contract:
contracts/cms/v1/openapi.yaml - Public base:
https://api.vagarylabs.com(the consolidated API gateway — one host, per-brand siblingapi.<zone>) - Auth: a product API key (
vgk_…) issued from the console —Authorization: Bearer vgk_… - Product face (customer-keyed):
https://api.vagarylabs.com/product/v1/cms/comments
Endpoints
| Method | Path | Summary |
|---|---|---|
POST | /v1/comments | Add a threaded comment (nested reply via parent_id; max depth 5; max length 5000 chars). |
GET | /v1/comments | List top-level comments (with nested replies attached) for an article, oldest first. |
GET | /v1/comments/flagged | The admin moderation queue — status='flagged', non-deleted, newest first. |
GET | /v1/comments/count | Non-deleted, non-rejected comment count for an article. |
DELETE | /v1/comments/{comment_id} | Soft-delete a comment (admin any; a user only their own). |
POST | /v1/comments/{comment_id}/moderate | Admin moderation — approve |
GET | /v1/locks/{article_id} | Check the current edit-lock for an article (evicts an expired lock). |
POST | /v1/locks/{article_id} | Acquire an edit lock (store-authoritative, atomic per org+article; granted to the holder or when expired). |
DELETE | /v1/locks/{article_id} | Release an edit lock (only the holder may release). |
POST | /v1/locks/{article_id}/force-release | Force-release a lock (admin). |
GET | /v1/locks | All currently-held locks for the org (evicts expired). |
POST | /v1/edit-sessions | Save an edit-session audit record (a held lock must be owned by this user). |
GET | /v1/edit-sessions | Edit history for an article, newest first. |
POST | /v1/submissions | Submit an article for editorial review (duplicate non-rejected URL refused). |
GET | /v1/submissions | List submissions (optionally by status). |
POST | /v1/submissions/{submission_id}/review | Approve or reject a pending submission. |
GET | /v1/submissions/user/{user_id} | List a user's submissions. |
GET | /v1/submissions/{submission_id} | Get a single submission by id. |
GET | /health | Liveness + store/tenancy posture (never the DSN). |
GET | /metrics | Prometheus metrics. |
Schemas
Error
| Field | Type | Description |
|---|---|---|
error | string | stable machine code (e.g. validation_error, not_found, max_depth) |
reason | string | human-readable one-line explanation (no secrets/PII) |
detail | object | |
request_id | string |
CommentCreate
| Field | Type | Description |
|---|---|---|
article_id | string | |
user_id | string | |
content | string | |
parent_id | string | parent comment id for a nested reply |
site_id | string | optional within-org sub-scope (site_ids array) |
organization_id | string | only honored for a trusted first-party caller (anti-spoof) |
CommentCreated
| Field | Type | Description |
|---|---|---|
comment_id | string | |
created | boolean |
Comment
| Field | Type | Description |
|---|---|---|
comment_id | string | |
article_id | string | |
user_id | string | |
content | string | |
parent_id | string | |
depth | integer | |
status | string | |
deleted | boolean | |
site_ids | array | |
created_at | number | epoch seconds |
replies | array |
CommentList
| Field | Type | Description |
|---|---|---|
comments | array |
CommentCount
| Field | Type | Description |
|---|---|---|
article_id | string | |
count | integer |
CommentDelete
| Field | Type | Description |
|---|---|---|
user_id | string | |
is_admin | boolean | |
organization_id | string |
DeleteResult
| Field | Type | Description |
|---|---|---|
deleted | boolean | |
reason | string |
Generated by scripts/gen-capability-docs.py from contracts/cms/v1/openapi.yaml — the contract IS the source of truth; edit the contract, not this page.