Pricing Docs Contact Status Blog
Log in Get Free API Key →

API Reference

Complete reference for integrating IP geolocation and threat intelligence into your applications.

Try it live → Read the quick start

Quick Start

Every lookup is a single HTTP GET request. No SDK install, no OAuth handshake, no request signing — just a token and, optionally, an IP. The example below is real: it's the exact shape of data you'll get back for 8.8.8.8.

GET https://ipfly.world/api?token=YOUR_TOKEN&ip=8.8.8.8&include=security
json — Example Response
{	
  "ip": "8.8.8.8",
  "hostname": "dns.google",
  "country_code2": "US",
  "country_code3": "USA",
  "country_name": "United States",
  "country_capital": "Washington",
  "state_prov": "California",
  "city": "Mountain View",
  "zipcode": "94043",
  "latitude": "37.4056",
  "longitude": "-122.0775",
  "is_eu": false,
  "country_emoji": "🇺🇸",
  "calling_code": "+1",
  "country_tld": ".us",
  "languages": "en",
  "currency": {
    "code": "USD",
    "name": "Dollar",
    "symbol": "$"
  },
  "time_zone": {
    "name": "America/New_York",
    "offset": -4,
    "offset_with_dst": -3,
    "current_time": "2026-08-21 03:12:46.964685-0400",
    "current_time_unix": 1787296366.9647,
    "current_tz_abbreviation": "EDT",
    "current_tz_full_name": "America/New_York",
    "is_dst": true
  },
  "asn": {
    "asn": "AS15169",
    "name": "Google LLC",
    "domain": "google.com",
    "route": "8.8.8.0/24",
    "type": "hosting"
  },
  "company": {
    "name": "AS15169 Google LLC",
    "domain": "google.com",
    "type": "isp"
  },
  "security": {
    "is_tor": false,
    "is_vpn": false,
    "is_icloud_relay": false,
    "is_proxy": false,
    "is_datacenter": true,
    "is_anonymous": false,
    "is_known_attacker": false,
    "is_known_abuser": false,
    "is_threat": false,
    "is_bogon": false,
    "blocklists": [],
    "scores": {
      "vpn_score": 100,
      "proxy_score": 1,
      "threat_score": 100,
      "trust_score": 33
    }
  }
}
		

Security and ASN Company Data fields availability depends on the subscription plan, starting from Pro Monthly plan.
See pricing for more details.

Try It Live

This calls the real IPFly API from your browser and renders the actual response — not a mock. Nothing is stored or logged by this page.

Live request runner Runs entirely client-side
Quick fill:

Enter your token above and click "Send request" to see a live response here.

Don't have a token yet? Create a free account — the free tier includes 1,000 requests/day, enough to fully exercise this panel. Requests made here count toward your normal usage.

Authentication

All requests require your API token as a query parameter. You can query your own IP by omitting the ip parameter.

Detect your own IP automatically:

GEThttps://ipfly.world/api?token=YOUR_TOKEN

Look up a specific IP address:

GEThttps://ipfly.world/api?token=YOUR_TOKEN&ip=IP_ADDRESS

Get your API token by signing up for a free account.

Never call the IPFly API directly from client-side JavaScript, a mobile app bundle, or any code a user can inspect. Your token will be visible in network requests and can be extracted and abused by anyone viewing your page source. Always proxy requests through your own backend.

Making Requests

All requests are simple HTTP GET calls. No special headers required.

Parameters

ParameterTypeRequiredDescription
tokenstringYesYour API authentication token
ipstringNoIP address to lookup (IPv4 or IPv6). Omit to detect caller's IP.

A note on IPv6

IPv6 addresses are fully supported and returned in the same response shape as IPv4 — pass them exactly as written (e.g. 2001:4860:4860::8888), no encoding needed. If a large share of your traffic is still IPv4-mapped through NAT64 or a CDN, expect the resolved location to reflect the edge or gateway, not the end user.

Sandbox & Test IPs

A handful of well-known, stable IPs are useful for integration tests and demos because their location and network ownership rarely change.

IPGood for testingTypical result
8.8.8.8Standard US result, hosting-type ASN🇺🇸Mountain View, CA — Google LLC
1.1.1.1Anycast edge network, non-US🇦🇺Sydney/Anycast — Cloudflare
9.9.9.9Privacy-focused resolver, EU-adjacent🇨🇭Quad9 Foundation
2001:4860:4860::8888IPv6 code pathSame fields as IPv4, Google IPv6 DNS
127.0.0.1 / 10.0.0.0/8Negative test — private/reserved rangesReturns an error; these are never publicly routable

