Limits and errors

How often you may ask, and what a refusal looks like.

Nothing is banned and nothing is billed for volume. Asking too fast is refused for a short time and then forgiven.

How many requests

Rate limits
Counted byEach minute
One key120
All the keys on one account720
Every request with a key we do not know, together60

720 is six keys at their full rate, so a Pro plan's six teams never wait for each other.

A live score read every ten seconds is six requests a minute for one game. Ten games at once, with the box score beside each one, is inside the limit for one key. If you need more than that, write to us — it is a conversation, not a wall.

Wrong keys share one count of 60 a minute between them. A key we know is never counted there, so nobody else's mistake can slow you down.

A list read answers at most 50 rows at a time. Ask for more and you get that many.

What we tell you about the limit

These come back on every answer we let through, and on every refusal for asking too often. The count they report is the one for your key. One refusal is different: when all the keys on your account together ask too often, the limit it reports is the one for the account.

Rate limit headers
HeaderWhat it says
X-RateLimit-LimitHow many requests this key may make in the current minute.
X-RateLimit-RemainingHow many of those requests are left.
X-RateLimit-ResetWhen the count goes back to the full limit, in whole seconds since 1 January 1970.
Retry-AfterHow many seconds to wait before asking again. Sent only when a request was refused for asking too often.

Asking less often

A game that is final changes rarely, but it can change: a coach may correct a play after the game, or resume scoring. So keep your copy of a final game for an hour or a day, not for ever, and ask again after that. A game in progress is the only thing worth asking about every few seconds.

This API answers a request from any page, on any address, so a browser may call it directly. Read Your key before you do: a key a browser can send is a key every visitor can copy, and it returns your players’ full names.

Refusals

A refusal is JSON, always the same shape: an error holding a code and a message. Branch on the code. The message is one sentence, safe to log, and it may be reworded.

Every refusal
CodeStatusWhat it says
not-authenticated401Send your API key as `Authorization: Bearer tb_live_…`.
key-in-url400Do not put the key in the address. Send it in the Authorization header.
api-lapsed402This account's plan is not active, so its Data API keys are paused. The owner can fix it from Billing & hours.
no-api-seat403This team's Data API is off. The owner can turn it on from Billing & hours.
key-scope403This key belongs to another team. Use that team's own key.
not-found404Nothing with that id.
rate-limited429Too many requests. Try again in {seconds} seconds.
internal500Something went wrong on our side.

One sentence has a blank in it. {seconds} is filled in with how long to wait, which is the same number as the Retry-After header.

A team or a game that belongs to somebody else answers not-found, the same as an id that never existed. That is on purpose: a stranger must not be able to learn which ids are real.

not-authenticated and key-in-url are both about the key itself, and Your key says where it goes.