Copy the full API reference as Markdown for tools like Cursor or Claude Code.

Documentation

FreeIPAPI

IP geolocation over HTTPS: send an IP (or omit it to use the caller’s IP), get JSON with country, city, coordinates, ASN, and more.

Quick start

  1. Get an API key from the dashboard (keys start with fip_).
  2. Call the API with Authorization: Bearer YOUR_API_KEY.
  3. Parse JSON from GET https://api.freeipapi.app/api/v1/lookup — see code examples below.

Authentication

Every request must send your key in the Authorization header:

Header
Authorization: Bearer YOUR_API_KEY
Keys

Keys use the fip_ prefix. Create or rotate them in the dashboard.

IP lookup

Base URL: https://api.freeipapi.app

GET https://api.freeipapi.app/api/v1/lookup?ip={IP_ADDRESS}

Omit ip to look up the requesting client’s public IP (useful for “where is this user?” flows).

Query parameters

Parameter Type Required Description
ip string No IPv4 or IPv6. If omitted, uses the caller’s IP.

Headers

Header Value Notes
Authorization Bearer <api_key> Required
Accept application/json Optional; default is JSON

Successful response

200 OK with a JSON body. Some plans may include an attribution field.

200 OK - Success Response
{
  "ip_address": "8.8.8.8",
  "ip_version": 4,
  "is_valid": true,
  "latitude": 37.4056,
  "longitude": -122.0775,
  "country": "United States",
  "country_code": "US",
  "region": "California",
  "city": "Mountain View",
  "postal_code": "94043",
  "continent": "North America",
  "continent_code": "NA",
  "capital": "Washington D.C.",
  "phone_codes": [1],
  "timezones": ["America/Los_Angeles"],
  "languages": ["en"],
  "currencies": ["USD"],
  "asn": 15169,
  "asn_org": "Google LLC",
  "is_proxy": false
}

Error responses

Errors use the HTTP status below; the body includes error, message, and code (mirrors HTTP status).

HTTP Error Code Description
400 INVALID_IP The IP address format is invalid
401 MISSING_AUTH Authorization header not provided
401 INVALID_KEY API key not found or malformed
402 SUBSCRIPTION_REQUIRED No active subscription
404 IP_NOT_FOUND IP not found in database
410 KEY_REVOKED API key has been revoked
429 RATE_LIMITED Rate limit exceeded, slow down requests
429 QUOTA_EXCEEDED Monthly request limit reached
503 SERVICE_ERROR Temporary service issue, retry later
Error Response Example
{
  "error": "QUOTA_EXCEEDED",
  "message": "Monthly request limit reached. Please upgrade your plan.",
  "code": 429
}

Rate limits & quotas

Limits apply per account (all keys on the account share one pool).

Plan Rate Limit Monthly Quota
Hobby 50 requests / 10 seconds 50,000 requests
Startup 100 requests / 10 seconds 2,000,000 requests
Business 1,000 requests / 10 seconds 10,000,000 requests

Rate Limit Headers

The API returns rate limit information in response headers:

Header Description
X-RateLimit-Limit Maximum requests allowed in the window
X-RateLimit-Remaining Remaining requests in current window
X-RateLimit-Reset Unix timestamp when the window resets

Response fields

JSON keys use snake_case. Types below reflect typical successful lookups.

Field Type Description
ip_address string Queried IP
ip_version integer 4 or 6
is_valid boolean Whether the IP was resolved
latitude number Latitude
longitude number Longitude
country string Country name
country_code string ISO 3166-1 alpha-2
region string Region / state / province
city string City
postal_code string Postal or ZIP code
continent string Continent name
continent_code string Two-letter continent code
capital string Country capital
phone_codes array Calling codes
timezones array IANA timezone ids
languages array ISO 639-1 codes
currencies array ISO 4217 codes
asn integer Autonomous System Number
asn_org string ASN organization
is_proxy boolean Known proxy / VPN heuristic

Code examples

Replace YOUR_API_KEY and adjust the ip query as needed.

curl -s "https://api.freeipapi.app/api/v1/lookup?ip=8.8.8.8" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
const response = await fetch('https://api.freeipapi.app/api/v1/lookup?ip=8.8.8.8', {
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Accept': 'application/json'
  }
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.freeipapi.app/api/v1/lookup?ip=8.8.8.8',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)

print(response.json())
<?php
$ch = curl_init('https://api.freeipapi.app/api/v1/lookup?ip=8.8.8.8');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer YOUR_API_KEY']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

echo $response;
package main

import (
    "fmt"
    "io"
    "net/http"
)

func main() {
    req, _ := http.NewRequest("GET", 
        "https://api.freeipapi.app/api/v1/lookup?ip=8.8.8.8", nil)
    req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
    
    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    
    body, _ := io.ReadAll(resp.Body)
    fmt.Println(string(body))
}
require 'net/http'
require 'json'

uri = URI('https://api.freeipapi.app/api/v1/lookup?ip=8.8.8.8')
req = Net::HTTP::Get.new(uri)
req['Authorization'] = 'Bearer YOUR_API_KEY'

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.pretty_generate(JSON.parse(res.body))
import java.net.URI;
import java.net.http.*;

public class Main {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.freeipapi.app/api/v1/lookup?ip=8.8.8.8"))
            .header("Authorization", "Bearer YOUR_API_KEY")
            .GET()
            .build();
            
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}
using System.Net.Http;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_API_KEY");

var response = await client.GetStringAsync("https://api.freeipapi.app/api/v1/lookup?ip=8.8.8.8");
Console.WriteLine(response);

Troubleshooting

401 Unauthorized

429 QUOTA_EXCEEDED

429 RATE_LIMITED

404 IP_NOT_FOUND

503 SERVICE_ERROR