Skip to content

Rate limits

The API rate-limits per token, not per tenant or per IP. Two integrations with their own tokens do not compete for the same budget - another reason to issue one token per integration.

Over the limit, the API returns 429 Too Many Requests. Nothing was processed; the request is safe to retry.

Retry with exponential backoff and jitter. Without jitter, several clients that hit the limit together will retry together and stay synchronised:

import random, time
import urllib.request, urllib.error
def call(req, attempts=6):
for attempt in range(attempts):
try:
return urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
if e.code != 429 or attempt == attempts - 1:
raise
# 1, 2, 4, 8 … seconds, plus up to a second of jitter
time.sleep(2 ** attempt + random.random())

Do not retry 4xx other than 429. A 403 will still be a 403 on the tenth attempt, and hammering it only burns your budget.

  • Page in bulk. One request with limit=500 beats 500 requests of one.
  • Poll on a sane interval. Certificate expiry moves on the scale of days. Polling the inventory every minute tells you nothing new - hourly is plenty, and for renewal state a few seconds is only reasonable briefly after you opened one.
  • Cache locally. Keep the last response and diff against it, rather than re-fetching to answer every internal question.
  • Do not poll to detect expiry. Alerting on expiry is something NextPKI already does. Let it mail you instead of rebuilding it against the API.