API Authentication Methods -- Common Questions Answered
API authentication is how services verify who is making a request and what they are allowed to do. Whether you're building a web scraper that calls search APIs, integrating a SaaS tool, or exposing your own API, understanding authentication methods is essential. This FAQ covers the most common questions developers ask about API authentication, with practical examples using SearchHive and other popular services.
Key Takeaways
- API keys are the simplest method -- a single token in the header or query string
- OAuth 2.0 is the standard for user-delegated access -- used by Google, GitHub, and most SaaS platforms
- Bearer tokens are the most common transport mechanism -- sent in the
Authorizationheader - JWT decoder tokens are stateless and self-contained -- no server-side session storage needed
- SearchHive uses API key authentication for simplicity, with HMAC signing for enterprise security
Q: What is the difference between API keys and OAuth tokens?
API keys are static identifiers issued by the API provider. They identify the caller but don't carry information about permissions or expiration. OAuth tokens, on the other hand, are dynamic, scoped to specific permissions, and can expire.
API keys: Best for server-to-server communication where the caller is a trusted application. Examples: SearchHive, OpenAI, SerpAPI.
OAuth tokens: Best when a third-party app needs to access user data on behalf of that user. Examples: Google Drive API, GitHub API, Slack API.
import requests
# API key authentication (SearchHive)
headers = {"Authorization": "Bearer sh_live_abc123"}
response = requests.get("https://api.searchhive.dev/v1/search", headers=headers)
# OAuth 2.0 bearer token (hypothetical Google API)
headers = {"Authorization": "Bearer ya29.a0AfH6SMB..."}
response = requests.get("https://www.googleapis.com/drive/v3/files", headers=headers)
Q: How do API keys work in practice?
Most APIs accept keys via one of three methods:
- Header-based:
Authorization: Bearer <key>orX-API-Key: <key> - Query parameter:
?api_key=<key>appended to the URL - Cookie-based: Set automatically by the API provider after login
Header-based is the most secure because keys don't appear in server logs, browser history, or proxy caches.
import requests
from searchhive import SwiftSearch
# SearchHive uses header-based API key auth
client = SwiftSearch(api_key="sh_live_your_key_here")
result = client.search(query="web scraping tools", engine="google")
print(result["organic_results"][0]["title"])
Q: What is Bearer token authentication?
"Bearer" means whoever holds the token can use it -- like a physical ticket. The server doesn't verify the sender's identity beyond checking that the token is valid.
GET /v1/search HTTP/1.1
Host: api.searchhive.dev
Authorization: Bearer sh_live_abc123xyz
Bearer tokens are the de facto standard for REST APIs. They're simple, stateless, and work across all HTTP clients.
Q: When should I use OAuth 2.0 instead of API keys?
Use OAuth 2.0 when:
- Your app accesses resources on behalf of an end user (e.g., reading their Google Drive files)
- You need fine-grained permission scopes (read-only vs. read-write)
- Tokens need to expire and be refreshed without user interaction
- You're building a third-party integration for a public platform
Use API keys when:
- Your server is the only thing calling the API
- You don't need user-level permissions
- You want the simplest possible setup
Q: What is JWT and how is it different from OAuth?
JWT (free JSON formatter Web Token) is a token format. OAuth 2.0 is an authorization protocol. They're often used together.
A JWT contains three parts: a header, payload, and signature, all Base64 encoder-encoded:
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMjM0NX0.abc123signature
The payload can include user ID, expiration time, permissions, and custom claims. The signature ensures the token hasn't been tampered with.
SearchHive uses API keys (not JWT) for authentication, which is simpler for server-to-server use. If you need JWT-based auth for your own API, libraries like PyJWT make it straightforward.
Q: How do I securely store API keys?
Never hardcode API keys in your source code. Instead:
- Environment variables:
export SEARCHHIVE_API_KEY="sh_live_abc" - Secret managers: AWS Secrets Manager, HashiCorp Vault, Doppler
.envfiles: With.gitignoreprotection andpython-dotenvfor loading
import os
from dotenv import load_dotenv
load_dotenv()
# This reads from environment -- not hardcoded
api_key = os.environ.get("SEARCHHIVE_API_KEY")
If you accidentally commit an API key to Git, revoke it immediately and generate a new one. Every API provider offers key rotation -- use it.
Q: What is HMAC authentication and when is it used?
HMAC (Hash-based Message Authentication Code) adds a cryptographic signature to each request. The sender hashes the request body + timestamp with a secret key, and the server verifies the hash.
This prevents replay attacks and ensures request integrity. It's used by AWS Signature V4, some payment APIs, and enterprise services where security requirements are strict.
Q: How do I handle API key rotation?
Best practices for key rotation:
- Generate a new key while the old one is still active
- Deploy the new key to your application
- Verify the new key works in production
- Revoke the old key after a grace period (24-48 hours)
- Document the rotation date for audit purposes
SearchHive supports multiple active API keys, so you can rotate without downtime.
Q: What is the difference between authentication and authorization?
- Authentication (AuthN): "Who are you?" -- Verifying identity via API key, password, certificate, etc.
- Authorization (AuthZ): "What can you do?" -- Checking permissions after identity is confirmed
A user might authenticate with a valid API key (AuthN) but get a 403 Forbidden if they lack permission to access a specific endpoint (AuthZ).
Q: How do I handle expired tokens?
For APIs that use expiring tokens (OAuth 2.0, JWT), handle expiration gracefully:
import requests
def make_authenticated_request(url, access_token, refresh_token):
response = requests.get(url, headers={"Authorization": f"Bearer {access_token}"})
if response.status_code == 401:
# Token expired -- use refresh token to get a new one
new_token = refresh_access_token(refresh_token)
response = requests.get(url, headers={"Authorization": f"Bearer {new_token}"})
return response.json()
SearchHive API keys don't expire, so you don't need to handle token refresh -- one less thing to manage.
Q: Which authentication method should I use for web scraping APIs?
For most web scraping use cases, API key authentication is the right choice:
- Server-to-server calls only (no end users)
- No need for user delegation
- Simple to implement and debug
- No token expiration to manage
SearchHive, SerpAPI, Firecrawl, and most scraping APIs use this approach. Get your API key, set it in an environment variable, and start making requests.
Summary
API authentication ranges from simple API keys to complex OAuth 2.0 flows. For server-to-server scraping, API keys are the practical choice. For user-facing integrations, OAuth 2.0 with refresh tokens is the standard. Choose based on your use case, not based on what's most sophisticated.
Ready to start scraping with simple API key auth? Sign up for SearchHive and get 500 free credits -- no credit card, no OAuth dance, just a key and a curl command.