API reference
Introspection
One request that returns your project's entire contract. The most useful call in the API.
/v1/introspection curl https://api.zevcontent.net/v1/introspection \
-H "Authorization: Bearer $ZEVCONTENT_KEY"
Works with any key kind.
Why it exists
Documentation goes stale. This does not: it is generated from the same code that serves every other request, and it describes your project rather than the product in general.
If you are an AI agent, or writing one, this replaces reading the rest of this site to learn what to send. These pages explain why.
What comes back
{
"data": {
"project": { "name": "…", "slug": "…" },
"release": { "id": "rel_…", "name": "Launch", "default": true },
"releases": [ /* secret keys only */ ],
"core_endpoints": [ /* /v1/content, /v1/schema, /v1/ping */ ],
"content_types": [ /* your types, with fields and response_shape */ ],
"media": { "access": "public", "urls": "permanent" },
"rich_text": { /* every node, mark and variant */ },
"conventions": { /* auth, pagination, filtering, rate limits, errors */ },
"modules": [ /* blog, kb, authors: endpoints, shapes, counts */ ]
}
}
content_types
Each type with its fields and a response_shape, which is what a response
actually contains, key by key:
{
"slug": "team-member",
"kind": "collection",
"fields": [ { "key": "photo", "type": "image", "required": false } ],
"response_shape": {
"photo": {
"url": "string",
"alt": "string|null",
"width": "number|null",
"height": "number|null",
"content_type": "string",
"url_expires_at": "string (ISO 8601). This URL stops working then."
}
}
}
Scalar fields map to a type string. image and gallery map to an object:
five keys you would otherwise discover by fetching content and guessing, plus
the sixth that only appears on a private project.
modules
Each built-in module with its endpoints, its query parameters, its shapes, the
notes that matter, and counts, which is how much is in it. Modules are always
present, because their endpoints exist on every project whether or not anything
has been written.
conventions
The rules that hold everywhere, stated once rather than repeated per module: authentication, pagination, filtering (including the operator list), rate limits (with the real numbers), and the error envelope.
Every number in it is read from the code that enforces it, so it cannot drift.
rich_text
The complete document contract: block nodes, inline nodes, marks, heading levels, callout variants, image sources, embed providers, and the rules for each. It is static and identical for every project, and it is here anyway, because “write a richtext value” is unanswerable without it and the caller this endpoint exists for has no documentation open.
Secret and publishable keys see different things
Everything else is identical. The schema is not a secret to someone already holding a key to the project, and hiding it would make every publishable-key integration start with a guessing game.
Counts and privacy
Module counts report published content only, and the knowledge base counts only visible collections and sections.
This response is readable with a publishable key. “This project has fourteen unpublished articles” is a fact about work in progress that a stranger reading a page source should not learn, and counting a hidden collection would advertise navigation nobody can reach.
Reading a specific release
curl "https://api.zevcontent.net/v1/introspection?release=rel_…" \
-H "Authorization: Bearer $ZEVCONTENT_KEY"
content_types then describes that release’s schema, which is the point of
a staging release: the new shape, before it is live.
The built-in modules are release-independent, so their part of the response does not change.
Updated at, Wednesday, September 2, 2026