Documentation menu

How to test a REST API

A step-by-step guide to testing a REST API: choose a method, set headers and a body, send the request, and read the response properly.

Updated

Testing a REST API means sending a request and checking that the response is what the contract promised — the right status code, the right shape, and a sane response time. Here is the whole loop in SchemaClient.

1. Pick a method and a URL

Open the REST Client tab and enter the endpoint. The method matters more than people expect, because it decides what the server is allowed to do:

  • GET — read something. Must not change server state.
  • POST — create something, or trigger an action.
  • PUT — replace a resource wholesale.
  • PATCH — update part of a resource.
  • DELETE — remove a resource.
  • HEAD — like GET, but headers only. Useful for checking whether something exists without downloading it.
  • OPTIONS — ask what the endpoint supports. This is also what a browser sends as a CORS preflight, so it is worth testing directly when CORS misbehaves.

Query parameters

Anything after ? filters or shapes the response rather than identifying the resource:

GET /api/users?status=active&limit=25&sort=-created_at

Two things break here regularly. Values need URL-encoding — a space is %20, an & inside a value is %26, and an unencoded one silently splits your parameter in half. And arrays have no single convention: some APIs want ?tag=a&tag=b, others ?tag[]=a&tag[]=b, others ?tag=a,b. Check the docs rather than guessing, because the wrong form usually returns a 200 with the filter ignored.

2. Add headers

Most failures at this stage are header failures. The two that matter most:

Content-Type: application/json
Authorization: Bearer <your-token>

If the API returns 415 Unsupported Media Type, your Content-Type is wrong. If it returns 401, the token is missing, expired, or in the wrong header.

The three auth schemes you will actually meet

Bearer tokenAuthorization: Bearer <token>. The most common. Tokens expire, and an expired token gives you a 401 that looks identical to a missing one.

Basic authAuthorization: Basic <base64 of user:password>. Still common on internal and legacy services. The base64 is encoding, not encryption; treat the credentials as plaintext.

API key — sometimes a header (X-API-Key), sometimes a query parameter (?api_key=…). The query-parameter form leaks keys into server logs and browser history, so prefer the header when the API offers both.

3. Add a body

For POST, PUT and PATCH, switch to the Body tab and send JSON:

{
  "email": "dev@example.com",
  "plan": "free"
}

Malformed JSON is the second most common cause of a 400 — a trailing comma is enough to break it. If you are uploading a file, use multipart form data rather than JSON, and let the client set the Content-Type boundary itself; hand-writing that header is a reliable way to get a 400.

4. Send it and read the status code

Status codes tell you who is at fault before you read a single line of the body:

  • 2xx — it worked.
  • 3xx — it moved. Check the Location header.
  • 4xxyou got it wrong. Bad input, bad auth, wrong URL.
  • 5xxthe server got it wrong. Your request may be fine; retry and check logs.

The ones worth recognising on sight:

CodeWhat it usually meansFirst thing to check
400Malformed requestJSON syntax, required fields
401Not authenticatedToken missing, expired, or wrong header
403Authenticated, not allowedPermissions or scope on the token
404Wrong URL, or the resource is gonePath, IDs, trailing slash
415Wrong Content-TypeThe header, not the body
422Well-formed but semantically invalidField-level validation errors in the body
429Rate limitedRetry-After header
500Server bugNot your request — check server logs
502 / 504Upstream failed or timed outInfrastructure, not your payload

There is a fuller reference in HTTP status codes explained.

5. Check the response body, not just the status

A 200 OK can still be wrong. An endpoint that returns {"users": null} instead of an empty array will pass a status-code check and break your app anyway. This is why it is worth validating responses against a schema rather than eyeballing them — and why a green test suite can still miss a breaking change.

Read the response headers too. Content-Type tells you whether you actually got JSON; rate-limit headers tell you how much budget is left; and cache headers explain why you are seeing a stale value.

Use variables instead of pasting values

As soon as you have more than one request, stop pasting the base URL and the token into each one. Put them in environment variables and reference them:

{{baseUrl}}/api/users
Authorization: Bearer {{token}}

Now switching between local, staging and production is changing one environment rather than editing every request, and a rotated token is a single edit.

A short checklist

Before you call an endpoint tested:

  • The happy path returns the expected status and the expected shape.
  • A missing required field returns a 4xx, not a 500.
  • An invalid or expired token returns 401, not 200 with empty data.
  • Asking for something that does not exist returns 404, not an empty 200.
  • The response time is in the range you expect.

Save it for next time

Once a request works, save it into a collection so you are not rebuilding it by hand every week — see collections and cloud sync. If the API you are testing runs on your own machine, you will also want a public URL for localhost. And once the collection is worth keeping green, run it in CI.

Frequently asked questions

What is the difference between PUT and PATCH?

PUT replaces the entire resource with the body you send, so any field you omit is typically cleared. PATCH applies a partial update and leaves unmentioned fields alone. If you send a PUT with only one field, expect the rest of the resource to be wiped.

Why does my request work in the browser but fail in an API client?

The browser is sending cookies and headers you are not reproducing. Open the browser devtools, find the request, copy it as cURL, and compare it against what you are sending — the difference is almost always an Authorization header, a session cookie, or a Content-Type.

What is a good response time for an API?

It depends entirely on what the endpoint does, but as a rough guide: under 100ms feels instant, under 300ms feels responsive, and anything over a second needs a reason. What matters more than the absolute number is whether it changed — a call that was 80ms last week and is 800ms today is a regression regardless of the threshold.

How do I test an endpoint that needs a token from another endpoint?

Send the login or token request first, then reuse its value. Storing it as an environment variable means the rest of your requests reference the variable rather than a pasted string, so refreshing the token is a one-line change instead of an edit to every request.