n4nAI

curl one-liners for checking LLM API rate limit headers

Practical curl rate limit headers one-liners to inspect LLM API throttling, quota, and reset times across OpenAI, Anthropic, and inference providers.

n4n Team3 min read748 words

Audio narration

Coming soon — every post will get a voice note here.

Rate limits are the silent killer of LLM integrations. These curl rate limit headers one-liners let you inspect exactly what a provider returns before you wire up retry logic or blame your SDK. We’ll cover the headers that matter and how to pull them from the command line without writing a single line of client code.

1. Dump full response headers with -i

The fastest way to see what an LLM API returns is curl -i. This prints the HTTP status line, all response headers, and the body. You avoid SDK abstractions that hide headers behind objects and can confirm rate limit fields exist at all.

curl -i https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY"

Look for x-ratelimit-limit-requests, x-ratelimit-remaining-requests, and x-ratelimit-reset-requests. Anthropic uses ratelimit-remaining-tokens and ratelimit-reset. These headers tell you the ceiling, the slack, and when the window slides.

If the body is large, pipe to head to keep noise down:

curl -i https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}]}' \
  | head -20

2. Filter only rate limit headers with grep

Scrolling through cookie and cache headers wastes time. Pipe to grep -i ratelimit to isolate the lines you care about. This is one of the most reused curl rate limit headers one-liners in my shell history.

curl -s -D - https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -d '{"model":"claude-3-5-sonnet-20241022","max_tokens":10,"messages":[{"role":"user","content":"hi"}]}' \
  -o /dev/null | grep -i ratelimit

-D - sends headers to stdout while -o /dev/null discards the body. You get a clean list: ratelimit-limit-tokens: 100000, ratelimit-remaining-tokens: 99850, ratelimit-reset: 2025-01-15T12:00:00Z.

When a provider is degraded, you may also see retry-after. Capture that too:

curl -s -D - https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -o /dev/null | grep -iE 'ratelimit|retry-after'

3. Parse headers into JSON with a small Python helper

Grepping is fine interactively, but scripts need structure. Use Python’s email parser to turn headers into a dict, then emit JSON. This turns curl rate limit headers one-liners into reusable monitoring.

curl -s -D - https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -o /dev/null | python3 -c '
import sys, json, email
headers = email.message_from_string(sys.stdin.read())
out = {k: v for k, v in headers.items() if "ratelimit" in k.lower() or "retry" in k.lower()}
print(json.dumps(out))
'

The output is machine-readable:

{"x-ratelimit-limit-requests": "200", "x-ratelimit-remaining-requests": "199", "x-ratelimit-reset-requests": "8s"}

Feed that into Prometheus or just log it. The pattern works for any OpenAI-compatible endpoint, including self-hosted vLLM or third-party gateways.

4. Convert reset timestamps to local time

Most LLM APIs return reset as a Unix epoch seconds or an ISO timestamp. Human brains don’t parse 1736947200 well. Convert it inline with date.

reset=$(curl -s -D - https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -o /dev/null | grep -i ratelimit-reset | awk '{print $2}' | tr -d '\r')
date -d "$reset" 2>/dev/null || date -r "$reset" 2>/dev/null

On Linux date -d parses ISO; on macOS date -r expects epoch. Anthropic sends ISO, OpenAI sends seconds. Branch accordingly.

Knowing the reset window lets you schedule batch jobs outside peak contention. I’ve shifted nightly embeddings to match a 00:00 UTC reset and cut 429s by half without changing any application code.

5. Check remaining quota without sending a real prompt

Some endpoints support a lightweight GET /v1/models or GET /v1/account that returns headers without consuming tokens. Use -I (HEAD) where allowed, but many LLM APIs reject HEAD. Fall back to GET with -o /dev/null.

curl -s -D - https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -o /dev/null | grep -i remaining

If you run this every minute from cron, you’ll build a time series of x-ratelimit-remaining-requests before your app ever hits the limit. That’s cheaper than parsing 429s in production and surfaces shared-tier exhaustion early.

6. Verify gateway fallback and cache hints

When you route through an inference gateway, you lose direct provider headers unless the gateway forwards them. A gateway like n4n.ai provides one OpenAI-compatible endpoint for 240+ models and automatically falls back when a provider is rate-limited; its responses include the upstream x-ratelimit-* and retry-after plus cache-control hints.

curl -s -D - https://api.n4n.ai/v1/chat/completions \
  -H "Authorization: Bearer $N4N_KEY" \
  -d '{"model":"auto","messages":[{"role":"user","content":"ping"}]}' \
  -o /dev/null | grep -iE 'ratelimit|retry|cache'

Seeing x-n4n-upstream: anthropic alongside ratelimit-remaining-tokens confirms the request landed on a live provider after fallback. If you set cache-control: max-age=300 in the request, the gateway should echo age or x-cache in the response.

7. Loop to catch limit drops during load tests

A single call hides bursting behavior. Wrap the curl rate limit headers one-liners in a for loop to simulate concurrent traffic and watch remaining counts decrement.

for i in $(seq 1 10); do
  curl -s -D - https://api.openai.com/v1/chat/completions \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"load test"}]}' \
    -o /dev/null | grep -i remaining | head -1
  sleep 0.5
done

You’ll see x-ratelimit-remaining-requests drop by 1 each iteration, then jump after reset. This catches misconfigured shared limits across API keys and reveals whether your tier is per-key or per-org.

8. Compare headers across providers in one script

If you multiplex models, diff the header schemas. Write a bash function that prints normalized fields so you can spot which provider uses what naming.

check_limits() {
  local url=$1; local auth=$2; local auth_header=$3
  curl -s -D - "$url" -H "$auth_header: $auth" -o /dev/null \
    | grep -iE 'ratelimit|retry-after' \
    | sed 's/://' | awk '{print tolower($1), $2}'
}
check_limits https://api.openai.com/v1/models "$OPENAI_API_KEY" "Authorization: Bearer"
check_limits https://api.anthropic.com/v1/messages "$ANTHROPIC_API_KEY" "x-api-key"

OpenAI prefixes with x-ratelimit-, Anthropic uses ratelimit-. Normalizing to lowercase keys makes side-by-side diffs trivial when you’re debugging a multi-model router.

9. Use curl’s built-in %{header_json} for zero-parse extraction

Modern curl (7.84+) can emit response headers as JSON with -w '%{header_json}'. This removes the Python helper for quick checks and keeps the curl rate limit headers one-liners self-contained.

curl -s https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -o /dev/null -w '%{header_json}' | python3 -m json.tool

The output includes all headers keyed by lowercase name. Filter with jq:

curl -s https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -o /dev/null -w '%{header_json}' | jq 'with_entries(select(.key | test("ratelimit|retry")))'

This is the cleanest way to script checks in CI without installing extra parsers, and it survives header order changes.

Summary table

Provider Header prefix Reset format Notes
OpenAI x-ratelimit- seconds epoch Per-org, per-model tiers
Anthropic ratelimit- ISO 8601 Tokens + requests separate
Gateway (n4n.ai) forwards upstream + x-n4n- varies Adds fallback metadata

These curl rate limit headers one-liners are the first thing I run when a new integration misbehaves. They expose the truth before you write retry code, and they keep your debugging honest.

Tagscurlrate-limitingheaderscli

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All curl llm api cookbook posts →