{"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, including its voice profile revision and signup form settings. A cleared voice profile returns configured: false with its current nonzero revision; send that revision as expectedUpdatedAt when recreating it. Revision zero means never configured. billingNotice appears only when the owner's subscription payment failed: paidFeaturesUntil is the latest guaranteed paid-through time, or null when no date is guaranteed (grace ended or unknown, or paid access continues through a separate sponsorship); null does not by itself mean paid features stopped. action tells the owner how to fix the payment. Requires scope: sites:read.","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"]},"logoUrl":{"type":["string","null"]},"faviconUrl":{"type":["string","null"]},"navLinks":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","maxLength":40},"url":{"type":"string"}},"required":["label","url"]},"maxItems":6},"socialLinks":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["x","github","linkedin","bluesky","mastodon","youtube","instagram","website","email"]},"url":{"type":"string"}},"required":["kind","url"]},"maxItems":8},"voiceSeedUrls":{"type":"array","items":{"type":"string"}},"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"]},"revision":{"type":"integer","minimum":0}},"required":["configured","audience","voiceSummary","guidelines","representativePosts","warnings","updatedByName","createdAt","updatedAt","revision"]},"signupForm":{"type":"object","properties":{"enabled":{"type":"boolean"},"heading":{"type":"string"},"description":{"type":"string"},"button":{"type":"string"},"externalForm":{"type":["object","null"],"properties":{"action":{"type":"string"},"emailField":{"type":"string"}},"required":["action","emailField"]}},"required":["enabled","heading","description","button","externalForm"]},"template":{"type":"string"},"byline":{"type":"object","properties":{"name":{"type":"string"},"agentCredit":{"type":"boolean"}},"required":["name","agentCredit"]},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"billingNotice":{"type":"object","properties":{"kind":{"type":"string","enum":["payment_failed"]},"paidFeaturesUntil":{"type":["string","null"]},"action":{"type":"string"}},"required":["kind","paidFeaturesUntil","action"]}},"required":["id","name","slug","description","url","logoUrl","faviconUrl","navLinks","socialLinks","voiceSeedUrls","voiceProfile","signupForm","template","byline","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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"operationId":"updateSite","description":"Change only the sent site fields, such as name, byline, SEO, images, navigation, or social links. First read sites.get and send its updatedAt as expectedUpdatedAt; stale values return CONFLICT. Example: {\"expectedUpdatedAt\": 123, \"name\": \"Field Notes\"}. Live change: needs explicit owner approval first (see server instructions). Requires scope: site:write.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedUpdatedAt":{"type":"integer","exclusiveMinimum":0},"name":{"type":"string","minLength":1,"maxLength":80},"description":{"type":["string","null"],"maxLength":220},"bylineName":{"type":["string","null"],"maxLength":80},"showAgentCredit":{"type":"boolean"},"defaultSeoTitle":{"type":"string","maxLength":120},"defaultSeoDescription":{"type":["string","null"],"maxLength":220},"defaultSocialAssetId":{"type":["string","null"]},"logoAssetId":{"type":["string","null"]},"faviconAssetId":{"type":["string","null"]},"navLinks":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":40},"url":{"type":"string","minLength":1}},"required":["label","url"],"additionalProperties":false},"maxItems":6},"socialLinks":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["x","github","linkedin","bluesky","mastodon","youtube","instagram","website","email"]},"url":{"type":"string","minLength":1}},"required":["kind","url"],"additionalProperties":false},"maxItems":8}},"required":["expectedUpdatedAt"],"additionalProperties":false}}}},"responses":{"200":{"description":"Updated site","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":["string","null"]},"url":{"type":["string","null"]},"logoUrl":{"type":["string","null"]},"faviconUrl":{"type":["string","null"]},"navLinks":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","maxLength":40},"url":{"type":"string"}},"required":["label","url"]},"maxItems":6},"socialLinks":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["x","github","linkedin","bluesky","mastodon","youtube","instagram","website","email"]},"url":{"type":"string"}},"required":["kind","url"]},"maxItems":8},"voiceSeedUrls":{"type":"array","items":{"type":"string"}},"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"]},"revision":{"type":"integer","minimum":0}},"required":["configured","audience","voiceSummary","guidelines","representativePosts","warnings","updatedByName","createdAt","updatedAt","revision"]},"signupForm":{"type":"object","properties":{"enabled":{"type":"boolean"},"heading":{"type":"string"},"description":{"type":"string"},"button":{"type":"string"},"externalForm":{"type":["object","null"],"properties":{"action":{"type":"string"},"emailField":{"type":"string"}},"required":["action","emailField"]}},"required":["enabled","heading","description","button","externalForm"]},"template":{"type":"string"},"byline":{"type":"object","properties":{"name":{"type":"string"},"agentCredit":{"type":"boolean"}},"required":["name","agentCredit"]},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"settings":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"defaultSeoTitle":{"type":"string"},"defaultSeoDescription":{"type":"string"},"defaultSocialAssetId":{"type":["string","null"]},"logoAssetId":{"type":["string","null"]},"faviconAssetId":{"type":["string","null"]},"navLinks":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","maxLength":40},"url":{"type":"string"}},"required":["label","url"]},"maxItems":6},"socialLinks":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["x","github","linkedin","bluesky","mastodon","youtube","instagram","website","email"]},"url":{"type":"string"}},"required":["kind","url"]},"maxItems":8},"theme":{"type":"string"},"slug":{"type":"string"},"themeAccent":{"type":"string"},"themeFont":{"type":"string"},"themeMode":{"type":"string"},"themeRadius":{"type":"string"},"themeWidth":{"type":"string"},"themeChrome":{"type":"string"},"themeIndex":{"type":"string"},"themeHeader":{"type":"string"},"bylineName":{"type":"string"},"showAgentCredit":{"type":"boolean"},"updatedAt":{"type":"number"}},"required":["name","description","defaultSeoTitle","defaultSeoDescription","defaultSocialAssetId","logoAssetId","faviconAssetId","navLinks","socialLinks","theme","slug","themeAccent","themeFont","themeMode","themeRadius","themeWidth","themeChrome","themeIndex","themeHeader","bylineName","showAgentCredit","updatedAt"]}},"required":["id","name","slug","description","url","logoUrl","faviconUrl","navLinks","socialLinks","voiceSeedUrls","voiceProfile","template","byline","createdAt","updatedAt","settings"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/site/theme":{"get":{"operationId":"getSiteTheme","description":"Read the current blog template and look, plus allowed values with human names. Use its updatedAt for a theme update. Example: {}. Requires scope: site:write.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current theme and options","content":{"application/json":{"schema":{"type":"object","properties":{"template":{"type":"string"},"accent":{"type":"string"},"font":{"type":"string"},"radius":{"type":"string"},"width":{"type":"string"},"chrome":{"type":"string"},"index":{"type":"string"},"header":{"type":"string"},"mode":{"type":"string"},"updatedAt":{"type":"number"},"options":{"type":"object","properties":{"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"accents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"fonts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"radii":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"widths":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"chromes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"indexes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"headers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"modes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}}},"required":["templates","accents","fonts","radii","widths","chromes","indexes","headers","modes"]},"url":{"type":["string","null"]},"canRevert":{"type":"boolean"}},"required":["template","accent","font","radius","width","chrome","index","header","mode","updatedAt","options","url","canRevert"]}}}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"operationId":"updateSiteTheme","description":"Change any part of the blog look. Templates: minimal (Minimal), editorial (Editorial), technical (Notebook), product (Magazine); display names are accepted too. A new template applies its curated accent, font, radius, width, and mode unless keepLook=true. Navigation, home page, and article header reset to that template; each can be set independently or null to use its default. Example: {\"expectedUpdatedAt\": 123, \"template\": \"editorial\", \"keepLook\": true}. The previous look is saved for one-step revert; changes are live immediately. Live change: needs explicit owner approval first (see server instructions). Requires scope: site:write.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedUpdatedAt":{"type":"integer","exclusiveMinimum":0},"template":{"type":"string","enum":["minimal","Minimal","editorial","Editorial","technical","Notebook","notebook","product","Magazine","magazine"]},"keepLook":{"type":"boolean"},"accent":{"type":"string","enum":["teal","blue","indigo","violet","magenta","crimson","rust","green","graphite"]},"font":{"type":"string","enum":["geist-sans","Geist","geist","serif","Newsreader","newsreader","grotesk","Space Grotesk","space grotesk","humanist","Hanken Grotesk","hanken grotesk","mono","Geist Mono","geist mono"]},"radius":{"type":["string","null"],"enum":["none","sm","md","lg",null]},"width":{"type":["string","null"],"enum":["narrow","normal","wide",null]},"chrome":{"type":["string","null"],"enum":["masthead","centered","sidebar",null]},"index":{"type":["string","null"],"enum":["list","grid","compact",null]},"header":{"type":["string","null"],"enum":["plain","centered","card",null]},"mode":{"type":"string","enum":["light","dark","system"]}},"required":["expectedUpdatedAt"],"additionalProperties":false}}}},"responses":{"200":{"description":"Updated theme","content":{"application/json":{"schema":{"type":"object","properties":{"template":{"type":"string"},"accent":{"type":"string"},"font":{"type":"string"},"radius":{"type":"string"},"width":{"type":"string"},"chrome":{"type":"string"},"index":{"type":"string"},"header":{"type":"string"},"mode":{"type":"string"},"updatedAt":{"type":"number"},"options":{"type":"object","properties":{"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"accents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"fonts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"radii":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"widths":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"chromes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"indexes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"headers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"modes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}}},"required":["templates","accents","fonts","radii","widths","chromes","indexes","headers","modes"]},"url":{"type":["string","null"]},"canRevert":{"type":"boolean"}},"required":["template","accent","font","radius","width","chrome","index","header","mode","updatedAt","options","url","canRevert"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/site/theme/revert":{"post":{"operationId":"revertSiteTheme","description":"Undo the last theme change and restore the exact previous look only when sites.theme.get.canRevert is true. Intervening site-setting changes can invalidate the saved revert. Example: {\"expectedUpdatedAt\": 124}. Live change: needs explicit owner approval first (see server instructions). Requires scope: site:write.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedUpdatedAt":{"type":"integer","exclusiveMinimum":0}},"required":["expectedUpdatedAt"],"additionalProperties":false}}}},"responses":{"200":{"description":"Restored theme","content":{"application/json":{"schema":{"type":"object","properties":{"template":{"type":"string"},"accent":{"type":"string"},"font":{"type":"string"},"radius":{"type":"string"},"width":{"type":"string"},"chrome":{"type":"string"},"index":{"type":"string"},"header":{"type":"string"},"mode":{"type":"string"},"updatedAt":{"type":"number"},"options":{"type":"object","properties":{"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"accents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"fonts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"radii":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"widths":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"chromes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"indexes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"headers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}},"modes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]}}},"required":["templates","accents","fonts","radii","widths","chromes","indexes","headers","modes"]},"url":{"type":["string","null"]},"canRevert":{"type":"boolean"}},"required":["template","accent","font","radius","width","chrome","index","header","mode","updatedAt","options","url","canRevert"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/site/voice":{"put":{"operationId":"updateSiteVoice","description":"Replace the writing profile. First read sites.get.voiceProfile; preserve existing fields unless the owner requested changes. Send its revision as expectedUpdatedAt (zero means never configured). Concurrent edits return CONFLICT. Example: {\"expectedUpdatedAt\":0,\"audience\":\"Developers\",\"tone\":\"Clear\",\"doRules\":[\"Use examples\"],\"dontRules\":[],\"representativePostIds\":[]}. Live change: needs explicit owner approval first (see server instructions). Requires scope: site:write.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedUpdatedAt":{"type":["integer","null"],"minimum":0},"audience":{"type":"string","maxLength":300},"tone":{"type":"string","maxLength":500},"doRules":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":12},"dontRules":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":12},"representativePostIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"maxItems":3}},"required":["expectedUpdatedAt","doRules","dontRules","representativePostIds"],"additionalProperties":false}}}},"responses":{"200":{"description":"Updated voice","content":{"application/json":{"schema":{"type":"object","properties":{"configured":{"type":"boolean"},"audience":{"type":"string"},"voiceSummary":{"type":"string"},"preferRules":{"type":"array","items":{"type":"string"}},"avoidRules":{"type":"array","items":{"type":"string"}},"representativePostIds":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}},"updatedByName":{"type":["string","null"]},"updatedAt":{"type":["number","null"]},"publishedPosts":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"updatedAt":{"type":"number"}},"required":["id","title","slug","updatedAt"]}}},"required":["configured","audience","voiceSummary","preferRules","avoidRules","representativePostIds","warnings","updatedByName","updatedAt","publishedPosts"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/site/signup-form":{"patch":{"operationId":"updateSignupForm","description":"Read the current signup form from sites.get and its updatedAt first. Update only supplied fields. externalForm posts signups to the owner’s newsletter tool (vibecms stores none); null restores vibecms storage. Example: {\"expectedUpdatedAt\":123,\"enabled\":true,\"heading\":\"Get new posts\"}. Returns the updated form. Concurrent changes return CONFLICT. Live change: needs explicit owner approval first (see server instructions). Requires scope: site:write.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"expectedUpdatedAt":{"type":"integer","exclusiveMinimum":0},"enabled":{"type":"boolean"},"heading":{"type":"string","minLength":1,"maxLength":80},"description":{"type":"string","minLength":1,"maxLength":160},"button":{"type":"string","minLength":1,"maxLength":24},"externalForm":{"type":["object","null"],"properties":{"action":{"type":"string","maxLength":500,"format":"uri"},"emailField":{"type":"string","pattern":"^[A-Za-z0-9_\\-\\[\\].:]{1,64}$"}},"required":["action","emailField"],"additionalProperties":false}},"required":["expectedUpdatedAt"],"additionalProperties":false}}}},"responses":{"200":{"description":"Updated signup form","content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"},"heading":{"type":"string"},"description":{"type":"string"},"button":{"type":"string"},"externalForm":{"type":["object","null"],"properties":{"action":{"type":"string"},"emailField":{"type":"string"}},"required":["action","emailField"]}},"required":["enabled","heading","description","button","externalForm"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/tags":{"get":{"operationId":"listTags","description":"List tags currently used by non-archived posts and their post counts. Reuse these spellings when tagging a post. Example: {}. Requires scope: site:write.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Tags in use","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"postCount":{"type":"integer","minimum":0}},"required":["name","postCount"]}}}}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/analytics":{"get":{"operationId":"getAnalytics","description":"Read aggregate views, trend, top posts, referrers, AI referrals, and agent fetches (agents.total/byCategory/topAgents/topPosts/markdownShare/llmsReads: AI crawlers, assistants, and search engines reading the blog server-side). Pass optional postId to scope per-post numbers to one post. Example: {\"range\":\"30\"}; ranges: 7, 30, 90, 365, all. No visitor data. Free plans return ANALYTICS_PAID_PLAN. Requires scope: analytics:read.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["7","30","90","365","all"],"default":"30"},"required":false,"name":"range","in":"query"},{"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,128}$"},"required":false,"name":"postId","in":"query"}],"responses":{"200":{"description":"Aggregate analytics","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["available","unavailable"]},"rangeDays":{"anyOf":[{"type":"number","enum":[7]},{"type":"number","enum":[30]},{"type":"number","enum":[90]},{"type":"number","enum":[365]},{"type":"string","enum":["all"]}]},"retentionDays":{"type":"number"},"views":{"type":"number"},"previousViews":{"type":["number","null"]},"trendPercent":{"type":["number","null"]},"seriesGranularity":{"type":"string","enum":["day","month"]},"aiReferralViews":{"type":"number"},"series":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"views":{"type":"number"},"aiCrawlerRequests":{"type":"number"}},"required":["date","views","aiCrawlerRequests"]}},"topPosts":{"type":"array","items":{"type":"object","properties":{"postId":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"views":{"type":"number"}},"required":["postId","slug","title","views"]}},"referrers":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string"},"views":{"type":"number"},"ai":{"type":"boolean"},"operator":{"type":["string","null"]}},"required":["domain","views","ai","operator"]}},"aiCrawlers":{"type":"object","properties":{"status":{"type":"string","enum":["available","unavailable"]},"lookbackDays":{"type":"number"},"requests":{"type":"number"},"agents":{"type":"array","items":{"type":"object","properties":{"agent":{"type":"string"},"operator":{"type":"string"},"category":{"type":"string"},"requests":{"type":"number"}},"required":["agent","operator","category","requests"]}}},"required":["status","lookbackDays","requests","agents"]},"agents":{"type":"object","properties":{"total":{"type":"number"},"byCategory":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"fetches":{"type":"number"}},"required":["category","fetches"]}},"topAgents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"operator":{"type":"string"},"category":{"type":"string"},"fetches":{"type":"number"}},"required":["id","label","operator","category","fetches"]}},"topPosts":{"type":"array","items":{"type":"object","properties":{"postId":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"fetches":{"type":"number"}},"required":["postId","slug","title","fetches"]}},"markdownShare":{"type":"number"},"signedShare":{"type":"number"},"llmsReads":{"type":"number"}},"required":["total","byCategory","topAgents","topPosts","markdownShare","signedShare","llmsReads"]},"reason":{"type":"string","enum":["self_hosted","not_configured","query_failed"]}},"required":["status","retentionDays"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/skills":{"get":{"operationId":"listSkills","description":"List the vibecms agent skills: free instructions that teach you how to work with vibecms. Each has name, description, url, and digest (sha256 of its SKILL.md). Compare digest with your installed copy to see whether it changed; call skills.get for the full text. Example: {}. Any valid key; no scope required.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"vibecms agent skills","content":{"application/json":{"schema":{"type":"object","properties":{"skills":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"url":{"type":"string"},"digest":{"type":"string"}},"required":["name","description","url","digest"]}}},"required":["skills"]}}}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/skills/{name}":{"get":{"operationId":"getSkill","description":"Get one vibecms agent skill by a name from skills.list, including its full SKILL.md as content. The content can be installed as <your skills folder>/<name>/SKILL.md (for example in .agents/skills or .claude/skills). Unknown names return NOT_FOUND. Example: {\"name\":\"vibecms-core\"}. Any valid key; no scope required.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,63}$"},"required":true,"name":"name","in":"path"}],"responses":{"200":{"description":"One skill with its full SKILL.md","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"url":{"type":"string"},"digest":{"type":"string"},"content":{"type":"string"}},"required":["name","description","url","digest","content"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/site/location":{"get":{"operationId":"getSiteLocation","description":"Read where this blog is served: the default host, a custom domain, or a path on the owner's site. Subpath rows include status and the last setup check; proxyTarget and snippets only appear for keys that may manage the location. Example: {}. Requires scope: sites:read.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current public location","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["default","custom","subpath"]},"url":{"type":["string","null"]},"status":{"type":["string","null"],"enum":["pending","active","failed","disabled",null]},"proxyTarget":{"type":"string"},"snippets":{"type":"object","properties":{"cloudflareWorker":{"type":"object","properties":{"code":{"type":"string"},"route":{"type":"string"}},"required":["code","route"]},"vercel":{"type":"string"},"nextjs":{"type":"string"},"netlify":{"type":"string"},"nginx":{"type":"string"},"caddy":{"type":"string"}},"required":["cloudflareWorker","vercel","nextjs","netlify","nginx","caddy"]},"lastCheck":{"type":"object","properties":{"ok":{"type":"boolean"},"checkedAt":{"type":"integer"},"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}}},"required":["ok","checkedAt","errors","warnings"]}},"required":["type","url","status"]}}}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}},"put":{"operationId":"setSubpathLocation","description":"Serve this blog at a path of the owner's site (https://customer.com/blog). Replaces any existing subpath location. Returns the proxy target and ready-to-paste snippets for Cloudflare/Vercel/Next.js/Netlify/nginx/Caddy; they are setup secrets, so share them only with the owner. The owner must save one, then call sites.location.check. Live change: needs explicit owner approval first (see server instructions). Example: {\"url\":\"https://customer.com/blog\"}. Requires scope: site:write.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048}},"required":["url"],"additionalProperties":false}}}},"responses":{"200":{"description":"Subpath location with proxy target and snippets","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["default","custom","subpath"]},"url":{"type":["string","null"]},"status":{"type":["string","null"],"enum":["pending","active","failed","disabled",null]},"proxyTarget":{"type":"string"},"snippets":{"type":"object","properties":{"cloudflareWorker":{"type":"object","properties":{"code":{"type":"string"},"route":{"type":"string"}},"required":["code","route"]},"vercel":{"type":"string"},"nextjs":{"type":"string"},"netlify":{"type":"string"},"nginx":{"type":"string"},"caddy":{"type":"string"}},"required":["cloudflareWorker","vercel","nextjs","netlify","nginx","caddy"]},"lastCheck":{"type":"object","properties":{"ok":{"type":"boolean"},"checkedAt":{"type":"integer"},"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}}},"required":["ok","checkedAt","errors","warnings"]}},"required":["type","url","status"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"operationId":"removeSiteLocation","description":"Remove the subpath location and stop serving the blog at the customer path. Live change: needs explicit owner approval first (see server instructions). Example: {}. Requires scope: site:write.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Resulting location","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["default","custom","subpath"]},"url":{"type":["string","null"]},"status":{"type":["string","null"],"enum":["pending","active","failed","disabled",null]},"proxyTarget":{"type":"string"},"snippets":{"type":"object","properties":{"cloudflareWorker":{"type":"object","properties":{"code":{"type":"string"},"route":{"type":"string"}},"required":["code","route"]},"vercel":{"type":"string"},"nextjs":{"type":"string"},"netlify":{"type":"string"},"nginx":{"type":"string"},"caddy":{"type":"string"}},"required":["cloudflareWorker","vercel","nextjs","netlify","nginx","caddy"]},"lastCheck":{"type":"object","properties":{"ok":{"type":"boolean"},"checkedAt":{"type":"integer"},"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}}},"required":["ok","checkedAt","errors","warnings"]}},"required":["type","url","status"]}}}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/site/location/check":{"post":{"operationId":"checkSiteLocation","description":"Verify the subpath proxy is live: probes https://<hostname><basePath>/_vc/health and compares site id and proxy fingerprint. A pass activates the location; a failure records plain-language errors. Call after the owner saves a snippet. Example: {}. Requires scope: site:write.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Setup check result and location","content":{"application/json":{"schema":{"type":"object","properties":{"check":{"type":"object","properties":{"ok":{"type":"boolean"},"checkedAt":{"type":"integer"},"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}}},"required":["ok","checkedAt","errors","warnings"]},"location":{"type":"object","properties":{"type":{"type":"string","enum":["default","custom","subpath"]},"url":{"type":["string","null"]},"status":{"type":["string","null"],"enum":["pending","active","failed","disabled",null]},"proxyTarget":{"type":"string"},"snippets":{"type":"object","properties":{"cloudflareWorker":{"type":"object","properties":{"code":{"type":"string"},"route":{"type":"string"}},"required":["code","route"]},"vercel":{"type":"string"},"nextjs":{"type":"string"},"netlify":{"type":"string"},"nginx":{"type":"string"},"caddy":{"type":"string"}},"required":["cloudflareWorker","vercel","nextjs","netlify","nginx","caddy"]},"lastCheck":{"type":"object","properties":{"ok":{"type":"boolean"},"checkedAt":{"type":"integer"},"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"warnings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}}},"required":["ok","checkedAt","errors","warnings"]}},"required":["type","url","status"]}},"required":["check","location"]}}}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/site/redirects":{"get":{"operationId":"listRedirects","description":"List exact-path redirects with total and plan limit. Requires scope: sites:read.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":["integer","null"],"minimum":0},"required":false,"name":"offset","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Redirects and plan limit","content":{"application/json":{"schema":{"type":"object","properties":{"redirects":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"createdAt":{"type":"integer"},"updatedAt":{"type":"integer"}},"required":["from","to","createdAt","updatedAt"]}},"total":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":0}},"required":["redirects","total","limit"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"operationId":"setRedirects","description":"Upsert up to 100 exact-path redirects to blog paths; all-or-nothing. Live change: needs owner approval (one may cover an import batch). Requires scope: site:write.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"redirects":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"],"additionalProperties":false},"minItems":1,"maxItems":100}},"required":["redirects"],"additionalProperties":false}}}},"responses":{"200":{"description":"Redirect results and plan limit","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"status":{"type":"string","enum":["created","updated","unchanged"]}},"required":["from","to","status"]}},"total":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":0}},"required":["results","total","limit"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/site/redirects/delete":{"post":{"operationId":"deleteRedirects","description":"Delete up to 100 redirects by source path. Live change: needs owner approval. Requires scope: site:write.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":100}},"required":["from"],"additionalProperties":false}}}},"responses":{"200":{"description":"Deleted redirect count","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"integer","minimum":0}},"required":["deleted"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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.","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"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish"]}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}},"post":{"operationId":"createPost","description":"Create a draft post from a Markdown body. Free sites may keep 5 drafts at a time; publishing or archiving frees a slot. Returns id, currentVersionNumber, and previewUrl. Omitted presentation uses the active preset default layout; call posts.format_guide for supportedLayouts. previewUrl is a secret bearer link to the current saved tip, not an immutable version. Share only with the owner or explicitly authorized reviewers; never put it in public content. Rotate it if exposed. Requires scope: posts:create.","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]+)*$","description":"Post slugs cannot use reserved site routes: dashboard, api, blog, login, mcp, media-assets, internal, feed.xml, sitemap.xml, robots.txt, llms.txt, llms-full.txt, docs-search.json, docs, __vc-health."},"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","essay","feature","wide"]},"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"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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.","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"},"syntax":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"summary":{"type":"string"},"example":{"type":"string"}},"required":["id","summary","example"]}},"presentationOptions":{"type":"object","properties":{"supportedLayouts":{"type":"array","items":{"type":"string","enum":["standard","essay","feature","wide"]}},"default":{"type":"object","properties":{"layout":{"type":"string","enum":["standard","essay","feature","wide"]},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Post slugs cannot use reserved site routes: dashboard, api, blog, login, mcp, media-assets, internal, feed.xml, sitemap.xml, robots.txt, llms.txt, llms-full.txt, docs-search.json, docs, __vc-health."},"required":true,"description":"Post slugs cannot use reserved site routes: dashboard, api, blog, login, mcp, media-assets, internal, feed.xml, sitemap.xml, robots.txt, llms.txt, llms-full.txt, docs-search.json, docs, __vc-health.","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"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}":{"get":{"operationId":"getPost","description":"Get one post by id, including full Markdown, currentVersionNumber, and previewUrl. previewUrl is a secret bearer link to the current saved tip, not an immutable version. Share only with the owner or explicitly authorized reviewers; never put it in public content. Rotate it if exposed. Requires scope: posts:read.","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"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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.","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]+)*$","description":"Post slugs cannot use reserved site routes: dashboard, api, blog, login, mcp, media-assets, internal, feed.xml, sitemap.xml, robots.txt, llms.txt, llms-full.txt, docs-search.json, docs, __vc-health."},"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","essay","feature","wide"]},"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"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/publish":{"post":{"operationId":"publishPost","description":"Publish exactly the approved draft version. Free sites may keep 5 published posts; publishing a draft frees its draft slot. After owner approval, pass posts.get.currentVersionNumber as expectedVersionNumber. The approved version must still be current; a newer edit returns CONFLICT without publishing. Imports may set originalPublishedAt on first publish. Live change: needs explicit owner approval first (see server instructions). Requires scope: posts:publish.","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},"originalPublishedAt":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"string","pattern":"^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d(?::\\d\\d(?:\\.\\d+)?)?(?:Z|[+-]\\d\\d:\\d\\d)$"}],"description":"For imports on the first publish only: Unix seconds or an ISO-8601 time with a timezone, from 1990-01-01 and strictly in the past."}},"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"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/schedule":{"post":{"operationId":"schedulePost","description":"Schedule an approved saved version. versionNumber selects the approved saved version; it is not a current-tip precondition. publishAt accepts Unix seconds or an ISO-8601 UTC string ending in Z or an explicit offset. Approve that exact version and time; later edits do not alter it. Live change: needs explicit owner approval first (see server instructions). Requires scope: posts:publish.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"versionNumber":{"type":"integer","minimum":1},"publishAt":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"string","pattern":"^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d(?::\\d\\d(?:\\.\\d+)?)?(?:Z|[+-]\\d\\d:\\d\\d)$"}]}},"required":["versionNumber","publishAt"],"additionalProperties":false}}}},"responses":{"200":{"description":"Scheduled post","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/unschedule":{"post":{"operationId":"unschedulePost","description":"Cancel a pending or failed scheduled publication. Requires scope: posts:publish.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"}],"responses":{"200":{"description":"Unscheduled post","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/preview/rotate":{"post":{"operationId":"rotatePostPreview","description":"Rotate a private preview link, immediately revoking the old URL. Requires scope: posts:update.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"}],"responses":{"200":{"description":"Rotated private preview link","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/archive":{"post":{"operationId":"archivePost","description":"Take a post off the blog (or shelve a draft); returns the archived post. Archiving saves a new version, so use the returned currentVersionNumber for any follow-up edit; an already archived post comes back unchanged. Restore with posts.unarchive. Send posts.get.currentVersionNumber as expectedVersionNumber after approval; a changed tip returns CONFLICT. Live change: needs explicit owner approval first (see server instructions). Requires scope: posts:archive.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"postId":{"type":"string","minLength":1},"expectedVersionNumber":{"type":"integer","minimum":1}},"additionalProperties":false}}}},"responses":{"200":{"description":"Archived post","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/unarchive":{"post":{"operationId":"unarchivePost","description":"Restore an archived post to draft. This saves a new version; use the returned currentVersionNumber for the next edit. Publish again to make it public. Requires scope: posts:update.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"}],"responses":{"200":{"description":"Restored draft post","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/assets":{"post":{"operationId":"uploadAsset","description":"Upload an image from base64 data. Free sites may keep 10 images; paid sites have 10 GB media storage. Decoded image must be 10 MB or smaller. Uploading makes the image public before post publication. Returns asset metadata and a public URL for Markdown. The CLI 'vibecms assets upload <path>' can upload a file without putting base64 in the conversation. Requires scope: assets:write.","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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}},"get":{"operationId":"listAssets","description":"List image assets for the current site, newest first. Requires scope: assets:write.","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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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.","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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}},"delete":{"operationId":"deleteAsset","description":"Delete an image asset (file + metadata). CONFLICT if it is a post cover or site social image. Live change: needs explicit owner approval first (see server instructions). Requires scope: assets:delete.","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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}},"patch":{"operationId":"updateAsset","description":"Update an image asset's alt text. Requires scope: assets:write.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"assetId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"altText":{"type":"string","maxLength":180}},"required":["altText"],"additionalProperties":false}}}},"responses":{"200":{"description":"Updated 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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/activity":{"get":{"operationId":"listActivity","description":"List activity for the current site with limit and offset pagination. Requires scope: activity:read.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"maximum":1000000,"default":0},"required":false,"name":"offset","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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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.","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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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.","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","essay","feature","wide"]},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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.","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"},"publishedSlug":{"type":["string","null"]},"url":{"type":["string","null"]},"excerpt":{"type":["string","null"]},"coverAssetId":{"type":["string","null"]},"status":{"type":"string","enum":["draft","published","archived"]},"publishedAt":{"type":["number","null"]},"originalPublishedAt":{"type":["number","null"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"scheduledPublish":{"type":["object","null"],"properties":{"versionNumber":{"type":"integer","exclusiveMinimum":0},"publishAt":{"type":"integer"},"status":{"type":"string","enum":["pending","processing","published","failed"]},"error":{"type":["string","null"]}},"required":["versionNumber","publishAt","status"]},"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","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"currentVersionNumber":{"type":"integer","exclusiveMinimum":0},"publishedVersionNumber":{"type":["integer","null"],"exclusiveMinimum":0},"previewUrl":{"type":["string","null"],"format":"uri"}},"required":["id","title","slug","publishedSlug","url","excerpt","coverAssetId","status","publishedAt","originalPublishedAt","tags","createdAt","updatedAt","scheduledPublish","contentMarkdown","seoTitle","seoDescription","canonicalUrl","presentation","currentVersionNumber","publishedVersionNumber","previewUrl"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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. Send either postId for the current saved tip or contentMarkdown for unsaved input, never both. previewUrl is a secret bearer link to the current saved tip, not an immutable version. Share only with the owner or explicitly authorized reviewers; never put it in public content. Rotate it if exposed. Requires scope: posts:read.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"postId":{"type":"string","minLength":1},"presetId":{"type":"string"},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false}},"required":["postId"],"additionalProperties":false},{"type":"object","properties":{"contentMarkdown":{"type":"string","maxLength":500000},"presetId":{"type":"string"},"presentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false}},"required":["contentMarkdown"],"additionalProperties":false}]}}}},"responses":{"200":{"description":"Rendered preview","content":{"application/json":{"schema":{"type":"object","properties":{"previewUrl":{"type":["string","null"],"format":"uri"},"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"}},"seo":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["error","warn","info"]},"field":{"type":"string"},"message":{"type":"string"},"fix":{"type":"string"},"position":{"type":"number"}},"required":["code","severity","field","message","fix"]}},"rendererVersion":{"type":"string"},"requestedPresentation":{"type":["object","null"],"properties":{"layout":{"type":"string","enum":["standard","essay","feature","wide"]},"toc":{"type":"boolean"}},"additionalProperties":false},"resolvedPresentation":{"type":"object","properties":{"layout":{"type":"string","enum":["standard","essay","feature","wide"]},"toc":{"type":"boolean"}},"required":["layout","toc"]},"presentationWarnings":{"type":"array","items":{"type":"string"}}},"required":["previewUrl","html","outline","warnings","seo","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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}},"/api/v1/posts/{postId}/seo":{"get":{"operationId":"seoCheckPost","description":"Check a saved post's SEO and AI-answer readiness on the current tip with deterministic rules; vibecms runs no AI model on the post. Returns versionNumber plus findings sorted by severity (error, warn, info); each finding has a stable code and a fix hint. posts.preview already returns the same findings in its seo field. Optional focusKeyword adds keyword checks. Judgment calls (does the opening answer the title, which claims need a source) are for your own agent; see the vibecms-seo skill. Example: {\"postId\": \"post_1\", \"focusKeyword\": \"release notes\"}. Requires scope: posts:read.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"postId","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":80},"required":false,"name":"focusKeyword","in":"query"}],"responses":{"200":{"description":"SEO findings for the post's current tip","content":{"application/json":{"schema":{"type":"object","properties":{"versionNumber":{"type":"integer"},"findings":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["error","warn","info"]},"field":{"type":"string"},"message":{"type":"string"},"fix":{"type":"string"},"position":{"type":"number"}},"required":["code","severity","field","message","fix"]}}},"required":["versionNumber","findings"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"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":{},"retryAfterSeconds":{"type":"integer","exclusiveMinimum":0}},"required":["code","message"]}},"required":["error"]}}}}}}}},"webhooks":{}}