Skip to content
SDETRole
SDETRole

Lesson 1 of 9 · API Testing

HTTP Fundamentals

Requests, responses, methods, status codes and headers: the HTTP model every API tester needs, with examples you can try in the browser.

beginner 9 min read Updated

You will learn to

  • Read and explain every part of an HTTP request and response
  • Choose the right method and expected status code for an operation
  • Explain safe and idempotent methods and why they matter for testing
  • Use common headers for content negotiation, caching and authentication

Prerequisites

  • None

Every API test you will ever write is, underneath, an HTTP request followed by checks on an HTTP response. Tools like Postman, REST Assured and Playwright’s request fixture are conveniences on top of that exchange. If you understand the exchange itself (methods, status codes, headers and bodies) you can test any HTTP API with any tool, read logs and browser network tabs with confidence, and write bug reports developers can act on immediately.

The authoritative definition of HTTP semantics is RFC 9110 (published in 2022), which replaced the older RFC 7231 family. This lesson follows its terminology.

The request–response model

HTTP is a request–response protocol. A client (browser, mobile app, test script) sends a request to a server; the server sends back exactly one response. Each exchange is stateless: the server does not inherently remember previous requests. Anything that must persist between requests, such as who you are, travels in every request, usually in a cookie or an Authorization header.

Anatomy of a request

Here is a complete HTTP/1.1 request to create a user:

POST /api/users?notify=true HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example
Content-Length: 58

{"name":"Ana Silva","email":"ana@example.com","role":"admin"}
Part Example Purpose
Method POST What you want to do
Target (path + query) /api/users?notify=true Which resource, with optional parameters
Version HTTP/1.1 Protocol version
Headers Content-Type: application/json Metadata about the request and body
Blank line Separates headers from body
Body {"name":"Ana Silva",...} The data being sent (optional)

Combined with the scheme and host, the full URL is https://api.example.com/api/users?notify=true. Its parts:

  • Scheme: https (HTTP over TLS, which is encrypted)
  • Host: api.example.com
  • Path: /api/users
  • Query string: ?notify=true, a set of key=value pairs separated by &

HTTP/2 and HTTP/3 change how these messages are encoded on the wire, but the semantics (methods, status codes, headers) are the same. Browser dev tools show them the same way.

Anatomy of a response

HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/users/u_42
Cache-Control: no-store
Date: Mon, 09 Nov 2026 10:15:00 GMT

{"id":"u_42","name":"Ana Silva","email":"ana@example.com","role":"admin"}
  • Status line: version, status code (201) and reason phrase (Created).
  • Headers: metadata, including where the new resource lives (Location).
  • Body: the representation of the result.

In API tests you typically assert on all three: the status code, important headers, and the body content and structure.

HTTP methods

Method Typical meaning Has request body? Safe Idempotent
GET Read a resource No (not meaningful) Yes Yes
HEAD Like GET but headers only No Yes Yes
POST Create, or trigger processing Yes No No
PUT Replace a resource entirely (or create at a known URL) Yes No Yes
PATCH Partially update a resource Yes No No (not guaranteed)
DELETE Remove a resource Usually no No Yes
OPTIONS Ask what the server supports (used in CORS preflight) No Yes Yes

Safe and idempotent: why testers care

  • A safe method is read-only by definition: the client is not requesting any change on the server. A GET that deletes data is a serious defect, because crawlers, link previews and browser prefetching can trigger GETs automatically.
  • An idempotent method has the same intended effect on the server whether you send it once or many times. Sending DELETE /users/42 twice leaves user 42 deleted either way. Sending PUT with the same body twice leaves the same final state.

Idempotency matters because networks fail and clients retry. Good tests for this:

  • Send the same PUT twice and check the resource is identical and no duplicate is created.
  • Send the same DELETE twice. The second response may be 404 Not Found or 204 No Content depending on the API’s design; check it matches the documented behaviour and that nothing else is deleted.
  • Send the same POST twice and check what happens. Without an idempotency key, two orders are usually created; if the API supports an Idempotency-Key header, the second request should not create a duplicate.

Status codes

Status codes are three-digit numbers grouped by their first digit:

Class Meaning Common codes
1xx Informational 100 Continue, 103 Early Hints
2xx Success 200 OK, 201 Created, 202 Accepted, 204 No Content
3xx Redirection 301 Moved Permanently, 302 Found, 304 Not Modified, 307, 308
4xx Client error: the request is wrong 400, 401, 403, 404, 405, 409, 415, 422, 429
5xx Server error: the server failed 500, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout

The client errors are where most API testing happens. Know these precisely:

