After this lesson, you will be able to: Read API documentation confidently, test endpoints in Postman or Bruno, recognize and interpret every common HTTP status code, call APIs from JavaScript with fetch + async/await + try/catch, and handle authentication via headers.
Every modern app talks to APIs. A frontend that loads users, a backend that integrates Stripe, an AI tool that calls Anthropic's API — they all speak HTTP. This lesson takes you from zero understanding of APIs to comfortable reading docs, testing endpoints, handling errors, and shipping a real network call in your own app. Working with APIs is a core professional skill: in every junior developer interview it's the line that separates candidates who built something real from candidates who only finished tutorials.
API stands for Application Programming Interface. In practice, when people say "API" today they almost always mean a REST API: a server that exposes a set of URLs (called endpoints) you can hit with HTTP requests to read or change data, usually exchanged as JSON. Think of an API as a menu: the documentation lists what's available, what each item costs (what input it needs), and what you get back. Your code is the customer placing the order.
REST APIs use HTTP verbs to describe intent. **GET** reads data (`GET /users/1` → user 1's profile). Should be safe and have no side effects. **POST** creates new data (`POST /users` with a JSON body → creates a user). **PUT** replaces data (`PUT /users/1` with the full new user object). **DELETE** removes data (`DELETE /users/1`). There's also `PATCH` (partial update) and `OPTIONS` (used by browsers for CORS preflight), but the four above cover 95% of what you'll write.
Every HTTP response has a status code. The first digit tells you the category. Memorize the bolded ones — they're the ones you'll see (and need to handle) every week.
// 2xx Success200 OK // generic success (most GETs)201 Created // POST that created a resource204 No Content // success, no body (DELETEs, some PUTs)// 3xx Redirect (usually handled transparently by the browser)301 Moved Permanently302 Found // temporary redirect304 Not Modified // cache hit// 4xx Client error — YOUR request was wrong400 Bad Request // malformed payload, missing field, invalid type401 Unauthorized // no/invalid auth credentials403 Forbidden // authenticated, but not allowed404 Not Found // the resource doesn't exist409 Conflict // e.g. signing up with an email that's taken422 Unprocessable // validation failed (common in REST APIs)429 Too Many Requests// you hit the rate limit// 5xx Server error — the SERVER broke, not you500 Internal Server Error502 Bad Gateway // upstream service failed503 Service Unavailable504 Gateway Timeout
Good API docs follow a predictable shape. For any endpoint you'll find: the HTTP method and URL, required and optional inputs (query params for GET, JSON body for POST/PUT), the response shape (with example), authentication requirements, and rate limits. Skim in that order. Start with: what URL, what method, what auth. Then look at the example request and response — those tell you more than the prose. Two reference-quality examples to study: Stripe (stripe.com/docs/api) and GitHub (docs.github.com/rest). Both are written by teams whose business depends on developers succeeding.
Before you write fetch code, hit the endpoint in a request client. **Postman** is the dominant tool — every backend job listing assumes you've used it. **Bruno** is the open-source alternative that stores requests as files in your repo (great for team workflows). Either works; learn one, recognize both. Workflow: paste the URL, pick the method, add headers (`Authorization: Bearer ...`, `Content-Type: application/json`), add a body if POST/PUT, hit Send. The response shows status code, headers, and parsed JSON. This three-second feedback loop is what makes API development sane — if your fetch call fails, the question is always 'does it work in Postman?' If yes, your JS is wrong; if no, the API/your auth is wrong.
Production-quality fetch always includes: status check, JSON parse, error handling, and (often) headers for auth and content type. Memorize this template.
async function createPost(token, post) {try {const response = await fetch("https://api.example.com/posts", {method: "POST",headers: {"Content-Type": "application/json","Authorization": `Bearer ${token}`,},body: JSON.stringify(post),});// fetch only rejects on network failure.// 4xx / 5xx responses still RESOLVE — you must check ok yourself.if (!response.ok) {const errorBody = await response.json().catch(() => ({}));throw new Error(`HTTP ${response.status}: ${errorBody.message ?? response.statusText}`);}return await response.json();} catch (error) {// Network failure OR thrown HTTP error from aboveconsole.error("createPost failed:", error);throw error; // let the caller decide how to show this to the user}}// Usagetry {const created = await createPost(myToken, { title: "Hello", body: "World" });console.log("Created post #", created.id);} catch (error) {alert("Could not save your post. Try again in a moment.");}
**API key** — a long secret string the server gave you. You pass it in a header (`Authorization: Bearer YOUR_KEY` or sometimes `X-API-Key: YOUR_KEY`). Used by most third-party APIs (OpenAI, Stripe, Resend). **JWT / Bearer token** — a signed token the server issued when you logged in, sent on every request in `Authorization: Bearer ...`. Common for auth between a frontend and your own backend. **OAuth 2.0** — a flow that lets users grant your app limited access to their account on a third-party service (e.g. "Log in with Google"). The output is still a Bearer token, but the way you obtain it is more elaborate. Never put API keys in client-side code shipped to users — anyone can read it. Keep secret keys server-side and proxy the request.
Build the smallest end-to-end API integration: a button that fetches a random user from https://jsonplaceholder.typicode.com/users/{1-10} and renders their name + email. The starter has the HTML scaffold and an empty handler — fill in the fetch call following the production pattern (status check, try/catch, async/await). Required patterns check for `async`, `await fetch`, `response.ok`, and `try`.
Pick the most accurate diagnosis.
Sign in and purchase access to unlock this lesson.