Docs
Dashboard

API reference

Authentication

Bearer keys, what each kind may do, and the failures that look like authentication and are not.

Authorization: Bearer sk_…

The key selects the project. No project id appears in any URL, so pointing a deploy at a different project is a change to one environment variable.

Key kinds

sk_…, secret. Server-side only. Reads everything the project serves, can list every release, and can write. Shown once at creation; we store a hash, so it cannot be recovered.

pk_…, publishable. Safe in a browser. Restricted to the origins listed on it, cannot list releases, and cannot write, with one deliberate exception: the knowledge base vote endpoint.

Full comparison in API keys.

Verify a key

GET /v1/ping
curl https://api.zevcontent.net/v1/ping \
  -H "Authorization: Bearer $ZEVCONTENT_KEY"

Confirms the key resolves and names its project. Make this call first when something is not behaving. It separates “wrong key” from “wrong request”, which look identical from a 404.

Failures

StatuscodeWhat it means
401unauthenticatedMissing, malformed, unknown or revoked key. Revocation is immediate.
403origin_not_allowedA publishable key used from an origin not on its list.
403secret_key_requiredA write, or a release listing, attempted with a publishable key.

The origin check

A publishable key with origins listed is refused from any other browser origin. The check compares the Origin header, ignoring www., so https://example.com covers https://www.example.com. Scheme and port are part of an origin: http://localhost:3000 and http://localhost:5173 are not the same.

It is best-effort by nature. curl sends whatever it likes, so an allow-list does not make a publishable key secret. It stops your key powering somebody else’s site, which is the realistic abuse.

What a key can see

A key sees its project’s published content, and nothing outside that project. There is no endpoint that crosses a project boundary, and an id from another project is not found rather than forbidden, because a “forbidden” would confirm the id exists.

Drafts are never served on /v1, whichever key you hold. A draft article answers blog_article_not_published or kb_article_not_published, which says what is wrong rather than pretending the slug does not exist.

Updated at, Wednesday, September 2, 2026