Cloudflare Workers · TanStack Start
One request resolves a public domain to its IPv4 address, country, flag, ASN organization and Tranco popularity rank. Results are cached in Cloudflare KV, upstream providers stay hidden behind this contract.
https://geoip.kristal.id/v1/lookup/{domain}{
"domain": "google.com",
"ip": "142.250.191.14",
"country": {
"code": "US",
"name": "United States",
"flag": "data:image/png;base64,iVBORw0KGgoAAA..."
},
"asn": {
"number": 15169,
"name": "Google LLC"
},
"rank": 1
}country.flag is a PNG data URI (or null if the flag provider is unavailable) and rank is null for unranked domains.
| code | status | when |
|---|---|---|
| INVALID_DOMAIN | 400 | Not a bare public hostname (URL, IP, localhost, reserved TLD). |
| DOMAIN_NOT_FOUND | 404 | No public IPv4 (A) record, or all records point at private space. |
| GEOIP_LOOKUP_FAILED | 502 | The geolocation / ASN provider could not answer. |
| UPSTREAM_ERROR | 502 | A provider returned an unexpected response. |
| UPSTREAM_TIMEOUT | 504 | A provider did not answer within 5 seconds. |
| RATE_LIMITED | 429 | Too many requests from this address. |
| INTERNAL_ERROR | 500 | Anything unexpected. |
| GET /health | Liveness probe, never calls an upstream provider. |
| Caching | 1 hour per domain, 30 days per flag, both in Cloudflare KV. |
| CORS | Open to any origin; no credentials or private data are involved. |