API Testing Guide: From Basics to Automated Workflows
Learn how to test REST APIs effectively — from manual testing with HTTP clients to automated test suites, status codes, and authentication strategies.
APIs are the contracts between software systems. When an API breaks, everything that depends on it breaks. Yet API testing is often treated as an afterthought — something you do manually in a browser tab right before deployment. A proper API testing strategy catches bugs early, documents expected behavior, and gives you confidence to ship.
What makes an API test?
An API test sends an HTTP request and asserts something about the response:
- Status code — Did we get
200 OKor404 Not Found? - Response body — Is the data structure correct? Are the values right?
- Headers — Is
Content-Typeset correctly? Is the auth header present? - Response time — Does the endpoint respond within an acceptable window?
- Error handling — What happens with bad input? Do we get meaningful errors?
HTTP status codes you must know
| Code | Meaning | When you'll see it |
|---|---|---|
200 |
OK | Successful GET, PUT, PATCH |
201 |
Created | Successful POST that creates a resource |
204 |
No Content | Successful DELETE or action with no body |
400 |
Bad Request | Invalid input, malformed JSON, missing fields |
401 |
Unauthorized | Missing or invalid authentication token |
403 |
Forbidden | Authenticated but not authorized |
404 |
Not Found | Resource doesn't exist |
409 |
Conflict | Duplicate resource, version conflict |
422 |
Unprocessable Entity | Validation errors on valid JSON |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Internal Server Error | Bug on the server side |
503 |
Service Unavailable | Server down or overloaded |
401means "who are you?" —403means "I know who you are, but you can't do that."
Testing manually with the API Request Builder
Before automating, understand your endpoints manually. Our API Request Builder lets you:
- Set the HTTP method (GET, POST, PUT, PATCH, DELETE)
- Add headers (Authorization, Content-Type, custom headers)
- Build query parameters without URL-encoding manually
- Write a JSON request body with syntax highlighting
- Inspect the full response including headers and timing
This is ideal for exploring a new API, debugging a specific endpoint, or quickly verifying a fix.
Testing REST APIs: the full CRUD cycle
For a hypothetical /users API, a complete test suite covers:
Create (POST)
POST /users
Content-Type: application/json
{
"name": "Alice Chen",
"email": "alice@example.com",
"role": "editor"
}
Assert:
- Status
201 Created - Response body contains the created user with a generated
id Locationheader points to the new resource (e.g.,/users/42)
Read (GET)
GET /users/42
Authorization: Bearer <token>
Assert:
- Status
200 OK - Body matches the created user
idis42
Update (PUT / PATCH)
PATCH /users/42
Content-Type: application/json
{ "role": "admin" }
Assert:
- Status
200 OK roleis now"admin"in the response- Other fields unchanged
Delete (DELETE)
DELETE /users/42
Authorization: Bearer <token>
Assert:
- Status
204 No Content - Subsequent
GET /users/42returns404
Negative testing: the tests most people skip
Positive tests verify the happy path. Negative tests verify that the API handles bad input gracefully:
- Missing required fields →
400with clear error message - Invalid data types (
"age": "twenty") →400 - Non-existent resource (
GET /users/99999) →404 - Expired token →
401 - Accessing another user's data →
403 - Sending a 10 MB payload →
413 Payload Too Large - Exceeding rate limits →
429withRetry-Afterheader
A well-designed API fails predictably and informatively.
Authentication testing patterns
Bearer tokens (JWT)
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Test scenarios:
- Valid token → correct response
- Expired token →
401with"Token expired"message - Tampered token (change one character) →
401 - Missing header →
401 - Token for different environment →
401
Use our JWT Decoder to inspect tokens and check expiration times during manual testing.
API keys
X-API-Key: sk_live_abc123
Test: wrong key, missing key, key with insufficient permissions.
OAuth 2.0 flows
OAuth adds complexity — test the token exchange endpoints separately from the resource endpoints.
Validating response bodies
Don't just check status codes. Validate the structure of responses:
// Using Jest + supertest
test("GET /users/:id returns the correct user", async () => {
const response = await request(app).get("/users/42").set("Authorization", `Bearer ${token}`);
expect(response.status).toBe(200);
expect(response.headers["content-type"]).toMatch(/json/);
expect(response.body).toMatchObject({
id: 42,
name: expect.any(String),
email: expect.stringMatching(/^[^\s@]+@[^\s@]+\.[^\s@]+$/),
role: expect.oneOf(["admin", "editor", "viewer"]),
});
});
For larger response schemas, use JSON Schema validation with our JSON Schema Validator to define the expected shape once and test all endpoints against it.
Contract testing
In microservices, contract testing ensures that a consumer and provider agree on the API shape. The consumer defines what they need; the provider verifies they fulfill it. Tools like Pact automate this.
This is particularly valuable when teams own different services — a contract test fails immediately when a field is renamed or removed, before integration.
Performance and load testing
Functional tests tell you if the API works. Performance tests tell you how well it works under load:
- Baseline — What's the p50/p95/p99 response time with a single user?
- Load test — How does it perform at expected peak traffic?
- Stress test — At what point does it start failing?
- Spike test — What happens with a sudden 10× traffic increase?
A common target: < 200ms for p95 at expected peak load.
API testing checklist
- Test all CRUD operations for each resource
- Test negative cases: invalid input, missing auth, not found
- Validate response bodies against a schema (not just status codes)
- Test authentication edge cases: expired, missing, tampered tokens
- Verify error responses have helpful messages
- Check that pagination, filtering, and sorting work correctly
- Test rate limiting behavior
- Verify no sensitive data leaks in error responses
- Check response time at expected load
Good API tests are your safety net for refactoring and the best documentation you can have — they show exactly what each endpoint does and what it expects.