IP Timezone API
You need to determine a user’s local time reliably from their IP address so you can schedule messages, localize timestamps, or coordinate time-based logic without prompting for manual settings. By the end of this guide, you will call the ipXapi IP Timezone endpoint, extract the timezone field, and integrate it into your application with production-safe handling, caching, and verification steps.
What you will build
This guide shows how to query a single geolocation endpoint to retrieve a canonical IANA timezone string for a known IP, then apply that value to display or compute local time. You will run a copy-pasteable curl command, examine the official JSON structure, and integrate a minimal client in code that focuses on the timezone field only.
All examples use a documented fixture IP and a single endpoint path. You will authenticate with a Bearer token, parse the response, and avoid common pitfalls such as relying on transient, non-timezone fields for time calculations.
Endpoint, auth, and scope
ipXapi provides a geolocation lookup for IPs that includes a timezone field. For this post, we will use the IP Timezone lookup via a single HTTP GET path:
- Path: /api/ip
- Base: https://ipxapi.com
- Query parameter: ip (IPv4 or IPv6 string)
- Auth: Authorization: Bearer YOUR_API_KEY
- Media type: application/json
You can find the broader reference in the Documentation, and a service status and exploration surface at MCP. For account creation and API key provisioning, use Register.
Trial, plan, and usage boundaries you should expect
The trial provides 7 days or 50 requests, whichever comes first. The Basic plan is $29.99/month. If you are prototyping a timezone feature or adding IP-based defaults to a product tour, the trial is typically enough to stand up an end-to-end test.
Because IP geolocation is probabilistic and live flags can change, always treat the returned data as dynamic and cache conservatively. When you begin production traffic, instrument error handling for network timeouts and non-200 statuses, and implement retries with a bounded backoff to avoid request storms.
Quickstart: curl request for a known IP
The following curl calls the IP Timezone API with a documented fixture IP. Replace YOUR_API_KEY with your actual token from your dashboard after you register.
curl "https://ipxapi.com/api/ip?ip=148.105.12.120" -H "Accept: application/json" -H "Authorization: Bearer YOUR_API_KEY"
This command requests a JSON body with the timezone among other fields. You can run it as-is after inserting your key. The fixture IP is static for documentation; do not assume it represents your own IP or location.
Official response sample and the field that matters
Below is the official product-fixture JSON for the same endpoint and IP. Your live results can differ (live flags can change), but you should treat the structure as stable for integration purposes.
{"status":"success","country":"United States","countryCode":"US","region":"US-CA","regionName":"California","city":"Mountain View","zip":"94043","lat":37.40599,"lon":-122.0786,"timezone":"America/Los_Angeles","isp":"MailChimp","org":"MailChimp","as":"AS14782 MailChimp","query":"148.105.12.120","inEU":false,"continentCode":"NA","security":{"is_proxy":false,"is_vpn":false,"is_cloud_provider":true}}
Field you will use:
- timezone: The IANA timezone identifier (for example, America/Los_Angeles). Use this value to format and compute local times. It is a stable string that libraries can load without additional mapping.
Other fields are included for context in the response. For the purpose of timezone features—formatting timestamps, Scheduler logic, or cron alignment—focus exclusively on the timezone key.
Turning the timezone into local time
Most programming languages have a standard or widely used library that understands IANA timezone names. After extracting timezone, convert server-side or client-side UTC timestamps to that zone to render clock time correctly. Avoid mapping by country or region; rely directly on timezone as returned.
Because daylight saving transitions are embedded in IANA zone data, you do not need to handle offsets manually. You can format display strings and compute offsets using the library’s time zone converter at runtime.
Minimal integration in JavaScript
The JavaScript example below fetches the timezone for the documented IP and converts a given UTC timestamp into local time for that zone. Replace YOUR_API_KEY with your credential. The code reads only the timezone field from the JSON.
async function fetchTimezone(ip) {
const url = `https://ipxapi.com/api/ip?ip=${encodeURIComponent(ip)}`;
const res = await fetch(url, {
headers: {
"Accept": "application/json",
"Authorization": "Bearer YOUR_API_KEY"
}
});
if (!res.ok) {
throw new Error(`ipXapi request failed: ${res.status} ${res.statusText}`);
}
const data = await res.json();
// Focus on the only key we need for time conversion
if (!data || typeof data.timezone !== "string" || data.timezone.length === 0) {
throw new Error("timezone not present in response");
}
return data.timezone;
}
// Example usage: convert a UTC timestamp to the IP's local time string
async function formatLocalTimeForIp(utcISOString, ip) {
const tz = await fetchTimezone(ip);
// Use Intl.DateTimeFormat with the returned IANA timezone
const dtf = new Intl.DateTimeFormat("en-US", {
timeZone: tz,
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit"
});
const d = new Date(utcISOString); // must be a valid ISO 8601 in UTC
return { timezone: tz, local: dtf.format(d) };
}
// Demo with the documented fixture IP and a UTC timestamp
formatLocalTimeForIp("2024-01-15T18:30:00Z", "148.105.12.120")
.then(result => {
console.log(`Timezone: ${result.timezone}`);
console.log(`Local time: ${result.local}`);
})
.catch(err => console.error(err));
Notes:
- timezone is an IANA string; Intl.DateTimeFormat and most modern libraries can use it directly.
- Always validate that timezone is present and non-empty before formatting.
- If you need to compute durations, do those in UTC, and format only at the last mile using the timezone.
Python alternative
If you prefer Python, the following snippet fetches timezone and uses zoneinfo (Python 3.9+) to convert an aware datetime. Install no extra packages if you are on 3.9+; otherwise, consider backports.zoneinfo on older versions.
import json
import urllib.request
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
def fetch_timezone(ip: str) -> str:
url = f"https://ipxapi.com/api/ip?ip={ip}"
req = urllib.request.Request(url, headers={
"Accept": "application/json",
"Authorization": "Bearer YOUR_API_KEY"
})
with urllib.request.urlopen(req, timeout=10) as resp:
if resp.status != 200:
raise RuntimeError(f"ipXapi request failed: {resp.status}")
data = json.loads(resp.read().decode("utf-8"))
tz = data.get("timezone")
if not isinstance(tz, str) or not tz:
raise RuntimeError("timezone not present in response")
return tz
def to_local(utc_dt: datetime, tz_name: str) -> datetime:
if utc_dt.tzinfo is None:
utc_dt = utc_dt.replace(tzinfo=timezone.utc)
return utc_dt.astimezone(ZoneInfo(tz_name))
if __name__ == "__main__":
ip = "148.105.12.120"
tz = fetch_timezone(ip)
utc_now = datetime.now(timezone.utc)
local_dt = to_local(utc_now, tz)
print(f"Timezone: {tz}")
print(f"Local time: {local_dt.strftime('%Y-%m-%d %H:%M:%S %Z')}")
This code keeps the logic minimal and focuses on the timezone return value to format local timestamps correctly.
When and how to cache
Because timezone is tied to an IP that can move, your cache should be conservative. For example, cache by IP for a short TTL that matches your product’s tolerance for location drift. If a user is authenticated and relatively stable, you can memoize for their session or a few hours and refresh on significant client network changes.
If you front your calls with a CDN or server cache, include the ip query in the cache key. Since the response is JSON and specific to a single IP, avoid sharing across different IPs. When you update your app, retain the interface such that clients can gracefully handle a missing or blank timezone by falling back to UTC display with a clear label.
Validation and fallbacks
Even with successful lookups, always validate timezone as a non-empty string before use. If it is missing, treat the case as a soft failure and default to UTC or a product-wide default. Consider logging the IP and response metadata for debugging and sampling.
Do not rely on non-timezone fields to infer a zone. For instance, do not map by country or city strings. The timezone field conveys the exact IANA name that you should use; it encapsulates daylight saving transitions and historical rules without extra authoring on your side.
Testing and inspection with MCP
To inspect behavior outside your app, use MCP. It’s useful for verifying connectivity, headers, and status codes. Keep in mind:
- Use the same Authorization: Bearer YOUR_API_KEY header as your production code.
- Confirm the path and ip query match what you ship to production.
- Treat the response as live; live flags can change and should not be snapshot-assumed.
Secure handling of API keys
Do not embed YOUR_API_KEY in client-side code that is served publicly. If you need to run the request from a browser, proxy the call through your backend where you can store the key securely. If you must expose a browser endpoint, implement rate limits and input validation to mitigate abuse.
Rotate keys if you suspect compromise and implement environment-based configuration for keys (e.g., development, staging, production) to avoid mixing traffic or leaking credentials in logs.
Operational concerns and deployment checklist
- Connectivity: Allow outbound HTTPS to ipxapi.com.
- Timeouts: Set a reasonable HTTP timeout (e.g., 5–10 seconds) and implement one retry with jittered backoff for transient failures.
- Observability: Log non-200 responses with correlation IDs if available. Track request rates to avoid surprising the trial quota.
- Resilience: On failure, default to UTC formatting and flag the event rather than blocking user flows.
- Input hygiene: Validate IP strings on the server before sending them to the API; reject malformed addresses early.
Putting it all together
To ship an IP-to-timezone feature end-to-end, you only need three steps:
- Call GET https://ipxapi.com/api/ip with the ip query set to the address you want to resolve and the Authorization: Bearer YOUR_API_KEY header.
- Extract timezone from the JSON response.
- Use a timezone-aware library to render or compute local time for that zone.
This sequence avoids guesswork and ensures DST transitions and historical rules are handled transparently by your time library.
Common pitfalls to avoid
- Inferring timezones from country or region text. Use the timezone field directly.
- Caching for too long. IPs can move; keep TTLs short relative to your tolerance for drift.
- Hardcoding offsets. Offsets change with DST; rely on IANA zone conversions.
- Embedding credentials in client code. Keep keys server-side or use a secure proxy.
FAQ
Q: Which endpoint returns the timezone string?
A: Use GET https://ipxapi.com/api/ip with the ip query parameter. The response includes timezone as an IANA string.
Q: Do I need to compute GMT offsets myself?
A: No. Use the IANA timezone string with your platform’s time library. It handles offsets and DST automatically.
Q: Can I treat the fixture IP as representative of my users?
A: No. The fixture is for documentation and testing. Live flags can change and the fixture does not reflect the current user’s IP or location.
Q: How should I cache results?
A: Cache by IP with a conservative TTL aligned with your product’s tolerance for location drift. Always validate that timezone is present on cache hits.
Q: What are the trial and basic plan details?
A: The trial is 7 days or 50 requests. The Basic plan is $29.99/month.
Next step
Register for an API key and ship your timezone integration in under an hour: Register. For additional fields and behavior, refer to the Documentation, and use MCP to verify calls during development.
