Skip to main content
Developer Tools

How to Test an API with Bearer Tokens, API Keys, and Basic Auth

11 min readUpdated August 17, 2026

Most APIs that do anything meaningful — read a private record, create something, charge a card — need to know who’s calling before they respond. That’s authentication: proving your identity on the request itself, since HTTP carries no memory of you between calls the way a logged-in browser session might.

Testing the authentication piece on its own, separate from whatever the endpoint actually does, makes it much faster to tell “my credentials are wrong” apart from “my request is wrong.” This guide covers the three schemes you’ll run into most often — Bearer tokens, API keys, and Basic Auth — with a live example of each you can open and send.

Authentication methods at a glance

The three schemes below aren’t interchangeable — which one an API expects is dictated entirely by that API’s own documentation, not by preference.

  • Bearer token — a string, often issued by a login endpoint or OAuth flow, sent in the Authorization header. The most common scheme for modern REST APIs.
  • API key — a key the provider issues you directly, sent as a header or a query parameter depending on the API. Simpler than a full token exchange; common for third-party and public APIs.
  • Basic Auth — a username and password combined and base64-encoded into the Authorization header. Older, but still common for internal tools and simple services.

Test an API with a Bearer token

A Bearer token is a credential proving who’s making the request — issued by a login endpoint, an OAuth flow, or generated directly in an API provider’s dashboard. Because HTTP requests carry no memory of who called last time, the token rides along in the Authorization header on every request that needs it.

There’s no one universal token format — a Bearer token might be an opaque string, a JWT, or something provider-specific — so treat it as whatever that API’s documentation says to send, not a fixed shape.

Rather than putting a real token into a public example, this one uses a {{token}} placeholder — the same syntax the API Request Builder’s environment variables use, so you can swap in your own value without editing the request itself:

  • Literal: Authorization: Bearer YOUR_TOKEN
  • Reusable: Authorization: Bearer {{token}} — resolved from an environment variable named token

Example request

Send a request with a Bearer token

A GET request with a templated Bearer token — safe to open and send, since {{token}} is left unresolved rather than a real credential.

GET https://httpbin.org/anything
Open in API Request Builder

Test an API with an API key

An API key is a credential the provider issues you directly — no login flow, no token exchange — that you attach to each request. Where it goes depends entirely on the API: some expect a header, some a query parameter, and the exact header or parameter name is whatever that provider chose.

A query-string API key proves the same thing a header one does, but it’s more exposed — URLs get written into server logs, browser history, and any proxy or CDN sitting in front of the API in ways headers usually aren’t. Use whichever the API’s documentation actually asks for, and default to a header when you have the choice.

  • Header: X-Api-Key: {{apiKey}}
  • Query parameter: https://example.com/data?api_key={{apiKey}}

Example request

Send a request with an API key

A GET request with a templated API key sent as a header — safe to open and send.

GET https://httpbin.org/anything
Open in API Request Builder

Test a Basic Auth API

Basic Auth sends a username and password, joined with a colon and base64-encoded, in the Authorization header: Authorization: Basic base64(username:password). Base64 is an encoding, not encryption — anyone who intercepts the header can decode it instantly, which is why Basic Auth only belongs on HTTPS.

The example below uses httpbin.org’s Basic Auth sandbox endpoint, which only accepts one specific username and password — both literally “demo” — and exists purely for testing. These are public example credentials for this one endpoint, not anything you’d reuse against a real API.

Opening the example carries over the method, URL, auth type, and username automatically; the password field arrives empty by design — type demo into it yourself before sending. See “What this tool does with your credentials” below for why.

Example request

Send a request with Basic Auth

A GET request to httpbin.org’s Basic Auth sandbox endpoint, which only accepts the public demo/demo username and password.

GET https://httpbin.org/basic-auth/demo/demo
Open in API Request Builder

How to test an authenticated request, step by step

The workflow is the same regardless of which scheme the API uses. Reaching for an environment variable instead of typing a credential directly is worth doing by default — the token or key lives in one place, and the request itself just references {{token}} or {{apiKey}}. One note on where the request actually goes: sending is browser-first, and most requests go straight from your browser to the target API, but if that API blocks cross-origin browser requests, this tool’s CORS proxy fallback (or a custom proxy you’ve configured) can route the request through a third-party server instead — it isn’t accurate to say a request always stays in the browser.

  • Identify the authentication method from the API’s documentation.
  • Open the API Request Builder.
  • Set the HTTP method and URL.
  • Open the Auth tab.
  • Select the matching authentication type — Bearer, API Key, or Basic Auth.
  • Enter the credential directly, or reference an environment variable (e.g. {{token}}).
  • Send the request.
  • Check the status code and response body before assuming it worked.

Using environment variables for auth

Instead of typing a real token or key directly into a request, define it once as an environment variable and reference it by name — the template stays in the request text, and the real value lives in whichever environment is active, swappable (e.g. staging vs. production) without touching the request itself.

Environment values are stored in this browser’s local storage, in plain text — not encrypted — the same as everything else this tool saves locally. Treat it the way you’d treat any other value sitting in your own browser: fine for a personal or team dev setup, not a place to leave a production credential you wouldn’t want exposed if the machine itself were compromised.

  • Environment: token = your-real-token
  • Environment: apiKey = your-real-api-key
  • Request header: Authorization: Bearer {{token}}
  • Request header: X-Api-Key: {{apiKey}}

API key placement: header vs. query parameter

