# The API Debugging Guide: Methods, Tools, and Common Failures

**Quick answer:** API debugging is the systematic work of locating where a request goes wrong — the client, the network, the gateway, or the service — by capturing the actual request and response, reproducing it deterministically, and narrowing from the boundary inward. The single most useful artifact is a reproducible request (the exact URL, headers, body, and environment), not a screenshot or a verbal description. Most "it works for me" bugs dissolve once the caller's environment — auth, content type, origin, proxy — is captured along with the error.

This guide covers the handoff that makes debugging possible, the recurring failures (CORS, content type, auth), how to debug across protocols, and how to hand a failure to an AI agent without handing it your conclusion. Follow the links for the concrete cases.

## A reproducible request is the starting point

Debugging cannot begin from "it returns an error." Capture the full request and the environment it ran in. The structure of a good handoff is in [an API debugging handoff: caller, environment, and state](https://www.powerduck.com/blog/api-debugging-handoff-caller-environment-state/), and a saved, working request is the most durable form of documentation — see [a working curl command as API documentation](https://www.powerduck.com/blog/working-curl-command-api-documentation/). A curl command alone is not a complete handoff, though; [a curl command is not an API handoff](https://www.powerduck.com/blog/a-curl-command-is-not-an-api-handoff/) explains what it leaves out.

## CORS: works in curl, fails in the browser

The classic signature is that a request succeeds from curl or Postman but fails from the browser, because the browser enforces the Same-Origin Policy and the server never returns the right CORS headers. The diagnosis and the headers you need are in [curl works, browser CORS debugging](https://www.powerduck.com/blog/curl-works-browser-cors-debugging/). The key insight is that CORS is enforced by the browser, not the server — a successful curl proves nothing about whether the browser will allow the call.

## Valid JSON, wrong content type

Another request that "looks right" but fails: the body is valid JSON, yet the server rejects it with 415 because the `Content-Type` header is missing or set to something the endpoint does not accept. Walk through it in [valid JSON, wrong content type (415)](https://www.powerduck.com/blog/valid-json-wrong-content-type-415/). On the response side, make sure errors are returned in a consistent, machine-readable shape using [RFC 9457 problem details](https://www.powerduck.com/blog/rest-api-error-response-rfc-9457/), so clients can branch on the type rather than parse prose.

## Debugging across protocols

HTTP is one of several transports a modern service uses, and switching tools for each one wastes the context you have built. The case for debugging REST, SSE, WebSocket, and gRPC in one workspace is in [debug every protocol in one workspace](https://www.powerduck.com/blog/debug-every-protocol-in-one-workspace/). For streams, the failure modes are sequence and timing rather than a single response; see [debugging SSE](https://www.powerduck.com/blog/how-to-test-sse-server-sent-events/) and [debugging WebSocket](https://www.powerduck.com/blog/how-to-test-websocket-apis/). Agent-to-agent communication adds another layer; [debug agent-to-agent (A2A) like REST](https://www.powerduck.com/blog/debug-agent-to-agent-a2a-like-rest/) treats it with the same discipline.

## From a curl command to a contract

When all you have is a captured request, convert it into something the team can build on. [convert curl or Postman to OpenAPI](https://www.powerduck.com/blog/convert-curl-postman-to-openapi/) turns a single request into a documented operation. Pasting raw curl into a chat window is a weaker move; [stop pasting curl into ChatGPT](https://www.powerduck.com/blog/stop-pasting-curl-into-chatgpt/) explains why a structured tool or MCP server gives the model better context.

## Handing a failure to an AI agent

When you ask an AI to debug, how you present the error determines whether it investigates or just echoes your guess. [pasting an error to an agent hands it your conclusion](https://www.powerduck.com/blog/pasting-error-to-agent-hands-your-conclusion/) shows the bias this introduces. A few code-level mistakes also make debugging much harder and are worth removing: [a broad try-catch that hides failures](https://www.powerduck.com/blog/agent-broad-try-catch-hides-failures/), [a catch that swallows the error](https://www.powerduck.com/blog/agent-try-catch-swallows-the-error/), [a debug print left in the shipped handler](https://www.powerduck.com/blog/agent-left-debug-print-in-shipped-handler/), and the security failure in [logging an authorization header in plaintext](https://www.powerduck.com/blog/agent-logged-authorization-header-in-plaintext-logs/).

## Where to go next

Powerduck is the local-first, OpenAPI-first workspace that carries this whole flow — from the contract through debug, test, mock, and the tools an agent can call. See it on the [Powerduck homepage](https://www.powerduck.com/).

Once a bug is reproduced, lock it down with a regression test from the [API testing guide](https://www.powerduck.com/blog/api-testing-guide-hub/); if the service is unavailable, reproduce it with the [API mocking guide](https://www.powerduck.com/blog/api-mocking-guide-hub/). To give AI agents the context to debug APIs themselves, read the [MCP server guide](https://www.powerduck.com/blog/mcp-server-guide-hub/).

## Frequently asked questions
**Why does my API work in Postman but not in my app?** Almost always an environment difference: the browser's CORS enforcement, a missing header Postman adds automatically, a proxy, or a different auth token. Capture both requests and diff them header by header.

**What is the first thing to check on a 401 or 403?** Confirm the token is present, unexpired, and sent with the correct scheme and scope; then check whether the gateway strips or forwards it. The contract for auth is in [documenting authentication with security schemes](https://www.powerduck.com/blog/document-api-authentication-openapi-security-schemes/).

**How do I debug a failure that only happens intermittently?** Add structured logging around the boundary, capture the request IDs of failures, and look for ordering, timing, or shared-state causes; a sleep is not a fix. Reproduce under load and in CI rather than waiting for the next occurrence.

