API overview
A REST API over your published content and your newsletter subscribers.
Base URL
https://api.inkform.dev
Not the apex. The platform routes by host, and only api. serves /api/v1/*.
A call to https://inkform.dev/api/v1/... gets a 308 to www.inkform.dev, which
307s on to app.inkform.dev. Redirect responses carry no CORS headers, so a browser
request fails on the chain rather than arriving anywhere useful.
What you can do
| Area | Endpoints | Key required |
|---|---|---|
| Blog | List posts, get one post, create/update a post | Read: no · Write: secret |
| Changelog | List entries, create an entry | Read: no · Write: secret |
| Docs | Get the nav tree, get a page | No |
| Subscribers | List subscribers, add a subscriber | Yes, always |
| Comments & reactions | Read threads and counts | No |
There is also a machine-readable spec at
/api/v1/openapi.json. It's generated
from the same schemas the endpoints validate against.
Identifying a project
Every request needs to know which project it's about, one of two ways:
- A
projectIdquery parameter — for public read calls. - An API key — a key is bound to one project, and that binding wins. If you send both, the key's project is used and the parameter is ignored.
Your project ID is shown in the project's API tab in the dashboard.
Response shape
Successful responses wrap the payload in data:
{ "data": { } }List endpoints add pagination metadata:
{
"data": [],
"pageInfo": { "hasNextPage": false, "endCursor": null },
"totalCount": 0
}Errors return a plain message — never a stack trace, never partial data:
{ "error": "API key is missing required scope(s): subscribers:read" }| Status | Meaning |
|---|---|
400 | Malformed request — missing projectId, invalid body, bad email |
401 | Missing or invalid key; revoked or expired |
403 | Valid key, but missing a required scope |
404 | No such project, post, page, or entry |
409 | Project has no connected GitHub repository (writes only) |
429 | Rate limited — see Rate limits |
CORS
All /api/v1/* endpoints send Access-Control-Allow-Origin: * and answer preflight
OPTIONS. Allowed headers are Content-Type, Authorization, and X-Inkform-Key.
Browser-side calls are therefore fine — but only with a publishable key. A secret key in client-side JavaScript is a secret you've published.
Versioning
The path carries the version (/api/v1/). Additive changes — new fields, new endpoints —
ship without a version bump, so parse defensively and ignore fields you don't recognise.