Changelog

List entries

GET /api/v1/changelog

Returns full entries including their MDX bodies — unlike the blog list endpoint, which is metadata-only. Changelog entries are short by nature, so one call renders a whole release-notes page.

Public; a key scopes and rate-limits the request.

ParameterDefaultNotes
projectId—Required unless a key is sent
limit20Clamped to 1–100
cursor—Opaque cursor from a previous pageInfo.endCursor
curl "https://api.inkform.dev/api/v1/changelog?projectId=YOUR_PROJECT_ID&limit=20"
{
  "data": [
    {
      "slug": "v2-1-0",
      "title": "Faster builds",
      "date": "2026-09-05",
      "version": "2.1.0",
      "tags": ["performance"],
      "excerpt": "Builds are 40% faster.",
      "body": "Builds are 40% faster.\n\n## How\n\nWe..."
    }
  ],
  "pageInfo": { "hasNextPage": true, "endCursor": "djItMS0wLm1keA" },
  "totalCount": 58
}

Paging

This endpoint is cursor-paginated (the blog list is offset-paginated — see Pagination). Pass the previous response's endCursor to continue:

curl "https://api.inkform.dev/api/v1/changelog?projectId=YOUR_PROJECT_ID&cursor=djItMS0wLm1keA"

Treat the cursor as opaque. It currently encodes the last item's filename, which is an implementation detail that may change.

If the entry a cursor points at is deleted, paging restarts from the beginning rather than erroring. For a stable snapshot of a large changelog, fetch it in one pass rather than paging slowly across edits.

Create an entry

POST /api/v1/changelog

Requires a secret key with content:write. Commits to your connected repo.

{
  "frontmatter": {
    "title": "Faster builds",
    "date": "2026-09-05",
    "version": "2.1.0",
    "status": "published",
    "tags": ["performance"]
  },
  "doc": {
    "blocks": [
      { "id": "1", "type": "raw", "mdx": "Builds are 40% faster." }
    ]
  }
}

Only title is required. date defaults to today, status defaults to published, and version is free-form — tag it however you version.

curl -X POST "https://api.inkform.dev/api/v1/changelog" \
  -H "Authorization: Bearer inkform_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "frontmatter": { "title": "Faster builds", "version": "2.1.0" },
    "doc": { "blocks": [{ "id": "1", "type": "raw", "mdx": "Builds are 40% faster." }] }
  }'

See Blog → the raw block for the block model and the same error table — changelog writes behave identically.

Releasing from CI

Publishing release notes from a release pipeline is the common case:

curl -X POST "https://api.inkform.dev/api/v1/changelog" \
  -H "Authorization: Bearer $INKFORM_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --arg v "$VERSION" --arg body "$RELEASE_NOTES" '{
    frontmatter: { title: ("Release " + $v), version: $v },
    doc: { blocks: [{ id: "1", type: "raw", mdx: $body }] }
  }')"

Keep the key in your CI secret store — it's a secret key, and anything that can read your CI environment can publish to your changelog.