Code Meaning Example test
400 Bad Request Malformed request, such as invalid JSON Send {"name": (truncated JSON)
401 Unauthorized Missing or invalid authentication credentials Call without a token, or with an expired one
403 Forbidden Authenticated, but not allowed A viewer tries to delete a user
404 Not Found Resource does not exist (or is hidden) GET /users/does-not-exist
405 Method Not Allowed Method not supported for this resource DELETE /health
409 Conflict Conflicts with current state Register an email that already exists
415 Unsupported Media Type Body format not accepted Send XML to a JSON-only endpoint
422 Unprocessable Content Well-formed but semantically invalid Valid JSON with "age": -5
429 Too Many Requests Rate limit exceeded Burst requests past the documented limit

The names 401 Unauthorized and 403 Forbidden are historically confusing: 401 really means “unauthenticated”. A useful memory aid is “401: who are you? 403: I know who you are, and no.”

Look up any code quickly with the HTTP Status Code Reference.

Headers you will test

Headers are case-insensitive Name: value pairs. A handful matter in almost every API test:

Header Direction What to check
Content-Type Both The format of the body, e.g. application/json. Responses should declare it accurately.
Accept Request Formats the client can handle. Sending Accept: application/xml to a JSON-only API should give 406 Not Acceptable or a documented fallback.
Authorization Request Credentials, e.g. Bearer <token> or Basic <base64>.
Location Response URL of a newly created resource after 201, or the redirect target for 3xx.
Cache-Control Both Caching rules. Responses with personal data should typically be no-store or private.
ETag / If-None-Match Both Conditional requests; a matching ETag should yield 304 Not Modified.
Set-Cookie / Cookie Response / Request Session cookies; check HttpOnly, Secure and SameSite attributes.
Retry-After Response How long to wait after a 429 or 503.

The HTTP Headers Reference explains many more.

Try it yourself

You do not need any tools to see real HTTP. Open your browser’s developer tools (F12), go to the Network tab, and reload any page. Click a request to see its method, URL, status, request headers, response headers and body.

From a terminal, curl shows the raw exchange:

# -i includes response headers in the output
curl -i https://jsonplaceholder.typicode.com/posts/1

# POST JSON, showing the full request and response with -v
curl -v -X POST https://jsonplaceholder.typicode.com/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"hello","body":"from curl","userId":1}'

jsonplaceholder.typicode.com is a free fake API: it returns realistic responses (including 201 Created for the POST) but does not actually persist your data. You can build commands like these visually with the cURL Generator.

And the same request in JavaScript (Node 22 or the browser console), with checks you would make in a test:

const res = await fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
  body: JSON.stringify({ title: 'hello', body: 'from fetch', userId: 1 }),
});

console.log(res.status);                        // 201
console.log(res.headers.get('content-type'));   // application/json; charset=utf-8
const body = await res.json();
console.log(body.id, body.title);               // 101 hello

Practice exercise

Open the API Playground (or use curl against a test API you are allowed to call) and, for a single resource such as users, send requests that produce at least five different status codes. For each request, record:

  1. Method and URL
  2. Relevant request headers and body
  3. Status code received
  4. Whether that status code is correct according to RFC 9110 semantics, and why

A good result covers at least one 2xx, one 401 or 403, one 404, and one validation error (400 or 422), and explains any response that looks wrong as a potential defect.

Show a model answer

Your exact endpoints will differ; this is the shape of a strong answer.

# Request Status Correct?
1 GET /users/1 with a valid token 200 Yes: resource exists and is readable
2 POST /users with valid JSON body 201 Yes, and a Location header points to the new user
3 GET /users/1 with no Authorization header 401 Yes: no credentials supplied
4 DELETE /users/1 as a viewer role 403 Yes: authenticated but not permitted
5 GET /users/999999 404 Yes: no such user
6 POST /users with "email": "not-an-email" 422 Yes: well-formed JSON, invalid content (400 is also commonly used; check the API docs)
7 POST /users with a truncated JSON body 500 No. This is a defect: malformed input should return 400 with an error message

The last row shows the mindset: you are not just recording codes, you are judging whether each one is the right answer.

Key takeaways

  • An HTTP exchange is a request (method, target, headers, optional body) and a response (status code, headers, optional body). RFC 9110 defines the semantics.
  • Safe methods do not request changes; idempotent methods have the same effect when repeated. Test both properties.
  • Know the 4xx codes precisely, especially 401 vs 403 and 400 vs 422.
  • Any request that triggers a 5xx is a bug worth reporting.
  • Use browser dev tools and curl -i / curl -v to see real HTTP traffic before reaching for heavier tools.

Key terms

Finished this lesson?

Progress is saved in this browser. No account needed.

Type to search across SDETRole.

Full-text search by Pagefind · runs in your browser Open search page →