Limits
The API is free during the beta. Each account has three limits, shared by all of its keys.
| Limit | Value | Resets |
|---|---|---|
| Requests a month | 20,000 | On the first of the month, 00:00 UTC |
| Requests a minute | 60 | At the start of each minute (UTC) |
| Requests at a time | 4 | When a request finishes |
What counts
A request counts when it gets an answer: 200s, 304s, and errors such as 400 and 404. These don’t count:
- requests refused with 429 because a limit was reached;
- requests that fail on Thaler’s side (500, 503, 504);
- requests without a valid key (401), which don’t reach an account.
The RateLimit headers
Every response to a request with a valid key carries two headers from the IETF RateLimit fields draft. RateLimit-Policy gives the limits; RateLimit gives what remains of each and the seconds until it resets.
ratelimit-policy: "minute";q= 60;w= 60, "month";q= 20000, "concurrent";q= 4;qu= "concurrent-requests"ratelimit: "minute";r= 59;t= 42, "month";r= 19873;t= 536400, "concurrent";r= 3In RateLimit-Policy, q is the limit and w the window in seconds. In RateLimit, r is what remains and t the seconds until the count resets.
When you reach a limit
The request is refused with a 429 and isn’t counted. The body is a problem of the type the RateLimit draft defines for an exceeded quota, and violated-policies names the limits reached. Retry-After gives the seconds to wait.
HTTP/ 2 429content-type: application/ problem+jsonretry-after: 23ratelimit: "minute";r= 0;t= 23, "month";r= 19811;t= 536400, "concurrent";r= 4 { "code": "rate_limited", "detail": "This account has reached its limit of 60 requests this minute. Try again in 23 seconds.", "request_id": "req_9d0e44b1a6f35c2e8b17", "status": 429, "title": "Request cannot be satisfied as assigned quota has been exceeded", "type": "https:/ / iana.org/ assignments/ http-problem-types#quota-exceeded", "violated-policies": ["minute"]}For the month’s limit, Retry-After is the time until the first of next month. The minute’s 60 are counted per calendar minute, so a burst across the turn of a minute can make 120 in two seconds, but not more.
Unchanged responses
Every response carries an ETag. Send it back in If-None-Match and, if nothing has changed, the answer is a 304 with no body. A 304 counts as a request. Data changes when a new release is published, and filings, insider trades, holders, segments and prices also change between releases.
Rows per request
List endpoints return a page of rows, usually 25. Ask for more with limit, up to each endpoint’s maximum (500 on most), and page through longer lists with offset where an endpoint takes it. The reference gives each endpoint’s parameters and limits.
During the beta
The limits may change during the beta. Changes are listed in the changelog.