What is API Testing? How to Test a REST API
API testing checks that an application programming interface returns the right data, status codes and headers for every request it is given — valid ones, invalid ones and malicious ones — and that it does so reliably and quickly. Because APIs sit between the user interface and the data, a bug found here is usually cheaper to fix and more dangerous to miss than one found in a screen.
This guide explains the types of API tests, the anatomy of a request and response, a repeatable method for testing a REST endpoint, the failures that show up most often, and how to do all of it from a browser without installing anything.
What API testing covers
"API testing" is a family of checks rather than one activity. Most teams run the first three on every change and the rest before a release.
- Functional testing — does each endpoint return the correct response for valid input? Does a POST create the record, does a GET return it, does a DELETE remove it?
- Validation and negative testing — what happens with missing fields, wrong types, values out of range, malformed JSON, an expired token or a request that is too large? The API should answer with a clear 4xx error, never a 500.
- Contract testing — does the response still match the agreed schema (OpenAPI, JSON Schema)? Removed fields and changed types break every consumer.
- Authentication and authorization — are protected endpoints rejecting anonymous requests (401) and requests from the wrong user or role (403)?
- Performance — how long does a request take, how large is the payload, and how does the endpoint behave under concurrent load?
- Security — headers, injection in query parameters and bodies, rate limiting, and whether error responses leak stack traces or internals.
Anatomy of a request and a response
Every HTTP exchange has the same parts, and every one of them is something to assert on.
- Method — GET reads, POST creates, PUT replaces, PATCH updates part of a resource, DELETE removes. Using the wrong one is a bug in itself.
- URL and query string — the resource path (/orders/42) plus filters and paging (?status=paid&page=2).
- Request headers — Content-Type tells the server what you are sending, Accept what you expect back, Authorization who you are.
- Request body — usually JSON for REST; must match the documented schema.
- Status code — 2xx success, 3xx redirect, 4xx the client did something wrong, 5xx the server failed. The exact code matters: 201 for created, 204 for no content, 400 for bad input, 404 for not found, 409 for conflicts, 422 for validation errors.
- Response headers — Content-Type, caching, rate-limit counters, CORS and security headers.
- Response body — the data, or a consistent error object with a machine-readable code and a human-readable message.
POST /api/v1/orders HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOi...
{"customerId": 7, "items": [{"sku": "A-100", "qty": 2}]}
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/orders/9021
{"id": 9021, "status": "pending", "total": 249.90}How to test a REST API, step by step
- Read the contract first. Open the OpenAPI/Swagger document or the API docs and list every endpoint, its parameters, the success response and every documented error.
- Send the happy path. For each endpoint, send a valid request and assert the status code, the response schema and the key values. Save the response — it is your baseline.
- Break the input on purpose. Remove required fields, send the wrong type, exceed lengths, use boundary values (0, -1, maximum + 1), send empty and very large bodies, and send malformed JSON. Expect precise 4xx codes and error messages that name the problem.
- Test authentication. Call protected endpoints with no token, an expired token, a token for another user and a token with the wrong scope. Expect 401 or 403, never data.
- Check state changes. After a POST, GET the resource and confirm it exists; after a DELETE, confirm it is gone; after a PUT, confirm every field changed and nothing else did.
- Assert on headers, not just bodies. Content-Type must be application/json, caching must be correct for private data, CORS must be right for browser clients.
- Measure. Record the response time of each call; anything that trends upward between releases is a regression even if it still "works".
- Automate what you repeated. Turn the requests and assertions into a collection or a script so they run on every build.
Try it: REST API Tester Try it: API Endpoint Tester Try it: API Authentication Tester
What to assert in every response
- Status code is exactly the documented one.
- Content-Type header is correct and the body parses.
- The body matches the schema: required fields present, types correct, no unexpected fields for strict contracts.
- Values are right: IDs, totals, dates in ISO 8601, enumerations within the allowed set.
- Errors are consistent: same shape on every endpoint, a stable machine code, no stack traces or SQL in the message.
- Response time is within the agreed budget.
Failures that show up most often
- 200 OK with an error inside the body — clients cannot tell success from failure without parsing text.
- 500 for bad input instead of 400/422 — the validation layer is missing or crashes.
- Different error shapes on different endpoints — every consumer needs custom handling.
- Silent contract changes — a field renamed or a type changed without a version bump.
- Missing authorization checks — the token is valid but belongs to a user who should not see the resource.
- Inconsistent pagination — page sizes, offsets and totals that disagree between endpoints.
- Time zone bugs — timestamps without an offset, or dates that shift by a day.
Try it: API Status Code Simulator Try it: Response Contract Comparator
Testing webhooks and callbacks
Webhooks reverse the direction: the API calls you. To test one you need a URL that accepts the call and shows you exactly what arrived — headers, signature, body and timing — so you can check the payload against the documentation and verify the signature with the shared secret before writing a single line of handler code.
API testing tools: desktop apps vs browser tools
Postman, Insomnia and Bruno are excellent for large, long-lived collections. For day-to-day work — checking an endpoint, reproducing a bug, validating a response, capturing a webhook — a browser tool is faster because there is nothing to install or sign in to. The Mutqan API tools cover that daily loop: build and send requests, validate responses against rules or a schema, simulate status codes, capture webhooks and generate test cases straight from an OpenAPI file.
Frequently asked questions
What is the difference between API testing and unit testing?
Unit tests exercise a function in isolation inside the codebase. API tests send real HTTP requests to a running service and check the response, so they cover routing, serialization, validation, authentication and the database together.
Can I test an API without Postman?
Yes. Any tool that can send an HTTP request and show the response works — cURL on the command line, a browser-based request builder, or a script. The important part is what you assert, not the client.
Which status code should a validation error return?
400 Bad Request is the general answer; 422 Unprocessable Entity is widely used when the JSON is well-formed but the values fail validation. Whichever you choose, use it consistently across the API.
How do I test an API that requires authentication?
Obtain a token the way a real client would (login endpoint, OAuth flow or an API key), send it in the Authorization header, and also test the negative cases: no token, expired token, wrong scope, another user's token.
What is contract testing?
Checking that an API's actual responses match its published contract — usually an OpenAPI document or JSON Schema — so that a change that would break consumers is caught before release.
How many test cases does an endpoint need?
At minimum one happy path, one for each documented error, one authentication failure and the boundary values of each parameter. A tool can generate that baseline from the OpenAPI spec; a tester then adds business-specific scenarios.
Tools mentioned in this guide
Compose and send HTTP requests (method, URL, headers, auth, body) and inspect the response — a lightweight Postman in your browser.
Test REST endpoints with full control over method, headers and JSON body, then assert on status, headers and JSON paths.
Quickly check that an API endpoint is reachable: status, response time, size, content type and TLS.
Validate an API response against expectations: status, required headers, JSON schema and field rules.
Validate API responses against a JSON Schema or an OpenAPI response schema.
Get a public endpoint that returns any HTTP status code, with optional delay and custom JSON body, to test client error handling.
Get a unique URL, send webhooks to it and inspect method, headers, body and timing in real time.
Generate a structured test-case matrix (positive, negative, auth, boundary) from an OpenAPI / Swagger specification.
Test Bearer, Basic, API-key and custom-header authentication against an endpoint and compare authorised vs unauthorised responses.
Measure an endpoint's response time over several samples: min, max, average, median and p95.