EU IP Check API
You need to determine if an IP is located in the European Union and act on that decision (e.g., gating consent flows, routing traffic, or toggling compliance features). By the end of this guide, you will query the ipXapi EU IP Check endpoint, read the inEU boolean, and integrate it into your application with a minimal, production-ready pattern.
What you’ll build
This guide focuses on a single task: calling ipXapi’s EU IP Check using /api/ip and reliably consuming the inEU field. You’ll get a copy-pasteable curl, a small client function, and pragmatic guidance on handling responses, errors, and caching. Links to the Documentation, Register, and MCP are included for setup and account management.
Endpoint and authentication
ipXapi exposes a simple GET endpoint for IP lookups.
- HTTP method: GET
- Path: /api/ip
- Base host: https://ipxapi.com
- Query parameter: ip (the IPv4 or IPv6 you want to check)
- Auth: Bearer token over HTTPS via Authorization: Bearer YOUR_API_KEY
Account basics:
- Basic plan is $29.99/mo.
- Trial is 7 days or 50 requests (whichever comes first).
Use the MCP to manage your key and view usage. If you don’t have an account, create one via Register.
Quick test with the documented fixture
Start by testing with the documented fixture IP to confirm your auth and response parsing. Note: this is a product fixture, not your user’s IP, and live flags can change. Keep your logic dynamic and do not hard-code sample values in production.
Official curl (copy/paste)
curl "https://ipxapi.com/api/ip?ip=148.105.12.120" -H "Accept: application/json" -H "Authorization: Bearer YOUR_KEY"
Official sample JSON (verbatim)
{
"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
}
}
What matters for EU checks:
- inEU: boolean. Your primary decision field. If true, treat the IP as located in the EU.
- countryCode and region fields can help with region-specific behavior when you need more than a binary EU decision.
- timezone reflects the IANA timezone string returned for the resolved location.
- security flags can inform risk and infrastructure-origin traffic handling.
Minimal integration pattern
You typically need a small utility that accepts an IP, calls /api/ip, and returns a structured result you can branch on. Keep it synchronous within your request cycle or precompute and cache, depending on your traffic and latency budget.
Python example
import os
import requests
API_HOST = "https://ipxapi.com"
API_PATH = "/api/ip"
API_KEY = os.getenv("IPXAPI_KEY", "YOUR_API_KEY")
def is_ip_in_eu(ip_address):
"""
Returns a dict with:
- in_eu: bool or None if undetermined
- country_code: str or None
- raw: the full JSON for optional downstream use
- error: str if a transport or API error occurred
"""
url = f"{API_HOST}{API_PATH}"
headers = {
"Accept": "application/json",
"Authorization": f"Bearer {API_KEY}",
}
try:
resp = requests.get(url, headers=headers, params={"ip": ip_address}, timeout=5)
except requests.RequestException as e:
return {"in_eu": None, "country_code": None, "raw": None, "error": str(e)}
if resp.status_code != 200:
return {"in_eu": None, "country_code": None, "raw": None, "error": f"HTTP {resp.status_code}"}
try:
data = resp.json()
except ValueError as e:
return {"in_eu": None, "country_code": None, "raw": resp.text, "error": "Invalid JSON"}
# ipXapi’s sample returns keys like 'status', 'inEU', 'countryCode'
in_eu = data.get("inEU")
country_code = data.get("countryCode")
return {"in_eu": in_eu, "country_code": country_code, "raw": data, "error": None}
# Example usage with the documented fixture IP (do not hard-code this for production logic)
if __name__ == "__main__":
result = is_ip_in_eu("148.105.12.120")
if result["error"]:
print("Lookup failed:", result["error"])
else:
print("inEU:", result["in_eu"], "countryCode:", result["country_code"])
Notes:
- Uses Authorization: Bearer YOUR_API_KEY. Replace with your real key via environment or secret store.
- Reads and returns inEU and countryCode without mutating keys.
- Times out quickly to avoid holding your request thread in case of network issues.
Implementing EU gating logic
Once you can read inEU, wire it into the smallest possible decision flow. For example:
- If inEU is true: present GDPR consent or route to your EU-compliant flow.
- If inEU is false: proceed normally.
- If inEU is None or the lookup fails: choose a safe default. Many teams assume EU until proven otherwise when compliance is critical, or skip gating to protect UX when risk is low. Make this explicit and consistent.
When additional geographic nuance is needed, extend the logic using countryCode or region. Keep this secondary to the primary EU decision, which is already surfaced by inEU.
Performance, caching, and operational guidance
IP lookups are read-heavy and cache-friendly. If you expect repeat traffic from the same IPs, add a small TTL cache in front of ipXapi calls. Even a 5–60 minute TTL can suppress the majority of requests during busy periods.
- Cache key: the normalized IP string.
- Cache value: a compact object with inEU and countryCode; optionally the full JSON if you need downstream fields.
- TTL strategy: pick a short TTL that balances freshness and API usage. If you detect high churn of IPs, you can still cap usage with a fixed-size LRU.
If you process logs or batch jobs, decouple ipXapi calls from the request path. Resolve and cache during ingestion or as a nightly job. This reduces latency for end users and controls request volume during peaks.
Handling timezones and units
ipXapi’s response includes timezone and geocoordinates:
- timezone: IANA zone string like America/Los_Angeles (example from the sample). Use it as-is when you must display local time or schedule region-specific events.
- lat and lon: decimal degrees.
If you do not need these fields for your EU decision, skip them to reduce payload handling. However, keeping timezone available in your data model can be useful for audits, logging, and support tooling.
Error handling and safety defaults
At minimum, handle the following failure modes:
- Transport errors and timeouts: short timeouts plus one retry (with jittered backoff) is typically sufficient for lookups. Keep the total budget small so you don’t stall responses.
- Non-200 responses: branch to a consistent fallback. Log status, request ID, and remote IP for later examination.
- Unexpected JSON: treat as lookup failure and rely on your safe default path.
Choose a default path intentionally. For example, you can set a policy flag like assume_eu_on_error and enforce it across all call sites.
Testing with the documented fixture
Use the fixture IP 148.105.12.120 during development to validate parsing, caching, and gating branches. Do not unit test against dynamic production IPs. Instead:
- Mock HTTP responses in tests, seeded with the official sample JSON above.
- Verify that inEU toggles your consent or routing logic as expected.
- Test error handling by simulating non-200 responses and timeouts.
Because live flags can change, never assert specific boolean values from a real-time API in your tests. Only assert on structural guarantees (e.g., presence and type of inEU).
Security and privacy considerations
Ensure your Authorization header never lands in client code or logs. Store YOUR_API_KEY in a server-side secret manager or environment variable and mask it in logs. If you record the ipXapi response for auditing, avoid writing full payloads to unaudited logs. Restrict exposure of security flags to systems that need them.
Operations: accounts, quotas, and monitoring
Account and usage management live in the MCP. You can:
- Rotate keys and confirm active tokens.
- Monitor usage against your plan.
If you’re starting out, the Basic plan is $29.99/mo. There’s a trial for 7 days or 50 requests to verify integration before committing. For implementation specifics beyond this guide, consult the Documentation.
End-to-end example flow
Here’s a typical flow for an API-backed web application:
- Your edge or API gateway extracts the client IP (be careful with proxies; prefer a trusted header like X-Forwarded-For set by your load balancer, or the direct remote address if available).
- Call ipXapi /api/ip with that IP. Use a short timeout and a shared cache.
- Read inEU from the JSON and store it in your request context.
- Branch your middleware: if inEU is true, enqueue the EU consent UI or apply stricter data handling. Otherwise proceed.
- Persist the decision (e.g., in a short-lived session attribute) to avoid re-checking during the same session.
Troubleshooting tips
- 401/403 responses: confirm the Authorization: Bearer header and token format. Verify the key state in MCP.
- Intermittent timeouts: keep the timeout small and add a single retry with jitter. Validate your network egress and DNS.
- Unexpected JSON structure: log the raw payload securely and compare with the Documentation for any changes.
- Stale results: your cache TTL may be too long. Reduce it or bypass cache during debugging.
FAQ
How do I authenticate requests?
Send Authorization: Bearer YOUR_API_KEY over HTTPS. Keep the key server-side only.
What endpoint should I call to check if an IP is in the EU?
Use GET https://ipxapi.com/api/ip with the ip query parameter. Read the inEU boolean from the JSON response.
Can I test without using production traffic?
Yes. Use the documented fixture ip=148.105.12.120 to validate your request and response parsing. Do not treat fixture values as stable in production logic.
What should I cache?
Cache the decision fields you actually use (e.g., inEU, countryCode) keyed by the IP. Pick a short TTL to balance freshness and usage.
How do I manage my key and see usage?
Use the MCP to rotate keys and monitor request counts. For endpoint details, see the Documentation.
Ready to ship your EU IP check? Start your 7-day or 50-request trial and get a key in minutes: Register. Then plug the Authorization header into the curl above and wire inEU into your gating logic.
