Skip to main content
PacketMentor logo
Open menu
← All topics
Automation & Programmability Foundational

REST API Authentication: Basic, Token, API Key, Bearer

The four auth styles you see on every Cisco API: HTTP Basic (user:pass), API key (custom header), bearer token (OAuth2 style), custom token. When to use each, with curl and Python requests examples.

Quick summary
  • Basic auth = user:password base64-encoded, sent in Authorization: Basic ... header. Only safe over HTTPS.
  • API key = long opaque string in a custom header (X-API-Key, X-Cisco-Meraki-API-Key) or a query parameter. Simpler than OAuth.
  • Bearer token = OAuth2-style short-lived token in Authorization: Bearer <token> header. Rotates frequently.

Mental model

Every REST API needs to know who you are before it answers. Cisco objective 2.7 says “Utilize common API authentication mechanisms: basic, custom token, and API keys”. These are the three big ones. In practice there is a fourth that shows up constantly: bearer tokens (used by OAuth2).

All four end up as a header on the request. The server reads the header, decides if you are allowed, and either answers your request or returns 401.

Four schemes side by side

SchemeHeader shapeWhere usedCisco example
HTTP BasicAuthorization: Basic <base64(user:pass)>Older APIs, internal toolsLegacy IOS-XE RESTCONF (optional)
API Key (custom header)X-API-Key: abc123... or X-Cisco-Meraki-API-Key: ...Vendor dashboardsMeraki Dashboard, Webex
Bearer tokenAuthorization: Bearer eyJhbGci...OAuth2 / OIDC flowsCatalyst Center, modern Cisco APIs
Custom tokenVaries — X-Auth-Token: abc, token=abc query paramOlder / vendor-specificNX-API, legacy ACI

HTTP Basic auth

curl

curl -u admin:cisco123 https://api.example.com/devices

-u encodes the credentials and sets Authorization: Basic <base64> for you.

Python requests

r = requests.get("https://api.example.com/devices", auth=("admin", "cisco123"))

When to use

Internal admin tools; APIs that have not moved to OAuth yet. Always over HTTPS; Basic auth over plain HTTP sends credentials in near-plaintext (base64 is encoding, not encryption).

API key

Long opaque string. Usually generated in a vendor dashboard (Meraki, Webex, etc.) and sent as a custom header or query parameter.

curl

curl -H "X-Cisco-Meraki-API-Key: abcdef0123456789" \
     https://api.meraki.com/api/v1/organizations

Python requests

r = requests.get(
    "https://api.meraki.com/api/v1/organizations",
    headers={"X-Cisco-Meraki-API-Key": "abcdef0123456789"},
)

When to use

Dashboard APIs where users generate their own key with a click. Simpler than OAuth, no token refresh needed. Treat the key like a password — rotate on compromise.

Bearer token (OAuth2 style)

Short-lived (hours), issued by an auth server after you log in with user+pass or client ID+secret.

Getting a token (typical two-step flow)

# 1. Trade credentials for a token
TOKEN=$(curl -u user:pass -X POST \
  https://api.example.com/oauth2/token \
  -d 'grant_type=client_credentials' \
  | jq -r .access_token)

# 2. Use the token for subsequent calls
curl -H "Authorization: Bearer $TOKEN" \
  https://api.example.com/devices

Python requests

# 1
r = requests.post(
    "https://api.example.com/oauth2/token",
    auth=("user", "pass"),
    data={"grant_type": "client_credentials"},
)
token = r.json()["access_token"]

# 2
r = requests.get(
    "https://api.example.com/devices",
    headers={"Authorization": f"Bearer {token}"},
)

When to use

Modern APIs. Catalyst Center uses this pattern. Tokens expire (usually 1 hour); your script re-authenticates when it gets a 401.

Custom token

Vendor-specific headers that are not standard Basic or Bearer. Common in older gear.

curl -H "X-Auth-Token: your-token" https://nxapi.example.com/ins

Treat it as “like an API key, but the header name is whatever the docs say”.

The 401 → 403 → 404 ladder

StatusMeansFix
401 UnauthorizedNo credentials OR wrong credentialsAdd / fix auth header
403 ForbiddenAuth was accepted but your account lacks permissionAsk an admin for the right role or scope
404 Not FoundURL does not exist OR you are authenticated but not allowed to see it (some APIs return 404 instead of 403 for security)Verify URL; check docs on 404-vs-403 behaviour

Security basics

  • Never commit tokens / API keys / passwords to Git. Use environment variables and a .env file in .gitignore.
  • Rotate on any suspected leak.
  • Use the shortest-lived token your workflow allows.
  • Use HTTPS. Always.

FAQ

My Bearer token looks like a huge string with dots in it. What is it? Almost certainly a JWT (JSON Web Token): three base64 segments separated by dots. You can inspect it (not change it) at jwt.io. The payload includes the user, expiry, and permissions.

Do I need to send a session cookie? Cookie auth is common in browser-based tools, uncommon in machine-to-machine REST. If an API asks for a cookie, you probably want its API-key / bearer alternative instead.

How do I debug “it works in curl but not Python”? Add verbose=True effect by printing r.request.headers after the call. Nine times out of ten, Python set an extra default header or encoded the body differently than you expected.

OAuth1 vs OAuth2 — is OAuth1 on the exam? No. 200-901 only cares about the resulting auth header style; OAuth1 (an older flow with signatures) is almost extinct in modern APIs.

Master this on a real network

Want this drilled into reflex?

1:1 weekly sessions, live feedback on your labs, and US interview prep: built around the CCNA Automation® exam blueprint. Free first session. No card on file until you decide.

Claim my free session →

Get the free CCNA 12-week roadmap

You're already reading up on REST API Authentication: Basic, Token, API Key, Bearer. The roadmap is the order I recommend studying every CCNA topic in: with what to lab each week and where REST API Authentication: Basic, Token, API Key, Bearer fits. A written personal reply, not an autoresponder. Expect it within one business day.

Personal reply from a senior network engineer. No third-party tracking. Unsubscribe any time.