Structured, traceable, high-coverage test design — faster.
treeifyai.com
“Spec is truth; tests are proof.”
Use this checklist to ensure every API surface is contracted, observable, and resilient—with test cases that prove behavior across happy, alt, and failure paths.
- Cover HTTP semantics: methods, status codes, headers, caching, idempotency.
- Verify contracts with schemas, example payloads, and message IDs for errors.
- Exercise pagination/filtering/sorting, rate limits, retries/timeouts, and webhooks.
- Include security, privacy, and tenancy gates.
- Capture evidence: logs, traces, metrics, and reproducible
curl/Postman collections.
- Spec available (OpenAPI/GraphQL schema/Protobuf) and versioned.
- Environments and credentials ready; test tenant/users seeded.
- Data contracts defined for inputs/outputs (types, ranges, required, enums, PII flags).
- Error taxonomy and message IDs mapped.
- Observability: log/metric/trace fields and correlation IDs defined.
Links:
- Contracts & Schemas →
../40-api-and-data-contracts/contracts-and-schemas.md - Error Taxonomy →
../40-api-and-data-contracts/error-taxonomy.md - Idempotency & Retries →
../40-api-and-data-contracts/idempotency-and-retries.md - Pagination & Filtering →
../40-api-and-data-contracts/pagination-and-filtering.md - Security Essentials →
../50-non-functional/security-essentials.md
For each route (e.g., POST /orders, GET /orders/:id, GET /orders):
- Method semantics correct (
GETis safe/idempotent;POST/PATCHunsafe). - Status codes:
2xxsuccess variants;4xxvalidation/policy;5xxdependency/unknown. - Headers:
Content-Type,Accept,ETag,If-None-Match,Idempotency-Key(unsafe),X-Correlation-Id. - Request validation: type, range, enum, required/optional, unknown fields rejected.
- Response shape: matches schema; fields typed; nullability correct; extra fields disallowed.
- Message IDs included on errors; error codes stable.
- Caching:
Cache-Control,ETag/conditional GET where applicable. - Latency within budget (p95/p99); payload sizes within limits.
- Observability: logs with
msgid, metrics RED, traces with db/cache spans.
Template (checklist to paste under each route)
Route: <METHOD PATH>
Scope: <tenants/locales/features>
[ ] HTTP method & status codes
[ ] Request schema validation (incl. unknown fields)
[ ] Response schema validation (nullability, enums)
[ ] Headers (Accept, Content-Type, caching, correlation)
[ ] Authn/Authz (role/tenant matrix)
[ ] Idempotency (unsafe operations)
[ ] Pagination/filtering/sorting (for list)
[ ] Rate limits & 429 handling
[ ] Timeouts/retries/deadlines
[ ] Evidence captured (logs, traces, metrics, curl)
- Idempotency-Key required for unsafe
POST/PATCH/DELETE. - Replays with same key return same response (
Idempotency-Status: replayed). - Duplicate suppression under concurrent requests (DB constraints/unique keys).
- Conditional requests for updates:
If-MatchwithETagto prevent lost updates.
- Cursor-based pagination with stable sort + tiebreaker.
-
next_cursor/prev_cursorbehavior correct; empty list edge cases. - Filters validated (types, ranges, enums); unknown filters rejected.
- Count/
totaloptional but consistent; documented costs. - Sorting whitelisted; invalid sort rejected.
See: ../40-api-and-data-contracts/pagination-and-filtering.md.
- Taxonomy: errors carry
codeand message ID; HTTP codes aligned. - Retryable vs non-retryable clearly separated;
Retry-Afteron 429/503. - Deadlines enforced server-side to avoid long tail.
- Partial failures return per-item statuses with stable IDs.
- Problem details style supported (JSON object with
type,title,detail,code).
Example error body
{
"code": "ERR.VALIDATION.email",
"message_id": "validation.email.invalid",
"title": "Invalid email",
"detail": "Must be a valid address",
"request_id": "req_7YkP0v"
}- Authn present (OAuth2/JWT/API key); tokens validated (aud/iss/exp/nonce).
- Authz matrix enforced; IDOR protections on path/body/query IDs.
- Tenant isolation proven; list endpoints scoped correctly.
- Headers:
CORSrules minimal; security headers where applicable. - PII minimization: payloads exclude secrets; hashing where needed; no PII in logs.
- Rate limits per IP/user/tenant; safe defaults.
Links: ../57-cross-discipline-bridges/for-security-compliance.md, ../50-non-functional/privacy-and-compliance.md.
- Webhooks signed (HMAC + timestamp), replay window enforced.
- Inbox dedupe table processes at-least-once deliveries; idempotent handlers.
- Retry policy with backoff + jitter; dead-letter and replay endpoints.
- Ordering not assumed; handlers reconstruct via
occurred_atand IDs. - Evidence: delivery logs, signature verify, dedupe hits, replay proof.
See: ../55-domain-playbooks/b2b-integrations.md and ../40-api-and-data-contracts/idempotency-and-retries.md.
- 202 Accepted with operation id and
Locationto poll status. - Status endpoint exposes
state(pending/running/succeeded/failed/canceled), progress, result/error. - Idempotent resubmits; cancellation supported.
- Evidence: job logs with control totals; final
MSG.job.completed.
Example
POST /imports -> 202 Location: /operations/op_123
GET /operations/op_123 -> { "state": "running", "progress": 0.42 }
- Versioned API (
/v1or media types); backwards-compatible changes only in minors. - Changelog and deprecation windows communicated; error on sunset after date.
- Test old and new versions side-by-side for critical routes.
- Route p95/p99 latency within budgets; payload sizes ≤ caps.
- Throughput under expected RPS; soak test for connection reuse.
- N+1 queries avoided; DB indices present.
- Compression (gzip/br) on large JSON; streaming for massive responses where appropriate.
- Cache hints honored (ETag/Last-Modified).
Links: ../50-non-functional/performance-p95-p99.md.
- JSON logs with
msgid,code,correlation_id/trace_id. - Metrics (RED): request counts, error rate by code, duration histograms.
- Traces across client/server/DB/cache; exemplars linked to latency histograms.
- Runbooks linked for top alerts; dashboards bookmarked.
- Evidence attached:
curl/Postman collection, HAR, logs, traces, metrics screenshots.
Links: ../57-cross-discipline-bridges/for-developers.md, ../57-cross-discipline-bridges/for-sres.md.
Create (unsafe) — idempotent POST
curl -s -X POST https://api.example.com/v1/orders \
-H "Authorization: Bearer <token>" \
-H "Idempotency-Key: idem:123" \
-H "Content-Type: application/json" \
-d '{"cart_id":"c_123","amount_minor":1099,"currency":"USD"}'List with cursor pagination
curl -s "https://api.example.com/v1/orders?limit=50&cursor=<c>&status=paid&sort=-created_at"Conditional GET with ETag
# First
ETAG=$(curl -sI https://api.example.com/v1/orders/ord_123 | grep ETag | cut -d' ' -f2)
# Second (should be 304)
curl -s -H "If-None-Match: $ETAG" https://api.example.com/v1/orders/ord_123 -o /dev/null -w "%{http_code}\n"429 handling (Retry-After)
curl -i https://api.example.com/v1/orders | grep -i Retry-After- Unknown fields; wrong types; overlong strings; invalid enums.
- Boundary values (0, max, empty arrays).
- Concurrency: two POSTs with same idempotency key vs different keys.
- Clock skew for signatures/timestamps.
- Out-of-order webhook deliveries; duplications; delayed events.
- Network failures: timeouts, DNS errors, TLS issues.
GraphQL
- Schema types & non-nullability; input validation; complexity limits.
- Pagination via connections + cursors.
- Partial errors in
errors[]vs data; avoid leaking internals. - Persisted queries / allowlist.
gRPC
- Proto versioning; deadline propagation; idempotency via request ids.
- Status codes mapped to errors; streaming backpressure.
Route inventory
method,path,auth,notes
POST,/v1/orders,oauth2,idempotent
GET,/v1/orders/:id,oauth2,etag
GET,/v1/orders,oauth2,cursor pagination, filters
POST,/v1/refunds,oauth2,idempotent
POST,/v1/webhooks/events,hmac,ingestError taxonomy mapping (snippet)
http,code,message_id
400,ERR.VALIDATION.email,validation.email.invalid
403,ERR.AUTHZ.scope,authz.scope.denied
404,ERR.RESOURCE.not_found,resource.not_found
409,ERR.CONFLICT.idempotency,idempotency.payload_mismatch
429,ERR.RATE.limit,rate.limit
503,ERR.DEPENDENCY.unavailable,dependency.unavailablePerf budgets
route,p95_ms,p99_ms,max_payload_kb
POST /v1/orders,400,1000,32
GET /v1/orders/:id,200,600,24
GET /v1/orders,300,800,64Webhook contract (canonical)
field,required,notes
event_id,yes,unique
type,yes,e.g., order.paid
occurred_at,yes,UTC ISO-8601 Z
signature,yes,HMAC header
data.id,yes,resource id- Routes covered with MAE + negative tests.
- Schemas validated; unknown fields rejected.
- Idempotency, pagination, rate limits verified.
- Security/privacy/tenancy gates pass.
- Webhooks/contracts exercised with dedupe/replay.
- Perf budgets met; evidence attached.
- Dashboards + runbooks linked; alerts green.
Built with Treeify — AI test case design copilot.
Structured, traceable, high-coverage test design — faster.