Skip to main content

CMS

  • Sells as: the cms product (a product-scoped API key). This capability has no separate product-face contract — its public product route reuses the capability contract below; see the Edge route table's Product face row.

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
  • Console: Manage the cms product in the console →
  • Runbook: operational checklist for cmsinternal (Vagary Labs ops; not part of this public site): docs/runbooks/capability-operations.md#cms
  • Public base: https://api.vagarylabs.com (the consolidated API gateway — one host, per-brand sibling api.<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

Edge route table

The routes this capability actually serves on the public edge — live-synced from GET https://api.vagarylabs.com/product/v1/_meta/catalog (snapshot v1). The metric is the request-granularity billing counter; the scope is the key permission required.

Product face (customer-keyed)

MethodPathMetricScope
POST/product/v1/cms/commentscms_operationswrite

Endpoints

MethodPathSummary
POST/v1/commentsAdd a threaded comment (nested reply via parent_id; max depth 5; max length 5000 chars).
GET/v1/commentsList top-level comments (with nested replies attached) for an article, oldest first.
GET/v1/comments/flaggedThe admin moderation queue — status='flagged', non-deleted, newest first.
GET/v1/comments/countNon-deleted, non-rejected comment count for an article.
DELETE/v1/comments/&#123;comment_id&#125;Soft-delete a comment (admin any; a user only their own).
POST/v1/comments/&#123;comment_id&#125;/moderateAdmin moderation — approve
GET/v1/locks/&#123;article_id&#125;Check the current edit-lock for an article (evicts an expired lock).
POST/v1/locks/&#123;article_id&#125;Acquire an edit lock (store-authoritative, atomic per org+article; granted to the holder or when expired).
DELETE/v1/locks/&#123;article_id&#125;Release an edit lock (only the holder may release).
POST/v1/locks/&#123;article_id&#125;/force-releaseForce-release a lock (admin).
GET/v1/locksAll currently-held locks for the org (evicts expired).
POST/v1/edit-sessionsSave an edit-session audit record (a held lock must be owned by this user).
GET/v1/edit-sessionsEdit history for an article, newest first.
POST/v1/submissionsSubmit an article for editorial review (duplicate non-rejected URL refused).
GET/v1/submissionsList submissions (optionally by status).
POST/v1/submissions/&#123;submission_id&#125;/reviewApprove or reject a pending submission.
GET/v1/submissions/user/&#123;user_id&#125;List a user's submissions.
GET/v1/submissions/&#123;submission_id&#125;Get a single submission by id.
GET/healthLiveness + store/tenancy posture (never the DSN).
GET/metricsPrometheus metrics.

Schemas

Error

FieldTypeDescription
errorstringstable machine code (e.g. validation_error, not_found, max_depth)
reasonstringhuman-readable one-line explanation (no secrets/PII)
detailobject
request_idstring

CommentCreate

FieldTypeDescription
article_idstring
user_idstring
contentstring
parent_idstringparent comment id for a nested reply
site_idstringoptional within-org sub-scope (site_ids array)
organization_idstringonly honored for a trusted first-party caller (anti-spoof)

CommentCreated

FieldTypeDescription
comment_idstring
createdboolean

Comment

FieldTypeDescription
comment_idstring
article_idstring
user_idstring
contentstring
parent_idstring
depthinteger
statusstring
deletedboolean
site_idsarray
created_atnumberepoch seconds
repliesarray

CommentList

FieldTypeDescription
commentsarray

CommentCount

FieldTypeDescription
article_idstring
countinteger

CommentDelete

FieldTypeDescription
user_idstring
is_adminboolean
organization_idstring

DeleteResult

FieldTypeDescription
deletedboolean
reasonstring

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. The Edge route table section is synced from the live edge catalog snapshot (v1) — re-sync with python3 scripts/sync-edge-catalog.py.