A blunt list, not a checklist
This is not "10 best practices for API testing in 2026". It is the small list of things we have watched teams skip, and then watched them pay for it on a Sunday at 3 a.m. If you do these, your API suite earns its keep. If you skip them, the suite becomes the thing people mute in CI.
Status codes are the floor, not the ceiling
"200 OK" tells you the server did not crash. It does not tell you the response body matches the contract, the side effects happened, or the new field your mobile client needs is actually present. Assert response shape (schema or fixture), assert side effects (DB row, queued job), and assert error shape for non-2xx — not just the code.
Determinism is a feature, not a nice-to-have
- Freeze time. Anything that depends on "now" must be controllable.
- Seed test data per run. Shared mutable fixtures are how you get the famous "passes locally, fails in CI on Tuesdays" bug.
- Isolate side effects. The test that sends a real email to a real address once is the test that sends 50 000 of them once.
Environment isolation
Run the API in CI against an ephemeral database, not against staging. Staging is shared, slow, and somebody else's test will eat your fixture. If you cannot run the API locally, your API tests are not really tests — they are integration probes against a moving target.
Secrets and auth
Do not bake real tokens into the suite. Use a test-only auth flow, expire tokens fast, and assume the suite repo will leak some day. Test the unhappy auth paths — expired token, wrong scope, revoked key. They are where production incidents actually live.
Wire it into CI without making the team hate the pipeline
- Run on every PR, not nightly. Nightly = "we'll find out tomorrow" = "we won't find out".
- Split fast and slow suites. The fast suite is a gate. The slow suite is a signal.
- Make a failure tell the engineer which contract broke and which commit changed it. Generic red checkmarks get muted.
Stop testing things that don't matter
Coverage is a vanity metric. 200 tests for one CRUD endpoint and zero tests for the payment webhook is a worse suite than 50 tests on the things that would page someone at night. Once a quarter, delete the tests that have not failed in a year and that no one would notice if they were gone.