Getting started
API keys
Two kinds of key, what each one may do, and why the browser gets its own.
Every request carries a key, and the key selects the project:
Authorization: Bearer sk_…
There is no project id in any URL. The same path serves different content for different keys, which means you can point a staging deploy at a different project by changing one environment variable.
The two kinds
sk_… secret | pk_… publishable | |
|---|---|---|
| Where it runs | Server-side only | Safe in a browser |
| Origin restriction | None | Locked to the origins you list |
| Can list releases | Yes | No |
| Can write | Yes | No, except a knowledge base vote |
| Recoverable after creation | No | Yes |
Secret keys
A secret key is shown once, when you create it. We store a hash, not the key, so there is no “reveal” button and support cannot recover it. Losing one means creating another and revoking the old.
Treat it like a database password. It reads everything the project serves, including unpublished releases, and it can write.
Publishable keys
A publishable key is designed to be readable. It ships in page source, in a
mobile bundle, in a view-source. That is the point, and it is why the key
alone is not trusted as a claim about who is calling.
Two things bound it:
- An origin allow-list. Add your site’s origins to the key and a browser
request from anywhere else is refused.
www.is ignored when matching, so listinghttps://example.comcovershttps://www.example.com. - A tighter rate budget. Publishable keys are counted per key and per address, so one visitor hammering your help centre is limited without limiting every other visitor holding the same key.
Check a key
/v1/ping curl https://api.zevcontent.net/v1/ping \
-H "Authorization: Bearer $ZEVCONTENT_KEY"
Confirms the key resolves and names the project it belongs to. This is the first call to make when something is not behaving. It separates “wrong key” from “wrong request”, which are the two problems that look identical from a 404.
Rotating and revoking
Revoking is immediate: the next request with that key is refused. There is no grace period, so create the replacement, deploy it, and revoke afterwards.
Because a key belongs to one project, rotating one never affects another.
Which key for which job
- A static site build. Secret. It runs on a build machine, not a browser,
and it can ask for
media_urls=permanentto refuse expiring image URLs. - A React or Vue frontend fetching at runtime. Publishable, with your origins listed.
- A help centre with helpful/not-helpful voting. Publishable. The vote endpoint is the one write a browser should ever make, and it explicitly expects a publishable key.
- A migration script or an AI agent creating content. Secret. Writes require one.
Updated at, Wednesday, September 2, 2026