What Is a Bearer Token? Bearer Token Authentication Explained
Updated 30 September 2026. Rewritten and merged with our newer bearer token guide, with current ApyHub endpoints and header details.
01Introduction
A bearer token is a credential where holding it is the proof. Whoever bears the token gets the access, and the server checks only that the token is valid, with no further check on who you are.
That is the entire model, and it is also the risk. A stolen bearer token works as well for the thief as for you, until it expires or is revoked.
You send it in the Authorization header:
GET /api/orders HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...The word Bearer, a space, then the token. That format comes from RFC 6750.
02How bearer token authentication works
Four steps, and the shape is the same across almost every API that uses them.
- You authenticate once. Username and password, an OAuth flow, or a client credentials exchange.
- The server issues a token. Usually short-lived, often with a refresh token alongside it.
- You send the token with every request in the
Authorizationheader. - The server validates it and either serves the request or returns
401.
The token replaces re-authenticating on every call. The server does not have to keep a session for you, because a self-contained token carries its own claims and expiry.
03Bearer token vs API key
These get used interchangeably, and they behave differently.
| API key | Bearer token | |
|---|---|---|
| Lifetime | Long-lived, often permanent | Short-lived, minutes to hours |
| Identifies | An application or account | Usually a user or a session |
| Issued by | A dashboard, once | An auth flow, repeatedly |
| Revocation | Manual, in a dashboard | Expiry, plus revocation |
| Typical header | Custom, for example apy-token | Authorization: Bearer |
| Carries claims | No | Often, if it is a JWT |
An API key says which application is calling. A bearer token usually says which user is calling, and for how long.
Plenty of APIs accept a long-lived API key in the Authorization: Bearer header, which blurs the line. What makes something a bearer credential is the model: if possession alone grants access, it is a bearer credential, whatever the header is called.
Some catalogs issue one key covering every service instead of one per API, which reduces the number of credentials you store and rotate. ApyHub works this way.
04Bearer token vs Basic auth
Basic authentication is the older scheme. The client joins a username and password with a colon, Base64-encodes the result, and sends it on every request:
GET /api/orders HTTP/1.1
Authorization: Basic dXNlcjpwYXNzDecode dXNlcjpwYXNz and you get user:pass. Anyone who can read the header can do the same in one line of code.
Base64 is encoding, and encoding is reversible by design. It makes the credentials safe to put in a header and leaves them readable. RFC 7617, which defines the scheme, says it is not a secure method of authentication unless it runs over an encrypted transport such as TLS.
The bigger difference is what travels. Basic auth sends the real password with every call, so a single leaked request exposes a credential the user may reuse elsewhere. A bearer token is issued for one API, can expire in minutes, and can be revoked without the user changing their password.
Basic auth still has a place for server-to-server calls over HTTPS where simplicity matters. ApyHub accepts Basic credentials in the Authorization header as an alternative to its token.
05Where OAuth 2.0 fits
RFC 6750, the spec that defines the Bearer format, is part of OAuth 2.0. That is where most bearer tokens come from.
OAuth 2.0 (RFC 6749) is an authorization framework. It defines how a client obtains a token: a user consenting to an app (the authorization code flow), a service authenticating as itself (client credentials), or a client swapping a refresh token for a new access token. It also defines scopes, which limit what a given token can do.
The division of labor:
- OAuth 2.0 decides who gets a token, with what scopes, for how long.
- Bearer is how the client presents that token on each request.
- JWT is one possible format for the token itself.
You can use bearer tokens without the full OAuth stack. Many APIs issue tokens from a plain login endpoint. OAuth earns its weight when third-party apps act on behalf of your users, or when you need consent screens and fine-grained scopes.
06Bearer tokens and JWTs
A common confusion worth clearing up.
- Bearer describes how a token is used: send it, and holding it is enough.
- JWT describes how a token is formatted: a signed, self-contained structure with claims inside.
Most JWTs are used as bearer tokens. Some bearer tokens are opaque random strings instead, which the server looks up rather than decodes.
Opaque tokens are easier to revoke, because the server holds the state. JWTs scale better, because validation needs no lookup. That is the trade.
Anatomy of a JWT
A JWT (RFC 7519) is three Base64url-encoded parts joined by dots:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Split on the dots and decode each part.
Header. The signing algorithm and the token type.
{
"alg": "HS256",
"typ": "JWT"
}Payload. The claims. sub is the subject (usually a user ID) and iat is the issue time as a Unix timestamp. Production tokens also carry exp (expiry), and often iss (issuer), aud (audience) and scopes.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}Signature. An HMAC-SHA256 of the encoded header and payload, computed with a secret only the issuer holds:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
The server recomputes the signature and compares. If anyone edits the payload, for example to change sub to another user, the signature no longer matches and the token is rejected.
Two things follow. The signature prevents tampering, so the claims can be trusted. The payload is only encoded, so anyone holding the token can read it: keep secrets and personal data out of it. To inspect a token while debugging, the JWT Decoder API returns the decoded header and payload.
07Sending a bearer token in code
The pattern is the same in every language: get a token, then attach it to each request. The examples keep credentials in environment variables, per the rules below.
Python with requests
import os
import requests
AUTH_URL = "https://auth.example.com/token"
API_URL = "https://api.example.com/data"
# 1. Authenticate once and get a token
auth_response = requests.post(
AUTH_URL,
json={
"username": os.environ["API_USERNAME"],
"password": os.environ["API_PASSWORD"],
},
timeout=10,
)
auth_response.raise_for_status()
token = auth_response.json()["access_token"]
# 2. Send it in the Authorization header on every request
response = requests.get(
API_URL,
headers={"Authorization": f"Bearer {token}"},
timeout=10,
)
if response.status_code == 401:
print("Token missing, malformed or expired. Get a new one.")
elif response.status_code == 403:
print("Token is valid but lacks permission for this resource.")
else:
response.raise_for_status()
print(response.json())Reuse the token until it expires. On a 401, fetch a new one (or use a refresh token) and retry once.
Node.js with axios
const axios = require("axios");
const AUTH_URL = "https://auth.example.com/token";
const API_URL = "https://api.example.com/data";
async function getData() {
// 1. Authenticate once and get a token
const auth = await axios.post(AUTH_URL, {
username: process.env.API_USERNAME,
password: process.env.API_PASSWORD,
});
const token = auth.data.access_token;
// 2. Send it in the Authorization header on every request
const response = await axios.get(API_URL, {
headers: { Authorization: `Bearer ${token}` },
timeout: 10000,
});
console.log(response.data);
}
getData().catch((err) => {
const status = err.response?.status;
if (status === 401) console.error("Token missing, malformed or expired.");
else if (status === 403) console.error("Token valid, permission denied.");
else console.error(err.message);
});For anything beyond a single call, create one axios instance with the header set, or add an interceptor that refreshes the token on a 401.
Testing bearer token requests
Before writing code, test the request in an API client. In Postman, Insomnia or Voiden, choose Bearer Token as the auth type and paste the token; the client adds the Authorization: Bearer header for you. Voiden stores the request as a plain Markdown file, so you can commit it next to your code with the token read from an environment variable. From the terminal, curl does the same:
curl https://api.example.com/data \
--header "Authorization: Bearer $API_TOKEN"08Getting an ApyHub token
ApyHub issues credentials from your workspace. By the definitions above, the token is a long-lived API key: you create it once in the dashboard, and it identifies your workspace across every API in the catalog.
- From your dashboard, click API Keys in the left panel, then click + API Keys.
- Select Token as the authentication type, give the token a name, and click Create.
- Download the credentials with Download your credentials, or copy the value to your clipboard. Secrets are generated on the fly and are not stored in plain text, so save the value in a secret manager or environment variable before you close the dialog.
ApyHub reads the token from the apy-token header. It does not go in Authorization: Bearer, which is a common mistake when moving between APIs.
bash
curl --request GET "https://api.eu.apyhub.com/apyhub/list-all-countries" \
--header "apy-token: $APY_TOKEN"
The same call in Python:
python
import os
import requests
response = requests.get(
"https://api.eu.apyhub.com/apyhub/list-all-countries",
headers={"apy-token": os.environ["APY_TOKEN"]},
timeout=10,
)
response.raise_for_status()
print(response.json())
The same rules apply to it as to any bearer credential: possession grants access, so it stays out of URLs, repos and browser storage.
If you use ApyHub from an AI assistant, you don't handle the token in code at all. Every endpoint is available through ApyHub MCP, so Claude, ChatGPT or Cursor can discover and call the APIs without a hand-written wrapper or tool definition. Sign-in happens once in the browser; for headless setups, the MCP server accepts Authorization: Bearer <your API key>.
09Six rules for handling bearer tokens
- Always use HTTPS. A bearer token sent over plain HTTP is a credential broadcast to the network. This one is non-negotiable.
- Keep it out of URLs. Query strings end up in server logs, browser history, referrer headers and analytics. Headers stay out of all of them.
- Keep it out of code repositories, public and private. Environment variables and secret managers exist for this.
- Keep the lifetime short. A token valid for an hour limits the damage from a leak. Pair it with a refresh token for continuity.
- Store browser tokens in httpOnly cookies, not localStorage. Any cross-site scripting flaw reads localStorage instantly, while JavaScript can't read an httpOnly cookie.
- Grant the least privilege the job needs. A token issued to read
/usershould not unlock/admin. Use scopes or separate tokens per job, so a leaked read-only token stays a read-only problem.
Rule five is the most commonly ignored. It decides whether an XSS bug is an annoyance or an account takeover.
10When a token fails: 401 vs 403
401 Unauthorized means the token is missing, malformed or expired. Get a new one.
403 Forbidden means the token is valid and lacks access to this resource. A new token won't help, because the permissions are wrong.
Mixing these up wastes debugging time. A 401 is about the credential. A 403 is about what the credential is allowed to do.
11Conclusion
A bearer token grants access to whoever holds it, which makes it simple to use and serious to leak. Send it only over HTTPS in the Authorization header, keep it short-lived and narrowly scoped, and store it where scripts and logs can't reach it. Know which layer you are dealing with: OAuth decides who gets a token, Bearer is how it travels, and JWT is one way to format it.
12FAQ
What is a bearer token? A credential where possession is proof of authorization. You send it in the Authorization header prefixed with Bearer, and the server grants access to whoever presents a valid one.
What is bearer token authentication? An authentication scheme where the client gets a token once, usually by logging in or through OAuth, and then sends it with every request. The server validates the token on each call instead of asking for credentials again.
What is the difference between a bearer token and an API key? An API key is typically long-lived and identifies an application. A bearer token is typically short-lived and identifies a user or session. Both are sent with requests, but their lifetime and what they represent differ.
Is a JWT a bearer token? Usually it is used as one, but the terms describe different things. Bearer is how a token is used; JWT is how it is formatted. An opaque random string can also be a bearer token.
Where should I store a bearer token in a browser app? In an httpOnly cookie, which JavaScript cannot read. Tokens in localStorage are exposed by any cross-site scripting vulnerability.
Why does my request return 401 with a valid token? Common causes: the token expired, the Bearer prefix is missing, there is whitespace or a newline in the value, or you are sending it to a different environment than the one that issued it.
What is the difference between 401 and 403? A 401 means the credential is missing or invalid, so a new token may help. A 403 means the credential is valid but lacks permission for this resource, so a new token won't help.
Should bearer tokens expire? Yes, and quickly. Short lifetimes limit the window in which a leaked token is useful. Use a refresh token to get new ones without asking the user to log in again.
Can I revoke a bearer token? It depends on the token type. An opaque token is revoked by deleting its record on the server. A JWT stays valid until its exp claim unless the server also checks a list of revoked token IDs; OAuth servers often expose a revocation endpoint defined in RFC 7009. For a long-lived key such as an ApyHub token, create a new one under API Keys, move your application to it, and retire the old one.
What happens if a bearer token is compromised? Whoever holds it can call the API as you until it expires or is revoked, and the server can't tell their requests from yours. Revoke or rotate it immediately, check logs for requests you didn't make, and find how it leaked before issuing the replacement.
How can I test a bearer token request? Use an API client such as Voiden, Postman or Insomnia and pick Bearer Token as the auth type, or send the header with curl. Every ApyHub API page also has a "Try it" panel that uses your key.
13Related
- What Is CORS and Why Is It Blocking My Request?: why the
Authorizationheader triggers a preflight - 405 Method Not Allowed: a different reason a request gets rejected
- API Fundamentals: authentication from scratch
14Sources
- RFC 6750: OAuth 2.0 Bearer Token Usage
- RFC 6749: The OAuth 2.0 Authorization Framework
- RFC 7617: The 'Basic' HTTP Authentication Scheme
- RFC 7519: JSON Web Token (JWT)
- RFC 7009: OAuth 2.0 Token Revocation
15About ApyHub
ApyHub is a curated API catalog and trusted operational layer for developers and AI agents, with over 1,500 endpoints or capabilities and growing. Teams use the whole catalog through a single subscription priced in atoms, a unit that reflects the actual work each call performs. Every endpoint ships with machine-readable certification aligned with GDPR, SOC 2 and ISO 27001, and is MCP-ready by default, so AI agents can discover and call it through ApyHub MCP without custom wrappers. ApyHub is headquartered in Amsterdam, with offices in the Netherlands, Greece and India, and serves 65,000+ developer workspaces every month. The free tier requires no card. Building an API of your own? Become a provider →
