The first API bug that really cost me an afternoon was a 401 Unauthorized that had nothing to do with my credentials. The key was correct. The endpoint was correct. What was wrong was that I had typed Authorisation instead of Authorization in the header name, and the server did what servers do: it ignored the header it did not recognize and told me I was not logged in.
I found it in about ten seconds once I stopped guessing and actually sent the request somewhere I could see every part of it. That is really all API testing is: making the invisible parts of a request visible so you can tell which one is wrong.
What “testing an API” actually means
When your app talks to an API, a lot happens that you never see. Your code builds a request, a library adds headers you did not write, the server responds, and somewhere in the middle something breaks. Testing an API means taking your application out of the loop entirely and sending the request by hand, so you can answer one question: is the problem my code, or is it the API?
That single question saves enormous amounts of time. If the request works when you send it manually, the bug is in your code. If it fails the same way manually, the bug is in your request, your credentials, or the API itself. You have just cut the search space in half.
Every request has exactly four parts
No matter how complicated an API looks, every request you will ever send is built from the same four pieces. Once you can see all four, debugging gets much easier.
- The method. The verb:
GET,POST,PUT,PATCH, orDELETE. It tells the server what kind of operation you want. - The URL. The address of the resource, including any query parameters after the
?. - The headers. Metadata about the request: what format you want back, who you are, what content you are sending.
- The body. The actual data you are sending, usually JSON.
GETandDELETEnormally have no body.
A minimal request looks like this:
GET https://api.github.com/users/octocat Accept: application/json
You can send exactly that from the free online API tester without installing anything. Pick the method, paste the URL, hit send, and read what comes back.
Picking the right method
Using the wrong verb is one of the most common reasons a request fails with a confusing error. The convention is consistent across almost every REST API:
- GET retrieves data and changes nothing. Safe to repeat.
- POST creates something new. Repeating it usually creates duplicates.
- PUT replaces a resource entirely with what you send.
- PATCH updates only the fields you include.
- DELETE removes the resource.
The PUT versus PATCH distinction catches people out constantly. If you send a PUT with only one field, a strict API will treat every field you left out as deliberately blanked. When you only mean to change one thing, PATCH is almost always what you want.
Reading the response
The status code is the first thing to look at, and it tells you far more than most people use it for. The pattern is simple: 2xx means it worked, 4xx means you made a mistake, 5xx means the server made a mistake.
- 200 OK — success, with data in the body.
- 201 Created — your
POSTworked and something new exists. - 204 No Content — success, but there is deliberately nothing to return. Common after a
DELETE. - 400 Bad Request — the server could not parse what you sent. Usually malformed JSON.
- 401 Unauthorized — the server does not know who you are. Your credentials are missing, malformed, or expired.
- 403 Forbidden — the server knows exactly who you are and you are not allowed. Do not go looking for a credentials bug here.
- 404 Not Found — wrong URL, or the resource genuinely does not exist.
- 422 Unprocessable Entity — your JSON was valid but the values failed validation. The body usually says which field.
- 429 Too Many Requests — you hit the rate limit. Look for a
Retry-Afterheader. - 500 Internal Server Error — the API crashed. Not your fault, though a malformed request can sometimes trigger it.
The 401 versus 403 distinction is worth committing to memory. It is the difference between “I don’t know you” and “I know you, and no.” People burn hours regenerating perfectly good API keys because they read a 403 as an authentication problem.
Your first request, step by step
Open the API tester and try a real public endpoint that needs no key:
- Set the method to
GET. - Enter
https://api.github.com/users/octocatas the URL. - Add a header: name
Accept, valueapplication/json. - Send it.
You should get a 200 back with a JSON object describing that account. Now change the username to something that does not exist and send it again. You will get a 404 with a short JSON body explaining the problem. That contrast, the same request succeeding and failing on one small change, is the whole debugging loop in miniature.
Next, try sending data. This endpoint accepts test posts and echoes back what it received:
POST https://jsonplaceholder.typicode.com/posts
Content-Type: application/json
{
"title": "Testing an API",
"body": "Sent from a browser.",
"userId": 1
}
The Content-Type header matters here. Leave it off and many servers will not parse your body at all, then reject the request for missing fields you clearly sent. If the response comes back as a dense unreadable blob, paste it into the JSON formatter to expand it, and to confirm your own request body was valid JSON in the first place.
Authentication: the three patterns
Nearly every authenticated API uses one of three approaches, and all three are just headers.
Bearer tokens are the most common. You send a token issued by the API:
Authorization: Bearer YOUR_TOKEN_HERE
The word Bearer, the single space, and the exact spelling of Authorization all matter. If the token is a JWT, you can check what is inside it and whether it has already expired using the JWT decoder. An expired token is a very common cause of a sudden 401 on code that worked yesterday.
API keys come in a custom header, and the name varies by service:
X-API-Key: YOUR_KEY_HERE
Some APIs instead want the key as a query parameter. Check the docs, because guessing wastes time.
Basic auth sends a username and password Base64-encoded. It is the oldest pattern and still turns up in internal and legacy systems. If you need to build or inspect one by hand, the Base64 encoder handles the encoding step. Worth remembering: Base64 is encoding, not encryption, so Basic auth over plain HTTP is effectively sending your password in the clear.
Why the browser sometimes blocks you
This is the one thing that confuses people testing APIs from a browser, and it is worth understanding rather than fighting.
Browsers enforce CORS, a security rule that stops a page on one domain from freely reading responses from another domain. If the API does not explicitly send back a header saying “requests from other origins are allowed,” the browser refuses to hand you the response, even though the server answered perfectly well.
The important part: a CORS error is not an API error. The request usually succeeded. The browser is simply declining to show you the result. Signs you are looking at CORS rather than a real failure:
- The status shows as
0, or there is no status at all. - The error mentions “origin”, “cross-origin”, or “Access-Control-Allow-Origin”.
- The same URL works fine when you open it directly in a new tab.
Public APIs designed for browser use, like the two in the examples above, send the right headers and work fine. Internal APIs and many paid services do not, by design. For those, test from a server-side tool or ask whoever runs the API to allow your origin.
The errors you will actually hit
- 401 on a key you know is right → check the header name spelling and that the word
Beareris present with one space after it. - 400 on a body that looks fine → run it through a JSON validator. A trailing comma or a smart quote from a word processor will do it.
- Server ignores your data → you almost certainly forgot
Content-Type: application/json. - 404 on a URL you copied from the docs → check for a missing or doubled slash, or a version prefix like
/v1/you left out. - Query parameters not working → special characters need escaping. The URL encoder shows you what your parameters really look like once encoded.
- Worked yesterday, 401 today → the token expired. Decode it and check the expiry claim.
Habits that save time
- Change one thing at a time. When you edit the URL, the headers, and the body together, a fix and a new bug cancel out and you learn nothing.
- Get a GET working first. Prove your credentials work on a simple read before debugging a complex write.
- Read the response body, not just the status. Most APIs explain the exact problem there, and most people never scroll down to it.
- Never paste production tokens into tools that send them to a server. A live token is a working key to your account until it expires. Prefer tools that run in your browser.
Frequently asked questions
Can I test an API without installing Postman?
Yes. A browser-based tool like the free online API tester sends the same requests with no install and no account. That makes it the practical option on a locked-down work laptop or a Chromebook where you cannot install desktop software.
What is the difference between 401 and 403?
A 401 means the server could not identify you: your credentials are missing, malformed, or expired. A 403 means it identified you successfully and you do not have permission for that action. Regenerating your API key will not fix a 403.
Why do I get a CORS error when the API works in a browser tab?
Opening a URL directly is not a cross-origin request, so CORS does not apply. Sending it from a page on a different domain is, and the browser will block you from reading the response unless the API sends an Access-Control-Allow-Origin header. The request itself usually succeeded.
Should I use PUT or PATCH to update something?
Use PATCH when you want to change specific fields and leave the rest alone. Use PUT when you are replacing the whole resource. Sending a partial PUT can blank out every field you omitted.
Is it safe to test with a real API key?
Only in tools that keep the key on your device rather than sending it to their own server, and ideally with a development or read-only key rather than a production one. Rotate any key you have pasted somewhere you are unsure about.
Why does the server ignore the data I send?
Almost always a missing Content-Type: application/json header. Without it many frameworks never parse the body, so the server behaves as though you sent nothing and complains about missing required fields.
The short version
Testing an API is just sending the four parts of a request by hand so you can see which one is wrong. Read the status code first, then the response body. Remember that 401 and 403 are different problems, that a missing Content-Type silently discards your data, and that a CORS error is the browser talking, not the API. Get a simple GET working before you debug anything complicated, and change one variable at a time.
When something breaks, open the API tester, rebuild the request piece by piece, and let the response tell you where the problem is. It is usually a header, and it is usually spelled slightly wrong. You can find the rest of the developer tools in one place when you need them.
Handy tools for this topic
70+ free tools, zero sign-up
Every ToolBrainy tool runs right in your browser — no accounts, no watermarks and no limits. Compress a PDF, generate a strong password, convert an image and plenty more.



