{"openapi":"3.0.0","info":{"title":"Inkform Headless Content API","version":"1.0.0","description":"Public, read-only delivery of changelog, blog, and docs content as MDX."},"components":{"securitySchemes":{"ApiKeySecret":{"type":"http","scheme":"bearer","description":"Secret API key (`inkform_sk_...`). Server-only — grants read + write + subscriber scopes. Send as `Authorization: Bearer <key>` or `X-Inkform-Key: <key>`."},"ApiKeyPublishable":{"type":"http","scheme":"bearer","description":"Publishable API key (`inkform_pk_...`). Safe for browser use — read-only (`content:read`). Send as `Authorization: Bearer <key>` or `X-Inkform-Key: <key>`."}},"schemas":{"ChangelogEntry":{"type":"object","properties":{"slug":{"type":"string","description":"URL slug of the entry"},"title":{"type":"string","description":"Entry title"},"date":{"type":"string","description":"Publish date, ISO YYYY-MM-DD"},"version":{"type":"string","nullable":true,"description":"Release version if tagged, else null"},"tags":{"type":"array","items":{"type":"string"},"description":"Free-form tags"},"excerpt":{"type":"string","description":"Short plaintext summary"},"body":{"type":"string","description":"MDX body without frontmatter — render with the SDK or framework"}},"required":["slug","title","date","version","tags","excerpt","body"]},"BlogPostMeta":{"type":"object","properties":{"slug":{"type":"string","description":"URL slug"},"title":{"type":"string","description":"Post title"},"date":{"type":"string","description":"Publish date, ISO YYYY-MM-DD"},"author":{"type":"string","nullable":true,"description":"Author display name, or null"},"tags":{"type":"array","items":{"type":"string"},"description":"Free-form tags"},"series":{"type":"string","nullable":true,"description":"Series slug this post belongs to, or null"},"description":{"type":"string","nullable":true,"description":"SEO/meta description, or null"},"coverImage":{"type":"string","nullable":true,"description":"Cover image URL, or null"},"excerpt":{"type":"string","description":"Short plaintext summary"},"readTimeMinutes":{"type":"number","description":"Estimated read time in minutes"}},"required":["slug","title","date","author","tags","series","description","coverImage","excerpt","readTimeMinutes"]},"BlogPost":{"allOf":[{"$ref":"#/components/schemas/BlogPostMeta"},{"type":"object","properties":{"body":{"type":"string","description":"MDX body without frontmatter"}},"required":["body"]}]},"DocsTree":{"type":"object","properties":{"name":{"type":"string","description":"Docs site name"},"version":{"type":"string","description":"Config schema version"},"navigation":{"type":"array","items":{"type":"object","properties":{"group":{"type":"string","description":"Sidebar group label"},"pages":{"type":"array","items":{"nullable":true},"description":"Pages (title/slug/file, optionally nested children)"}},"required":["group","pages"]},"description":"Ordered sidebar groups"}},"required":["name","version","navigation"]},"DocPage":{"type":"object","properties":{"slug":{"type":"string","description":"Nav slug (independent of the file path)"},"title":{"type":"string","description":"Page title"},"description":{"type":"string","nullable":true,"description":"SEO/meta description, or null"},"body":{"type":"string","description":"MDX body without frontmatter"}},"required":["slug","title","description","body"]},"Subscriber":{"type":"object","properties":{"id":{"type":"string","description":"Subscriber id"},"email":{"type":"string","description":"Subscriber email"},"status":{"type":"string","enum":["pending","active","unsubscribed","bounced","complained"],"description":"Subscription status"},"source":{"type":"string","nullable":true,"description":"Signup-source label"},"subscribed_at":{"type":"string","description":"ISO timestamp of first signup"}},"required":["id","email","status","source","subscribed_at"]},"PageInfo":{"type":"object","properties":{"hasNextPage":{"type":"boolean","description":"Whether more items exist after this page"},"endCursor":{"type":"string","nullable":true,"description":"Opaque cursor for the next page, or null"}},"required":["hasNextPage","endCursor"]},"ChangelogResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ChangelogEntry"}},"pageInfo":{"$ref":"#/components/schemas/PageInfo"},"totalCount":{"type":"number"}},"required":["data","pageInfo","totalCount"]},"WriteResult":{"type":"object","properties":{"data":{"type":"object","properties":{"slug":{"type":"string"},"fileName":{"type":"string"},"commitUrl":{"type":"string"}},"required":["commitUrl"]}},"required":["data"]},"BlogListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BlogPostMeta"}},"pageInfo":{"$ref":"#/components/schemas/PageInfo"},"totalCount":{"type":"number"}},"required":["data","pageInfo","totalCount"]},"BlogPostResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BlogPost"}},"required":["data"]},"DocsTreeResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/DocsTree"}},"required":["data"]},"DocPageResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/DocPage"}},"required":["data"]},"SubscribersListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Subscriber"}}},"required":["data"]},"SubscriberCreateResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"status":{"type":"string","description":"New signups are always 'pending' — the platform emails a confirm link; there is no API-returned token to bypass it"}},"required":["id","email","status"]}},"required":["data"]}},"parameters":{}},"paths":{"/api/v1/changelog":{"get":{"summary":"List published changelog entries (cursor-paginated). Public without a key; a key scopes + rate-limits the request.","security":[{"ApiKeyPublishable":[]},{"ApiKeySecret":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"projectId","in":"query"},{"schema":{"type":"number"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangelogResponse"}}}}}},"post":{"summary":"Create a changelog entry, committed to the connected GitHub repo","security":[{"ApiKeySecret":[]}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteResult"}}}},"400":{"description":"Invalid body"}}}},"/api/v1/blog/posts":{"get":{"summary":"List published blog posts (metadata; offset-paginated). Public without a key; a key scopes + rate-limits the request.","security":[{"ApiKeyPublishable":[]},{"ApiKeySecret":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"projectId","in":"query"},{"schema":{"type":"string"},"required":false,"name":"tag","in":"query"},{"schema":{"type":"number"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"number"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogListResponse"}}}}}},"post":{"summary":"Create or update a blog post, committed to the connected GitHub repo","security":[{"ApiKeySecret":[]}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteResult"}}}},"400":{"description":"Invalid body"}}}},"/api/v1/blog/posts/{slug}":{"get":{"summary":"A single published blog post including its MDX body. Public without a key.","security":[{"ApiKeyPublishable":[]},{"ApiKeySecret":[]}],"parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string"},"description":"The Inkform project UUID"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlogPostResponse"}}}},"404":{"description":"Not found"}}}},"/api/v1/docs/tree":{"get":{"summary":"The docs navigation tree (docs.json). Public without a key.","security":[{"ApiKeyPublishable":[]},{"ApiKeySecret":[]}],"parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string"},"description":"The Inkform project UUID"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocsTreeResponse"}}}},"404":{"description":"Not found"}}}},"/api/v1/docs/{slug}":{"get":{"summary":"A single published doc page (MDX body), resolved by nav slug. Public without a key. Combined with /api/v1/docs/tree, this makes a docs project fully retrievable by an AI agent (structure + content) over the same scoped-key surface as blog/changelog.","security":[{"ApiKeyPublishable":[]},{"ApiKeySecret":[]}],"parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string"},"description":"The Inkform project UUID"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocPageResponse"}}}},"404":{"description":"Not found"}}}},"/api/v1/subscribers":{"get":{"summary":"List a project's newsletter subscribers — requires subscribers:read, no public fallback","security":[{"ApiKeySecret":[]}],"parameters":[{"schema":{"type":"string","enum":["pending","active","unsubscribed","bounced","complained"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"number"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"number"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribersListResponse"}}}}}},"post":{"summary":"Add a subscriber (double opt-in pending) — requires subscribers:write","security":[{"ApiKeySecret":[]}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriberCreateResponse"}}}},"400":{"description":"Invalid body"}}}}}}