API Documentation
IPTrace's public REST API: IP geolocation and risk, BGP / ASN topology, Whois, DNS, TCP probing and MMDB dataset downloads. Every endpoint lives under https://iptrace.net and answers with UTF-8 JSON.
Contents
Overview
Authentication
| Method | Example | Description |
|---|---|---|
| Authorization | Authorization: Bearer YOUR_API_KEY |
Recommended. A header never leaks into access logs or Referer. |
| ?token= | ?token=YOUR_API_KEY |
Deprecated, kept only for legacy clients: the key ends up in server logs and browser history — move to the header. |
| Anonymous | — | Endpoints marked "API key optional" work without one, metered per source IP: 30/minute, 1000/day, batch size 5, and no credits are charged. |
Note: the CORS preflight advertises X-API-Key, but the server does not currently read that header — use one of the two methods above.
Rate Limits
| Plan | Requests / min | Requests / day | Batch Limit | Monthly Credits | Monthly Price |
|---|---|---|---|---|---|
| Anonymous | 30 | 1000 | 5 | — | — |
| 免费版 (free) | 120 | 10,000 | 10 | 1,000 | Free |
| 专业版 (pro) | 600 | 100,000 | 100 | 50,000 | $9.99 |
| 企业版 (enterprise) | 3,000 | Unlimited | 500 | 500,000 | $49.99 |
Every response carries X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset (Reset is a Unix timestamp). Over the limit you get HTTP 429: the per-minute and dataset limits add Retry-After in seconds, but the exhausted daily quota does not — wait until 00:00 server time. Failed calls consume neither daily quota nor credits.
Credit Costs
Authenticated calls spend credits as listed below; anonymous calls spend none (but are capped by the anonymous quota). Running out gives HTTP 402.
| Endpoint | Credits |
|---|---|
| /api/ip/{target} | 1 |
| /api/ip/{target}/sources | 2 |
| /api/ip/batch | 5 |
| /api/whois/{target} | 1 |
| /api/dns/{domain} | 1 |
| /api/dns/{domain}/{type} | 1 |
| /api/tcping/{target} | 1 × count (count defaults to 4, clamped to 1–10). Node-relayed probes (country/node) always run 4 attempts and are billed as 4 credits. |
| /api/user/me | — |
| /api/user/usage | — |
| /api/datasets/{dataset} | No credits, but metered per dataset at 5/hour and 30/day — an aborted download still counts. |
Error Codes
Business errors live in the body as code / msg while the HTTP status usually stays 200; only infrastructure-level failures (401 / 402 / 429) change the status. Always test for code === 0.
| HTTP Status | code | Description |
|---|---|---|
| 200 | 0 | Success |
| 200 | 400 | Bad request: invalid target, missing parameter, batch over batch_limit, … |
| 200 | 401 | Unauthenticated: this endpoint requires a valid API key (the HTTP status is still 200 — the error is in the body's code) |
| 200 | 403 | Forbidden: plan too low (dataset download) or private/reserved target (tcping) |
| 200 | 404 | Target not found or could not be resolved |
| 402 | 402 | Not enough credits; credits_required in the body says how many this call needs |
| 429 | 429 | Rate limited (per-minute, per-day or dataset quota). The per-minute and dataset limits send Retry-After; the daily quota does not — wait until 00:00 server time |
| 504 | 504 | The probe node did not answer in time (node-relayed probes only) |
Keyless endpoints
These three endpoints describe the caller's own egress IP. No API key, 60 requests/minute per source IP, CORS enabled (Access-Control-Allow-Origin: *), so they work straight from a browser or a shell.
Full lookup of your own IP
Same envelope and fields as GET /api/ip/{target} ({code, data}), with the caller's egress IP as the target.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| lang | query | string | — | zh or en — language of country / region / ISP names, default zh |
Example Request
curl 'https://iptrace.net/api/ip?lang=en'
Example Response
{
"code": 0,
"data": {
"ip": "1.1.1.1",
"version": 4,
"country": "Australia",
"country_code": "AU",
"region": "New South Wales",
"city": "Sydney",
"latitude": -33.8688,
"longitude": 151.209,
"timezone": "Australia/Brisbane",
"asn": 13335,
"org": "CloudFlare Inc",
"isp": "APNIC and CloudFlare DNS Resolver Project",
"ip_type": "",
"rdns": "",
"as_domain": "cloudflare.com",
"continent": "",
"continent_code": "",
"bgp": {
"prefix": "1.1.1.0/24",
"as": 13335,
"as_name": "CLOUDFLARENET",
"as_cc": "US",
"allocation": "1.1.1.0/24",
"allocation_cc": "AU",
"rpki_status": "valid",
"peers": [],
"ix": []
},
"is_proxy": false,
"proxy_type": "",
"usage_type": "",
"proxy_domain": "",
"proxy_isp": "",
"threat": "",
"fraud_score": "",
"last_seen": "",
"provider": "",
"location": "Australia New South Wales Sydney APNIC and CloudFlare DNS Resolver Project",
"is_cloud_idc": true,
"cloud_provider": "Cloud/IDC"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| code | integer | 0 means success; anything else is a business error code |
| data.ip | string | The IP that was looked up |
| data.version | integer | 4 or 6 |
| data.country | string | Country name (localized by lang) |
| data.country_code | string | ISO 3166-1 alpha-2 |
| data.region | string | Region / state |
| data.city | string | City |
| data.latitude / longitude | number|null | Latitude / longitude |
| data.timezone | string | IANA time zone |
| data.asn | integer|null | Autonomous system number |
| data.org | string | Registered organisation of the ASN |
| data.isp | string | ISP name |
| data.as_domain | string | Primary domain of the AS |
| data.continent / continent_code | string | Continent |
| data.ip_type | string | Usage label — filled only when the IP is flagged as a proxy |
| data.rdns | string | Reverse DNS; always empty here because it is slow — use /api/rdns |
| data.location | string | Pre-formatted location string, ready to display |
| data.is_reserved | boolean | true for reserved / special-use ranges; the other fields are then empty |
| data.bgp.prefix | string|null | BGP prefix announcing this IP |
| data.bgp.as | integer|null | Origin AS |
| data.bgp.as_name | string|null | Origin AS name |
| data.bgp.as_cc | string|null | Origin AS registration country |
| data.bgp.allocation | string|null | Parent block allocated by the RIR |
| data.bgp.allocation_cc | string|null | Country the parent block is registered in |
| data.bgp.rpki_status | string|null | RPKI validation: valid / invalid / unknown |
| data.bgp.peers | array | Peer AS list |
| data.bgp.ix | array | Internet exchanges |
| data.bgp.line | string | Recognized carrier line (e.g. CN2 GIA); key absent when unknown |
| data.is_proxy | boolean | Whether the IP is in the proxy / VPN database |
| data.proxy_type | string | Proxy type: VPN / TOR / DCH / PUB / WEB / SES … |
| data.usage_type | string | Usage class: COM / ORG / ISP / MOB / DCH … |
| data.proxy_domain | string | Domain of the proxy service |
| data.proxy_isp | string | ISP of the proxy service |
| data.threat | string | Threat label |
| data.fraud_score | string | Fraud score |
| data.last_seen | string | Last time the proxy database saw this IP |
| data.provider | string | Proxy service provider |
| data.is_cloud_idc | boolean | Whether the IP belongs to a cloud provider or IDC |
| data.cloud_provider | string | Cloud provider name |
Flat geo payload for your own IP
Flat object with no {code,data} envelope — convenient for shell scripts. Equivalent to GET /?format=json.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| lang | query | string | — | zh or en — language of country / region / ISP names, default zh |
Example Request
curl 'https://iptrace.net/json'
Example Response
{
"ip": "203.0.113.45",
"country": "美国",
"country_code": "US",
"region": "California",
"city": "San Francisco",
"isp": "Cloudflare",
"asn": 13335,
"org": "CloudFlare Inc",
"latitude": 37.7749,
"longitude": -122.4194,
"timezone": "America/Los_Angeles"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| ip | string | Egress IP address |
| country | string | Country name (localized by lang) |
| country_code | string | ISO 3166-1 alpha-2 country code |
| region | string | Region / state |
| city | string | City |
| isp | string | ISP name |
| asn | integer|null | Autonomous system number |
| org | string | Registered organisation of the ASN |
| latitude | number|null | Latitude |
| longitude | number|null | Longitude |
| timezone | string | IANA time zone |
Your IP as plain text
text/plain, a single IP plus a newline — made for $(curl -s https://iptrace.net/ip).
Example Request
curl -s 'https://iptrace.net/ip'
Example Response
203.0.113.45
IP lookup
Merges eight geolocation databases with the IPNetDB BGP table plus proxy / cloud detection. Callable anonymously (anonymous quota, no credits charged); with an API key it uses your plan quota and spends credits.
Look up one IP or hostname
target may be an IPv4 address, an IPv6 address or a hostname; hostnames are resolved to an IP first.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| target | path | string | Required | IPv4 / IPv6 / hostname, e.g. 1.1.1.1, 2606:4700::1111, example.com |
| lang | query | string | — | zh or en — language of country / region / ISP names, default zh |
Example Request
curl -H 'Authorization: Bearer YOUR_API_KEY' \
'https://iptrace.net/api/ip/1.1.1.1?lang=en'
Example Response
{
"code": 0,
"data": {
"ip": "1.1.1.1",
"version": 4,
"country": "Australia",
"country_code": "AU",
"region": "New South Wales",
"city": "Sydney",
"latitude": -33.8688,
"longitude": 151.209,
"timezone": "Australia/Brisbane",
"asn": 13335,
"org": "CloudFlare Inc",
"isp": "APNIC and CloudFlare DNS Resolver Project",
"ip_type": "",
"rdns": "",
"as_domain": "cloudflare.com",
"continent": "",
"continent_code": "",
"bgp": {
"prefix": "1.1.1.0/24",
"as": 13335,
"as_name": "CLOUDFLARENET",
"as_cc": "US",
"allocation": "1.1.1.0/24",
"allocation_cc": "AU",
"rpki_status": "valid",
"peers": [],
"ix": []
},
"is_proxy": false,
"proxy_type": "",
"usage_type": "",
"proxy_domain": "",
"proxy_isp": "",
"threat": "",
"fraud_score": "",
"last_seen": "",
"provider": "",
"location": "Australia New South Wales Sydney APNIC and CloudFlare DNS Resolver Project",
"is_cloud_idc": true,
"cloud_provider": "Cloud/IDC"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| code | integer | 0 means success; anything else is a business error code |
| data.ip | string | The IP that was looked up |
| data.version | integer | 4 or 6 |
| data.country | string | Country name (localized by lang) |
| data.country_code | string | ISO 3166-1 alpha-2 |
| data.region | string | Region / state |
| data.city | string | City |
| data.latitude / longitude | number|null | Latitude / longitude |
| data.timezone | string | IANA time zone |
| data.asn | integer|null | Autonomous system number |
| data.org | string | Registered organisation of the ASN |
| data.isp | string | ISP name |
| data.as_domain | string | Primary domain of the AS |
| data.continent / continent_code | string | Continent |
| data.ip_type | string | Usage label — filled only when the IP is flagged as a proxy |
| data.rdns | string | Reverse DNS; always empty here because it is slow — use /api/rdns |
| data.location | string | Pre-formatted location string, ready to display |
| data.is_reserved | boolean | true for reserved / special-use ranges; the other fields are then empty |
| data.bgp.prefix | string|null | BGP prefix announcing this IP |
| data.bgp.as | integer|null | Origin AS |
| data.bgp.as_name | string|null | Origin AS name |
| data.bgp.as_cc | string|null | Origin AS registration country |
| data.bgp.allocation | string|null | Parent block allocated by the RIR |
| data.bgp.allocation_cc | string|null | Country the parent block is registered in |
| data.bgp.rpki_status | string|null | RPKI validation: valid / invalid / unknown |
| data.bgp.peers | array | Peer AS list |
| data.bgp.ix | array | Internet exchanges |
| data.bgp.line | string | Recognized carrier line (e.g. CN2 GIA); key absent when unknown |
| data.is_proxy | boolean | Whether the IP is in the proxy / VPN database |
| data.proxy_type | string | Proxy type: VPN / TOR / DCH / PUB / WEB / SES … |
| data.usage_type | string | Usage class: COM / ORG / ISP / MOB / DCH … |
| data.proxy_domain | string | Domain of the proxy service |
| data.proxy_isp | string | ISP of the proxy service |
| data.threat | string | Threat label |
| data.fraud_score | string | Fraud score |
| data.last_seen | string | Last time the proxy database saw this IP |
| data.provider | string | Proxy service provider |
| data.is_cloud_idc | boolean | Whether the IP belongs to a cloud provider or IDC |
| data.cloud_provider | string | Cloud provider name |
Multi-source comparison
Returns each geolocation database's own verdict for the IP without merging, so you can compare them side by side.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| target | path | string | Required | IPv4 / IPv6 / hostname |
Example Request
curl -H 'Authorization: Bearer YOUR_API_KEY' \
'https://iptrace.net/api/ip/1.1.1.1/sources'
Example Response
{
"code": 0,
"data": {
"ip": "1.1.1.1",
"sources": [
{"source": "IPTrace", "country": "Australia", "region": "", "city": "", "lat": null, "lng": null, "isp": "APNIC and CloudFlare DNS Resolver Project"},
{"source": "MaxMind", "country": "Australia", "region": "", "city": "", "lat": null, "lng": null, "isp": ""},
{"source": "DB-IP", "country": "Australia", "region": "New South Wales", "city": "Sydney", "lat": -33.8688, "lng": 151.209, "isp": ""},
{"source": "IP2Location", "country": "Australia", "region": "Queensland", "city": "Brisbane", "lat": -27.467541, "lng": 153.028091, "isp": "APNIC and CloudFlare DNS Resolver Project"},
{"source": "IPinfo", "country": "Australia", "region": "", "city": "", "lat": null, "lng": null, "isp": "Cloudflare, Inc. (cloudflare.com)"}
]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.ip | string | Resolved IP address |
| data.sources[].source | string | Database name (IPTrace / MaxMind / DB-IP / IP2Location / CZ88 / IPIP / Ip2region / IPinfo) |
| data.sources[].country | string | Country according to that database |
| data.sources[].region | string | Region according to that database |
| data.sources[].city | string | City according to that database |
| data.sources[].lat | number|null | Latitude |
| data.sources[].lng | number|null | Longitude |
| data.sources[].isp | string | ISP according to that database |
Batch IP lookup
Up to batch_limit targets per call (5 anonymously, see the plan table otherwise). The whole batch is billed once. An invalid target yields an error field on that entry only.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| ips | body | string[] | Required | JSON body: {"ips":["1.1.1.1","example.com"]} |
Example Request
curl -X POST 'https://iptrace.net/api/ip/batch' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"ips":["1.1.1.1","192.0.2.999"]}'
Example Response
{
"code": 0,
"data": [
{
"ip": "1.1.1.1",
"version": 4,
"country": "澳大利亚",
"country_code": "AU",
"city": "Brisbane",
"asn": 13335,
"isp": "Cloudflare",
"bgp": {"prefix": "1.1.1.0/24", "as": 13335, "as_name": "CLOUDFLARENET", "rpki_status": "valid"},
"is_proxy": false,
"is_cloud_idc": true,
"cloud_provider": "Cloud/IDC",
"location": "澳大利亚 Queensland Brisbane Cloudflare"
},
{"ip": "192.0.2.999", "error": "无效的IP地址或域名"}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data[] | object | One entry per target; same fields as data in /api/ip/{target} |
| data[].error | string | Present on failed entries only: invalid target, or resolution failed |
The successful entry above is abridged; the real response carries the full field set of /api/ip/{target}.
Whois & DNS
Registration data for domains, IP ranges and ASNs, plus authoritative DNS records.
Whois / RDAP lookup
target accepts a domain, an IP, a CIDR prefix or ASxxxx. RDAP first, falling back to classic whois.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| target | path | string | Required | Domain / IP / CIDR / ASxxxx, e.g. cloudflare.com, 1.1.1.1, AS13335 |
Example Request
curl -H 'Authorization: Bearer YOUR_API_KEY' \
'https://iptrace.net/api/whois/cloudflare.com'
Example Response
{
"code": 0,
"data": {
"target": "cloudflare.com",
"raw": "Domain Name: CLOUDFLARE.COM\nRegistry Domain ID: 1542998887_DOMAIN_COM-VRSN\nRegistrar WHOIS Server: whois.cloudflare.com\n...",
"registrar": "Cloudflare, Inc.",
"creation_date": "2009-02-17T22:07:54Z",
"expiry_date": "2033-02-17T22:07:54Z",
"updated_date": "2024-01-15T01:58:26Z",
"nameservers": ["ns3.cloudflare.com", "ns4.cloudflare.com", "ns5.cloudflare.com"],
"status": ["clientdeleteprohibited", "clienttransferprohibited"],
"registrant": "DATA REDACTED",
"dnssec": "signedDelegation",
"is_asn": false,
"available": false
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.target | string | Echo of the query target |
| data.raw | string | Raw whois / RDAP text |
| data.registrar | string | Registrar |
| data.creation_date | string | Creation date (ISO 8601) |
| data.expiry_date | string | Expiry date (ISO 8601) |
| data.updated_date | string | Last updated date |
| data.nameservers | string[] | Name servers |
| data.status | string[] | EPP status codes |
| data.registrant | string | Registrant (usually redacted) |
| data.dnssec | string | DNSSEC status |
| data.is_asn | boolean | Whether the target is an ASN |
| data.available | boolean | Whether the domain is unregistered |
All DNS records
Returns every resolvable record at once: A / AAAA / NS / MX / TXT / SOA / CNAME …
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| domain | path | string | Required | Domain name; only a-z A-Z 0-9 . - are accepted |
Example Request
curl -H 'Authorization: Bearer YOUR_API_KEY' \
'https://iptrace.net/api/dns/example.com'
Example Response
{
"code": 0,
"data": {
"domain": "example.com",
"records": [
{"type": "A", "name": "example.com", "ttl": 8, "value": "104.20.23.154"},
{"type": "AAAA", "name": "example.com", "ttl": 68, "value": "2606:4700:10::ac42:93f3"},
{"type": "NS", "name": "example.com", "ttl": 55249, "value": "hera.ns.cloudflare.com"},
{"type": "TXT", "name": "example.com", "ttl": 157, "value": "v=spf1 -all"},
{"type": "SOA", "name": "example.com", "ttl": 1784, "value": "elliott.ns.cloudflare.com dns.cloudflare.com", "serial": 2413856909, "refresh": 10000, "retry": 2400, "expire": 604800, "minimum_ttl": 1800}
]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.domain | string | Echo of the domain |
| data.records[].type | string | Record type |
| data.records[].name | string | Record name |
| data.records[].ttl | integer | TTL in seconds |
| data.records[].value | string | Record value |
| data.records[].priority | integer | MX / SRV only |
| data.records[].serial|refresh|retry|expire|minimum_ttl | integer | SOA only |
DNS records of one type
Supported types: A, AAAA, CNAME, MX, NS, TXT, SOA, SRV, PTR (case-insensitive). An unsupported type returns code 400.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| domain | path | string | Required | Domain name |
| type | path | string | Required | A / AAAA / CNAME / MX / NS / TXT / SOA / SRV / PTR |
Example Request
curl -H 'Authorization: Bearer YOUR_API_KEY' \
'https://iptrace.net/api/dns/google.com/MX'
Example Response
{
"code": 0,
"data": {
"records": [
{"type": "MX", "name": "google.com", "ttl": 176, "value": "smtp.google.com", "priority": 10}
],
"query": "google.com",
"type": "MX",
"server": ""
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.records[] | object | Record array with the fields above; empty when nothing resolves |
| data.query | string | Echo of the domain |
| data.type | string | Echo of the record type |
| data.server | string | Resolver used (empty = system resolver) |
Network probing
Active probes from our origin server or from a global probe node. An API key is required.
TCP port reachability and latency
Synchronous, at most 10 attempts spaced 100 ms apart. target may be host, host:port or [ipv6]:port; ?port= works too. Private and reserved ranges are refused with code 403.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| target | path | string | Required | host, host:port or [ipv6]:port |
| port | query | integer | — | Port 1–65535, used when target carries none; defaults to 80 |
| count | query | integer | — | Number of attempts, 1–10, default 4 |
| timeout | query | integer | — | Per-attempt timeout in ms, 100–5000, default 3000 |
| country | query | string | — | ISO 3166-1 alpha-2 — probe from a node in that country |
| node | query | string | — | Exact node code; takes precedence over country |
Example Request
curl -H 'Authorization: Bearer YOUR_API_KEY' \
'https://iptrace.net/api/tcping/1.1.1.1:443?count=4'
Example Response
{
"code": 0,
"data": {
"target": "1.1.1.1:443",
"host": "1.1.1.1",
"ip": "1.1.1.1",
"port": 443,
"sent": 4,
"recv": 4,
"loss": 0,
"min": 1.412,
"max": 2.038,
"avg": 1.664,
"rtts": [2.038, 1.55, 1.412, 1.656],
"timeout_ms": 3000,
"source": {"type": "origin"}
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.target | string | Echo of the raw target |
| data.host | string | Host part parsed out of the target |
| data.ip | string | IP actually probed |
| data.port | integer | Port actually probed |
| data.sent | integer | Attempts sent |
| data.recv | integer | Successful connects |
| data.loss | number | Failure rate (%) |
| data.min|max|avg | number|null | Min / max / average RTT in ms |
| data.rtts | array | Per-attempt RTT; null for a failed attempt |
| data.timeout_ms | integer | Timeout used (origin probes only) |
| data.source.type | string | origin (our server) or node (probe node) |
| data.source.code|name|country_code|city | string | Node identity when source.type is node |
With country or node set: code 404 plus an available_countries list when no node is online there, and code 504 when the node does not answer within 14 seconds.
BGP & ASN data
No API key, no credits — only a per-source-IP limit of 60 requests/minute. All of them send CORS headers except /api/rdns.
AS profile
Registry data for the AS plus every prefix it originates. Returns code 404 for an unknown ASN.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| asn | path | integer | Required | Autonomous system number, digits only (no AS prefix) |
Example Request
curl 'https://iptrace.net/api/as-profile/13335'
Example Response
{
"code": 0,
"data": {
"asn": 13335,
"name": "CLOUDFLARENET",
"entity": "Cloudflare, Inc.",
"cc": "US",
"registry": "arin",
"status": "assigned",
"in_use": true,
"private": false,
"ipv4_prefix_count": 2367,
"ipv6_prefix_count": 2898,
"ipv4_prefixes": ["1.1.1.0/24", "104.16.0.0/13", "162.158.0.0/15"],
"ipv6_prefixes": ["2606:4700::/32", "2a06:98c0::/29"]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.asn | integer | Autonomous system number |
| data.name | string | AS name |
| data.entity | string | Registered entity |
| data.cc | string | Registration country code |
| data.registry | string | RIR (arin / ripe / apnic / lacnic / afrinic) |
| data.status | string | Allocation status |
| data.in_use | boolean | Whether it currently originates prefixes |
| data.private | boolean | Whether it is a private ASN |
| data.ipv4_prefix_count | integer | Number of IPv4 prefixes |
| data.ipv6_prefix_count | integer | Number of IPv6 prefixes |
| data.ipv4_prefixes | string[] | IPv4 prefix list |
| data.ipv6_prefixes | string[] | IPv6 prefix list |
AS topology
Upstream / downstream / peer ASes ranked by observation strength (power). Returns code 404 when no topology data exists.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| asn | path | integer | Required | Autonomous system number |
Example Request
curl 'https://iptrace.net/api/as-topo/13335'
Example Response
{
"code": 0,
"data": {
"asn": 13335,
"upstreams": [
{"asn": 1299, "power": 8260, "name": "Arelion (Twelve99)"},
{"asn": 3257, "power": 5773, "name": "GTT Communications (AS3257)"},
{"asn": 3356, "power": 5473, "name": "Lumen AS3356"}
],
"downstreams": [],
"peers": []
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.asn | integer | The ASN queried |
| data.upstreams[] | object | Upstream ASes: {asn, power, name} |
| data.downstreams[] | object | Downstream ASes: {asn, power, name} |
| data.peers[] | object | Peer ASes: {asn, power, name} |
Prefix-level upstreams
Upstreams observed for one specific prefix rather than the whole AS; count is how many paths showed that upstream.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| prefix | query | string | Required | CIDR prefix, e.g. 1.1.1.0/24 |
Example Request
curl 'https://iptrace.net/api/prefix-upstreams?prefix=1.1.1.0/24'
Example Response
{
"code": 0,
"data": {
"prefix": "1.1.1.0/24",
"origin_as": 13335,
"upstreams": [
{"asn": 24482, "count": 11},
{"asn": 199524, "count": 8},
{"asn": 1299, "count": 7}
]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.prefix | string | Echo of the prefix |
| data.origin_as | integer | Origin AS |
| data.upstreams[].asn | integer | Upstream ASN |
| data.upstreams[].count | integer | Number of observed paths |
PeeringDB search
Searches the local PeeringDB index for networks and facilities, capped at 20 hits. A query shorter than 2 characters returns code 400.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| q | query | string | Required | Query: ASN, network name or facility name; at least 2 characters |
Example Request
curl 'https://iptrace.net/api/peeringdb/search?q=cloudflare'
Example Response
{
"code": 0,
"data": {
"nets": [
{"asn": 13335, "name": "Cloudflare", "aka": "", "info_type": "Content"},
{"asn": 209242, "name": "Cloudflare London", "aka": "", "info_type": ""}
],
"facs": []
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.nets[] | object | Networks: {asn, name, aka, info_type} |
| data.facs[] | object | Facilities: {id, name, city, country} |
Batch reverse DNS (PTR)
Up to 40 public IPs per call. To keep blocking resolution off the worker, at most 6 uncached lookups run per call under a 3-second budget; the rest come back in pending for a follow-up call (by then usually cached). Private and reserved addresses are dropped.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| ips | query | string | Required | Comma-separated IP list, at most 40 |
Example Request
curl 'https://iptrace.net/api/rdns?ips=1.1.1.1,8.8.8.8'
Example Response
{
"resolved": {"1.1.1.1": "one.one.one.one", "8.8.8.8": "dns.google"},
"pending": []
}
Response Fields
| Field | Type | Description |
|---|---|---|
| resolved | object | IP → PTR hostname; an empty string means "confirmed no PTR", do not ask again |
| pending | string[] | IPs not resolved this round; ask again shortly |
This endpoint carries no CORS headers, so cross-site fetch from a browser is blocked (server-side calls are fine). Its body has no {code} envelope either.
Online probe nodes
Lists currently online probe nodes; use the code field as the node parameter of /api/tcping.
Example Request
curl 'https://iptrace.net/api/nodes'
Example Response
{
"code": 0,
"data": [
{
"id": 30,
"name": "示例节点",
"name_en": "Sample Node",
"code": "sample-node-01",
"isp": "ct",
"region": "华中",
"country": "中国",
"country_code": "CN",
"province": "湖北",
"city": "襄阳市",
"ipv6": 0,
"agent_version": "1.0.2",
"status": 1,
"last_seen": "2026-09-11 02:55:43"
}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data[].code | string | Node identifier, used as /api/tcping?node= |
| data[].name / name_en | string | Node name (Chinese / English) |
| data[].country / country_code / province / city | string | Node location |
| data[].isp | string | ISP code |
| data[].ipv6 | integer | Whether IPv6 probing is supported (1/0) |
| data[].status | integer | 1 = online |
| data[].last_seen | string | Last heartbeat time |
Global DNS (DoH)
DoH queries carrying an EDNS Client Subnet, so you can see how one domain resolves from different regions. No key, 120 requests/minute per source IP.
Available regions
Returns the regions accepted by the region parameter as a bare array (no {code} envelope).
Example Request
curl 'https://iptrace.net/dns_global/api/regions'
Example Response
[
{"code": 0, "label": "中国 - 电信", "flag": "cn", "subnet": "218.30.118.0/24"},
{"code": 1, "label": "中国 - 联通", "flag": "cn", "subnet": "221.12.1.0/24"},
{"code": 3, "label": "中国 - 香港", "flag": "hk", "subnet": "203.218.0.0/24"}
]
Response Fields
| Field | Type | Description |
|---|---|---|
| [].code | integer | Value to pass as region |
| [].label | string | Region label (localized) |
| [].flag | string | Country code for the flag |
| [].subnet | string | EDNS Client Subnet actually sent |
Query DNS from a region
A and AAAA answers are enriched with geolocation for each IP. The body is a bare object with no {code} envelope; failures carry an error field.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| domain | query | string | Required | Domain name |
| type | query | string | — | Record type, default A; an unknown type falls back to A |
| provider | query | integer | — | Resolver index 0–13: 0=google 1=cloudflare 2=alidns 3=dnspod 4=adguard 5=nextdns 6=dns.sb 7=360 8=wikimedia 9=iij 10=cleanbrowsing 11=controld 12=surfshark 13=stormycloud; default 0 |
| region | query | integer | — | Region index from /dns_global/api/regions |
Example Request
curl 'https://iptrace.net/dns_global/api/query?domain=example.com&type=A&provider=1®ion=0'
Example Response
{
"records": [
{"name": "example.com", "type": "A", "ttl": 36, "value": "104.20.23.154", "geo": "美国 California San Francisco Cloudflare", "isp": "Cloudflare", "asn": 13335, "org": "CloudFlare Inc"}
],
"rcode": "NOERROR",
"time_ms": 1,
"resolver": "cloudflare",
"edns_client_subnet": "218.30.118.0/24",
"colo": "CDG",
"country": "FR",
"location": "Lauterbourg, Grand Est, FR",
"source": "worker",
"region": 0,
"regionLabel": "中国 - 电信",
"subnet": "218.30.118.0/24"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| records[] | object | {name, type, ttl, value}; A and AAAA also carry geo / isp / asn / org |
| rcode | string | DNS response code, e.g. NOERROR / NXDOMAIN |
| time_ms | integer | Resolution time in ms |
| resolver | string | Resolver actually used |
| edns_client_subnet | string | ECS that was sent |
| colo / country / location | string | Resolver PoP information (present on the worker path) |
| source | string | worker or doh — which path answered |
| region / regionLabel / subnet | mixed | Echo of the requested region |
| error | string | Present only on failure |
Account
Inspect your own plan and usage. An API key is required, and these calls count against your rate limit like any other.
Current account
Returns the account behind the API key and the limits currently in effect.
Example Request
curl -H 'Authorization: Bearer YOUR_API_KEY' \
'https://iptrace.net/api/user/me'
Example Response
{
"code": 0,
"data": {
"id": 1024,
"email": "[email protected]",
"nickname": "example",
"plan": "专业版",
"rate_limit": 600,
"daily_limit": 100000,
"batch_limit": 100
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.id | integer | User ID |
| data.email | string | Email address |
| data.nickname | string | Nickname |
| data.plan | string | Plan name |
| data.rate_limit | integer | Requests per minute |
| data.daily_limit | integer | Requests per day, 0 = unlimited |
| data.batch_limit | integer | Targets per batch call |
Usage statistics
Today's call count, the 30-day total and a per-day breakdown (daily always has 30 entries; days with no calls are zero-filled).
Example Request
curl -H 'Authorization: Bearer YOUR_API_KEY' \
'https://iptrace.net/api/user/usage'
Example Response
{
"code": 0,
"data": {
"today": 128,
"month_total": 4213,
"daily_limit": 100000,
"daily": [
{"date": "2026-08-13", "count": 96},
{"date": "2026-08-14", "count": 210},
{"date": "2026-09-11", "count": 128}
]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.today | integer | Successful calls today |
| data.month_total | integer | Total over the last 30 days |
| data.daily_limit | integer | Daily cap, 0 = unlimited |
| data.daily[] | object | {date, count} — 30 entries in ascending date order |
Only successful calls are counted: a request ApiAuth judges failed (HTTP ≥ 400, or code ≠ 0 in the JSON body) is neither counted nor billed, and its daily-quota slot is released.
Dataset downloads
Three MMDB database files. The /info endpoints are free and keyless; the downloads themselves are enterprise-only and metered per dataset at 5 per hour and 30 per day. Downloads cost no credits.
Dataset metadata
dataset is one of mmdb (geolocation, ~120 MB), asn (~10 MB) or isp (~140 MB). Compare sha256 before re-downloading — it saves a whole day of quota.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| dataset | path | string | Required | mmdb / asn / isp |
Example Request
curl 'https://iptrace.net/api/datasets/mmdb/info'
Example Response
{
"code": 0,
"data": {
"filename": "merged_geoip2_ccpa.mmdb",
"format": "mmdb",
"size": 126352313,
"mtime": 1778358197,
"mtime_iso": "2026-05-09T20:23:17Z",
"sha256": "fa22f93e2ce790b5da8a626c7fd3ac0c45c064a7da73b22b1a1e1018195a89ab",
"build_epoch": 1778357692,
"build_iso": "2026-05-09T20:14:52Z",
"node_count": 11780233,
"ip_version": 6,
"languages": ["de", "en", "es", "fr", "ja", "pt-BR", "ru", "zh-CN"]
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| data.filename | string | File name |
| data.format | string | Always mmdb |
| data.size | integer | Size in bytes |
| data.mtime / mtime_iso | mixed | File modification time |
| data.sha256 | string | SHA-256 of the file |
| data.build_epoch / build_iso | mixed | MMDB build time |
| data.node_count | integer | MMDB node count |
| data.ip_version | integer | 4 or 6 |
| data.languages | string[] | Languages present in the database |
Download a dataset (enterprise)
On success the body is the raw file (application/octet-stream), not JSON. Non-enterprise plans get code 403; exceeding the meter gives HTTP 429.
Request Parameters
| Parameters | Location | Type | Required | Description |
|---|---|---|---|---|
| dataset | path | string | Required | mmdb / asn / isp |
Example Request
curl -H 'Authorization: Bearer YOUR_API_KEY' \
-o merged_geoip2_ccpa.mmdb \
'https://iptrace.net/api/datasets/mmdb'
Example Response
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="merged_geoip2_ccpa.mmdb"
X-Dataset-Hourly-Limit: 5
X-Dataset-Hourly-Used: 1
X-Dataset-Daily-Limit: 30
X-Dataset-Daily-Used: 1
<binary mmdb>
Response Fields
| Field | Type | Description |
|---|---|---|
| X-Dataset-Hourly-Limit / X-Dataset-Hourly-Used | header | Hourly quota and usage |
| X-Dataset-Daily-Limit / X-Dataset-Daily-Used | header | Daily quota and usage |
| Content-Disposition | header | attachment; filename="…mmdb" |
Over the meter you get HTTP 429 with Retry-After and a body of {"code":429,"msg":"…","limit":N,"reset_at":…,"reset_iso":"…"}.