API Documentation

VectraIP delivers real-time IP intelligence — VPN/proxy/Tor detection, geo enrichment, threat feeds, risk scoring, behavioral signals, and AI-assisted classification — through a single REST endpoint.

Base URL: https://api.vectraip.com

Quickstart

Three steps to your first enrichment result:

1. Create a free API key

curl
curl -X POST https://api.vectraip.com/v1/keys \
  -H "Content-Type: application/json" \
  -d '{"label":"My App","owner_email":"[email protected]"}'

Copy the key from the response — it is shown once only.

2. Look up an IP

curl
curl https://api.vectraip.com/v1/ip/45.130.202.105 \
  -H "X-API-Key: vip_live_YOUR_KEY"

3. Read the response

The response contains up to 12 top-level blocks. The most commonly used fields for a quick decision:

Key decision fields
{
  "privacy": { "is_vpn": true, "is_proxy": false, "is_tor": false },
  "risk":    { "score": 74, "level": "high", "fraud_probability": 70 },
  "threat":  { "is_threat": true, "threat_level": "high" },
  "classification": { "ip_type": "vpn", "confidence": "high" }
}

Authentication

Every request must include your API key in the X-API-Key request header.

Header
X-API-Key: vip_live_YOUR_KEY_HERE

Keys are prefixed with vip_live_ followed by 32 hex characters. Keys are stored as SHA-256 hashes — the raw key is shown once at creation and cannot be retrieved afterwards.

Tip: Store your key in an environment variable, never hard-code it in source files.

Errors

All errors return a JSON body with a detail field:

Error envelope
{
  "detail": "Invalid IP address: 999.999.999.999"
}
StatusMeaning
401Missing, invalid, or revoked API key
422Request body or path parameter failed validation (e.g. private IP address)
429Rate limit or monthly quota exceeded — back off and retry
500Internal server error — transient; safe to retry with exponential backoff

Rate Limits

Rate limits are enforced per API key using a sliding 60-second window. When exceeded the API returns HTTP 429.

PlanRequests / minuteMonthly quota
Free101,000
Developer6050,000
Business300500,000
Enterprise1,000Unlimited

Unauthenticated requests (no key) are allowed on non-production environments only, subject to strict IP-level throttling.

IP Validation

The following address ranges are rejected with 422 — they carry no meaningful intelligence:

RangeExampleReason
Private (RFC 1918)10.x.x.x, 192.168.x.x, 172.16–31.x.xInternal network addresses
Loopback127.0.0.1, ::1Local machine only
Link-local169.254.x.x, fe80::/10Not globally routable
Reserved / documentation0.0.0.0, 255.255.255.255Not valid host addresses

Both IPv4 and IPv6 public addresses are supported.

IP Lookup

GET /v1/ip/{ip}

Returns the full enriched intelligence response for a single public IP address. Results are cached for 3 hours — the query.cache_status field indicates whether the result came from cache, the database, or a live provider fetch.

Request
curl https://api.vectraip.com/v1/ip/45.130.202.105 \
  -H "X-API-Key: vip_live_YOUR_KEY"
Python (requests)
import requests

