REST API Debugging Checklist: A Step-by-Step Guide

#1REST API debugging: a workflow for finding the real failure
What we tested: We sent requests from our browser-based HTTP tools to test endpoints on localhost and remote servers. Header inspection, status code handling, and CORS preflight behavior were verified against Express.js, Fastify, and nginx backends.
When an API fails, the better question is not “what should I try next?” It is “which layer actually broke?”
This checklist is a practical order of operations for debugging REST APIs: status code, headers, payload, auth, CORS, network timing, and then reproducible requests.
#2Step 1: Decode the HTTP Status Code (The First Responder)
Every HTTP response returns a 3-digit status code. The status code tells you immediately which architectural layer caused the issue:
┌─────────────────────────────────────────────────────────────┐
│ HTTP STATUS CODE MAP │
├───────────────┬─────────────────────────────────────────────┤
│ 2xx Success │ Request accepted & processed successfully. │
│ 3xx Redirection│ Resource moved; client must follow location.│
│ 4xx Client │ YOUR request is invalid / unauthorized. │
│ 5xx Server │ BACKEND server failed / threw exception. │
└───────────────┴─────────────────────────────────────────────┘#3Critical 4xx & 5xx Status Code Breakdown
400 Bad Request: The request payload or query parameters violate syntax rules or server validation logic.401 Unauthorized: Authentication credentials (Authorizationheader or session cookie) are missing, expired, or invalid.403 Forbidden: Authentication succeeded, but the authenticated user lacks permissions/roles to access the requested resource.404 Not Found: The endpoint URL path is incorrect, or the requested resource ID does not exist in the database.405 Method Not Allowed: You sent aPOSTrequest to an endpoint that only acceptsGETorPUT.415 Unsupported Media Type: You sent JSON data without specifyingContent-Type: application/json.429 Too Many Requests: You exceeded the API rate limit. Inspect theRetry-Afterheader.500 Internal Server Error: Unhandled exception on the backend server.502 Bad Gateway: Nginx/Cloudflare proxy could not connect to the upstream backend application process.503 Service Unavailable: Server is overloaded or undergoing maintenance.504 Gateway Timeout: Upstream backend took longer to respond than the gateway proxy timeout limit (e.g., 30s).
#2Step 2: Inspect Request & Response Headers
HTTP headers control request routing, content negotiation, security policies, and session state. Missing or malformed headers cause up to 40% of API failures.
#3Essential Request Headers Checklist
POST /api/v1/orders HTTP/1.1
Host: api.yourcompany.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...
Content-Type: application/json
Accept: application/json
User-Agent: YourAppClient/2.1.0Authorization:- Verify the prefix format:
Bearer <token>(forgetting the space or the wordBeareris a common mistake). - Audit token expiration using the AllDevToolsHub JWT Decoder locally.
- Verify the prefix format:
Content-Type:- Must be
application/jsonwhen sending a JSON body. Omitting this header causes many frameworks (Express, Spring, Rails) to parse the request body asundefined.
- Must be
Accept:- Tells the server which response format the client expects (
application/json).
- Tells the server which response format the client expects (
User-Agent:- Public APIs (GitHub, Cloudflare) block requests with missing or generic user-agent strings to prevent bot abuse.
#2Step 3: Validate Payload Integrity & Data Types
If your POST, PUT, or PATCH request returns 400 Bad Request or 422 Unprocessable Entity:
#31. Check JSON Syntax Rules
- Double Quotes Only: Keys and string values must use double quotes (
"key": "value"). Single quotes are invalid. - No Trailing Commas: Ensure the last item in an object or array does NOT end with a comma
,. - Escaped Control Characters: Verify inner quotes and backslashes are escaped (
\",\\).
Use the AllDevToolsHub JSON Validator to pinpoint exact syntax error line numbers.
#32. Verify Data Types
- Strings vs. Integers: Check if the server expects
"age": 30(number) instead of"age": "30"(string). - Date Formats: Ensure timestamps use standard ISO 8601 formatting (
"2025-02-20T14:30:00Z"). - Null Values: Verify whether mandatory fields accept
nullor require non-empty arrays[].
#2Step 4: Solve Browser CORS & Preflight Issues
If an API request works perfectly in Postman, cURL, or Insomnia, but fails inside a web browser (React, Vue, Angular):
#3Understanding the CORS Preflight (OPTIONS) Request
When a browser script sends a cross-origin request (e.g., frontend on app.company.com calling API on api.company.com) with custom headers or non-simple HTTP methods (POST, PUT, DELETE), the browser automatically sends an initial OPTIONS Preflight Request.
Browser API Gateway / Server
│ │
│ ── 1. OPTIONS /api/v1/orders ─────────────────────────────> │
│ Access-Control-Request-Method: POST │
│ Access-Control-Request-Headers: authorization │
│ │
│ <── 2. 204 No Content ───────────────────────────────────── │
│ Access-Control-Allow-Origin: https://app.company.com │
│ Access-Control-Allow-Methods: POST, GET, OPTIONS │
│ Access-Control-Allow-Headers: Authorization, Content-Type
│ │
│ ── 3. Actual POST /api/v1/orders Request ─────────────────> │#3Common CORS Failure Symptoms
- Browser Console:
Access to fetch at 'api.company.com' from origin 'app.company.com' has been blocked by CORS policy. - Browser Console:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present.
#3The Server-Side CORS Fix
The backend server or API Gateway must be configured to handle OPTIONS requests and return the following headers:
Access-Control-Allow-Origin: https://app.company.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type, Accept
Access-Control-Allow-Credentials: trueUse the AllDevToolsHub CORS Header Checker to test whether your server responds correctly to preflight headers.
#2Step 5: Network, DNS, and TLS Latency Audit
If an API call hangs or fails before reaching application code:
- DNS Resolution Failure: Verify that the domain name resolves to an IP address (
nslookup api.company.comordig api.company.com). - TLS/SSL Certificate Expiration: An expired SSL certificate causes clients to abort requests (
NET::ERR_CERT_DATE_INVALID). Use the AllDevToolsHub SSL Checker to inspect certificate chain validity. - Network Proxy Timeouts: If a backend database query takes 45 seconds, Nginx or AWS ALB will close the connection at 30 seconds with
504 Gateway Timeout.
#3Decoding Rate Limiting Headers (429 Too Many Requests)
When an application receives an HTTP 429 Too Many Requests status code, inspect the response headers to implement intelligent exponential backoff:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 60
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1740000000Retry-After: Number of seconds the client must wait before retrying the request.X-RateLimit-Remaining: Number of remaining allowed requests in the current window.X-RateLimit-Reset: Unix timestamp when the current quota window resets.
#2Step 6: Developer Workflow Tools (cURL Reproducibility)
The single best habit for API debugging is creating a reproducible cURL command:
#3Copy as cURL from Chrome DevTools
- Open Chrome DevTools (
F12) → Select Network tab. - Trigger the failing API request.
- Right-click the failing request → Select Copy → Copy as cURL (cmd) or Copy as cURL (bash).
# Exact cURL command reproducing all headers and payload
curl 'https://api.yourcompany.com/v1/orders' \
-H 'Authorization: Bearer eyJhbGci...' \
-H 'Content-Type: application/json' \
--data-raw '{"product_id":101,"quantity":2}' \
--compressedExecuting the cURL command directly in your terminal isolates the API from browser caching, extensions, and CORS policies.
#3Automated Contract Testing with OpenAPI 3.1 Specs
To prevent API regressions and schema mismatches between backend microservices and frontend clients, integrate automated OpenAPI Contract Validation into your CI/CD pipelines:
// Automated OpenAPI schema validation in API integration tests
import OpenAPIValidator from "openapi-validator-middleware";
const validator = new OpenAPIValidator({
apiSpec: "./docs/openapi.yaml",
validateRequests: true,
validateResponses: true
});
// Middleware validates request bodies and response payloads against spec
app.use(validator.match());Validating requests against an OpenAPI specification catches schema violations (missing fields, wrong data types, unpermitted enum values) before code hits production.
#3Exponential Backoff with Jitter for Transient Errors
When clients encounter transient network errors (502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout, or 429 Too Many Requests), retrying requests immediately in a tight loop causes server overload ("thundering herd").
Implement Full Jitter Exponential Backoff:
// Full Jitter Exponential Backoff algorithm for API calls
async function fetchWithRetry(url: string, options: RequestInit, retries = 3) {
for (let attempt = 0; attempt < retries; attempt++) {
try {
const response = await fetch(url, options);
if (response.status < 500 && response.status !== 429) {
return response; // Success or client error (do not retry 4xx except 429)
}
} catch (networkError) {
if (attempt === retries - 1) throw networkError;
}
// Calculate exponential delay with randomized jitter
const baseDelay = Math.pow(2, attempt) * 1000;
const jitteredDelay = Math.random() * baseDelay;
await new Promise((resolve) => setTimeout(resolve, jitteredDelay));
}
throw new Error("Max retries reached");
}#3Idempotency Keys (Idempotency-Key Header)
When network timeouts occur during financial transactions or order creation (POST endpoints), clients cannot know whether the server successfully processed the request before dropping the network connection.
Use Idempotency Keys:
POST /api/v1/payments HTTP/1.1
Host: api.stripe.com
Authorization: Bearer sk_live_...
Idempotency-Key: 7b9e02a4-5612-4c31-b8d9-291b10a27318
Content-Type: application/json
{ "amount": 5000, "currency": "usd" }- The client generates a unique UUID
Idempotency-Keyfor the transaction. - If network timeouts force a retry, the client resends the exact same
Idempotency-Key. - The server checks its cache (Redis): if the key was already executed, it returns the cached response without charging the customer twice.
#2Step 7: The Master API Debugging Checklist
Run through this 7-step checklist whenever an API call fails:
### 1. Status Code Audit
- [ ] Check exact HTTP status code (2xx, 4xx, 5xx)
- [ ] Read response body error message (e.g., 400 validation details)
### 2. Header Verification
- [ ] Verify `Content-Type: application/json` is present
- [ ] Verify `Authorization: Bearer <token>` format
- [ ] Decode JWT token locally using JWT Decoder to check `exp` and claims
### 3. Payload Integrity
- [ ] Validate JSON syntax (no trailing commas, double quotes only)
- [ ] Verify data types (numbers vs strings, ISO dates)
### 4. CORS Check (Browser Only)
- [ ] Inspect `OPTIONS` preflight request response
- [ ] Verify `Access-Control-Allow-Origin` matches client domain
### 5. Network, Gateway & Rate Limits Audit
- [ ] Verify SSL certificate validity and chain using SSL Checker
- [ ] Check gateway timeout limits (504 errors on long database queries)
- [ ] Inspect `Retry-After` and `X-RateLimit-Reset` headers on HTTP 429 status codes
- [ ] Include unique `Idempotency-Key` headers on POST payment/order endpoints
### 6. Terminal Isolation
- [ ] Copy request as cURL and test directly in terminal#2Summary
Debugging REST APIs systematically requires relying on empirical network diagnostics:
- Decode Status Codes: Instantly identify client (4xx) vs. server (5xx) fault domains.
- Audit Headers: Ensure
Content-Type: application/jsonandAuthorizationBearer formats are correct. - Validate Payloads: Use browser-based tools to fix JSON syntax errors.
- Fix CORS at the Gateway: Configure
OPTIONSpreflight response headers for cross-origin clients. - Isolate with cURL: Test raw requests in the terminal to bypass browser interference.
Debug and validate your API payloads privately at the AllDevToolsHub API Suite.
#2Related Tools
- HTTP Status Code Reference, Complete dictionary of HTTP status codes and resolution steps
- JSON Validator, Locate JSON payload syntax errors instantly
- JWT Decoder, Inspect authorization tokens locally for expiration
- CORS Header Checker, Test server CORS preflight configuration
#2Related Articles
- How to Debug Webhooks: Complete Developer Playbook
- HTTP Security Headers Complete Checklist
- Essential API and Web Development Tools
#2Frequently Asked Questions
Q: Why does my API return 404 when I know the endpoint path exists?
A: In addition to incorrect URLs, servers often return 404 Not Found when: (1) You send an unpermitted HTTP method (e.g., POST instead of GET); (2) The requested resource ID inside the URL path does not exist in the database; or (3) The server uses 404 intentionally to prevent leaking whether a private resource exists to unauthenticated clients.
Q: What is the difference between a 502 Bad Gateway and a 504 Gateway Timeout?
A: A 502 Bad Gateway error means the reverse proxy (Nginx, Cloudflare, AWS ALB) received an invalid response or connection refusal from the upstream application process (e.g., Node.js service crashed or port closed). A 504 Gateway Timeout means the upstream application process accepted the connection but took longer to finish responding than the proxy server's timeout limit (e.g. database query took >30 seconds).
Written by Rahul Jalavadiya, founder of AllDevToolsHub. All tools run locally in your browser.
#2Sources / Further reading
- IETF - RFC 9110: HTTP Semantics
- IETF - RFC 7807: Problem Details for HTTP APIs
- OpenAPI Initiative - OpenAPI Specification 3.1
- MDN Web Docs - HTTP status codes
Quick Summary
API debugging can be frustrating when errors are vague. This checklist provides a systematic approach to isolate the problem, from checking HTTP status codes to inspecting raw payloads and validating security headers.
Key Takeaways
- Always start with the HTTP status code; it tells you who is at fault (Client or Server).
- Verify your `Content-Type` and `Accept` headers to avoid format mismatches.
- Use a proxy or interceptor to see exactly what is being sent over the wire.
- Check for CORS issues if your API works in Postman but fails in the browser.
When to use it
- Troubleshooting 4xx and 5xx errors in production.
- Optimizing API performance and reducing latency.
- Onboarding new developers to an existing API ecosystem.
- Building more resilient client-side error handling.
Common Mistakes
- Ignoring the response body of a 400 Bad Request (it often contains the fix).
- Forgetting that some headers are case-sensitive or have specific formatting requirements.
- Testing against the wrong environment (Staging vs. Production).
- Not accounting for network timeouts or rate limiting (429 Too Many Requests).
REST API Debugging Checklist: A Step-by-Step Guide, Frequently Asked
What is the most common API error?
The 401 Unauthorized error is extremely common, usually caused by a missing, expired, or malformed Bearer token.
Why does my API work in Postman but not in my code?
This is often due to CORS (Cross-Origin Resource Sharing) or missing headers (like `User-Agent`) that Postman adds automatically but your code does not.
How do I debug a 500 Internal Server Error?
Since 500 is a generic "catch-all," you must check the server-side logs. Client-side debugging alone cannot solve a true 500 error.
Tools Mentioned in This Article
API Response Diff
Compare two API responses to find structural differences.
HTTP Methods Reference
Interactive reference for all HTTP methods with safe, idempotent, and cacheable properties.
HTTP Request Builder
Build and send HTTP requests to test APIs right from your browser.
OpenAPI / Swagger Validator
Validate OpenAPI 3.x and Swagger 2.x specifications with detailed error reporting.
Tools, tactics, and toughened-up tips, once a week
New tools, deep-dives on developer workflows, and the occasional gem we found this week. No spam, no tracking. Unsubscribe anytime.
Found an error or have feedback?
We correct errors quickly and document changes in our changelog. Report issues at support@alldevtoolshub.com.