JavaScript Core/
Lesson

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 });
HeaderPurposeExample value
Content-TypeFormat of the request bodyapplication/json
AcceptFormat you want in the responseapplication/json
AuthorizationAuthentication credentialsBearer eyJhbGci...
X-API-KeyAPI key (custom header)sk-abc123
Cache-ControlCaching behaviorno-cache
02

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}`
  }
});
Security warning
Basic auth sends credentials with every request. Always use it over HTTPS, never plain HTTP.
AI pitfall
AI tools love to hardcode API keys directly in client-side JavaScript. Code like 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.
03

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' });
04

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 key
05

Quick reference

Auth methodHeader formatUse case
Bearer tokenAuthorization: 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 authAuthorization: Basic <base64>Legacy systems