resp = requests.get(
    "https://api.vectraip.com/v1/ip/45.130.202.105",
    headers={"X-API-Key": "vip_live_YOUR_KEY"},
)
data = resp.json()
print(data["risk"]["level"])     # "high"
print(data["privacy"]["is_vpn"])  # True
JavaScript (fetch)
const resp = await fetch(
  "https://api.vectraip.com/v1/ip/45.130.202.105",
  { headers: { "X-API-Key": "vip_live_YOUR_KEY" } }
);
const data = await resp.json();
console.log(data.risk.level);       // "high"
console.log(data.privacy.is_vpn);   // true
Full response (200 OK)
{
  "query": {
    "ip": "45.130.202.105",
    "processed_at": "2026-06-17T09:00:00Z",
    "cache_status": "miss",
    "request_id": "req_a1b2c3d4e5f6a7b8"
  },
  "privacy": {
    "is_vpn": true,
    "is_proxy": false,
    "is_tor": false,
    "is_relay": false,
    "risk_score": 72
  },
  "geo": {
    "country_code": "TR",
    "country_name": "Turkey",
    "region": "Bursa",
    "city": "Bursa",
    "timezone": "Europe/Istanbul",
    "continent": "Asia",
    "coordinates": { "lat": 40.19, "lng": 29.06 }
  },
  "network": {
    "asn": "AS137409",
    "organization": "GSL Networks Pty LTD",
    "cidr": "45.130.202.0/23",
    "connection_type": "hosting",
    "usage_type": "hosting",
    "traffic_class": "vpn_exit"
  },
  "monitoring": {
    "detected": false,
    "provider": null,
    "category": null,
    "confidence": null
  },
  "risk": {
    "score": 74,
    "level": "high",
    "fraud_probability": 70,
    "bot_probability": 45,
    "abuse_probability": 60,
    "datacenter_risk": 80,
    "vpn_confidence": 88,
    "residential_trust": 10,
    "synthetic_traffic_probability": 5,
    "cloud_abuse_score": 62,
    "infrastructure_trust_score": 22
  },
  "reputation": {
    "reputation_score": 18,
    "status": "malicious",
    "confidence": "high",
    "abuse_score": 75,
    "total_requests": 412,
    "flags": ["vpn_exit", "high_velocity"]
  },
  "threat": {
    "is_threat": true,
    "threat_types": ["vpn_exit", "proxy"],
    "threat_level": "high",
    "sources": ["firehol_level1", "tor_exits"],
    "matched_entries": 2,
    "abuse_report_count": 3,
    "is_known_vpn_exit": true
  },
  "classification": {
    "ip_type": "vpn",
    "hosting_probability": 75,
    "residential_probability": 5,
    "vpn_probability": 90,
    "proxy_farm_probability": 10,
    "bot_probability": 20,
    "confidence": "high",
    "mobile_carrier": null,
    "suspicious_routing": false
  },
  "behavior": {
    "request_velocity": 14.2,
    "total_queries_24h": 341,
    "unique_callers": 7,
    "geo_anomaly": false,
    "suspicious_pattern": true,
    "asn_switch_detected": false,
    "asn_switch_count": 0,
    "velocity_flag": true,
    "high_demand": true,
    "cluster_threat_count": 4,
    "suspicious_cluster": true,
    "shared_hosting_abuse_count": 8,
    "shared_hosting_abuse": true
  },
  "ai_signals": {
    "fraud": { "probability": 0.6788, "confidence": 0.3577 },
    "infra_classification": { "predicted_type": "vpn", "confidence": 1.0 },
    "monitoring_prediction": null,
    "proxy_detection": null,
    "risk_anomaly": null,
    "model_versions": { "fraud_detection": "baseline-20260530", "infra_classification": "baseline-20260530" },
    "advisory_only": true
  },
  "meta": {
    "response_time_ms": 2285,
    "data_sources": ["vpnapi.io", "maxmind", "vectraip_internal", "vectraip_asn_intel"]
  }
}

Batch Lookup

POST /v1/batch/ip

Enrich up to 100 IP addresses in a single request. All IPs are processed concurrently. Duplicates are deduplicated automatically. Invalid IPs are reported in the errors array without failing the whole request.

Request
curl -X POST https://api.vectraip.com/v1/batch/ip \
  -H "X-API-Key: vip_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ips":["8.8.8.8","1.1.1.1","45.130.202.105"]}'
Python
resp = requests.post(
    "https://api.vectraip.com/v1/batch/ip",
    headers={"X-API-Key": "vip_live_YOUR_KEY"},
    json={"ips": ["8.8.8.8", "1.1.1.1", "45.130.202.105"]},
)
data = resp.json()
for result in data["results"]:
    print(result["query"]["ip"], result["risk"]["level"])
JavaScript
const resp = await fetch("https://api.vectraip.com/v1/batch/ip", {
  method: "POST",
  headers: {
    "X-API-Key": "vip_live_YOUR_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ ips: ["8.8.8.8", "1.1.1.1", "45.130.202.105"] }),
});
const { results } = await resp.json();
Response (200 OK)
{
  "results": [ /* array of full IPEnrichmentResponse objects */ ],
  "processed": 3,
  "errors": 0
}

Create API Key

POST /v1/keys
Request body
{
  "label":       "My App",          // required — human-readable name
  "owner_email": "[email protected]", // required
  "plan":        "free"            // optional — free | developer | business | enterprise
}
Response (201 Created)
{
  "key":                   "vip_live_…",  // shown once — store immediately
  "key_prefix":            "vip_live_ab12cd",
  "plan":                  "free",
  "monthly_quota":         1000,
  "rate_limit_per_minute": 10,
  "created_at":            "2026-06-17T09:00:00Z"
}

Rotate API Key

POST /v1/keys/{key_prefix}/rotate

Revokes the existing key and issues a new one with the same plan, label, and owner. Use key_prefix (e.g. vip_live_ab12cd). The new raw key is returned once.

Revoke API Key

DELETE /v1/keys/{key_prefix}

Permanently deactivates the key. All subsequent requests using the revoked key return 401. This action cannot be undone.

Key Usage

GET /v1/keys/{key_prefix}/usage

Returns quota, rate limit, request count, and last used timestamp for a key.

Response
{
  "plan":                  "developer",
  "monthly_quota":         50000,
  "requests_this_month":   1243,
  "rate_limit_per_minute": 60,
  "last_used_at":          "2026-06-17T08:55:00Z"
}

Full API Reference

The interactive reference covers all endpoints — including competitive intelligence, proxy detection, scoring, custom rules, webhooks, abuse reporting, and analytics — with live request/response schemas that always reflect the current API.

Open Interactive API Reference →  All endpoints, all fields, always up to date.