A common first bug: testing from localhost during development. Your server's outbound IP (not 127.0.0.1) is what gets geolocated — if you're behind a home router or corporate NAT, expect an approximate result centered on your ISP, not your exact address. This is expected behavior for every IP geolocation provider, not an IPFly-specific limitation.

Standalone Fields

Root-level fields returned for every lookup.

FieldTypeDescriptionStatus
ipstringThe queried IP address.Required
hostnamestringReverse DNS hostname of the IP.Required
country_code2stringISO 3166-1 alpha-2 country code.Required
country_code3stringISO 3166-1 alpha-3 country code.Required
country_namestringCommon name of the country.Required
country_capitalstringCapital city of the country.Required
country_emojistringCountry flag emoji.Required
calling_codestringInternational dialing code.Required
country_tldstringCountry code top-level domain (e.g. .ua).Required
languagesstringOfficial languages of the country.Required
is_eubooleanWhether the country is an EU member.Required

Location Object

Detailed geographic data for the IP address.

FieldTypeDescriptionStatus
state_provstringState / province / region name.Optional
state_codestringState/province code.Optional
districtstringDistrict or sub-region.Optional
citystringCity name.Optional
zipcodestringZIP / postal code.Optional
latitudestringLatitude coordinate.Required
longitudestringLongitude coordinate.Required

ASN Object

Autonomous System Number information.

FieldTypeDescription
asn.asnstringAS number (e.g. AS15169).
asn.namestringOrganization name.
asn.domainstringOrganization's domain.
asn.routestringIP route/prefix (CIDR notation).
asn.typestringNetwork type: isp, hosting, business, education.

Timezone Object

Current time and timezone data for the IP's location.

FieldTypeDescription
time_zone.namestringIANA timezone name (e.g. Europe/Paris).
time_zone.offsetnumberUTC offset in hours (without DST).
time_zone.offset_with_dstnumberUTC offset including DST.
time_zone.current_timestringCurrent local time string.
time_zone.current_time_unixnumberCurrent time as Unix timestamp.
time_zone.current_tz_abbreviationstringTimezone abbreviation (e.g. EEST).
time_zone.is_dstbooleanWhether DST is currently active.

Security Object

Threat intelligence and anonymization detection flags.

FieldTypeDescription
security.is_torbooleanWhether the IP is a Tor exit node.
security.is_vpnbooleanWhether the IP is a used for VPN.
security.is_icloud_relaybooleanWhether the IP is a iCloud Apple proxy.
security.is_proxybooleanWhether the IP is a known proxy.
security.is_datacenterbooleanWhether the IP belongs to a datacenter allocation.
security.is_anonymousbooleanWhether the IP is a used for anonymization.
security.is_known_attackerbooleanWhether the IP is used for DoS attacks, flood etc.
security.is_known_abuserbooleanWhether the IP is a used for abusing like hijack, malware etc.
security.is_threatbooleanWhether the IP belongs to a high and risk threat.
security.is_bogonbooleanWhether the IP belongs to a bogon CIDR ranges.
security.blocklistsbooleanWhether the IP belongs to a specific organic ban-lists.
security.scoresbooleanIP Reputation scores for VPN, Proxy, Threat and Trust Score.

Currency Object

Local currency information for the IP's country.

FieldTypeDescription
currency.codestringISO 4217 currency code (e.g. EUR).
currency.namestringCurrency name (e.g. Euro).
currency.symbolstringCurrency symbol (e.g. €).

Errors & Status Codes

The API uses standard HTTP status codes: 2xx for success, 4xx for problems with the request, 5xx for problems on our end. Every error also returns a JSON body so you can branch on error.code without parsing status text.

StatusMeaningTypical cause
200OKLookup succeeded.
400Bad RequestMalformed or unparseable IP address.
401UnauthorizedMissing or invalid token.
403ForbiddenToken valid but suspended, or plan doesn't include this field set.
404Not FoundNo record for a private, reserved, or bogon IP.
500 / 503Server ErrorTransient issue on our side. Safe to retry with backoff.

Example error response

json — 401 Unauthorized
{
  "error": "Invalid API token! Please recheck your token or sign up at https://ipfly.world/billing"
}

Tip: check error.code rather than the human-readable message in your code — the message text is meant for logs and dashboards, and its wording may evolve over time, while the code is stable.

Best Practices

A few patterns that separate integrations that hold up in production from ones that break under real traffic.

Cache by IP

A given IP's location rarely changes hour to hour. Cache responses for 12–24 hours keyed on the IP to cut request volume dramatically — most apps see 80%+ cache hit rates once traffic has a returning-user base.

Keep the token server-side

Proxy lookups through your own backend. A token embedded in a browser bundle or mobile app will eventually be scraped and used to burn your quota.

Treat security flags as signals, not verdicts

