Errors
The API uses conventional HTTP status codes and always returns errors as JSON. A 2xx
status means success; 4xx means the request needs changing. One 3xx is used — 300
asks you to choose between equally-valid matches (see
Disambiguation).
At a glance
| Status | Meaning | When |
|---|---|---|
300 |
Multiple Choices | An identifier matches more than one time zone (a bare abbreviation code, or a convert from/to token). |
401 |
Unauthorized | The token is missing, malformed, or revoked. |
403 |
Forbidden | The account's email address isn't verified. |
404 |
Not Found | No resource matches the identifier in the URL. |
422 |
Unprocessable Entity | A query parameter failed validation. |
429 |
Too Many Requests | You exceeded the rate limit. |
Error shape
Most errors return a single message:
{
"message": "Unauthenticated."
}
Validation errors (422) add an errors object keyed by parameter, with an array of
messages per field — show these to developers, not end users:
{
"message": "The offset must look like -04:00 or bare minutes like -240.",
"errors": {
"offset": [
"The offset must look like -04:00 or bare minutes like -240."
]
}
}
Disambiguation (300)
GET /v1/abbreviations/{code} — and GET /v1/convert for its from/to tokens —
return 300 Multiple Choices when an identifier matches more than one named time zone
(many share a code — AST, CST, …) or when a country has more than one timezone.
Unlike the message-only error shape it returns a candidates list:
{
"message": "The abbreviation \"AST\" matches 9 time zones. Re-request by slug, or add ?offset= or ?continent= to disambiguate.",
"candidates": [
{
"code": "AST",
"name": "Atlantic Standard Time",
"slug": "atlantic-standard-time",
"continent": "Americas",
"current": { "utc_offset": "-04:00", "is_dst": false },
"links": {
"self": "https://api.timezone.io/v1/abbreviations/atlantic-standard-time"
}
},
{
"code": "AST",
"name": "Arabian Standard Time",
"slug": "arabian-standard-time",
"continent": "Asia",
"current": { "utc_offset": "+03:00", "is_dst": false },
"links": {
"self": "https://api.timezone.io/v1/abbreviations/arabian-standard-time"
}
}
]
}
(Remaining candidates trimmed.) Recover by re-requesting with the unique slug from the
candidate you meant, or narrow with ?offset= / ?continent=. For convert's country
matches, re-request with one of the candidate IANA identifiers.
Treat 300 as a prompt, not a failure: surface the candidates to your user the way a
search box surfaces suggestions.
Common cases
401 Unauthenticated.— Check theAuthorization: Bearer <token>header. See Authentication.403— Verify your email address, then retry. Body:{ "message": "Your email address is not verified." }.404— The identifier doesn't exist. Double-check spelling and casing (America/New_York, notAmerica/NewYork), and remember to encode+as%2B.422— Readerrorsfor the exact parameter and rule that failed.429— Back off and retry using theRetry-Afterheader — see rate limits for a worked retry example.