How to test a REST API manually: a checklist
To test a REST API manually, read its documentation first, then for every endpoint send one request that should work and several that should be refused. In each response, check the status code, the body and the headers, and then check with a second request that the change really happened. A refused request must fail with the right code and a clear message: 400 for invalid data, 401 when the API does not know who you are, 403 when you are known but not allowed, 404 when the thing is not there or not yours, and 409 when the request conflicts with the current state. You need no code: an API client such as Postman, or the documentation's own "Try it out" button, is enough.
- 7 checks
- for every endpoint
- 15 example requests
- to a practice shop's API
- No code
- an API client is enough
How to test an endpoint, step by step
- Step 1
Read the documentation for the endpoint
Note the method, the path, the required fields with their types and limits, and every response code the documentation lists. Each listed code is at least one test.
- Step 2
Send the request that should work
Use the documentation's example body. Check the status code first, then every value in the body against the rule, then the headers.
- Step 3
Confirm the change with a second request
After a POST, PUT, PATCH or DELETE, read the same resource with GET. The answer to a change says what the API claims; the next read shows what it kept.
- Step 4
Break one input at a time
A missing required field, a wrong type, a value outside the limits, an id that does not exist. One fault per request, so the refusal points at one rule.
- Step 5
Test access
Send the request without a token, then with a token for data that belongs to someone else, then on a resource you may read but not change.
- Step 6
Test the state
Repeat the request, send it in the wrong order or on an empty resource. These are where 409 and the business rules show up.
- Step 7
Write down the evidence
For a defect, keep the method, address, body, the status and body you got, the status the documentation promises, and the response's trace header if there is one.
Open
What to check in a REST API
A REST API exposes resources (products, a cart, orders) at addresses, and you act on them with HTTP methods: GET reads, POST creates, PUT replaces, PATCH changes some fields, DELETE removes. Every answer has a status code, headers and usually a body. Manual API testing means sending those requests yourself and comparing each part of the answer with the documentation.
The examples use the API of Shelf, the practice shop the courses use. Its base address and the link to its documentation are on the start page of your own sandbox; below, the base address is written as {{base_url}}, so {{base_url}}/products means the products endpoint. The API writes money as a number of dollars: 49 is USD 49.00.
1. Status code
The one the documentation lists for this case, not just "something in the 200s".
2. Body values
Each value against the rule: the right product, the right quantity, the right total.
3. Body shape
Field names and types as documented: a price is a number, not a string; an id is a whole number.
4. Headers
Content-Type of the body, Location after a create, trace or request ids, nothing that leaks internals.
5. The change itself
A second request shows that the create, update or delete was kept.
6. Refusals
Invalid data, missing access and wrong state each fail with their own code and a clear message.
7. Nothing extra
No password hashes and no other users' data in any answer.
Reading the OpenAPI documentation
Most REST APIs publish an OpenAPI description, often shown in Swagger UI. Shelf's start page links to it with "REST docs in Swagger UI", and offers the raw description to import into Postman. Endpoints are grouped by tags; in Shelf they are Account, Catalog, Cart, Orders and Service.
Open one endpoint and read four things: the parameters, the request body (its "Example Value" and "Schema" views), the security it needs, and the "Responses" list. "Try it out" and then "Execute" send a real request from the page and show the "Request URL", the "Server response" and a ready curl command. "Authorize" takes your token once for the whole page.
Turn the responses list into a test list. Here is what the documentation of one endpoint gives you before you send anything.
POST /api/cart/items "Add a product (adds to the quantity
if it is already in the cart)"
Body: product_id (required, integer), quantity (1 to 10, default 1)
201 Added -> a product not yet in the cart
200 Quantity increased -> the same product again
400 Validation failed -> product_id missing
401 Not signed in -> no token
404 Not found -> a product id that does not exist
409 Out of stock or not enough -> a product with stock 0
422 More than 10 of one product -> 8 in the cart, add 3 moreStatus codes and what they should mean
The status code is the API's verdict, and programs that call the API act on it. A refusal sent with 200 breaks those programs even when the body reads well. Check the exact code the documentation names for each case, not just its first digit.
Some codes are worth knowing by their Shelf examples, all from its documentation and messages.
200 OK
A read or a change that worked. GET {{base_url}}/products?category=toys is 200 with "items": [] and "total": 0: an empty list is a valid answer, not a 404.
201 Created
Something new exists. POST {{base_url}}/products with your token creates your own product and answers with a Location header that points to it.
204 No Content
Done, and there is no body to read, as when you empty your cart with DELETE {{base_url}}/cart.
400 Bad Request
The data breaks a rule. PATCH your product with {"stock": 1000} gives "stock must be from 0 to 999."
402 Payment Required
Shelf's answer to a declined test card: 4000000000000002 gives "The card was declined. Try another test card."
409 Conflict
The request is fine, the state is not. A coupon on an empty cart: "Your cart is empty. Add something before you apply a coupon."
422 Unprocessable
Well formed, but the rule refuses it. An unknown coupon: "There is no coupon SAVE30. Check the code and try again."
Checking the body: values, not just presence
A body that has all the fields can still be wrong. Work out the expected values from the rule before you send, then compare. Calculated fields such as totals, counts and flags are where the mistakes hide, because each one depends on several other values.
Take Shelf's cart rules from its documentation: the coupon SAVE25 takes USD 25.00 off, never more than the subtotal; shipping is USD 4.99 and free from a subtotal of USD 50.00 (before the discount) or when every item ships free; the total is subtotal minus discount plus shipping. One Hearthline Classic Kettle 1.7 l (product 1, USD 49.00, does not ship free) with SAVE25 gives the cart below.
Check the shape too. Every Shelf error has the same body: an error object with a code, a message and, for validation, details. A client program reads the code, so a misspelled or missing code is a defect even when the message is fine.
POST {{base_url}}/cart/items {"product_id": 1, "quantity": 1} -> 201
POST {{base_url}}/cart/coupon {"code": "SAVE25"} -> 200
Expected in the cart:
"subtotal": 49 one kettle at USD 49.00
"discount": 25 SAVE25, less than the subtotal
"shipping": 4.99 subtotal under USD 50.00, kettle not free
"total": 28.99 49 - 25 + 4.99Checking the headers
Headers carry what the body does not. Check that Content-Type matches the body (JSON for a JSON API), that a 201 has a Location header pointing to the new resource, and that the server does not announce more than it needs, such as its framework and version.
Shelf puts an x-trace-id header on every response, refused ones included. Copy it into every API bug report: it lets a developer find the exact request in the logs. Header names are not case sensitive, so x-trace-id and X-Trace-Id are the same header.
Access: 401, 403 and 404
Access checks need at least two accounts, or one account and data that belongs to someone else. 401 means the API does not know who you are: no token, or an invalid or expired one. 403 means it knows who you are and you may not do this. Shelf's start page states the rule in one line: "401 no token or key, or an expired one · 403 signed in, but not allowed".
Some APIs answer 404 for another customer's data instead of 403, so that the answer does not even confirm the order exists. Shelf does this: its 404 means not there, or not yours. Whatever the API chose, the documentation must say it and every endpoint must follow it.
GET {{base_url}}/me, no token
401 "Sign in first: send Authorization: Bearer <token>."
DELETE {{base_url}}/products/3, your token, a shared catalog product
403 "read_only_product"
GET {{base_url}}/orders/1, your token, another customer's order
404 "There is no order 1 in your account."Negative cases and state
For each required field, send the request without it. For each limit, send the values just inside and just outside it. For each typed field, send the wrong type, such as a price as the string "19.99" instead of the number 19.99. One fault per request: two faults in one request leave you guessing which rule refused it.
Then test state. Read the same resource after a change. A PUT replaces all fields, so in Shelf a PUT without a name is refused with "name is required.", while a PATCH changes only the fields you send: PATCH your product with {"stock": 7}, then GET it, and the stock should read 7 and in_stock true. Repeat a request that should happen once, and send steps in the wrong order, such as a coupon before anything is in the cart.
An API bug report template
An API defect is reproduced from text alone, so the report carries the request exactly as sent. Keep the base address as a variable and say where its value comes from, and quote the documentation for the expected result.
Title: <METHOD> <path>: <what is wrong> when <condition> Environment: <server or sandbox>, <API version or build> Preconditions: <signed in as / cart state / existing data> Request: <METHOD> <full address> Headers: <only the ones that matter> Body: <exact JSON> Expected: <status and body>, per <documentation section> Actual: <status and body you got>. Reproduced <N of N>. Trace id: <x-trace-id from the response>
Where to learn this
Questions and answers
Can I test a REST API without writing code?
Yes. An API client such as Postman sends any request you build by hand, and Swagger UI's "Try it out" and "Execute" send one from the documentation page. Code is needed only to automate checks.
What is the difference between 400 and 422?
Both refuse the data. Many APIs use 400 when the request breaks the format or a field rule, and 422 when it is well formed but the business rule refuses it, such as an unknown coupon. APIs differ; the documentation decides, and every endpoint should follow the same choice.
Should an empty search result be 404?
Usually not. A list endpoint that finds nothing answers 200 with an empty list. 404 is for one resource that does not exist, such as a product id nobody has.
Why answer 404 instead of 403 for someone else's data?
A 403 confirms that the thing exists. A 404 tells a stranger nothing, which is safer for data such as orders. Check that the API does the same on every endpoint that holds private data.
What goes into an API test checklist?
For each endpoint: the success case, every documented error code, each required field missing, each limit just inside and outside, the wrong type, no token, someone else's data, and a second request that confirms the change.
More guides
- Start hereHow to become a software testerWhat a software tester does, what to learn and in what order, and how to practice without a job: six steps from zero to a small portfolio.
- Bug reportsHow to write a bug reportThe fields of a bug report, a template to copy, a complete example from a practice shop, severity and priority with examples, and the mistakes that send a report back to you.
- Test casesHow to write test casesThe parts of a test case, a template, a complete example and its negative cases, the difference between a test case, a test scenario and a checklist, and how to fix a weak case.
- Test designBoundary value analysis and equivalence partitioning, with examplesHow to split inputs into equivalence partitions, pick boundary values with the 2-value and 3-value methods, and choose the step, worked through four fields of a practice shop.
- Bug reportsSeverity vs priority, with examplesWhat severity and priority mean, who sets each, the scales teams use, and all four combinations worked through on one practice shop, with a short answer for interviews.
- Test documentationTest case vs test scenario vs checklistWhat a test scenario, a checklist and a test case are, one shop feature written all three ways, when to use which, and how a scenario turns into checklists and test cases.
- Test designHow to test a login pageTest cases for a login page derived from partitions, a decision table, boundaries and states, plus the security checks every login page needs, worked through on a practice shop.
- API testingAPI testing with Postman: a beginner's guideHow to send your first requests in Postman, read the response, keep addresses and tokens in variables, test 401 and 403, add a status check and run a collection, on a practice shop's API.
- DatabasesSQL for testers: check what the app savedHow testers use SQL: the queries that check what an online shop saved after an order (order row, items, payments), SELECT, WHERE, GROUP BY and JOIN on a real schema, and the mistakes to avoid.
- Web testingChrome DevTools for testers: how to collect evidence for a bug reportWhich Chrome DevTools panels a tester needs and how to use them to collect the Console error, the request, the server's response and the storage values that make a web bug report reproducible.
- Test processSmoke vs sanity vs regression testingWhat smoke, sanity, regression testing and retesting usually mean, why teams use the names differently, how to ask on a new team, and how to choose the checks for a new build.
- Mobile testingHow to test a mobile appWhat breaks only on a phone, how to choose between an emulator, a simulator and a real device, how to read the app's log and its traffic through a proxy, and a checklist to start from.
See the first course
The full outline of every course is available: you can see each lesson before you start.

