Skip to main content
The Country State City API returns errors in two shapes. Which one you get depends on the endpoint and the kind of failure, so write your error handling to read both.

The two error shapes

Structured envelope — used by plan-gate 403 responses, 429 rate limits, and the ?fields=/?sort= validation errors:
details is optional. It’s present when the error carries structured metadata, like the 403 and 429 responses below. Other errors in this shape return just status and message. Bare error object — used by a small set of geographical 404 responses: country details, state details, region details, subregion details, and currency by country:
There is no single envelope that covers every failure. Read the message from message or error, and treat details as optional.
Reading either shape
Each endpoint page lists the exact error bodies that endpoint returns. When you need the precise wording for one endpoint, check its page — for example Get Currency by Country or Parse Phone Number.

HTTP status codes

A 401 is rejected by the authentication layer before any plan or usage check runs. See Authentication for its response body and the usual causes.

403 — Forbidden

A 403 means your API key authenticated fine, but the request isn’t allowed. Most 403 responses are plan gates, and those carry a details object.

Plan-gate 403

Returned when the endpoint, query parameter, or feature you’re using isn’t included in your plan — for example, calling Fuzzy Search on a Community plan:
403 - Feature not available
string
Internal name of the gated feature (e.g. fuzzySearch, searchEndpoint, fieldsFiltering, sortParameter, regionsApi, currencyApi).
string
Your plan’s tier at the time of the request.
string | null
The minimum tier that unlocks this feature, or null. See Usage limits by tier below for what each tier includes.
string
Direct link to upgrade your plan.
requiredTier is null when there is no higher active plan the API can safely recommend, or when the live plan catalogue could not be read. The gate itself is still real — only the “upgrade to this tier” hint is missing. Follow details.upgradeUrl (or see Pricing) to compare the available plans. Handle it as details.requiredTier ?? 'see pricing' rather than printing null to your users.

Other 403s

Not every 403 is a plan gate. A 403 raised for any other reason returns the envelope with no details object:
403 - No details
Check that details exists before you branch on it. error.details?.feature tells you it’s a plan gate; a missing details means the message is all you get, and upgrading won’t help.

404 — Not Found

Most 404 responses use the structured envelope. Five geographical handlers deliberately return the bare error object instead: country details, state details, region details, subregion details, and currency by country. They use it for two cases:
404 - Record doesn't exist
404 - No data for this record
The first means the code or ID you passed matches nothing. The second means the record exists, but has nothing on file for the attribute you asked for — a country with no currency on record, a city with no timezone. Both are 404, and the wording varies per endpoint.
Retrying won’t change a 404. Treat “no data on record” as a legitimate empty result in your integration rather than as a failure to retry.

429 — Rate limit exceeded

Every plan has a daily and a monthly request quota. Exceeding either returns 429 Too Many Requests:
429 - Daily limit exceeded
429 - Monthly limit exceeded
integer
The quota you exceeded, in requests.
string
daily or monthly — which quota was exceeded.
string
ISO 8601 UTC timestamp for when the quota resets: next UTC midnight for daily, the 1st of next UTC month for monthly. Use this to schedule your retry instead of guessing a backoff window.
string
Your plan’s tier at the time of the request.

Handling a 429 in your integration

Usage headers

When a request is authenticated and counted against your quota — the normal case on a successful /v1 call — the response carries your plan and current usage as headers. Use them to watch your quota instead of waiting for a 429:
These headers are not on every /v1 response. They’re added when the request is authenticated and counted, so error responses may not carry them. In particular:
  • 401 — rejected before any usage is counted, so no usage headers.
  • 429 — the request was refused, so no usage headers. Read details.limit and details.resetAt from the body instead.
Treat a missing header as unknown, never as 0.
Reading the usage headers safely

Usage limits by tier

See Pricing for what each tier unlocks beyond request volume — data fields, ?fields=/?sort=, search, and other gated features.

Authentication

API key setup and the 401 Unauthorized response.

Field Filtering & Sorting

?fields=/?sort= — the other common source of 400 and 403 responses.

FAQ

Common questions, including rate-limit troubleshooting.