DEV Community

Michael Lip
Michael Lip

Posted on • Originally published at zovo.one

How I Debug APIs Without Postman Taking Over My RAM

Postman was a Chrome extension when I first used it. Lightweight, fast, did one thing well. Then it became an Electron app. Then it wanted me to create an account. Then it started syncing to the cloud. Then it added workspaces, teams, monitors, mock servers, flow diagrams, and an AI assistant. The download is now over 200 MB. For a tool that sends HTTP requests.

I'm not saying Postman is bad. For teams that use its collaboration features, it's valuable. But if you just need to test an API endpoint -- send a request, see the response, check the status code -- you don't need a 200 MB application running a Chromium instance in the background.

What API testing actually involves

When developers say "API testing," they usually mean one of three things:

Exploratory testing. You're poking at a new API to understand how it works. You send GET requests to different endpoints, try various parameters, and read the responses. This is the discovery phase.

Integration testing. You're verifying that your code correctly communicates with an external API. This usually involves automated tests, mocks, and assertions about response structure.

Debugging. Something is broken. You need to isolate whether the problem is in your client code, the API itself, or somewhere in between. This means sending raw requests and examining every detail of the response.

For the first and third cases, you don't need an IDE-sized application. You need something that lets you fire a request and read the result.

The curl approach

Curl is the most universal API testing tool because it's installed on virtually every Unix system and available on Windows.

The basics:

# Simple GET
curl https://api.example.com/users

# GET with headers
curl -H "Authorization: Bearer abc123" https://api.example.com/users

# POST with JSON body
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Michael"}'

# See response headers
curl -i https://api.example.com/users

# See everything (request headers, response headers, body)
curl -v https://api.example.com/users

# Follow redirects
curl -L https://api.example.com/old-endpoint

# Save response to file
curl -o response.json https://api.example.com/users
Enter fullscreen mode Exit fullscreen mode

The -v flag is the one people underuse. It shows you the entire conversation: the request line, request headers, TLS handshake details, response headers, and the response body. When something isn't working, this is where you find the answer. Maybe the server is returning a 301 redirect you didn't expect. Maybe your Content-Type header isn't being sent. Maybe there's a CORS preflight response you're not seeing in the browser.

Reading response headers

The response body gets all the attention, but the headers often contain the information you actually need.

HTTP/2 200
content-type: application/json; charset=utf-8
x-ratelimit-limit: 1000
x-ratelimit-remaining: 997
x-ratelimit-reset: 1710892800
cache-control: max-age=300
etag: "abc123"
Enter fullscreen mode Exit fullscreen mode

x-ratelimit-remaining tells you how many requests you have left before getting throttled. x-ratelimit-reset is a Unix timestamp telling you when the limit resets. cache-control tells you how long the response can be cached. etag is a version identifier you can send in subsequent requests with If-None-Match to get a 304 (not modified) instead of re-downloading the full response.

Ignoring these headers is how people build clients that get rate-limited, miss caching opportunities, and make unnecessary requests.

Status codes that matter

You should know what these mean without looking them up:

  • 200 OK. The request succeeded.
  • 201 Created. The resource was created. Common response to POST requests.
  • 204 No Content. Success, but there's no response body. Common for DELETE.
  • 301 Moved Permanently. The resource has a new URL. Update your references.
  • 304 Not Modified. Your cached version is still valid.
  • 400 Bad Request. Your request is malformed. Check the body.
  • 401 Unauthorized. You're not authenticated. Check your credentials.
  • 403 Forbidden. You're authenticated but don't have permission.
  • 404 Not Found. The endpoint or resource doesn't exist.
  • 429 Too Many Requests. You're rate-limited. Back off and retry.
  • 500 Internal Server Error. The server broke. Not your fault.
  • 502 Bad Gateway. A proxy or load balancer couldn't reach the upstream server.
  • 503 Service Unavailable. The server is overloaded or in maintenance.

The distinction between 401 and 403 trips people up. 401 means "I don't know who you are." 403 means "I know who you are and you're not allowed." If you're getting 401, fix your auth. If you're getting 403, you need different permissions.

When the browser lies to you

If you're testing APIs from a frontend app, the browser adds layers of behavior that don't exist in a raw HTTP client.

CORS preflight requests. Before sending a cross-origin POST with custom headers, the browser sends an OPTIONS request to ask the server if the real request is allowed. If the server doesn't respond with the right CORS headers, the browser blocks your request. This never happens in curl, Postman, or server-side code. CORS is a browser-only security mechanism.

Cookie handling. The browser automatically attaches cookies for the domain. A raw HTTP client doesn't. If your API relies on session cookies, you need to explicitly manage them in your test tool.

Redirect following. Browsers automatically follow redirects and show you the final response. Curl doesn't follow redirects by default (you need -L). Knowing about the redirect matters because it might indicate an authentication flow or an API version change.

A lighter approach

For quick API testing without installing anything, I built a browser-based tool at zovo.one/free-tools/api-tester. You pick a method, enter the URL, add headers and a body, and see the full response including status, headers, and body. It runs entirely in your browser, so your requests and API keys never touch a server.

It doesn't replace Postman for teams that need shared collections and environments. But for the "I just need to hit this endpoint and see what comes back" use case, it's faster than launching an Electron app.


I'm Michael Lip. I build free developer tools at zovo.one. 350+ tools, all private, all free.

Top comments (0)