DOCUMENTATION / V1

Ready to connect.

A JSON API for approximate location and autonomous system lookups on IPv4 and IPv6 addresses.

Getting started

  1. Create your account and verify your email address.
  2. Generate a key in your dashboard. The complete key is shown only once.
  3. Send the key in the header of every request.
Terminal
curl 'https://iplumo.com/api/v1/lookup?ip=8.8.8.8' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Base URL: https://iplumo.com/api/v1. All dashboard usage dates use UTC.

Authentication

HTTP
Authorization: Bearer YOUR_API_KEY

An API key is required on Free, Pro and Business. Store it as a server environment variable. Keys in URLs are not accepted. Revoked keys stop authorizing new requests.

The public home page demo supports individual lookups without an account and shares the source IP's free limit. It does not replace authenticated endpoints.

Look up an IP or domain

GET/api/v1/lookup?ip=8.8.8.8

ip is required. It accepts a public IP or a domain without a protocol or path. Domain lookups use one public address, not all addresses or the website's content.

Terminal
curl 'https://iplumo.com/api/v1/lookup?ip=example.com&fields=countryCode,city,as,security' -H 'Authorization: Bearer YOUR_API_KEY'
JSON · abbreviated example
{
  "status": "success",
  "query": "8.8.8.8",
  "country": "United States",
  "countryCode": "US",
  "as": "AS15169 GOOGLE",
  "asname": "GOOGLE"
}

Fields without data are returned as null. Data may change and does not represent an exact location.

Up to 100 IPs in a batch

POST/api/v1/batch
Terminal
curl -X POST 'https://iplumo.com/api/v1/batch' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '["8.8.8.8", "1.1.1.1", "2606:4700:4700::1111"]'

The body must be an array of 1 to 100 IPs. Objects with per-item options are also supported:

JSON
[
  "8.8.8.8",
  {
    "query": "1.1.1.1",
    "fields": "country,as",
    "lang": "en"
  }
]

Results retain input order. Batches accept IPs, not domains. Invalid or private IPs produce a result with status: "fail", without preventing other lookups. Malformed batches or more than 100 items return HTTP 422.

JSON · batch with a partial error
[
  {
    "status": "success",
    "query": "8.8.8.8",
    "country": "United States"
  },
  {
    "status": "fail",
    "query": "192.168.1.1",
    "message": "The IP belongs to a private or reserved range."
  }
]

Fields and languages

Use ?fields=country,city,as&lang=es to reduce the response. Available languages: es and en; English is the default. Options in each batch item override the URL options.

status and query are always included. Successful responses also retain source, dataUpdatedAt, fetchedAt and attribution, even when selecting fields. Errors also retain message.

FieldsDescription
status, message, queryStatus, error reason and normalized IP.
continent, continentCodeContinent name and code.
country, countryCodeCountry and two-letter ISO code.
region, regionName, city, zipRegion, city and postal code, when available.
lat, lon, accuracyRadiusApproximate location center and accuracy radius in kilometers.
timezoneIANA time zone.
source, dataUpdatedAt, fetchedAt, attributionRecord metadata. dataUpdatedAt identifies the local edition; fetchedAt records retrieval. Unknown dates are null.
district, offset, currency, isp, orgDistrict, UTC offset in seconds, currency, ISP and organization when available. null if unavailable.
securityAdditive object: proxy and hosting mirror their existing indicators. vpn, tor, datacenter and residential_proxy remain null until specific evidence is available. Existing fields are unchanged.
mobile, proxy, hostingNetwork indicators. proxy groups proxies, VPNs and Tor without distinguishing between them. null means unknown, not false.
as, asnameAutonomous system number and organization. This is not necessarily the user's ISP.

IPLumo uses stored records and regular updates without mixing locations in a response. Expired results are refreshed through a queue. See sources and frequency. This API does not detect the visitor’s DNS resolver.

Limits and retries

PlanRequests/minBatch/minIPs/minKeys
Free501010001
Pro1000200200005
Business5000100010000015

No monthly quota. Rolling 60-second window. Keys share the account limit; limits also apply per key and source IP within the plan. A batch of N IPs consumes one request, one batch slot and N IPs. 429 rejections consume no additional capacity. Admitted requests may consume capacity even if the subsequent lookup fails.

HeaderMeaning
X-RateLimit-Batch-Limit / -RemainingMaximum and remaining batch capacity (POST batch only).
X-RateLimit-IP-Limit / -RemainingMaximum and remaining processed-IP capacity.
X-RateLimit-ReasonOn 429: requests, batch or ips identifies the exhausted limit.
X-RateLimit-LimitMaximum requests in 60 seconds.
X-RateLimit-Remaining / X-RlRequests remaining after this call.
X-TtlRetry delay on 429; on admitted requests, 60 seconds until this new request expires.
X-RateLimit-ResetUnix timestamp in seconds for that deadline.
Retry-AfterOn HTTP 429, seconds to wait before retrying.

The dashboard combines historical completed lookups with new per-minute/key metrics, including errors and 429 rejections after key authentication. Attempts without a valid key cannot be attributed to an account. Minute metrics are approximate; use API headers for exact rolling-window headroom.

Predictable errors

HTTPReason
200Request processed. In a batch, check each item's status: it may be fail.
404Route or resource not found; an IP without data uses status: fail.
500Unexpected application or infrastructure error.
400Invalid JSON, fields, language or source IP.
401Missing, invalid or revoked key.
403Key paused by plan, denied permission or IP/origin; or unverified account.
413Request body too large (32 KiB maximum for batch).
415The body requires Content-Type: application/json.
422Invalid parameters or batch; private IP in an individual lookup.
429Rate limit reached. Respect Retry-After.
503Service or data temporarily unavailable.

JavaScript example

Node.js
// Run this code on your server, never in the browser.
const response = await fetch(
  'https://iplumo.com/api/v1/batch?lang=es',
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.IP_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(['8.8.8.8', '1.1.1.1']),
  }
);

if (!response.ok) {
  const error = await response.json();
  throw new Error(error.message);
}
const results = await response.json();

Python

Python · requests
import os
import requests

r = requests.get(
    "https://iplumo.com/api/v1/lookup",
    params={"ip": "8.8.8.8", "fields": "countryCode,city,as,security"},
    headers={"Authorization": "Bearer " + os.environ["IP_API_KEY"]},
    timeout=15,
)
r.raise_for_status()
print(r.json())

PHP

PHP · cURL
<?php
$ch = curl_init('https://iplumo.com/api/v1/batch');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 15,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('IP_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['8.8.8.8', '1.1.1.1']),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($body === false || $status !== 200) {
    throw new RuntimeException('IPLumo request failed: ' . $status);
}
print_r(json_decode($body, true, 512, JSON_THROW_ON_ERROR));
curl_close($ch);

Key security

Keep keys on your server. Rename, regenerate, revoke and scope permissions from your dashboard. Business supports IP/CIDR and exact origins (for example https://example.com). An empty list is unrestricted. With an origin list, requests without Origin are rejected. Origin can be forged outside browsers and does not replace authentication; this setting does not enable CORS. Configured restrictions persist on downgrade.

For 429 responses, wait for the duration indicated by Retry-After. For 503 errors, use bounded retries with exponential backoff.