APIs
A Beginner's Guide to Testing REST APIs
A REST API is how one program talks to another over HTTP. You send a request to a URL, the server does something, and it sends back a response. Testing an API means exactly that: you send requests and then check that the responses are what you expected. No magic — just asking the right questions and reading the answers carefully.
This guide walks through the pieces you need to understand — HTTP methods, request parts, status codes, and authentication — and then ties them together into a simple workflow you can follow every time.
HTTP methods and what they mean
Every request uses a method (sometimes called a verb) that signals your intent. The common ones map neatly to the things you do with data:
- GET — read something. It should never change data.
- POST — create a new thing.
- PUT — replace an existing thing entirely.
- PATCH — update part of an existing thing.
- DELETE — remove a thing.
A useful property to remember is idempotency: making the same request more than once has the same effect as making it once. GET, PUT, and DELETE are idempotent — deleting the same record twice leaves you in the same place. POST usually is not: sending it twice typically creates two records. Knowing this tells you what should happen when a request gets retried.
The parts of a request
A request is made of a few building blocks, and testing often comes down to getting these right:
- The URL, optionally with query parameters after a
?— for example/users?role=admin&limit=10to filter and page through results. - Headers, which carry metadata.
Content-Typetells the server what you are sending (usuallyapplication/json),Acceptsays what you want back, andAuthorizationproves who you are. - A body, used with POST, PUT, and PATCH to carry the actual data — almost always JSON. GET and DELETE normally have no body.
Reading status codes
The server replies with a three-digit status code that tells you, at a glance, how things went. They come in families:
- 2xx — success.
200 OK(it worked),201 Created(a new resource was made),204 No Content(it worked, nothing to return). - 3xx — redirects. The resource lives somewhere else and the client should follow along.
- 4xx — client errors. You sent something wrong.
400bad request,401unauthorized,403forbidden,404not found,429too many requests. - 5xx — server errors. The server broke.
500internal error,502bad gateway,503service unavailable.
A handy rule of thumb: 4xx means "fix your request," while 5xx means "the problem is on their end."
| Code | Meaning |
|---|---|
| 200 | OK — request succeeded |
| 201 | Created — a new resource was made |
| 204 | No Content — success, nothing to return |
| 400 | Bad Request — the request was malformed |
| 401 | Unauthorized — authentication is missing or invalid |
| 403 | Forbidden — authenticated, but not allowed |
| 404 | Not Found — no resource at that URL |
| 429 | Too Many Requests — you have been rate limited |
| 500 | Internal Server Error — the server failed |
| 503 | Service Unavailable — the server is temporarily down |
Authentication basics
Most real APIs will not talk to a stranger, so you need to prove who you are. Three common approaches:
- API keys — a long secret string you pass in a header or query parameter. Simple, but treat it like a password.
- Bearer tokens — a token sent as
Authorization: Bearer <token>, often short-lived and issued after you log in. - Basic auth — a username and password encoded and sent in the
Authorizationheader. Only safe over HTTPS.
When a request fails with 401, bad or missing credentials are almost always the cause.
A simple testing workflow
Once you understand the pieces, testing follows a predictable rhythm:
- Start with the happy path. Send a valid request the way the docs describe it.
- Check the response in three places: the status code (does it match intent — did a POST return
201?), the body (are the right fields present with the right values?), and the headers (isContent-Typewhat you expected?). - Then break it on purpose. Test the error and edge cases: leave out a required field, send bad or no credentials, request an ID that does not exist.
- Confirm the codes match intent. A missing field should give
400, bad auth401, a missing record404— not a generic500.
It is also worth watching the response time and simply confirming the endpoint is up at all. A fast, reliable 200 is part of a healthy API, and basic uptime checks catch outages before your users do.
The takeaway
Testing a REST API is not about memorizing every rule — it is about asking clear questions and reading the answers. Pick the right method, send the right headers and body, and then check that the status code, body, and headers all line up with what you intended. Test the happy path first, then poke at the edges, and you will catch problems long before they reach production.