Using the API
Errors
One error envelope, a stable code and a request id. Failed requests are never billed.
Every error answers with the same body:
{
"error": {
"code": "invalid_request",
"message": "limit must be a whole number from 1 to 100.",
"param": "limit",
"request_id": "req_4f8Kq2ZtW9mXb7Lc1RnP"
}
}codeis stable. Branch on it, not on the message.messagesays what went wrong in plain words. It may change.paramnames the parameter to fix, oninvalid_request.request_idis also theX-Request-Idheader. Every answer carries it, errors and successes alike. Quote it when you ask us about a request.
An error is never cached, and an error is never billed. Only an answer in the 2xx range counts toward your bill.
Error codes
| Code | Status | What it means |
|---|---|---|
unauthorized | 401 | No key, or not a valid one: unknown, revoked, or not a Hey Town Hall Data key. The answer carries WWW-Authenticate: Bearer. |
forbidden | 403 | Signed in, but not allowed. The dashboard answers it for an action only an account owner can take; /v1 and /mcp do not use it. |
live_not_open | 403 | A live key, or a request made with one, while live keys are closed. They open once the rates are final; sandbox keys work now. |
invalid_request | 400 | A parameter is missing or not valid, a parameter the endpoint does not take was sent, or one was sent twice. param names it. |
not_found | 404 | No such record, or it is no longer published. Also a path the API does not have. |
rate_limited | 429 | Past the key's requests per minute. Retry-After says how many seconds to wait. |
spend_cap_reached | 402 | This month's bill has reached the spending cap you set. Live requests stop until you raise or remove the cap. |
billing_required | 402 | A live key with no payment method on file, or live keys paused for an unpaid invoice. Add billing in the dashboard. |
upstream_unavailable | 503 | The data could not be read right now. It is never an empty answer in disguise; try again shortly. |
internal | 500 | Something went wrong on our side. Try again shortly. |
What to do
400: fix the parameter thatparamnames. Retrying the same request gets the same answer.401: check the key and the header. See Authentication.402: add billing or raise your spending cap in the dashboard. See Billing.404: the record is gone or never existed. Check the id against a list.429: wait the seconds thatRetry-Aftergives, then try again. See Rate limits.500and503: try again shortly, waiting a little longer each time. A503is never an empty answer in disguise: nothing was left out, the data could not be read.
Errors in MCP
A tool call that fails returns a tool result marked as an error, with the same envelope as its text. A missing or invalid key is refused before the handshake, with 401 or 402 as an HTTP answer.