What it means
A bearer token is a string that means "let this request through". The server checks the string, not the sender. There is no signature to verify, no key exchange, no challenge and response. Presenting the token is the authentication.
RFC 6750, "The OAuth 2.0 Authorization Framework: Bearer Token Usage", defines the mechanics and states the security model in one sentence: any party in possession of a bearer token can use it. The metaphor is a banknote. The bank does not ask who you are, and a note that falls out of your pocket is spendable by whoever finds it.
Everything else about bearer tokens is a consequence of that sentence. Use TLS, because anyone who reads the token owns it. Keep them out of URLs, because URLs are logged. Keep them out of browsers, because devtools is a log. Scope them narrowly, because a stolen token does whatever the token was allowed to do. Make them revocable, because you will eventually need to kill one at two in the morning.
Where the token goes
RFC 6750 defines three transmission methods, and only the first should be used in new work.
- Section 2.1, the Authorization header.
Authorization: Bearer <token>. The scheme name is case-insensitive as an HTTP auth scheme, but write it asBearerbecause some servers compare it naively. This is the method to use. - Section 2.2, a form-encoded body parameter. Allowed for constrained clients that cannot set headers. Requires a specific content type and rules out sending anything else in the body, so it is rarely useful.
- Section 2.3, a URI query parameter. Defined, and marked NOT RECOMMENDED in the specification itself. URLs end up in access logs, proxy logs, browser history and, for a long time, in the Referer header sent to third parties. A token in a URL is a token that has been written down in half a dozen places you do not control.
The Pinlyx Data API accepts a key in a header only, either as a bearer token or as the equivalent x-api-key header for clients where that is more convenient. Both carry the same value; neither is a query parameter.
The token's own grammar
RFC 6750 defines the token value as b64token: one or more characters from ALPHA, DIGIT, -, ., _, ~, +, /, followed by optional = padding. No spaces, no colons, no commas. That constraint is why nearly every API key you have seen is letters, digits and underscores, and it is what makes a prefix like psk_live_ both legal and useful.
The prefix is not decoration. Secret scanners in source hosts, CI systems and log pipelines match on distinctive prefixes, so a token that starts with a recognisable marker gets caught when it is committed by accident. A separate psk_test_ prefix for test keys buys a second thing: a test key that reaches production fails loudly instead of quietly spending real budget.
Opaque, self-contained, or sender-constrained
"Bearer" describes how the token is transmitted, not what is inside it. Three families exist, and the choice is a real trade-off rather than a matter of taste.
An opaque token is a random string that means nothing outside the issuer's own store. Every request costs a lookup, which is the price of the property that matters most in practice: revocation is instant. Delete the row and the very next request fails.
A JWT carries its own claims and signature, so a resource server can verify it without asking anyone. RFC 9068 profiles exactly this for OAuth 2.0 access tokens. The cost is that you cannot un-issue it: a JWT stays valid until it expires unless you add a denylist, at which point you have paid for the lookup you were avoiding. Short lifetimes plus refresh is the usual compromise.
A sender-constrained token binds the credential to a key the client holds, via mutual TLS (RFC 8705) or DPoP (RFC 9449). A thief who copies the token but not the key gets nothing. This is strictly stronger, and it is still uncommon in data APIs because it pushes key management onto every integrator.
What the server says when it refuses
RFC 6750 section 3.1 defines a WWW-Authenticate challenge and three error codes, and the mapping to status codes is the part worth memorising:
invalid_requestwith 400: the request itself is malformed, for example two authentication methods at once.invalid_tokenwith 401: missing, expired, revoked or malformed credential. Re-authenticating might help.insufficient_scopewith 403: the token is genuinely valid and still not allowed to do this. Re-authenticating cannot help; the credential needs a different scope.
That last distinction is why 401 and 403 must not be used interchangeably. A client that receives 401 will refresh its credential and try again, which is precisely the wrong response to a scope problem and produces an infinite loop of successful authentications followed by identical refusals.
The Data API expresses the same distinctions in its own envelope: 401 with code unauthorized or invalid_key, and 403 with code forbidden_scope. It adds a fourth that RFC 6750 does not model at all: forbidden_ip, when a valid key with the right scope is used from an address outside its allowlist. That is a sender constraint bolted onto a bearer scheme, and it is one of the cheapest ways to blunt the impact of a leak.
Handling rules that actually matter
- TLS, always. RFC 6750 requires it. A bearer token sent over plain HTTP is a credential published to every hop on the path.
- Never in front-end code. An API key is a server-to-server credential. Anyone who opens devtools on a page that carries one has your whole quota. Call the API from your own backend and forward the result.
- Never in a log. Redact the Authorization header at the logging layer, not at each call site, because the call site you forget is the one that ships.
- One key per job. Separate keys per environment, per service and per integration mean a leak is contained and revocation does not take everything else down with it.
- Rotate on a schedule you have actually rehearsed. A rotation procedure that has never been run is not a procedure.
Related concepts
- API scope: what limits the damage a stolen token can do.
- HMAC signature: the other authentication model, where a leaked value is worthless on its own.
- Rate limit: the ceilings that are counted per key rather than per user.
- Webhook: the inbound direction, where you verify rather than present a credential.
How Pinlyx handles it
Data API keys are opaque, prefixed psk_live_ for production and psk_test_ for test, minted in the panel in about a minute, and revocable instantly. A key carries the scopes your plan allows and a rate tier, and it can be restricted to an IP allowlist. Send it as a bearer token or as x-api-key, over TLS, from your own backend. A revoked key produces a 401 with the code invalid_key and a message that says exactly that, so an expired credential is never mistaken for an outage.