# 5 of 35 APIs sent a rate-limit header on errors

More of the APIs that answered our bad requests replied in JSON every time than sent a rate-limit header.

Source: https://agentdrives.com/research/5-of-35-products-whose-api-sent-a-rate-limit-header?via=md · Published 2026-11-01 · 193 products, driven 2026-10-01 to 2026-10-31

As of 31 October 2026, 5 of 35 products whose API answered our bad requests on 25 October 2026 sent a rate-limit header (`RateLimit`, `X-RateLimit-*` or `Retry-After`). An agent builder can't count on a rate-limit header in an API's error answer. The count covers the headers on those error answers only, not other responses from the same APIs, nor the rest of the 193 [products we drove](/research/software-isnt-ready-for-agent-customers).

## `X-RateLimit-*` headers outnumbered the IETF RateLimit fields

Of the products whose API answered our bad requests, 4 of 35 sent `X-RateLimit-*` headers, at [GitHub](/tools/github), [Make](/tools/make), [Nifty](/tools/niftypm) and [SignWell](/tools/signwell). Each count here comes from the bad requests we sent to the APIs on 25 October 2026, and says what came back, not why.

The IETF RateLimit header fields came back at 1 of 35 products, at [Fillout](/tools/fillout). The error answers at Fillout, GitHub, Make, Nifty and SignWell also said how many requests were left.

On these error answers, a client reading only `X-RateLimit-*` names misses Fillout's header, and a client reading only the IETF fields misses the headers of GitHub, Make, Nifty and SignWell. 

<ToolEmbed slug="fillout" />

## JSON errors outnumbered web-page errors

21 of 35 products whose API answered our bad requests replied to each of them in JSON.

**APIs that answered each bad request in JSON**

|   | Products | Out of | Share |
| --- | --- | --- | --- |
| APIs that answered each bad request in JSON | 21 | 35 | 60% |


At 8 of 35, a bad request got a web page instead of an API error. An agent reading that answer got markup where it looked for an error message it could parse.

Fillout, GitHub and Nifty answered in JSON and also sent a rate-limit header, so an owner has those error answers to set beside their own.

## 11 of 35 products named what was wrong in every answer

At Attio, Brevo, Canva, Firecrawl, Notion, Postiz, Resend, Steel, Tinybird, Twenty and UploadThing, the error answers carried no rate-limit header. Steel aside, that list's error answers all came in JSON. Without a key, [UploadThing](/tools/uploadthing)'s API answered "Missing API Key" and [Resend](/tools/resend)'s answered `missing_api_key`. [Twenty](/tools/twenty)'s documented key endpoint told API-key callers "This endpoint is not available to this caller".

Across the products whose API answered our bad requests, 33 of 35 named what was wrong in an answer, a wider group than the products above. [Nifty](/tools/niftypm)'s API answered a project create on a new workspace with an error asking for portfolioId.

## A request id came back at more products than a docs link

16 of 35 products whose API answered our bad requests gave a request id with an error, and 7 of 35 linked to their docs in an error.

**APIs that gave a request id with an error**

|   | Products | Out of | Share |
| --- | --- | --- | --- |
| APIs that gave a request id with an error | 16 | 35 | 46% |


[GitHub](/tools/github) is on the docs-link list but not the request-id list; Make and SignWell are on the request-id list as well as the header list.

For an owner comparing their own error answers, [Nifty](/tools/niftypm)'s carried JSON on every bad request, `X-RateLimit-*` headers, a request id and a docs link. [Steel](/tools/steel) and [Tinybird](/tools/tinybird) named the fault in every answer, and each gave a request id and linked its docs in an error.

## Method and limits

- Products: 193, driven 2026-10-01 to 2026-10-31.
- Numbers: each one links to its definition and the products behind it.
- Limits: Cloudflare has listed our agent as a signed agent since 24 October 2026. Drives before 24 October 2026 ran signed but unlisted: a check could see the signature but had no listed identity to trust. No other bot-check provider lists it yet.
- Every number, with its products: [our facts](/data/facts). How we drive and score: [our method](/method).

## Questions

**How many products' API docs did we read for their error format?**

We read the API docs of 132 of 193 products we drove for their error format. The counts in this piece come from what the APIs answered, not from those docs.

**How fast does our agent send requests to a product?**

The pace our agent keeps is one drive per product at a time, at a person's pace (about one page action every few seconds); up to three drives at once across different products, about a hundred a day. Before a drive it reads the product's public docs one page at a time, at most one a second per host, or slower when robots.txt asks a Crawl-delay. A drive may send one short burst of 10–20 calls to one endpoint to check rate limiting, and stops at the first 429. [How we drive](/method) has the rest.
