How to Test an API: Tools and a Simple Checklist for Beginners
Testing an API means sending requests and checking the responses — by hand with curl, Postman, Bruno or your editor, and automatically with tests that run on every change. What to check (status codes, body, auth, bad input), example tests, and a checklist.
An API is a set of URLs your app (or other apps) can call. Testing it means sending requests and checking that the responses are what they should be — including when something goes wrong. (What is an API?)
There are two kinds of testing, and you want both.
1. Manual testing: poke it and see
Good for exploring, debugging, and checking a new endpoint works at all.
curl (terminal)
curl -i http://localhost:3000/api/products
curl -i -X POST http://localhost:3000/api/products \
-H "Content-Type: application/json" \
-d '{"name": "Lamp", "price": 39}'
-i shows the status code and headers as well as the body. (What is curl?)
A graphical API client
- Postman — the best-known; collections, environments, sharing.
- Bruno — open source, stores requests as files in your repo, no account needed.
- Insomnia, Hoppscotch (in the browser).
- REST Client extension for VS Code — write requests in a
.httpfile:
POST http://localhost:3000/api/products
Content-Type: application/json
{ "name": "Lamp", "price": 39 }
Your browser
GET requests can be opened directly in a tab, and DevTools' Network tab shows every request your frontend makes. (Browser developer tools)
What to check
For each endpoint, test more than the happy path:
| Check | Example |
|---|---|
| Status code | 200/201 on success, not 200 with an error message inside (status codes) |
| Response body | Right fields, right types, nothing sensitive (no password hashes!) |
| Bad input | Missing fields, wrong types, huge values → 400 with a clear message |
| No login | Protected endpoint without a token → 401 |
| Someone else's data | User A requests User B's order → 403 or 404 (IDOR) |
| Not found | /api/products/999999 → 404 |
| Duplicates | Submitting the same thing twice behaves sensibly |
| Speed | Responds in a reasonable time with realistic data |
The "someone else's data" check is the one most often skipped — and the one that matters most for security. (401 vs 403)
2. Automated testing: let the computer check every time
Manual tests catch problems once. Automated tests catch them every time you change something — including when an AI tool changes something. (Unit vs integration vs E2E tests)
An example with Vitest and Supertest for an Express API:
import request from 'supertest'
import { app } from '../src/app'
describe('POST /api/products', () => {
it('creates a product', async () => {
const res = await request(app)
.post('/api/products')
.set('Authorization', `Bearer ${adminToken}`)
.send({ name: 'Lamp', price: 39 })
expect(res.status).toBe(201)
expect(res.body.name).toBe('Lamp')
})
it('rejects a missing price', async () => {
const res = await request(app)
.post('/api/products')
.set('Authorization', `Bearer ${adminToken}`)
.send({ name: 'Lamp' })
expect(res.status).toBe(400)
})
it('requires login', async () => {
const res = await request(app).post('/api/products').send({ name: 'Lamp', price: 39 })
expect(res.status).toBe(401)
})
})
Run them on every push with CI. (Set up CI with GitHub Actions)
AI coding tools are good at writing these — ask for tests that cover bad input and authorisation, not just the happy path, and check they fail when they should. (Getting AI to write tests that catch bugs)
Testing against a real database
Tests are most trustworthy when they use a real (test) database rather than mocks — that's where many bugs live. Use a separate test database that's reset between runs, never your production one.
Load testing
Once it works, check how it behaves under many requests at once. (Load testing your app)
A beginner's checklist
- Every endpoint returns the right status codes.
- Bad input gets a 400, not a crash (500).
- Protected endpoints return 401 without login.
- Users can't read or change other users' data.
- Responses don't leak sensitive fields.
- There's at least one automated test per endpoint, running in CI.
EasySpawn runs your API with a separate development database next to production, so you and Claude Code can test freely without touching real data. See how it works or join the waitlist.
Related: What Is curl? · How to Test Your App Before Launch · Designing a REST API · Unit vs Integration vs E2E Tests
Keep reading
What Is ngrok? Share Your Localhost With the Internet
ngrok gives your local app a public HTTPS URL by tunnelling traffic to your machine. What it's for (webhooks, demos, mobile testing), how to use it, the request inspector, free vs paid limits, security cautions, and alternatives like Cloudflare Tunnel.
What Is curl? A Beginner's Guide With Practical Examples
curl is a command-line tool for making web requests, installed on almost every computer. The commands you'll actually use — GET, POST JSON, headers, authentication, following redirects, downloading files, seeing response headers — and how to read API docs that use it.