Both forms send the same key; they just carry it in a different part of the request. The API’s own documentation decides which one is required — not personal preference — though a header is generally the safer default when an API supports both.

  • Header — X-Api-Key: {{apiKey}}. Not visible in the URL; the usual recommendation when an API supports both.
  • Query parameter — https://example.com/data?api_key={{apiKey}}. Visible in the URL itself, so it can end up in server logs, browser history, and any intermediary sitting in front of the API.

Authentication vs. authorization — and what 401 and 403 actually mean

Authentication answers “who are you?” — a Bearer token, API key, or Basic Auth credential is how you answer it. Authorization is a separate question: “what are you allowed to do, now that the server knows who you are?” A request can pass the first check and still fail the second.

The two status codes map roughly onto that distinction, though neither has one single universal cause:

  • 401 Unauthorized — the server doesn’t recognize you as authenticated. Common causes: no credential was sent, the token expired, the token or key is simply wrong, or the auth header isn’t formatted the way the API expects.
  • 403 Forbidden — the server knows who you are, but won’t let this particular request through. Common causes: the token or key lacks a required scope or permission, the account behind it doesn’t have access to this resource, or a policy is blocking the request for a reason unrelated to identity.

Bearer token as a cURL command

The example above, generated straight from its own request definition, so it can never drift out of sync with it:

  • curl -X GET 'https://httpbin.org/anything' \
  • --max-time 30 \
  • -H 'Authorization: Bearer {{token}}'

Bearer token as a JavaScript (Fetch) call

The same request as a fetch() call:

  • const controller = new AbortController();
  • const timeoutId = setTimeout(() => controller.abort(), 30000);
  • try {
  • const response = await fetch("https://httpbin.org/anything", {
  • method: "GET",
  • headers: {
  • "Authorization": "Bearer {{token}}",
  • },
  • credentials: "same-origin",
  • signal: controller.signal,
  • });
  • const data = await response.text();
  • console.log(data);
  • } finally {
  • clearTimeout(timeoutId);
  • }

Bearer token as a Python request

And using the requests library:

  • import requests
  • response = requests.get(
  • "https://httpbin.org/anything",
  • headers={
  • "Authorization": "Bearer {{token}}",
  • },
  • timeout=30,
  • )
  • print(response.status_code)
  • print(response.text)

Basic Auth as a cURL command

For comparison, the Basic Auth example as cURL — note requests handles the base64 encoding for you via -u:

  • curl -X GET 'https://httpbin.org/basic-auth/demo/demo' \
  • --max-time 30 \
  • -H 'Authorization: Basic ZGVtbzpkZW1v'

Works in cURL but fails in your browser?

An authenticated request that works fine from cURL, or from this tool, can still fail once it’s called from your own frontend’s JavaScript — and the reason is almost always CORS, not the authentication itself. CORS is enforced by browsers specifically, so cURL, this tool, and any server-to-server call bypass it entirely, which is why “it works everywhere except my frontend” is such a common report.

See What Is a CORS Error, and How Do You Fix It? (linked below) for what’s actually happening and how to fix it depending on whether you control the API.

What this tool does with your credentials

This section covers specifically what happens to a token, key, or password you type into a request’s Auth tab — worth reading before relying on any of it for something sensitive.

Request and environment state, including any credential you enter, lives in this browser’s local storage, not a cloud account — nothing needs to be created or signed into to use this tool.

Requests are sent browser-first with fetch(). If the target API doesn’t allow cross-origin browser requests, this tool’s CORS proxy fallback (or a custom proxy you’ve configured) can route the request through a third-party server instead — and that request, credentials included, does pass through that proxy, the way any proxy works. It is not accurate to say your credentials never leave your browser; whether they do depends on whether a proxy was involved.

Opening one of this guide’s examples only carries a credential value over if it’s written as a {{template}} — which is why the Bearer and API-key examples above open with {{token}} and {{apiKey}} intact, but the Basic Auth example’s username comes through while its literal “demo” password does not. That’s the link-sharing mechanism deliberately refusing to put a literal secret in a URL, not a bug in the example — type demo back into the password field yourself after opening it.

Saving a request, or letting one land in history, goes further still: the Bearer token, Basic Auth password, and API key value are always cleared before anything is written to local storage — template or not — so reopening a saved or historical request later means re-entering that value again.

localStorage itself is not encrypted. Anyone with access to this browser profile, or a script running on this page’s own origin, could in principle read what’s stored — the same caveat that applies to local storage in any web app, not something unique to this tool.

FAQ

What’s the difference between a Bearer token and an API key?

Both are credentials sent with the request, but a Bearer token is usually issued through a login or OAuth flow and can expire or get refreshed, while an API key is typically a long-lived value the provider hands you directly with no separate exchange step. Which one an API uses is decided by that API, not by you.

Why does my authenticated request work in cURL but fail from my frontend?

That’s almost always CORS, not the authentication — CORS is enforced by browsers specifically, so cURL, this tool, and any server-to-server call bypass it entirely. See What Is a CORS Error, and How Do You Fix It? for the real fix, which depends on whether you control the API.

Is Basic Auth secure?

Basic Auth only encodes the credentials (base64) — it doesn’t encrypt them, and anyone who intercepts the request can decode the header instantly. It’s fine to use, but only over HTTPS, which is what actually protects the credentials in transit, not the encoding itself.

Does using a {{token}} template keep my credential secret?

It keeps the literal value out of a saved request, a share link, or a public example like the ones on this page — the template is just a placeholder resolved from whichever environment is active when the request is sent. The real value still lives in that environment’s storage, unencrypted, the same as anything else this tool saves locally.

Test an authenticated request yourself.

Try the free API Request Builder

Related Guides