API Documentation
Free IP address API. No rate limits. No tracking.
Overview
whatsmy.fyi provides a single REST endpoint that returns IP address, geolocation, and connection metadata for the requesting IP. All data comes directly from the Cloudflare edge network β no third-party databases, no caching, no IP query logging.
- Free tier β 10,000 requests/day per key (Enterprise for unlimited)
- No IP query logging β we never store the IPs you look up
- Powered by Cloudflare Workers β global sub-50ms latency
- Three scopes:
ip,geo,full
Base URL
https://whatsmy.fyi/api/v1
Authentication
All requests require an API key. Pass it as a Bearer token in the Authorization header (preferred) or as a key query parameter.
# Header (preferred) curl https://whatsmy.fyi/api/v1/ip \ -H "Authorization: Bearer wmf_your_api_key" # Query parameter (fallback) curl "https://whatsmy.fyi/api/v1/ip?key=wmf_your_api_key"
Don't have a key? Create a free account β
Scopes
Each API key has a scope that controls which fields are returned. You choose the scope when creating a key and can change it anytime from the dashboard.
status, ip, ipv6
status, ip, ipv6, city, region, region_code, country, country_name,
continent, latitude, longitude, timezone, timezone_offset, postal_code,
asn, org, as, is_eu, currency
Everything in Geo, plus: http_protocol, tls_version, tls_cipher, rtt, colo, proxy, hosting
Endpoint
/api/v1/ipReturns IP metadata for the caller. The response shape depends on the key's scope.
Request
GET /api/v1/ip HTTP/1.1 Host: whatsmy.fyi Authorization: Bearer wmf_your_api_key
Response by scope
{
"status": "success",
"ip": "203.0.113.42",
"ipv6": null,
"city": "Amsterdam",
"region": "North Holland",
"region_code": "NH",
"country": "NL",
"country_name": "Netherlands",
"continent": "EU",
"latitude": 52.374,
"longitude": 4.8897,
"timezone": "Europe/Amsterdam",
"timezone_offset": 7200,
"postal_code": "1011",
"asn": 1101,
"org": "SURF B.V.",
"as": "AS1101 SURF B.V.",
"is_eu": true,
"currency": "EUR"
}Response fields
The Scope column shows which key scope includes each field. ALL = all scopes, GEO+ = geo and full, FULL = full only.
| Field | Type | Scope | Description |
|---|---|---|---|
status | string | ALL | Always "success" on a valid response |
ip | string | ALL | IPv4 address of the request (null if IPv6) |
ipv6 | string | ALL | IPv6 address of the request (null if IPv4) |
city | string | GEO+ | City name |
region | string | GEO+ | Region / state name |
region_code | string | GEO+ | ISO 3166-2 subdivision code (e.g. "NH", "34") |
country | string | GEO+ | ISO 3166-1 alpha-2 country code (e.g. "NL") |
country_name | string | GEO+ | Full country name in English (e.g. "Netherlands") |
continent | string | GEO+ | Two-letter continent code (e.g. "EU") |
latitude | number | GEO+ | Latitude (decimal degrees) |
longitude | number | GEO+ | Longitude (decimal degrees) |
timezone | string | GEO+ | IANA timezone identifier (e.g. "Europe/Amsterdam") |
timezone_offset | number | GEO+ | UTC offset in seconds (e.g. 7200 = UTC+2) |
postal_code | string | GEO+ | Postal / ZIP code |
asn | number | GEO+ | Autonomous System Number |
org | string | GEO+ | AS organisation name (ISP) |
as | string | GEO+ | Formatted AS string (e.g. "AS1101 SURF B.V.") |
is_eu | boolean | GEO+ | Whether the IP is located in the EU |
currency | string | GEO+ | ISO 4217 currency code for the country (e.g. "EUR") |
http_protocol | string | FULL | HTTP protocol version (e.g. "HTTP/3", "HTTP/2") |
tls_version | string | FULL | TLS version (e.g. "TLSv1.3") |
tls_cipher | string | FULL | TLS cipher suite |
rtt | number | FULL | Round-trip time from client to Cloudflare edge (ms) |
colo | string | FULL | Cloudflare datacenter IATA code that handled the request |
proxy | boolean | FULL | Whether the ASN is a known VPN or proxy provider |
hosting | boolean | FULL | Whether the ASN is a known hosting or cloud provider |
Error reference
| Status | Error | Meaning |
|---|---|---|
| 401 | missing_api_key | No API key was provided in the request |
| 401 | invalid_api_key | The key does not exist or was deleted |
| 403 | inactive_api_key | The key exists but has been deactivated |
| 429 | rate_limit_exceeded | Free tier limit of 10,000 req/day reached; resets at midnight UTC |
| 500 | internal_error | Unexpected server error β please try again |
Code examples
curl https://whatsmy.fyi/api/v1/ip \ -H "Authorization: Bearer wmf_your_api_key"
Rate limits
The free tier allows 10,000 requests per day per API key. The counter resets at midnight UTC. Rate limit status is returned on every response via headers:
X-RateLimit-Limit: 10000 X-RateLimit-Remaining: 9987 X-RateLimit-Reset: 1749081600 # Unix timestamp of next reset
When the limit is exceeded, the API returns a 429 response:
{
"error": "rate_limit_exceeded",
"message": "You have reached the free tier limit of 10,000 requests/day. Resets at midnight UTC.",
"docs": "https://whatsmy.fyi/docs#rate-limits",
"enterprise": "https://whatsmy.fyi/enterprise"
}Need more? Enterprise plan β
Official Node.js SDK
Install the official @whatsmyfyi/sdk package for TypeScript-first access with automatic retries and full type definitions.
npm install @whatsmyfyi/sdk
import { WhatsMyFyi } from '@whatsmyfyi/sdk'
const client = new WhatsMyFyi({ apiKey: 'wmf_your_api_key' })
// Full response
const data = await client.ip.lookup()
console.log(data.city) // "Amsterdam"
console.log(data.country) // "NL"
// Quick helpers
const ip = await client.ip.address() // "203.0.113.42"
const loc = await client.ip.location() // { city, country, countryCode, lat, lng }
const org = await client.ip.org() // { asn, name }- Zero dependencies β uses native
fetch - Works in Node.js, Deno, Bun, and the browser
- Auto-retry on 5xx with exponential backoff (max 3 attempts)
- Typed
WhatsMyFyiErrorwithcode,message,status
OpenAPI Specification
The full OpenAPI 3.1 spec is available for import into Postman, Insomnia, or any compatible tool. In Postman, go to File β Import β Link and paste the URL below.
https://whatsmy.fyi/openapi.jsonBadge
Add a badge to your README or website to show that you use the whatsmy.fyi API.
HTML
<a href="https://whatsmy.fyi"> <img src="https://whatsmy.fyi/api/badge" alt="Powered by whatsmy.fyi" height="40" /> </a>
Markdown (GitHub README)
[](https://whatsmy.fyi)
Try it live
Make a real API request right here β no account or API key needed. You'll see your own IP data returned directly from the Cloudflare edge.
Live demo β no API key needed
This returns your real IP data from the Cloudflare edge.
Hit "Send Request" to see your real IP data.
Get started
Create a free account to get your API key in under a minute.
Create a free account β