Authentication

Public API requests carry either an X-API-Key header or an OAuth2 bearer token. What each is scoped to, and what a rejected request looks like.

The Kilevel public API lives under https://api.kilevel.com/api/external/v1 and takes either of two credentials.

curl -s https://api.kilevel.com/api/external/v1/balance \
  -H "X-API-Key: $KILEVEL_API_KEY"
X-API-Keyheader

The workspace API key, sent raw — no Bearer prefix. If this header is present it is the credential used, and Authorization is ignored.

Authorizationheader

Bearer <access_token>, where the token came from the OAuth2 client credentials flow. Read only when no X-API-Key header was sent.

Which one to use

A key is the shorter path: create it, paste it into your integration, done. It also never expires unless you give it an expiry, which is the argument against handing one to something you do not fully control.

An OAuth2 client is the better fit for agents and anything long-running. The client secret is exchanged for a token that lasts at most 24 hours, so a leaked token stops being useful on its own, and you can revoke the client without touching the integration's configuration. Tokens carry the permissions their client was given, so one workspace can hand out several narrowly-scoped credentials instead of copies of one key.

Scope

A key authenticates as the workspace that issued it. Every endpoint resolves its data from that workspace, so there is no account or tenant identifier in any path — a call job listed with your key is your call job, and there is no way to address another workspace's data by id.

This also means a key is as privileged as the workspace it belongs to. Treat it as a production credential: keep it in a secret store, never in client-side code, and rotate it if it has ever been pasted anywhere shared.

Never ship a key to a browser

The API is called from your backend. A key in frontend JavaScript, in a mobile bundle, or in an automation platform's public template is readable by anyone who opens it, and it can place calls that bill to your wallet.

Failed authentication

A missing or unrecognised key returns 401 with a JSON body rather than an HTML error page:

{
  "error": "Missing API key. Use X-API-Key header."
}

API keys are masked in request logs, alongside the Authorization header, so a key that reaches the platform does not end up readable in an audit trail.

Next