Every request carries your key in the x-api-key header. There is no OAuth flow, no token
exchange, no per-endpoint scope to request, and nothing expires unless you decide it should.
curl 'https://api.apiverve.com/v1/dadjokes' \
-H 'x-api-key: YOUR_API_KEY'Your key is on the API keys page of the dashboard. A new account has one the moment it exists — there is no provisioning step.
The header
x-api-key is the canonical form, and header names are case-insensitive, so X-API-Key and
X-API-KEY are the same header. Two alternates are accepted for clients that only speak
Authorization:
| Form | When to use it |
|---|---|
x-api-key: <key> | Default. Every example in these docs. |
Authorization: Bearer <key> | HTTP clients and SDK wrappers that only expose bearer auth. |
x-jwt: <token> | Dashboard-issued session tokens, not raw keys. |
All three resolve to the same account and the same billing. Pick one — sending more than one is not an error, but it makes the failure harder to read when something is wrong.
What a key is
A key is a UUID: a1b2c3d4-e5f6-7890-abcd-ef1234567890.
One key covers your whole account: everything your plan includes, with no per-source enablement. What the key controls is:
- Which plan applies — credits, rate limit and concurrency all come from the key's account.
- What it may reach — optionally narrowed with key scoping.
- Where it may be used from — optionally narrowed with an IP allow-list.
- How long it lives — optionally given an expiry, see key expiration.
Additional keys, each with their own name and restrictions, are sub-keys.
The three rejection modes
Authentication fails in three visibly different ways, and knowing which is which saves the most common hour of debugging on this API.
It is an HTML 403 from the edge, with no JSON body and no CORS headers. In a browser that
surfaces as TypeError: Failed to fetch with no readable status at all.
| What you sent | What you get | What it means |
|---|---|---|
No x-api-key header | HTML 403 | The request never reached the API |
| A key that is not UUID-shaped | HTML 403 | Rejected on shape — truncated key, or YOUR_API_KEY left in |
| A UUID that is not yours | JSON 401 unauthorized | Reached the API, key not recognised |
| A valid key, blocked call | JSON 403 | Scoping, IP allow-list, or revoked — see errors |
The practical version: if you get Failed to fetch or an HTML page, look at whether the header
is being sent at all. An undefined environment variable produces x-api-key: undefined, which
is not UUID-shaped, which is the second row.
# What "the key isn't reaching the request" looks like
curl -i 'https://api.apiverve.com/v1/dadjokes' -H 'x-api-key: undefined'
HTTP/1.1 403 Forbidden
Content-Type: text/html; charset=UTF-8Keeping the key out of your code
The key is a bearer credential: anyone who has it can spend your credits. It needs the same handling as a database password.
// Never this — it ships to every client and lives forever in git history
const KEY = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
// This
const KEY = process.env.APIVERVE_API_KEY;
if (!KEY) throw new Error('APIVERVE_API_KEY is not set');That second line is worth writing every time. Without it, a missing variable does not fail at
startup — it fails at the first API call, as an opaque 403, in production.
import os, requests
key = os.environ["APIVERVE_API_KEY"] # KeyError at import if unset
requests.get(
"https://api.apiverve.com/v1/dadjokes",
headers={"x-api-key": key},
timeout=10,
)# Docker / CI — inject, never bake
docker run -e APIVERVE_API_KEY="$APIVERVE_API_KEY" myappThe rules that actually prevent incidents:
- Environment variables or a secrets manager, never source. Add
.envto.gitignorebefore the first commit, not after. - Never in frontend JavaScript. A key in a browser bundle is a published key. If a browser must call the API, put a thin endpoint of your own in front and keep the key on the server — see CORS for the full argument.
- Never in logs. Redact the header when logging requests; log the last four characters if you need to identify which key was used.
- One key per environment. Staging and production sharing a key means revoking one takes down both.
Rotating a key
Rotation replaces the key with a new one and invalidates the old one immediately. There is no grace period, so the order matters:
- Create a sub-key for the workload, or note where the current key is in use.
- Roll the new key out everywhere first.
- Rotate only once nothing is still reading the old value.
If a key has leaked, invert that: rotate first and accept the downtime. A leaked key is spending your credits for as long as it works.
Full procedure, including the zero-downtime pattern with overlapping sub-keys, is in key rotation.
Checking a key works
The analytics endpoint is the probe to reach for: every valid key can read it, it takes no parameters, and it is never billed — so testing a key costs nothing.
curl 'https://api.apiverve.com/v1/analytics' \
-H 'x-api-key: YOUR_API_KEY'A 200 means the key is good. A 401 means it is not — the only status that is a verdict on the
key itself. A 429 means the key is fine and the account is out of credits, and a 403 HTML page
means the request never left your client in the right shape.
Next
Now that a call authenticates, making requests covers parameters, bodies and timeouts.
If your key needs to be narrower than your account, start at key scoping. The key itself lives on the dashboard, alongside the usage it spends.