Skip to content

Limits

The API is free during the beta. Each account has three limits, shared by all of its keys.

LimitValueResets
Requests a month20,000On the first of the month, 00:00 UTC
Requests a minute60At the start of each minute (UTC)
Requests at a time4When 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.

Response headers
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=3

In 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.

A request over the minute’s limit
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.