Call the free timezones api endpoint
A single GET request lists every zone. The free Timezones API endpoint takes no key, no account and no header, so a plain curl call is the entire integration.
curl https://aisenseapi.com/services/v1/timezones{"timezones":[{"timezone":"Africa/Abidjan","offset":"+0000"},{"timezone":"Africa/Accra","offset":"+0000"},{"timezone":"Africa/Addis_Ababa","offset":"+0300"}, ...]}That response is truncated for display. A full call on 20 August 2026 returned 418 entries, one for every zone in the IANA database.
Pass an offset as a path segment to filter the list:
curl https://aisenseapi.com/services/v1/timezones/+0200{"timezones":[{"timezone":"Africa/Blantyre","offset":"+0200"},{"timezone":"Africa/Bujumbura","offset":"+0200"},{"timezone":"Africa/Ceuta","offset":"+0200"}, ...]}Truncated again. That filter returned 50 zones on the same run. Narrower offsets come back short enough to read in full:
curl https://aisenseapi.com/services/v1/timezones/+0530{"timezones":[{"timezone":"Asia/Colombo","offset":"+0530"},{"timezone":"Asia/Kolkata","offset":"+0530"}]}Both shapes are the same JSON object, so one parser handles the list and the filter. Sibling clocks live on the Time APIs hub if you need the current moment rather than the zone table.
Response fields
| Field | Type | Description |
|---|---|---|
| timezones | array | One object per zone, ordered by zone name. Always present on success, even when it holds a single entry. |
| timezones[].timezone | string | The canonical IANA name, such as Europe/Oslo or America/Argentina/Buenos_Aires. This is the value you store. |
| timezones[].offset | string | Signed four-digit offset from UTC for that zone at the time of the request, for example +0200 or -0500. A reading, not a fixed attribute. |
The offset segment is four digits with an optional sign. A leading plus is accepted and so is a bare 0200. Negative offsets need the minus, as in /timezones/-0500. The last two digits are minutes rather than a decimal fraction, which is why India is +0530 and not +0550.
A well-formed offset that nobody is currently on returns an error instead of an empty array:
{"error":"No timezones found for the given offset."}A path segment that is not an offset at all does not reach this endpoint:
{"error":"Unknown endpoint. See https://www.aisense.no/free-public-apis for the reference."}So branch on the presence of the timezones key, never on its length, and treat a missing key as a failed lookup.
The offset is a live reading
This is the part that catches people. The offset field describes where a zone happens to be sitting when your request arrives. It is not a stable fact about the zone.
- Ask in July, ask in January
Europe/Oslocame back as+0200on a run in August. In winter the same zone reports+0100. Nothing changed about the zone. The clocks moved. - The filter moves with them
Membership of
/timezones/+0200is not fixed either. Half of Europe joins in spring and leaves in autumn, while a set of African zones that never change sits at+0200all year. The list is a snapshot of now. - Which is why you store the name
Store
Europe/Oslo, never+0200. A saved offset is a photograph of one instant that quietly goes wrong at the next transition. Reminders fire an hour early, a business-hours check opens the shop at the wrong time, and a booking made in March lands in the wrong slot in November.
Because the free Timezones API endpoint recomputes each offset per request, a stored zone name stays correct while a stored number rots. The same reasoning covers the transition rules themselves, which governments change with little notice. A zone name is a pointer into a database that gets updated. A number you saved is just a number you saved.
When you do need an instant rather than a zone, reach for the Datetime API endpoint or the Timestamp API endpoint, both of which report UTC and leave the local rendering to you.
An offset cannot name a place
Many unrelated zones share one offset, so the mapping only runs one way. Given a zone you can always compute the offset. Given an offset you get a crowd. The August run of /timezones/+0200 put Ceuta, Johannesburg, Oslo, Blantyre and Bujumbura in the same bucket, which tells you nothing about where anybody is.
The extremes make the point from the other side. One offset returns exactly one zone:
curl https://aisenseapi.com/services/v1/timezones/+1400{"timezones":[{"timezone":"Pacific/Kiritimati","offset":"+1400"}]}That is the only place on earth that far ahead, and it is the exception. Around +0000 and the busy European and American offsets you get dozens of candidates spread across continents.
This matters for anything that guesses a user region from a browser offset. The offset narrows the field and never closes it. Two users you grouped together may sit in zones whose clocks diverge next month, when one of them changes and the other does not. If you need a place, ask for a place: a picker filled from this list, or an explicit choice from the user. If you need an offset, resolve it from the stored zone name at the moment you need it.
Common uses
Timezone pickers
Populate a dropdown from the live list instead of a hardcoded array that drifts out of date as zones are added, renamed or merged upstream.
Validating input
Check a zone name submitted through a form against the real IANA list before you write it to a profile, so a typo fails at the boundary rather than at the first conversion.
Who is at this offset
Resolve which regions currently run at a given offset when you are reading a log line, a calendar file or a legacy record that only kept the number.
Scheduling in local time
Keep each user zone name on their record and resolve it when the job runs, so a nine in the morning reminder stays at nine through both transitions.
Refreshing a local copy
Pull the list in a build step to keep an offline copy of valid zone names current, without shipping a full tz database in a thin client.
Privacy and limits
The request carries nothing but an optional offset in the path, so there is nothing about the caller to store. The response depends only on the IANA database and the server clock.
Cache the zone names freely, since the set changes rarely. Do not cache the offsets. They are correct only at the moment of the request and go stale at every daylight saving transition. If you keep a copy, keep the names and recompute the offsets.
Like every route on the service, the free Timezones API endpoint is capped at 5000 requests per IP per 24 hours. That is ample for filling pickers and validating input, and not intended for a per-request lookup on a hot path. The base URL is https://aisenseapi.com/services/v1 for this and for every other route in the free public REST APIs reference.