Tout ce dont vous avez besoin pour intégrer OpenIPApi dans votre application. URL de base : https://api.openipapi.com (versionnée en /v1).
threat_score et les indicateurs VPN/proxy/Tor sont des entrées pour votre logique de décision. Combinez-les avec les signaux de compte, paiement, appareil et comportement — ne les utilisez jamais comme seule base pour bloquer. Voir la méthodologie des données pour plus de détails.
Toutes les requêtes API doivent inclure votre clé API dans l'en-tête X-API-Key . Vous pouvez trouver votre clé API dans la console.
X-API-Key: oip_your_api_key_here
Toutes les requêtes API sont effectuées vers l'URL de base suivante via HTTPS :
https://api.openipapi.com
Spécification lisible par machine (OpenAPI 3.1) : /openapi.yaml.
Toutes les réponses sont en JSON. Les réponses réussies retournent HTTP 200.
Les réponses d'erreur retournent un code de statut 4xx ou 5xx approprié avec un champ error .
{
"error": "invalid_api_key",
"message": "The provided API key is invalid or has been revoked.",
"status": 401
}
Recherchez la géolocalisation, le réseau et les données de menace pour une seule adresse IP.
https://api.openipapi.com/v1/lookup/{ip}
| Paramètre | Type | Description |
|---|---|---|
| ip | path | Adresse IPv4 ou IPv6 à rechercher. |
| fields | query (optional) | Liste séparée par des virgules des champs de premier niveau à retourner : geo,network,threat,abuse. |
| date | query (optional) | Lookup historique — retourner le snapshot de cette IP à la date indiquée (YYYY-MM-DD). Jusqu'à 365 jours en arrière. Requiert Pro+. Retourne une erreur no_snapshot si aucune donnée n'est disponible pour cette date. |
| Champ | Description | Plan |
|---|---|---|
| ip | The queried IP address. | All |
| type | IPv4 or IPv6. | All |
| geo.country_code | 2-letter ISO 3166-1 country code. | All |
| geo.country | Full country name. | All |
| geo.region | Region / state name. | All |
| geo.region_code | Region / state code. | All |
| geo.city | City name. | All |
| geo.postal_code | Postal / ZIP code. | All |
| geo.latitude | Latitude (decimal degrees). | All |
| geo.longitude | Longitude (decimal degrees). | All |
| geo.timezone | IANA timezone identifier (e.g. Europe/Berlin). | All |
| geo.is_sanctioned | True if the country is on OFAC, EU, or UN sanction lists. | All |
| geo.sanction_lists | Array of applicable sanction programs, e.g. ["OFAC","EU"]. | All |
| network.asn | Autonomous System Number. | Starter+ |
| network.as_name | AS organisation name. | Starter+ |
| network.as_domain | AS organisation domain. | Starter+ |
| network.isp | Internet Service Provider name. | All |
| network.organization | Network organisation name. | All |
| network.connection_type | residential, datacenter, mobile, education, or government. | All |
| threat.is_vpn | True if the IP is a known VPN endpoint. | Pro+ |
| threat.is_proxy | True if the IP is a known open proxy. | Pro+ |
| threat.is_tor | True if the IP is a Tor exit node. | Pro+ |
| threat.is_relay | True if the IP is an anonymous relay. | Pro+ |
| threat.is_hosting | True if the IP belongs to a hosting provider. | Pro+ |
| threat.threat_score | Composite risk score 0–100. A signal, not a final verdict — combine with account, payment, device and behavior data. | Pro+ |
| threat.threat_categories | Array of threat category strings. | Pro+ |
| threat.bot_type | Verified bot identifier (e.g. "googlebot", "bingbot") or null. Verified via reverse-DNS + forward confirmation. | All |
| abuse.contact_email | Abuse contact email from WHOIS data. | Pro+ |
$ curl https://api.openipapi.com/v1/lookup/185.220.101.45 \
-H "X-API-Key: oip_your_api_key_here"
{
"ip": "185.220.101.45",
"type": "IPv4",
"geo": {
"country_code": "DE",
"country": "Germany",
"region": "Hessen",
"region_code": "HE",
"city": "Frankfurt am Main",
"postal_code": "60313",
"latitude": 50.1109,
"longitude": 8.6821,
"timezone": "Europe/Berlin",
"is_sanctioned": false,
"sanction_lists": []
},
"network": {
"asn": 205100,
"as_name": "F3 Netze e.V.",
"as_domain": "f3netze.de",
"isp": "F3 Netze",
"organization": "F3 Netze e.V.",
"connection_type": "datacenter"
},
"threat": {
"is_vpn": true,
"is_proxy": false,
"is_tor": true,
"is_relay": false,
"is_hosting": true,
"threat_score": 85,
"threat_categories": ["tor_exit_node", "known_abuser"],
"bot_type": null
},
"abuse": {
"contact_email": "abuse@f3netze.de"
}
}
Recherchez plusieurs adresses IP en une seule requête. Les limites de taille de lot dépendent de votre plan.
https://api.openipapi.com/v1/lookup/batch
plan_required . | Plan | IP max par requête |
|---|---|
| Starter | 100 |
| Pro | 500 |
| Business | 1,000 |
| Enterprise | 5,000 |
{
"ips": [
"185.220.101.45",
"8.8.8.8",
"1.1.1.1"
]
}
Retourne un tableau encapsulé d'objets de lookup complets, dans le même ordre que la requête.
{
"results": [
{ "ip": "185.220.101.45", /* full lookup object */ },
{ "ip": "8.8.8.8", /* full lookup object */ },
{ "ip": "1.1.1.1", /* full lookup object */ }
],
"count": 3
}
Retourne la géolocalisation et les données de menace pour l'adresse IP effectuant la requête. Utile pour les fonctionnalités « Quelle est mon IP ? ».
https://api.openipapi.com/v1/me
La réponse est identique à GET /v1/lookup/{ip} avec l'IP de l'appelant pré-remplie.
$ curl https://api.openipapi.com/v1/me \
-H "X-API-Key: oip_your_api_key_here"
Récupérez des informations détaillées sur un numéro de système autonome. Nécessite un plan Starter ou supérieur.
https://api.openipapi.com/v1/asn/{asn}
Le paramètre asn accepte à la fois les formats 13335 et AS13335 .
$ curl https://api.openipapi.com/v1/asn/13335 \
-H "X-API-Key: oip_your_api_key_here"
{
"asn": 13335,
"as_name": "Cloudflare, Inc.",
"as_domain": "cloudflare.com",
"organization": "Cloudflare, Inc.",
"country_code": "US",
"ip_ranges_count": 1284,
"total_ips": 2359296
}
Validez une adresse IP et déterminez son type. Ne consomme pas de quota de lookup.
https://api.openipapi.com/v1/validate/{ip}
{
"ip": "185.220.101.45",
"valid": true,
"type": "IPv4",
"private": false,
"bogon": false
}
Score de fraude composite (0–100) avec niveau de risque et recommandation actionnable. Combine les signaux VPN, proxy, Tor, datacenter et abus historiques. Plan Starter ou supérieur
https://api.openipapi.com/v1/fraud/{ip}
{
"ip": "185.220.101.45",
"fraud_score": 92,
"risk_level": "critical",
"signals": {
"is_vpn": true,
"is_proxy": false,
"is_tor": true,
"is_datacenter": true,
"is_known_attacker": true,
"high_risk_country": false
},
"recommendation": "block"
}
| Score | Niveau de risque | Recommandation | Action typique |
|---|---|---|---|
| 0–30 | low | allow | Laisser passer la requête |
| 31–60 | medium | review | Journaliser pour examen manuel |
| 61–85 | high | challenge | Exiger CAPTCHA / 2FA / authentification renforcée |
| 86–100 | critical | block | Rejeter et alerter |
Données de sondage réseau en temps réel depuis nos 60+ nœuds de sondage actif : ports TCP ouverts, bannières de service, DNS inversé, détail complet des certificats TLS (sujet, émetteur, SANs, validité) et catégories de service détectées. Plan Pro ou supérieur
https://api.openipapi.com/v1/probe/{ip}
"stale": true.{
"ip": "185.220.101.45",
"reachable": true,
"last_probed": "2026-04-18T14:23:11+00:00",
"age_hours": 2.3,
"stale": false,
"refresh_queued": false,
"probe_count_24h": 14,
"probed_from_nodes": 8,
"open_ports": [
{ "port": 22, "service": "ssh", "banner": "SSH-2.0-OpenSSH_8.9p1" },
{ "port": 80, "service": "http", "banner": "nginx/1.24.0" },
{ "port": 443, "service": "https", "banner": null },
{ "port": 9001, "service": "tor-relay", "banner": null }
],
"reverse_dns": "tor-exit.f3netze.de",
"tls": {
"subject_cn": "*.f3netze.de",
"issuer": "Let's Encrypt",
"valid_from": "2026-02-10T00:00:00Z",
"valid_to": "2026-05-10T00:00:00Z",
"sans": ["f3netze.de", "*.f3netze.de"],
"fingerprint": "7e:4f:...:b2:e1"
},
"banners": {
"22": "SSH-2.0-OpenSSH_8.9p1",
"80": "nginx/1.24.0"
},
"detected_services": {
"is_tor_relay": true,
"is_ssh_open": true,
"is_web_server": true,
"is_vpn": false,
"is_proxy": false
}
}
22 (ssh), 80 / 8080 (http), 443 / 8443 (https), 1080 (socks5), 3128 / 8888 (http-proxy), 9001 / 9030 (tor-relay / tor-dir), 9050 / 9150 (tor-socks), 1194 (openvpn), 4500 (ipsec-nat-t), 51820 (wireguard).
Identifie si une IP appartient à un pool de proxies résidentiels connu, un VPN commercial ou une plage de datacenter. Contrairement aux indicateurs génériques is_proxy , cet endpoint attribue l'IP au fournisseur spécifique (Bright Data, Oxylabs, NordVPN, etc.) — essentiel pour les équipes anti-fraude qui doivent autoriser certains fournisseurs et en bloquer d'autres. Extension Proxy Intel
https://api.openipapi.com/v1/proxy-attribution/{ip}
{
"ip": "2.56.16.42",
"detected": true,
"primary_provider": {
"provider": "unknown_vpn",
"display_name": "Unknown VPN",
"network_type": "vpn",
"confidence": 0.75
},
"networks": [
{
"provider": "unknown_vpn",
"network_type": "vpn",
"confidence": 0.75,
"source": "x4bnet-vpn",
"cidr": "2.56.16.0/22"
},
{
"provider": "unknown_datacenter",
"network_type": "datacenter",
"confidence": 0.75,
"source": "x4bnet-datacenter"
}
],
"recommendation": "treat_as_vpn"
}
residential — pools de proxies résidentiels (Bright Data, Oxylabs, Smartproxy, IPRoyal, Hola, Honeygain, EarnApp, Peer2Profit, SOAX)vpn — fournisseurs VPN commerciaux (NordVPN, ExpressVPN, Surfshark, Mullvad, ProtonVPN, PIA, IPVanish, CyberGhost)datacenter — hébergeurs fréquemment utilisés pour les sorties de proxy commercial (AWS, DigitalOcean, OVH, Hetzner, etc.)tor — nœuds de sortie / relais Tormobile — pools de proxies opérateurs mobiles| Recommandation | Signification |
|---|---|
| no_proxy_detected | IP non correspondante dans aucun pool connu — traiter comme trafic normal. |
| treat_as_commercial_proxy | L'IP est dans un pool de proxies résidentiels — probablement malveillant sur les sites non-scraping. |
| treat_as_vpn | L'IP est dans une plage VPN commercial — appliquer la politique VPN. |
| treat_as_datacenter | L'IP provient d'une plage datacenter — pas un vrai utilisateur résidentiel. |
| block_or_challenge | Nœud de sortie Tor — bloquer ou exiger une authentification forte. |
Retourne les statistiques d'utilisation de la période de facturation en cours pour votre compte.
https://api.openipapi.com/v1/account/usage
{
"plan": "Pro",
"period_start": "2026-03-01",
"period_end": "2026-03-31",
"lookups_used": 184320,
"lookups_limit": 500000,
"lookups_remaining": 315680,
"reset_at": "2026-04-01T00:00:00Z"
}
Liste les bases de données MMDB disponibles pour votre plan. Remplaçants directs MaxMind .mmdb pour usage hors ligne / en périphérie — fonctionne avec n'importe quel lecteur MaxMind DB (PHP, Go, Python, Node.js, Rust, Java).
https://api.openipapi.com/v1/database/list
{
"plan": "Business",
"sources": [
{
"source": "country",
"filename": "geo-whois-asn-country.mmdb",
"size_bytes": 8225621,
"updated_at": "2026-04-18T02:00:00+00:00",
"etag": "\"fa2b851f9155838b\"",
"download_url": "https://api.openipapi.com/v1/database/download/country"
}
]
}
Télécharge le fichier MMDB brut en streaming. Supporte ETag +
If-None-Match pour les GET conditionnels (304 Not Modified si le fichier est inchangé). Limite de débit : 10 téléchargements par source par jour.
https://api.openipapi.com/v1/database/download/{source}
| Source | Contenu | Licence | Plan requis |
|---|---|---|---|
| country | Code pays + ASN | CC0 | Pro |
| asn | ASN + organisation | CC0 | Business |
| city-geolite2 | Ville, région, lat/lon, fuseau horaire (GeoLite2) | MaxMind GeoLite2 EULA | Business |
| city-dbip | Ville (alternative à GeoLite2) | DB-IP Lite | Enterprise |
# Download latest MMDB
$ curl -H "X-API-Key: YOUR_KEY" \
-o asn.mmdb \
https://api.openipapi.com/v1/database/download/asn
# Use with maxmind-db/reader
$ composer require maxmind-db/reader
<?php
use MaxMind\Db\Reader;
$reader = new Reader('asn.mmdb');
$record = $reader->get('8.8.8.8');
// ['autonomous_system_number' => 15169,
// 'autonomous_system_organization' => 'Google LLC']
Chaque réponse /v1/lookup inclut deux champs dans le bloc geo qui indiquent si le pays de l'IP est soumis à des sanctions internationales.
| Champ | Description |
|---|---|
| geo.is_sanctioned | true si le pays figure sur une liste de sanctions surveillée ; false sinon. |
| geo.sanction_lists | Tableau des identifiants de programmes de sanctions applicables : OFAC, EU, UN, UK. Tableau vide [] si pas de sanctions. |
Listes de sanctions couvertes : OFAC (États-Unis), UE, Conseil de sécurité de l'ONU, OFSI britannique. Les pays actuellement signalés incluent l'Iran, la Corée du Nord, la Russie, la Biélorussie, la Syrie, Cuba, le Venezuela, le Soudan, et d'autres. La liste est maintenue et mise à jour au fil des changements de programmes.
"geo": {
"country_code": "IR",
"country": "Iran",
...
"is_sanctioned": true,
"sanction_lists": ["OFAC", "EU", "UN"]
}
OpenIPApi effectue une vérification DNS inversé double pour identifier les robots légitimes. Le résultat est disponible dans threat.bot_type à chaque lookup.
| Champ | Valeurs |
|---|---|
| threat.bot_type |
null (pas un bot vérifié) ou l'une des valeurs suivantes : googlebot,
google_special_crawl,
bingbot,
applebot,
yandexbot,
duckduckbot,
facebookbot,
semrushbot,
ahrefsbot,
mj12bot
|
Méthode de vérification : (1) Lookup PTR sur l'IP → nom d'hôte. (2) Le nom d'hôte doit correspondre au modèle de domaine du bot (ex. *.googlebot.com). (3) Le DNS direct sur le nom d'hôte doit se résoudre à l'IP d'origine. Les résultats sont mis en cache pendant 24 heures.
"threat": {
"is_vpn": false,
"is_proxy": false,
"is_tor": false,
"threat_score": 0,
"bot_type": "googlebot"
}
Ajoutez un paramètre ?date=YYYY-MM-DD à n'importe quel lookup d'IP unique pour récupérer le snapshot à cette date.
https://api.openipapi.com/v1/lookup/{ip}?date=2026-01-15
$ curl "https://api.openipapi.com/v1/lookup/185.220.101.45?date=2026-01-15" \
-H "X-API-Key: oip_your_api_key_here"
{
"ip": "185.220.101.45",
"snapshot_date": "2026-01-15",
"is_historical": true,
"data": {
/* standard lookup response */
}
}
{
"error": "No historical snapshot available for this IP on 2026-01-15",
"code": "no_snapshot"
}
| Code | Statut HTTP | Description |
|---|---|---|
| invalid_api_key | 401 | La clé API est manquante, malformée ou a été révoquée. |
| limit_exceeded | 429 | Vous avez utilisé tous les lookups de votre période de facturation en cours. |
| plan_required | 403 | La fonctionnalité demandée n'est pas disponible dans votre plan actuel. |
| invalid_ip | 400 | L'adresse IP fournie n'est pas une adresse IPv4 ou IPv6 valide. |
| not_found | 404 | Aucune donnée trouvée pour la ressource demandée (ex. : ASN inconnu). |
| no_snapshot | 404 | Aucun snapshot historique n'existe pour cette IP à la date demandée. |
| date_out_of_range | 400 | La date de lookup historique est antérieure à 365 jours. |
| invalid_date | 400 | Le paramètre de date est manquant, malformé ou dans le futur. |
| plan_upgrade_required | 403 | La fonctionnalité demandée nécessite un plan de niveau supérieur. |
| rate_limited | 429 | Trop de requêtes dans un court laps de temps. Attendez et réessayez. |
| internal_error | 500 | Une erreur serveur inattendue s'est produite. Contactez le support si le problème persiste. |
En plus des quotas de lookups mensuels, les requêtes sont limitées par clé API via une fenêtre glissante. En cas de dépassement, l'API retourne HTTP 429 avec un en-tête Retry-After .
| Plan | Requêtes / minute | Lookups / mois |
|---|---|---|
| Free | 30 | 10,000 |
| Starter | 120 | 100,000 |
| Pro | 300 | 500,000 |
| Business | 600 | 2,000,000 |
| Enterprise | Custom | Unlimited |
Limites supplémentaires : /v1/validate (non authentifié) est limité à 60 req/min par IP appelante ; /v1/me à 30 req/min. Les téléchargements MMDB sont limités à 10/jour par source par compte. Les réponses de limitation de débit incluent Retry-After.
Les webhooks vous permettent de recevoir des notifications HTTP POST en temps réel lorsque le statut d'une IP surveillée change. Configurez-les dans la console → Webhooks, ou via l'interface du tableau de bord — aucun appel API requis.
| Événement | Déclenché quand |
|---|---|
| vpn_detected | Une IP surveillée est nouvellement détectée comme endpoint VPN. |
| tor_detected | Une IP surveillée apparaît sur une liste de nœuds de sortie Tor ou est sondée comme relais Tor. |
| proxy_detected | Une IP surveillée est détectée comme proxy ouvert ou SOCKS. |
| high_threat | Le score de menace dépasse votre seuil configuré (50–95). |
POST https://your-endpoint.example.com/webhook
Content-Type: application/json
User-Agent: OpenIPApi-Webhook/1.0
X-OpenIPApi-Event: high_threat
X-OpenIPApi-Signature: sha256=8c7f1a...b2e
{
"event": "high_threat",
"delivered_at": "2026-04-18T12:34:56Z",
"webhook_id": 142,
"data": {
"ip": "185.220.101.45",
"threat_score": 92,
"previous_score": 45,
"is_tor": true,
"is_vpn": true
}
}
Chaque webhook est signé via HMAC-SHA256 du corps JSON brut avec votre secret webhook. La signature est envoyée dans l'en-tête X-OpenIPApi-Signature sous la forme sha256=<hex>.
Vérifiez toujours avant d'agir sur le payload :
PHP
$body = file_get_contents('php://input');
$hdr = $_SERVER['HTTP_X_OPENIPAPI_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac(
'sha256', $body, $webhookSecret
);
if (!hash_equals($expected, $hdr)) {
http_response_code(401);
exit;
}
// Safe to process $body now
Node.js (Express)
const crypto = require('crypto');
app.post('/webhook',
express.raw({ type: 'application/json' }),
(req, res) => {
const hdr = req.headers['x-openipapi-signature'];
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(req.body).digest('hex');
if (expected !== hdr) return res.status(401).end();
// Process JSON.parse(req.body)
});
Votre endpoint doit répondre dans les 10 secondes avec HTTP 2xx pour accuser réception. Tout autre statut (ou délai dépassé) déclenche des relances avec recul exponentiel : 1 min, 5 min, 30 min, 2 h, 12 h. Après la dernière tentative, le webhook est marqué comme échoué et une alerte tableau de bord est levée.
La console → Webhooks conserve les 100 dernières tentatives de livraison par compte, affichant le type d'événement, le code de statut HTTP et le corps de réponse retourné par votre endpoint. Vous pouvez rejouer n'importe quelle livraison précédente pour renvoyer le payload signé original, et utiliser le Débogueur de signature pour vérifier les signatures HMAC-SHA256 côté client sans partager votre secret avec un serveur.
Les livraisons rejouées incluent un en-tête supplémentaire X-OpenIPApi-Replay: 1 pour que votre endpoint puisse les distinguer des événements en direct.
$ curl https://api.openipapi.com/v1/lookup/8.8.8.8 \
-H "X-API-Key: oip_your_api_key_here"
$ curl -X POST https://api.openipapi.com/v1/lookup/batch \
-H "X-API-Key: oip_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"ips": ["8.8.8.8", "1.1.1.1", "185.220.101.45"]}'
$ curl https://api.openipapi.com/v1/me \
-H "X-API-Key: oip_your_api_key_here"
const response = await fetch('https://api.openipapi.com/v1/lookup/8.8.8.8', {
headers: {
'X-API-Key': 'oip_your_api_key_here'
}
});
const data = await response.json();
console.log(data.geo.country); // "United States"
console.log(data.threat.is_vpn); // false
console.log(data.threat.threat_score); // 0
const response = await fetch('https://api.openipapi.com/v1/lookup/batch', {
method: 'POST',
headers: {
'X-API-Key': 'oip_your_api_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
ips: ['8.8.8.8', '1.1.1.1', '185.220.101.45']
})
});
const { results } = await response.json();
for (const info of results) {
console.log(info.ip, info.geo.city, info.threat.threat_score);
}
import requests
API_KEY = "oip_your_api_key_here"
headers = {"X-API-Key": API_KEY}
r = requests.get(
"https://api.openipapi.com/v1/lookup/8.8.8.8",
headers=headers
)
r.raise_for_status()
data = r.json()
print(data["geo"]["country"]) # United States
print(data["threat"]["is_vpn"]) # False
print(data["threat"]["threat_score"]) # 0
import requests
API_KEY = "oip_your_api_key_here"
headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
payload = {
"ips": ["8.8.8.8", "1.1.1.1", "185.220.101.45"]
}
r = requests.post(
"https://api.openipapi.com/v1/lookup/batch",
json=payload,
headers=headers
)
r.raise_for_status()
for info in r.json()["results"]:
print(info["ip"], info["geo"]["city"], info["threat"]["threat_score"])
10 000 lookups gratuits par mois. Aucune carte de crédit requise.
Obtenir votre clé API gratuite