You've been making public APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. requests so far, but most real-world APIs require proof of identity before they'll give you anything. This lesson covers HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. headers, the metadata layer of every request, and the different ways APIs verify who you are.
What headers do
Headers are key-value pairs that travel alongside every HTTPWhat is http?The protocol browsers and servers use to exchange web pages, API data, and other resources, defining how requests and responses are formatted. request and response. They're like the envelope around a letter: they describe what's inside and who it's from, without being the letter itself. You've already used one: Content-Type: application/json.
const headers = {
// Tell server what response format we can handle
'Accept': 'application/json',
// Tell server what format we're sending
'Content-Type': 'application/json',
// Authentication
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIs...',
// API key (some APIs use a custom header name)
'X-API-Key': 'your-api-key-here',
// Custom headers (X- prefix is a common convention for non-standard headers)
'X-Request-ID': 'uuid-123'
};
const response = await fetch('https://api.example.com/data', { headers });| Header | Purpose | Example value |
|---|---|---|
Content-Type | Format of the request body | application/json |
Accept | Format you want in the response | application/json |
Authorization | Authentication credentials | Bearer eyJhbGci... |
X-API-Key | API key (custom header) | sk-abc123 |
Cache-Control | Caching behavior | no-cache |
AuthenticationWhat is authentication?Verifying who a user is, typically through credentials like a password or token. methods
Bearer tokens (JWTWhat is jwt?JSON Web Token - a self-contained, signed token that carries user data (like user ID and role). The server can verify it without a database lookup.)
This is how most modern APIs work. You log in once, the server gives you a tokenWhat is token?The smallest unit of text an LLM processes - roughly three-quarters of a word. API pricing is based on how many tokens you use., and you send that token with every subsequent request to prove your identity. The token is usually a JWT (JSON Web Token), a self-contained string the server can verify without hitting the database.
const token = localStorage.getItem('auth_token');
const response = await fetch('https://api.example.com/protected', {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});The format is always Bearer (with a space) followed by the token. Forgetting that prefix is a common mistake, the server will reject the request.
APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. keys
Simpler than tokens: you get one static key and include it with every request. Common for third-party services like maps, weather, or email APIs.
// Option 1: Custom header (preferred - less likely to appear in server logs)
const response = await fetch('https://api.example.com/data', {
headers: { 'X-API-Key': 'your-api-key-here' }
});
// Option 2: Query parameter (easier to leak - shows up in URLs and logs)
const response = await fetch('https://api.example.com/data?api_key=your-key');Basic authentication
An older approach that encodes username:password in Base64 and sends it in the Authorization header. Rarely used for new APIs, but you'll encounter it with legacy systems or some internal tools.
const credentials = btoa('username:password'); // btoa = Base64 encode
const response = await fetch('https://api.example.com/protected', {
headers: {
'Authorization': `Basic ${credentials}`
}
});const API_KEY = 'sk-live-abc123' in a React component means every visitor to your site can open DevTools and steal your key. Copilot does this constantly. Always proxy secret keys through your own backend, the client should never see them.Building a reusable auth client
Copying auth headers into every fetch call is tedious and error-prone. Centralizing this logic into a class pays off immediately.
class APIClient {
constructor(baseURL, authToken = null) {
this.baseURL = baseURL;
this.authToken = authToken;
}
setAuthToken(token) {
this.authToken = token;
}
async request(endpoint, options = {}) {
const url = `${this.baseURL}${endpoint}`;
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
...options.headers
};
if (this.authToken) {
headers['Authorization'] = `Bearer ${this.authToken}`;
}
const response = await fetch(url, { ...options, headers });
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
}
get(endpoint) {
return this.request(endpoint);
}
post(endpoint, data) {
return this.request(endpoint, {
method: 'POST',
body: JSON.stringify(data)
});
}
}
// Set up once
const api = new APIClient('https://api.example.com');
api.setAuthToken(localStorage.getItem('token'));
// Use everywhere without repeating headers
const user = await api.get('/user/profile');
const post = await api.post('/posts', { title: 'Hello', body: 'World' });Where to store APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. keys
This is non-negotiable: API keys and tokens that give access to paid or private resources must never live in your client-side JavaScript. Any user can open DevTools and read them.
// NEVER do this in browser code
const API_KEY = 'sk-live-123456789'; // Exposed to every visitor
// Correct approach: keep secrets on your server
// Client → Your Backend → Third-party API (key stays on your server)
const response = await fetch('/api/weather?city=Paris');
// Your backend makes the actual call to the weather API with the hidden keyQuick reference
| Auth method | Header format | Use case |
|---|---|---|
| Bearer token | Authorization: Bearer <token> | Login sessions, OAuth, JWT |
| API key (header) | X-API-Key: <key> | Third-party services |
| API key (query) | ?api_key=<key> | Quick prototyping only |
| Basic auth | Authorization: Basic <base64> | Legacy systems |