is_vpn, is_proxy, and is_tor are strong risk signals, not proof of intent. Combine them with your own account and behavior signals before blocking a user outright — false positives on shared corporate NATs and mobile carrier gateways are common across every provider.

Fail open, not closed

If a lookup errors or times out, don't block the user's core action (checkout, login, page load) on it. Default to a safe fallback — e.g. no personalization, or a conservative currency — and log the failure for later review.

Batch thoughtfully

Processing a large IP list (log analysis, offline enrichment)? Parallelize with a bounded worker pool (5–10 concurrent requests) instead of firing everything at once — it's both friendlier to the API and easier to reason about failures.

Mind data-retention rules

An IP address paired with derived location data can count as personal data under GDPR and similar regimes. If you store lookups long-term, apply the same retention and deletion policies you use for other user PII.

Code Examples

The same lookup in six languages. Every snippet uses only the standard library or a single common HTTP package — no IPFly-specific SDK required.

bash
curl "https://ipfly.world/api?token=YOUR_TOKEN"
curl "https://ipfly.world/api?token=YOUR_TOKEN&ip=8.8.8.8"

# Pretty-print with jq
curl -s "https://ipfly.world/api?token=YOUR_TOKEN&ip=8.8.8.8" | jq .
javascript — browser / Deno
const res  = await fetch('https://ipfly.world/api?token=YOUR_TOKEN&ip=8.8.8.8');
if (!res.ok) throw new Error(`IPFly error: ${res.status}`);
const data = await res.json();

console.log(data.country_name);      // "United States"
console.log(data.city);              // "Mountain View"
console.log(data.security.is_vpn);   // false
console.log(data.currency.symbol);   // "$"
javascript — Node.js 18+
// Native fetch, no dependencies needed on Node 18+
async function lookupIP(ip) {
  const url = new URL('https://ipfly.world/api');
  url.searchParams.set('token', process.env.IPFLY_TOKEN);
  if (ip) url.searchParams.set('ip', ip);

  const res = await fetch(url);
  if (!res.ok) throw new Error(`IPFly ${res.status}`);
  return res.json();
}

const geo = await lookupIP('8.8.8.8');
console.log(geo.country_name, geo.asn.name);
php
<?php
$url  = 'https://ipfly.world/api?token=' . urlencode($_ENV['IPFLY_TOKEN']) . '&ip=8.8.8.8';
$ctx  = stream_context_create(['http' => ['timeout' => 5]]);
$json = @file_get_contents($url, false, $ctx);

if ($json === false) {
    // network-level failure — fail open
    exit;
}

$data = json_decode($json, true);
if (isset($data['error'])) {
    error_log('IPFly error: ' . $data['error']['code']);
    exit;
}

echo $data['country_name'];         // "United States"
echo $data['security']['is_vpn'];   // false
python
import os
import requests

def lookup_ip(ip: str | None = None, timeout: float = 5.0) -> dict:
    params = {"token": os.environ["IPFLY_TOKEN"]}
    if ip:
        params["ip"] = ip
    r = requests.get("https://ipfly.world/api", params=params, timeout=timeout)
    r.raise_for_status()
    return r.json()

data = lookup_ip("8.8.8.8")
print(data["city"], data["asn"]["name"])   # Mountain View Google LLC
java — 11+
import java.net.URI;
import java.net.http.*;
import java.time.Duration;

var client  = HttpClient.newBuilder()
    .connectTimeout(Duration.ofSeconds(5))
    .build();
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://ipfly.world/api?token=" + System.getenv("IPFLY_TOKEN") + "&ip=8.8.8.8"))
    .timeout(Duration.ofSeconds(5))
    .build();

var response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
    throw new RuntimeException("IPFly error: " + response.statusCode());
}
System.out.println(response.body());
ruby
require 'net/http'
require 'json'

uri = URI("https://ipfly.world/api")
uri.query = URI.encode_www_form(token: ENV['IPFLY_TOKEN'], ip: '8.8.8.8')

response = Net::HTTP.get_response(uri)
data     = JSON.parse(response.body)

raise "IPFly error: #{data['error']['code']}" if data['error']

puts data['country_name']
puts data['security']['is_vpn']
go
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "net/url"
    "os"
    "time"
)

func main() {
    q := url.Values{}
    q.Set("token", os.Getenv("IPFLY_TOKEN"))
    q.Set("ip", "8.8.8.8")

    client := &http.Client{Timeout: 5 * time.Second}
    resp, err := client.Get("https://ipfly.world/api?" + q.Encode())
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    var data map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&data)
    fmt.Println(data["country_name"])
}

Build on reliable IP Intelligence

Start with 1,000 free requests per day. No credit card. No commitments. Scale when you’re ready.