API Limits

Rate-limiting keys

We limit requests using rate-limiting keys. All routes that share the same rate-limiting key will also share the same quota.

Rate-limiting keys can use a combination of different properties to set a quota. For example:

  • session - This is the simplest key, and limits calls on a per-customer basis.
  • session_device - Limits calls per customer and per target device.
  • session_pop - Limits calls per customer and per destination location (the POP in which the target device is located).

Time window for limits

The window for quotas can be a minute, an hour, or a day. Our quotas are all currently set on a per-minute basis, or 60 seconds.

Rate-limited routes

Route Key Window Limit
POST /v2/ports session_pop Minute 30
PATCH /v2/ports/<port_circuit_id> session_device Minute 30
DELETE /v2/ports/<port_circuit_id> session_device Minute 30
POST /v2/ports/<port_circuit_id>/disable session_device Minute 30
POST /v2/ports/<port_circuit_id>/enable session_device Minute 30
POST /v2/auth/login Minute 6
GET /v2/signup/email-validation Minute 6
POST /v2/users/reset-password Hour 6
POST /v2/documents 24 hours 10

Sliding window calculation

We enforce rate limits using a “sliding window” algorithm.

(last_fixed_window_requests * last_window_weight) + current_fixed_window_requests <= api_limit

This algorithm “slides” a relative time frame across fixed time frames.

  • Fixed window - 60 seconds as read from the system clock (HH:MM:00 to HH:MM:59).
  • Relative window - The past 60 seconds.

Weight of the last minute

This answers the question, “Of the last 60 seconds, what percentage happened before the seconds on the clock (HH:MM:SS) read 00?”

We can figure this out using a simple formula:

(60 - seconds_in_current_clock_minute)/60

If the time is 11:28:25, then we are 25 seconds into the current clock minute (i.e. our fixed window):

(60 - 25)/60
35/60 = 0.583

In other words, 0.583 (or 58.3%) of the last 60 seconds happened before the clock rolled over into a new minute.

Last window’s requests

Again, we’ll use 11:28:25 as our time, so the weight of the last minute is 0.583.

We check our API counter to see how many requests the key/route received in the previous clock minute (11:27:00 to 11:27:59).

For the purpose of this example, we’ll say there were 12 requests.

(12 * 0.583) + current_fixed_window_requests <= api_limit

Current window’s requests

We check how many requests have been sent during the current clock minute (11:28:00 to 11:28:25). We’ll say there have been 5 requests.

(12 * 0.583) + 5 <= api_limit

Putting it all together

Finally, let’s say the API requests are limited to 15 per minute.

(12 * 0.583) + 5  

6.996 + 5 = 11.996

11.996 <= 15
    returns true

The limit has not been reached, so the request is allowed.

Exceeded limits and rate limit headers

Should the rate limit be exceeded, you will get a 429 — Too Many Requests response error.

The response body will also tell you the applicable rate limit in the format X per (minute|hour|day).

To make it easier to comply with these limits, every request to a rate-limited route will return a response with headers that provide information about the rate limit, window, and remaining quota.

These headers are:

  • X-RateLimit-Limit - An integer value representing the defined limit.

  • X-RateLimit-Remaining - A float value representing the remaining quota.

  • X-RateLimit-Window - A string value of minute|hour|day.

Can I increase my quota?

This is not currently possible, but we have development plans to allow this.