{"openapi":"3.1.0","info":{"title":"vibecms API","version":"1.0.0"},"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Workspace API token (vc_…)"}},"schemas":{},"parameters":{}},"paths":{"/api/v1/site":{"get":{"operationId":"getSite","description":"Get the current site for this token. Requires scope: sites:read. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current site","content":{"application/json":{"schema":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":["string","null"]},"url":{"type":["string","null"]},"voiceProfile":{"type":"object","properties":{"configured":{"type":"boolean"},"audience":{"type":["string","null"]},"voiceSummary":{"type":["string","null"]},"guidelines":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["prefer","avoid"]},"text":{"type":"string"},"source":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["explicit"]}},"required":["kind"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","enum":["approved_edit"]},"postId":{"type":"string"},"versionNumber":{"type":"integer","exclusiveMinimum":0}},"required":["kind","postId","versionNumber"],"additionalProperties":false}]}},"required":["kind","text","source"]}},"representativePosts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"updatedAt":{"type":"number"}},"required":["id","title","slug","updatedAt"]}},"warnings":{"type":"array","items":{"type":"string"}},"updatedByName":{"type":["string","null"]},"createdAt":{"type":["number","null"]},"updatedAt":{"type":["number","null"]}},"required":["configured","audience","voiceSummary","guidelines","representativePosts","warnings","updatedByName","createdAt","updatedAt"]},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","name","slug","description","url","voiceProfile","createdAt","updatedAt"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts":{"get":{"operationId":"listPosts","description":"List bounded post summaries for the current site. Use posts.get for full Markdown. Requires scope: posts:read. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["draft","published","archived"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","maxLength":160},"required":false,"name":"search","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"maximum":10000,"default":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"Bounded post summaries","content":{"application/json":{"schema":{"type":"object","properties":{"posts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","title","slug","url","excerpt","coverAssetId","status","publishedAt","tags","createdAt","updatedAt"]}},"pagination":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"count":{"type":"integer"}},"required":["limit","offset","count"]}},"required":["posts","pagination"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"operationId":"createPost","description":"Create a draft post from a Markdown body. Returns the new post id; make it live with posts.publish. Requires scope: posts:create. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded. CONFLICT when a slug is already in use; BILLING_REQUIRED when a paid subscription is required.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":160},"slug":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"excerpt":{"type":"string","maxLength":500},"contentMarkdown":{"type":"string","maxLength":500000},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":40},"maxItems":20,"default":[]},"coverAssetId":{"type":["string","null"],"maxLength":120},"canonicalUrl":{"type":["string","null"],"maxLength":2048},"seoTitle":{"type":"string","maxLength":70},"seoDescription":{"type":"string","maxLength":180},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false}},"required":["title","slug","contentMarkdown"],"additionalProperties":false}}}},"responses":{"201":{"description":"Created post","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"contentMarkdown":{"type":"string"},"seoTitle":{"type":["string","null"]},"seoDescription":{"type":["string","null"]},"canonicalUrl":{"type":["string","null"]},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0}},"required":["id","title","slug","url","excerpt","coverAssetId","status","publishedAt","tags","createdAt","updatedAt","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/format-guide":{"get":{"operationId":"getFormatGuide","description":"Returns supported post-formatting syntax + guidance; CALL BEFORE DRAFTING OR PUBLISHING. Site-theme-aware. Requires scope: posts:read. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"presetId","in":"query"}],"responses":{"200":{"description":"Post formatting syntax guide","content":{"application/json":{"schema":{"type":"object","properties":{"activePresetId":{"type":"string"},"activePresetName":{"type":"string"},"guideVersion":{"type":"string"},"rendererVersion":{"type":"string"},"recommendedComponents":{"type":"array","items":{"type":"string"}},"presetGuidance":{"type":"string"},"examples":{"type":"string"},"presentationOptions":{"type":"object","properties":{"supportedLayouts":{"type":"array","items":{"type":"string","enum":["standard","feature","essay"]}},"default":{"type":"object","properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"required":["layout","toc"]},"supportsToc":{"type":"boolean"},"notes":{"type":"string"}},"required":["supportedLayouts","default","supportsToc","notes"]}},"required":["activePresetId","activePresetName","guideVersion","rendererVersion","recommendedComponents","presetGuidance","examples","presentationOptions"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/by-slug/{slug}":{"get":{"operationId":"getPostBySlug","description":"Get one post by its exact slug, including full Markdown. Requires scope: posts:read. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"required":true,"name":"slug","in":"path"}],"responses":{"200":{"description":"Post with full Markdown","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"contentMarkdown":{"type":"string"},"seoTitle":{"type":["string","null"]},"seoDescription":{"type":["string","null"]},"canonicalUrl":{"type":["string","null"]},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0}},"required":["id","title","slug","url","excerpt","coverAssetId","status","publishedAt","tags","createdAt","updatedAt","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}":{"get":{"operationId":"getPost","description":"Get one post by id, including full Markdown. Requires scope: posts:read. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"}],"responses":{"200":{"description":"Post with full Markdown","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"contentMarkdown":{"type":"string"},"seoTitle":{"type":["string","null"]},"seoDescription":{"type":["string","null"]},"canonicalUrl":{"type":["string","null"]},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0}},"required":["id","title","slug","url","excerpt","coverAssetId","status","publishedAt","tags","createdAt","updatedAt","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"operationId":"updatePost","description":"Update a post. Provide postId, expectedVersionNumber (current tip), and only the fields to change; contentMarkdown is the full Markdown body. Stale expectedVersionNumber returns CONFLICT. Requires scope: posts:update. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded. CONFLICT when a slug is already in use; BILLING_REQUIRED when a paid subscription is required.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedVersionNumber":{"type":"integer","minimum":1},"title":{"type":"string","minLength":1,"maxLength":160},"slug":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"excerpt":{"type":"string","maxLength":500},"contentMarkdown":{"type":"string","maxLength":500000},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":40},"maxItems":20},"coverAssetId":{"type":["string","null"],"maxLength":120},"canonicalUrl":{"type":["string","null"],"maxLength":2048},"seoTitle":{"type":"string","maxLength":70},"seoDescription":{"type":"string","maxLength":180},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false}},"required":["expectedVersionNumber"],"additionalProperties":false}}}},"responses":{"200":{"description":"Updated post","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"contentMarkdown":{"type":"string"},"seoTitle":{"type":["string","null"]},"seoDescription":{"type":["string","null"]},"canonicalUrl":{"type":["string","null"]},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0}},"required":["id","title","slug","url","excerpt","coverAssetId","status","publishedAt","tags","createdAt","updatedAt","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/publish":{"post":{"operationId":"publishPost","description":"Publish exactly the approved draft version. Pass the latest versionNumber as expectedVersionNumber; a newer edit returns CONFLICT without publishing. Requires scope: posts:publish. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded. CONFLICT when a slug is already in use; BILLING_REQUIRED when a paid subscription is required.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedVersionNumber":{"type":"integer","minimum":1}},"required":["expectedVersionNumber"],"additionalProperties":false}}}},"responses":{"200":{"description":"Published post","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"contentMarkdown":{"type":"string"},"seoTitle":{"type":["string","null"]},"seoDescription":{"type":["string","null"]},"canonicalUrl":{"type":["string","null"]},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0}},"required":["id","title","slug","url","excerpt","coverAssetId","status","publishedAt","tags","createdAt","updatedAt","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Billing required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/archive":{"post":{"operationId":"archivePost","description":"Archive a post. Requires scope: posts:archive. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded. CONFLICT when a slug is already in use; BILLING_REQUIRED when a paid subscription is required.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"}],"responses":{"200":{"description":"Archived post","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"contentMarkdown":{"type":"string"},"seoTitle":{"type":["string","null"]},"seoDescription":{"type":["string","null"]},"canonicalUrl":{"type":["string","null"]},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0}},"required":["id","title","slug","url","excerpt","coverAssetId","status","publishedAt","tags","createdAt","updatedAt","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/assets":{"post":{"operationId":"uploadAsset","description":"Upload an image from base64 data. Decoded image must be 10 MB or smaller. Returns asset metadata and a public URL for Markdown. Requires scope: assets:write. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded. CONFLICT when a slug is already in use; BILLING_REQUIRED when a paid subscription is required. Upload validation failures surface as VALIDATION_ERROR or billing/quota messages.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":180},"mimeType":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif"]},"dataBase64":{"type":"string","minLength":1},"altText":{"type":"string","maxLength":180}},"required":["filename","mimeType","dataBase64"],"additionalProperties":false}}}},"responses":{"201":{"description":"Uploaded asset","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"number"},"width":{"type":["number","null"]},"height":{"type":["number","null"]},"altText":{"type":["string","null"]},"url":{"type":"string"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","filename","mimeType","sizeBytes","width","height","altText","url","createdAt","updatedAt"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"402":{"description":"Billing required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}},"get":{"operationId":"listAssets","description":"List image assets for the current site, newest first. Requires scope: assets:write. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Image assets for the current site, newest first","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"number"},"width":{"type":["number","null"]},"height":{"type":["number","null"]},"altText":{"type":["string","null"]},"url":{"type":"string"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","filename","mimeType","sizeBytes","width","height","altText","url","createdAt","updatedAt"]}}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/assets/{assetId}":{"get":{"operationId":"getAsset","description":"Get one image asset's metadata + public URL by id. Requires scope: assets:write. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"assetId","in":"path"}],"responses":{"200":{"description":"Asset metadata + public URL","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"number"},"width":{"type":["number","null"]},"height":{"type":["number","null"]},"altText":{"type":["string","null"]},"url":{"type":"string"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","filename","mimeType","sizeBytes","width","height","altText","url","createdAt","updatedAt"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"operationId":"deleteAsset","description":"Delete an image asset (file + metadata). CONFLICT if it is a post cover image. Requires scope: assets:write. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded. CONFLICT when a slug is already in use; BILLING_REQUIRED when a paid subscription is required.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"assetId","in":"path"}],"responses":{"200":{"description":"Deleted asset metadata","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"number"},"width":{"type":["number","null"]},"height":{"type":["number","null"]},"altText":{"type":["string","null"]},"url":{"type":"string"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","filename","mimeType","sizeBytes","width","height","altText","url","createdAt","updatedAt"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/activity":{"get":{"operationId":"listActivity","description":"List recent activity for the current site. Requires scope: activity:read. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Recent activity","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"action":{"type":"string"},"entityType":{"type":"string"},"entityId":{"type":"string"},"summary":{"type":"string"},"actorType":{"type":"string"},"actorId":{"type":"string"},"actorName":{"type":"string"},"createdAt":{"type":"number"}},"required":["id","action","entityType","entityId","summary","actorType","actorId","actorName","createdAt"]}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/versions":{"get":{"operationId":"listPostVersions","description":"List version history for a post, newest first. Each summary includes versionNumber, actorType, actorName, changeSummary, and status. Requires scope: posts:read. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"}],"responses":{"200":{"description":"Post version history","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"versionNumber":{"type":"integer"},"title":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string","enum":["draft","published","archived"]},"changeSummary":{"type":["string","null"]},"actorType":{"type":"string","enum":["human","api_key","agent","system"]},"actorName":{"type":"string"},"createdAt":{"type":"number"}},"required":["versionNumber","title","slug","status","changeSummary","actorType","actorName","createdAt"]}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/versions/{versionNumber}":{"get":{"operationId":"getPostVersion","description":"Get a specific version of a post by versionNumber, including full Markdown content. Requires scope: posts:read. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"},{"schema":{"type":"integer","minimum":1},"required":true,"name":"versionNumber","in":"path"}],"responses":{"200":{"description":"Post version with full Markdown","content":{"application/json":{"schema":{"type":"object","properties":{"versionNumber":{"type":"integer"},"title":{"type":"string"},"slug":{"type":"string"},"status":{"type":"string","enum":["draft","published","archived"]},"changeSummary":{"type":["string","null"]},"actorType":{"type":"string","enum":["human","api_key","agent","system"]},"actorName":{"type":"string"},"createdAt":{"type":"number"},"excerpt":{"type":["string","null"]},"contentMarkdown":{"type":"string"},"coverAssetId":{"type":["string","null"]},"seoTitle":{"type":["string","null"]},"seoDescription":{"type":["string","null"]},"canonicalUrl":{"type":["string","null"]},"tags":{"type":"array","items":{"type":"string"}},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false}},"required":["versionNumber","title","slug","status","changeSummary","actorType","actorName","createdAt","excerpt","contentMarkdown","coverAssetId","seoTitle","seoDescription","canonicalUrl","tags","presentation"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/versions/{versionNumber}/restore":{"post":{"operationId":"restorePostVersion","description":"Restore a post to a previous version. Provide expectedVersionNumber for the current tip; stale tips return CONFLICT. Content-only restore (never re-publishes). Creates a new version entry and a post.restored activity. Returns the updated post. Requires scope: posts:update. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded. CONFLICT when a slug is already in use; BILLING_REQUIRED when a paid subscription is required.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"},{"schema":{"type":"integer","minimum":1},"required":true,"name":"versionNumber","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedVersionNumber":{"type":"integer","minimum":1}},"required":["expectedVersionNumber"],"additionalProperties":false}}}},"responses":{"200":{"description":"Updated post after restore","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"contentMarkdown":{"type":"string"},"seoTitle":{"type":["string","null"]},"seoDescription":{"type":["string","null"]},"canonicalUrl":{"type":["string","null"]},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0}},"required":["id","title","slug","url","excerpt","coverAssetId","status","publishedAt","tags","createdAt","updatedAt","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/preview":{"post":{"operationId":"previewPost","description":"Render markdown to HTML with the same renderer as the public blog; returns outline + warnings; call to self-check before publishing. Requires scope: posts:read. Returns NOT_FOUND when a resource is missing; VALIDATION_ERROR when input is invalid; FORBIDDEN without scope; RATE_LIMIT when the workspace budget is exceeded.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"contentMarkdown":{"type":"string","maxLength":500000},"presetId":{"type":"string"},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false}},"required":["contentMarkdown"],"additionalProperties":false}}}},"responses":{"200":{"description":"Rendered preview","content":{"application/json":{"schema":{"type":"object","properties":{"html":{"type":"string"},"outline":{"type":"array","items":{"type":"object","properties":{"depth":{"type":"number"},"text":{"type":"string"},"id":{"type":"string"}},"required":["depth","text","id"]}},"warnings":{"type":"array","items":{"type":"string"}},"rendererVersion":{"type":"string"},"requestedPresentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"additionalProperties":false},"resolvedPresentation":{"type":"object","properties":{"layout":{"type":"string","enum":["standard","feature","essay"]},"toc":{"type":"boolean"}},"required":["layout","toc"]},"presentationWarnings":{"type":"array","items":{"type":"string"}}},"required":["html","outline","warnings","rendererVersion","requestedPresentation","resolvedPresentation","presentationWarnings"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]}}}}}}}},"webhooks":{}}