Skip to content

Errors & rate limits

Typed errors

Every SDK maps HTTP status codes to the same four error types (names per language, all sharing a base that carries status):

HTTP Error Extra
401 UnauthorizedError missing/invalid/deactivated key
404 NotFoundError unknown country, division or postal code
429 RateLimitedError retryAfterSeconds from the Retry-After header
other 4xx/5xx ApiError status + server message

The API returns {"error": "<message>"} for every 4xx/5xx; 401/404 bodies may be empty, in which case the SDK uses fixed text.

import { NotFoundError, RateLimitedError, NationKitError } from "nationkit";
try {
  await client.getDivision("dz", 999999);
} catch (err) {
  if (err instanceof RateLimitedError) console.log(err.retryAfterSeconds);
  else if (err instanceof NotFoundError) console.log("no such division");
  else if (err instanceof NationKitError) console.log(err.status, err.message);
}
from nationkit import NotFoundError, RateLimitedError, ApiError
try:
    client.get_division("dz", 999999)
except RateLimitedError as e:
    print(e.retry_after_seconds)
except NotFoundError:
    print("no such division")
except ApiError as e:
    print(e.status, e.message)
case NationKit.Client.get_division(client, "dz", 999_999) do
  {:ok, division}          -> division
  {:error, e} -> "HTTP #{NationKit.Error.status(e)}: #{e.message}"
end

No automatic retries anywhere — you decide. On 429, wait Retry-After seconds and try again; every 429 response carries that header.

Rate limits

Window Counted per Reset
minute API key sliding 60 s window
day API key UTC calendar day
month API key UTC calendar month

Quotas come from your tier (Free today; higher tiers on request). Every response carries X-RateLimit-Limit-Minute and X-RateLimit-Remaining-Minute so you can pace yourself:

X-RateLimit-Limit-Minute: 60
X-RateLimit-Remaining-Minute: 59

Login/register routes are additionally throttled per IP. If you deploy NationKit yourself with multiple API replicas, set ConnectionStrings__Redis so all replicas share one per-key budget (see the repo README).