IP Geolocation API для разработчиков

Бесплатный IP lookup API для интеграторов: один JSON-запрос возвращает геолокацию IP, данные RDAP по IP-адресу, идентификацию IP-to-ASN, обратный DNS и классификацию IP (hosting, mobile, business) — без регистрации, без API-ключа для базовых запросов.

Эта страница про сам API и путь интеграции — оцениваете детекцию VPN/прокси/Tor и скоринг фрода? Смотрите страницу по детекции фрода, а для бизнес-оценки — страницу для бизнеса.

IP address lookup API для разработчиков

Быстрый старт

Каждый запрос ниже не требует авторизации — API-ключ не нужен для начала работы. В каждом запрашиваются группы geo, network и security для примера IP.

curl
curl "https://ip.xakki.pro/api/v1/ip?include=geo,network,security&ip=9.9.9.9"
Go
package main

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

type geoBlock struct {
	CountryCode string `json:"countryCode"`
	City        string `json:"city"`
}

type ipResponse struct {
	Status string    `json:"status"`
	IP     string    `json:"ip"`
	Geo    *geoBlock `json:"geo"`
}

func main() {
	resp, err := http.Get("https://ip.xakki.pro/api/v1/ip?include=geo&ip=9.9.9.9")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	var out ipResponse
	if err := json.Unmarshal(body, &out); err != nil {
		panic(err)
	}

	if out.Geo != nil {
		fmt.Printf("%s: %s, %s\n", out.IP, out.Geo.City, out.Geo.CountryCode)
	}
}
Python
import requests

resp = requests.get(
    "https://ip.xakki.pro/api/v1/ip",
    params={"include": "geo,network,security", "ip": "9.9.9.9"},
    timeout=5,
)
resp.raise_for_status()
data = resp.json()

print(data["status"], data["ip"])
if data.get("geo"):
    print(data["geo"]["countryCode"], data["geo"]["city"])
classification = (data.get("network") or {}).get("classification")
if classification:
    print(classification["type"])

Пример ответа

Сокращённый реальный ответ (для читаемости — полный справочник полей смотрите в документации API).

{
  "schemaVersion": 15,
  "status": "ok",
  "ip": "9.9.9.9",
  "version": 4,
  "cachedAt": "2026-07-28T12:00:06Z",
  "flags": {
    "isGlobal": true,
    "isBogon": false,
    "isCloud": false,
    "isTor": false,
    "isAnycast": true
  },
  "network": {
    "asn": "19281",
    "asName": "QUAD9-AS-1 - Quad9, US",
    "asnOrg": "Quad9",
    "asnDomain": "quad9.net",
    "prefix": "9.9.9.0/24",
    "registry": "arin",
    "classification": {
      "type": "gov",
      "provider": "QUAD9-AS-1 - Quad9",
      "confidence": "medium"
    },
    "rdap": {
      "handle": "NET-9-9-9-0-1",
      "name": "CLEAN-97",
      "org": "Quad9 Admin"
    }
  },
  "dns": {
    "ptr": "dns9.quad9.net",
    "hostnames": ["dns9.quad9.net"]
  },
  "geo": {
    "countryCode": "US",
    "region": "California",
    "city": "Berkeley",
    "timezone": "-07:00",
    "lat": 37.87159,
    "lon": -122.27275
  },
  "privacy": {
    "isProxy": false,
    "isVpn": false,
    "isTor": false,
    "isAnonymous": false
  },
  "threat": {
    "isMalicious": false,
    "sources": []
  },
  "fraud": {
    "score": 0,
    "level": "low",
    "signals": []
  },
  "tier": "anonymous"
}

Ошибки и лимиты запросов

Базовая классификация (flags, сводка network, обратный DNS) всегда выполняется и возвращается с HTTP 200 — некорректное значение ?ip= просто игнорируется, и эндпоинт использует ваш собственный адрес вместо ошибки.

Группы geo, network и security ограничены по количеству уникальных IP-адресов в день (и есть лимит в минуту). При превышении бюджета группа мягко отключается: она указывается в массиве limited ответа, status снижается до partial, устанавливаются обычные заголовки RateLimit-Limit / RateLimit-Remaining / RateLimit-Reset — при этом HTTP-статус остаётся 200.

Повторные запросы одного и того же IP-адреса в пределах одного окна бесплатны: счётчик учитывает только уникальные адреса, а не запросы, поэтому опрос собственного трафика никогда не расходует бюджет.

Полный сбой обогащения (когда каждый источник вернул ошибку) — единственный случай, возвращающий статус, отличный от 200: status становится error, а HTTP-код — 500.

На этом пути у API нет жёсткого 429. Единственный 429 приходит от собственного лимита скорости на шлюзе nginx — он не зависит от лимитов вашего тарифа и находится вне JSON-контракта API.

Текущие лимиты запросов

Загружается вживую из того же каталога, что использует страница тарифов — ничего ниже не захардкожено, поэтому данные никогда не устаревают.

Загрузка текущих лимитов…

* Лимиты в минуту и в день считаются на уникальный запрошенный IP-адрес. На шлюзе также действует отдельный лимит скорости запросов, независимый от указанных выше лимитов в минуту/в день, при превышении которого возвращается HTTP 429.

Готовы интегрироваться?

Часто задаваемые вопросы

Этот IP geolocation API бесплатен?
Да — базовая классификация и запросы не требуют регистрации или API-ключа. Бесплатный зарегистрированный тариф добавляет собственный бюджет запросов по группам geo, network и security; платные тарифы поднимают лимиты в минуту/в день ещё выше. Актуальные лимиты — на странице тарифов.
Как получить полную запись RDAP для IP-адреса?
Добавьте network в ?include=: объект network.rdap в ответе содержит полную запись RDAP — handle, name, status, events и contacts — вместо сокращённого базового набора.
Что означает поле классификации IP (hosting, mobile, business и т.д.)?
network.classification.type принимает значения hosting, datacenter, isp, mobile, home, business или private от runtime-эвристики, плюс метки edu, gov или telco из курируемых сетевых датасетов — это итоговый вердикт на основе имени AS, данных RDAP, PTR и признаков IP-блока, с собственной уверенностью и источником (rule, cloud или heuristic) для прозрачности.
Возвращает ли обратный DNS больше одного хоста?
Базовый блок dns всегда содержит ptr (определённый обратный DNS-хост) и hostnames (все хосты, которые вернул multi-PTR запрос) для любого адреса с обратной записью.
Что происходит при превышении лимита моего тарифа?
Соответствующая группа (geo, network или security) мягко отключается — указывается в limited[], а status снижается до partial — при этом ответ всё равно возвращается с HTTP 200 и остальными данными. Жёсткого 429 от самого API нет; только собственный лимит скорости шлюза может вернуть обычный 429, независимо от вашего тарифа.