Skip to main content
AllDevToolsHub
2026-06-12
Last reviewed: Aug 2026
API
Est Read: 10_MIN

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

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

#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:

protocol
┌─────────────────────────────────────────────────────────────┐
│                    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 (Authorization header 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 a POST request to an endpoint that only accepts GET or PUT.
  • 415 Unsupported Media Type: You sent JSON data without specifying Content-Type: application/json.
  • 429 Too Many Requests: You exceeded the API rate limit. Inspect the Retry-After header.
  • 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

http
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.0
  1. Authorization:
    • Verify the prefix format: Bearer <token> (forgetting the space or the word Bearer is a common mistake).
    • Audit token expiration using the AllDevToolsHub JWT Decoder locally.
  2. Content-Type:
    • Must be application/json when sending a JSON body. Omitting this header causes many frameworks (Express, Spring, Rails) to parse the request body as undefined.
  3. Accept:
    • Tells the server which response format the client expects (application/json).
  4. 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 null or 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.

protocol
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:

http
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: true

Use 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:

  1. DNS Resolution Failure: Verify that the domain name resolves to an IP address (nslookup api.company.com or dig api.company.com).
  2. 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.
  3. 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
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: 1740000000
  • Retry-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

  1. Open Chrome DevTools (F12) → Select Network tab.
  2. Trigger the failing API request.
  3. Right-click the failing request → Select CopyCopy as cURL (cmd) or Copy as cURL (bash).
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}' \
  --compressed

Executing 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:

typescript
// 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:

typescript
// 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:

http
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-Key for 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:

markdown
### 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:

  1. Decode Status Codes: Instantly identify client (4xx) vs. server (5xx) fault domains.
  2. Audit Headers: Ensure Content-Type: application/json and Authorization Bearer formats are correct.
  3. Validate Payloads: Use browser-based tools to fix JSON syntax errors.
  4. Fix CORS at the Gateway: Configure OPTIONS preflight response headers for cross-origin clients.
  5. 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

#2Related Articles


#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

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

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.
Use Cases

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.
Watch out

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).
FAQ

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.

RJRahul JalavadiyaFounder & Lead Engineer
Published 2026-06-12Last reviewed 2026-08-23

Tools Mentioned in This Article

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.

Last reviewed: 2026-08-23
Security Memo
AT

Rahul Jalavadiya

Engineering Protocol V1

Specializing in local-first architecture and Zero-Trust developer workflows. No data leaves the machine.