API Documentation
Build powerful location-aware applications with our simple and reliable IP geolocation API
<50ms
Avg Response Time
99.9%
Uptime SLA
Weekly
Database Updates
HTTPS
Encrypted Requests
Quick Start
Get started with our IP Geolocation API in minutes. No credit card required for the free tier.
3 Simple Steps
Sign Up
Create a free account to get your API token
Get Your Key
Copy your API token from the dashboard
Make Requests
Start making API calls immediately
Base URL
All API endpoints are relative to the base URL:
https://ip-api.in/api/v1
Authentication
Authenticate your API requests using a Bearer token in the Authorization header. This gives you higher rate limits and access to usage analytics.
With Authentication
- ✓ 200 requests/min
- ✓ Usage analytics
- ✓ Priority support
- ✓ Account management
Without Authentication
- • 60 requests/min
- • No analytics
- • Community support
- • Limited by IP address
/ip/{ip_address}
Retrieve comprehensive geolocation information for any IPv4 or IPv6 address.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ip_address |
string | Required | The IPv4 or IPv6 address to lookup (e.g., 8.8.8.8 or 2001:4860:4860::8888) |
Example Request
curl -X GET "https://ip-api.in/api/v1/ip/8.8.8.8" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://ip-api.in/api/v1/ip/8.8.8.8', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_TOKEN',
'Accept' => 'application/json',
],
]);
$data = json_decode($response->getBody(), true);
echo $data['data']['country'];
import requests
url = "https://ip-api.in/api/v1/ip/8.8.8.8"
headers = {
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
data = response.json()
print(data['data']['country'])
fetch('https://ip-api.in/api/v1/ip/8.8.8.8', {
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json'
}
})
.then(response => response.json())
.then(data => console.log(data.data.country));
Success Response (200 OK)
{
"success": true,
"message": "IP lookup successful",
"api_version": "v1",
"data": {
"ip": "8.8.8.8",
"country": "United States",
"country_code": "US",
"region": "California",
"region_code": "CA",
"city": "Mountain View",
"postal_code": "94035",
"latitude": 37.386,
"longitude": -122.0838,
"timezone": "America/Los_Angeles",
"continent": "North America",
"continent_code": "NA",
"asn": "AS15169",
"organization": "GOOGLE",
"is_in_european_union": false
}
}
/ip
Automatically detect and geolocate the IP address making the request. Perfect for client-side integrations.
Example Request
curl -X GET "https://ip-api.in/api/v1/ip" \
-H "Accept: application/json"
/ip/bulk
Look up multiple IP addresses in a single request. More efficient than making individual calls.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
ips |
array | Required | Array of IP addresses to lookup (max 100 per request) |
Example Request
curl -X POST "https://ip-api.in/api/v1/ip/bulk" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ips": ["8.8.8.8", "1.1.1.1", "208.67.222.222"]
}'
Example Response
{
"success": true,
"message": "Bulk lookup successful",
"api_version": "v1",
"count": 3,
"data": {
"8.8.8.8": {
"ip": "8.8.8.8",
"country": "United States",
"country_code": "US",
...
},
"1.1.1.1": {
"ip": "1.1.1.1",
"country": "Australia",
"country_code": "AU",
...
},
"208.67.222.222": {
"ip": "208.67.222.222",
"country": "United States",
"country_code": "US",
...
}
}
}
Rate Limits
Our API uses rate limiting to ensure fair usage and maintain service quality for all users.
Unauthenticated
requests per minute
- No signup required
- Limited by IP address
- Resets every minute
Authenticated
requests per minute
- Free tier available
- 3.3x higher limits
- Upgrade for more
Rate Limit Headers
Every response includes headers showing your current rate limit status:
429 Too Many Requests response. Wait for the reset time or upgrade your plan for higher limits.
Error Handling
Our API uses standard HTTP status codes and returns detailed error messages in JSON format.
Common HTTP Status Codes
| Code | Status | Description |
|---|---|---|
200 |
OK | Request successful |
400 |
Bad Request | Invalid request parameters |
401 |
Unauthorized | Invalid or missing API token |
404 |
Not Found | IP address not found in database |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Server Error | Internal server error |
Error Response Format
{
"success": false,
"message": "Too Many Requests",
"error": "Rate limit exceeded",
"code": 429,
"retry_after": 60
}
Response Fields
Detailed description of all fields returned in a successful response.
| Field | Type | Description |
|---|---|---|
ip |
string | The IP address that was queried |
country |
string | Full country name |
country_code |
string | ISO 3166-1 alpha-2 country code |
region |
string|null | Region or state name |
region_code |
string|null | Region or state code |
city |
string|null | City name |
postal_code |
string|null | Postal or ZIP code |
latitude |
float | Latitude coordinate |
longitude |
float | Longitude coordinate |
timezone |
string | Timezone identifier (e.g., America/New_York) |
continent |
string | Continent name |
continent_code |
string | Two-letter continent code |
asn |
string|null | Autonomous System Number |
organization |
string|null | ISP or organization name |
is_in_european_union |
boolean | Whether the country is in the EU |
Code Examples
Ready-to-use code examples in popular programming languages. Copy and paste to integrate our API into your application.
curl -X GET "https://ip-api.in/api/v1/ip/8.8.8.8" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
$client = new \GuzzleHttp\Client([
'base_uri' => 'https://ip-api.in/api/v1',
'headers' => [
'Authorization' => 'Bearer YOUR_API_TOKEN',
'Accept' => 'application/json',
],
]);
try {
$response = $client->get('/ip/8.8.8.8');
$data = json_decode($response->getBody(), true);
if ($data['success']) {
echo "Country: " . $data['data']['country'] . "\n";
echo "City: " . $data['data']['city'] . "\n";
echo "Latitude: " . $data['data']['latitude'] . "\n";
echo "Longitude: " . $data['data']['longitude'] . "\n";
}
} catch (\Exception $e) {
echo "Error: " . $e->getMessage();
}
$url = "https://ip-api.in/api/v1/ip/8.8.8.8";
$options = [
'http' => [
'header' => "Authorization: Bearer YOUR_API_TOKEN\r\n" .
"Accept: application/json\r\n",
'method' => 'GET'
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
$data = json_decode($response, true);
if ($data['success']) {
echo "Country: " . $data['data']['country'] . "\n";
echo "City: " . $data['data']['city'] . "\n";
}
import requests
url = "https://ip-api.in/api/v1/ip/8.8.8.8"
headers = {
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = response.json()
if data['success']:
print(f"Country: {data['data']['country']}")
print(f"City: {data['data']['city']}")
print(f"Latitude: {data['data']['latitude']}")
print(f"Longitude: {data['data']['longitude']}")
else:
print(f"Error: {response.status_code}")
fetch('https://ip-api.in/api/v1/ip/8.8.8.8', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
console.log('Country:', data.data.country);
console.log('City:', data.data.city);
console.log('Latitude:', data.data.latitude);
console.log('Longitude:', data.data.longitude);
}
})
.catch(error => console.error('Error:', error));
const axios = require('axios');
axios.get('https://ip-api.in/api/v1/ip/8.8.8.8', {
headers: {
'Authorization': 'Bearer YOUR_API_TOKEN',
'Accept': 'application/json'
}
})
.then(response => {
const data = response.data;
if (data.success) {
console.log('Country:', data.data.country);
console.log('City:', data.data.city);
console.log('Latitude:', data.data.latitude);
console.log('Longitude:', data.data.longitude);
}
})
.catch(error => {
console.error('Error:', error.message);
});
require 'net/http'
require 'json'
url = URI("https://ip-api.in/api/v1/ip/8.8.8.8")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer YOUR_API_TOKEN"
request["Accept"] = "application/json"
response = http.request(request)
data = JSON.parse(response.body)
if data['success']
puts "Country: #{data['data']['country']}"
puts "City: #{data['data']['city']}"
puts "Latitude: #{data['data']['latitude']}"
puts "Longitude: #{data['data']['longitude']}"
end
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type Response struct {
Success bool `json:"success"`
Message string `json:"message"`
Data struct {
IP string `json:"ip"`
Country string `json:"country"`
City string `json:"city"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
} `json:"data"`
}
func main() {
url := "https://ip-api.in/api/v1/ip/8.8.8.8"
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("Error creating request:", err)
return
}
req.Header.Add("Authorization", "Bearer YOUR_API_TOKEN")
req.Header.Add("Accept", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return
}
var response Response
json.Unmarshal(body, &response)
if response.Success {
fmt.Printf("Country: %s\n", response.Data.Country)
fmt.Printf("City: %s\n", response.Data.City)
fmt.Printf("Latitude: %.2f\n", response.Data.Latitude)
fmt.Printf("Longitude: %.2f\n", response.Data.Longitude)
}
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONObject;
public class IPLookup {
public static void main(String[] args) {
try {
URL url = new URL("https://ip-api.in/api/v1/ip/8.8.8.8");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Bearer YOUR_API_TOKEN");
conn.setRequestProperty("Accept", "application/json");
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
JSONObject json = new JSONObject(response.toString());
if (json.getBoolean("success")) {
JSONObject data = json.getJSONObject("data");
System.out.println("Country: " + data.getString("country"));
System.out.println("City: " + data.getString("city"));
System.out.println("Latitude: " + data.getDouble("latitude"));
System.out.println("Longitude: " + data.getDouble("longitude"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
class Program
{
static async Task Main(string[] args)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "YOUR_API_TOKEN");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
try
{
var response = await client.GetAsync(
"https://ip-api.in/api/v1/ip/8.8.8.8"
);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
JObject json = JObject.Parse(responseBody);
if ((bool)json["success"])
{
Console.WriteLine($"Country: {json["data"]["country"]}");
Console.WriteLine($"City: {json["data"]["city"]}");
Console.WriteLine($"Latitude: {json["data"]["latitude"]}");
Console.WriteLine($"Longitude: {json["data"]["longitude"]}");
}
}
catch (HttpRequestException e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
}
import Foundation
let url = URL(string: "https://ip-api.in/api/v1/ip/8.8.8.8")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Bearer YOUR_API_TOKEN", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error.localizedDescription)")
return
}
guard let data = data else { return }
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any],
let success = json["success"] as? Bool, success == true,
let dataDict = json["data"] as? [String: Any] {
print("Country: \(dataDict["country"] ?? "")")
print("City: \(dataDict["city"] ?? "")")
print("Latitude: \(dataDict["latitude"] ?? 0)")
print("Longitude: \(dataDict["longitude"] ?? 0)")
}
} catch {
print("JSON Error: \(error.localizedDescription)")
}
}
task.resume()
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject
fun getIPLocation() {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://ip-api.in/api/v1/ip/8.8.8.8")
.addHeader("Authorization", "Bearer YOUR_API_TOKEN")
.addHeader("Accept", "application/json")
.build()
client.newCall(request).execute().use { response ->
if (response.isSuccessful) {
val responseBody = response.body?.string()
val json = JSONObject(responseBody)
if (json.getBoolean("success")) {
val data = json.getJSONObject("data")
println("Country: ${data.getString("country")}")
println("City: ${data.getString("city")}")
println("Latitude: ${data.getDouble("latitude")}")
println("Longitude: ${data.getDouble("longitude")}")
}
}
}
}
use reqwest;
use serde_json::Value;
#[tokio::main]
async fn main() -> Result<(), Box> {
let client = reqwest::Client::new();
let response = client
.get("https://ip-api.in/api/v1/ip/8.8.8.8")
.header("Authorization", "Bearer YOUR_API_TOKEN")
.header("Accept", "application/json")
.send()
.await?;
let json: Value = response.json().await?;
if json["success"].as_bool().unwrap_or(false) {
println!("Country: {}", json["data"]["country"]);
println!("City: {}", json["data"]["city"]);
println!("Latitude: {}", json["data"]["latitude"]);
println!("Longitude: {}", json["data"]["longitude"]);
}
Ok(())
}
$headers = @{
"Authorization" = "Bearer YOUR_API_TOKEN"
"Accept" = "application/json"
}
$response = Invoke-RestMethod -Uri "https://ip-api.in/api/v1/ip/8.8.8.8" -Headers $headers -Method Get
if ($response.success) {
Write-Host "Country: $($response.data.country)"
Write-Host "City: $($response.data.city)"
Write-Host "Latitude: $($response.data.latitude)"
Write-Host "Longitude: $($response.data.longitude)"
}
YOUR_API_TOKEN with your actual API token from your dashboard. For production use, ensure you handle errors appropriately and never expose your API token in client-side code.
Ready to Get Started?
Create a free account and start building with our IP Geolocation API