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 minute and then forgiven.
How many requests
| Counted by | Each minute |
|---|---|
| One key | 120 |
| All the keys on one account | 600 |
| Every request with a key we do not know, together | 60 |
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.
| Header | What it says |
|---|---|
X-RateLimit-Limit | How many requests this key may make in the current minute. |
X-RateLimit-Remaining | How many of those requests are left. |
X-RateLimit-Reset | When the count goes back to the full limit, in whole seconds since 1 January 1970. |
Retry-After | How 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 never changes again, so its reads are stable and you may cache them for as long as you like. A game in progress is the only thing worth asking about twice.
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.
| Code | Status | What it says |
|---|---|---|
not-authenticated | 401 | Send your API key as `Authorization: Bearer tb_live_…`. |
key-in-url | 400 | Do not put the key in the address. Send it in the Authorization header. |
api-lapsed | 402 | This account's API access has lapsed. The owner can restore it from the plan screen. |
no-api-seat | 403 | This team has no API seat. The owner can place one from the plan screen. |
key-scope | 403 | This key belongs to another team. Use that team's own key. |
not-found | 404 | Nothing with that id. |
rate-limited | 429 | Too many requests. Try again in {seconds} seconds. |
internal | 500 | Something 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.