Free IP Lookup API
Free to use, no registration required (anonymous calls are rate limited); an API key raises your quota. Returns JSON, CORS enabled.
1. Look up your own IP
GET /api/myip
Returns the caller's public IP and its geolocation.
2. Look up a specific IP
GET /api/ip?ip=8.8.8.8
Optional &key=YOUR_API_KEY raises the rate limit.
3. Look up a domain (resolve, then locate each IP)
GET /api/ip?domain=baidu.com
Returns every IP the domain resolves to, each with its geolocation.
4. Plain-text lookup for the command line
GET /ip
Built for curl and shell scripts — returns a single line of plain text instead of JSON.
$ curl https://www.i5p.com/ip 103.118.252.70 | Hong Kong Island, Hong Kong, China | Alibaba Cloud $ curl "https://www.i5p.com/ip?ip=8.8.8.8" 8.8.8.8 | Mountain View, California, United States | Google Cloud/DNS/DoH/DoT
No parameter looks up your own address; ?ip= looks up a specific one; ?lang=en or ja switches language.
# Through a proxy — returns the proxy exit IP (no auth) curl -x http://127.0.0.1:8080 https://www.i5p.com/ip # When the proxy needs credentials curl -x http://user:password@127.0.0.1:8080 https://www.i5p.com/ip
For a SOCKS5 proxy just use socks5:// instead of http://. This is the quickest way to confirm a proxy is working and where it exits.
Example response
{
"code": 0,
"msg": "ok",
"data": {
"ip": "8.8.8.8",
"country": "United States",
"province": "California",
"city": "Mountain View",
"zip": "",
"isp": "Google Cloud/DNS/DoH/DoT",
"asn": "AS15169",
"as_name": "Google LLC",
"as_domain": "google.com",
"network": "8.8.8.0/24",
"range_start": "8.8.8.0",
"range_end": "8.8.8.255",
"asn_source": "IPtoASN",
"ip_type": "DCH",
"ip_type_source": "IPLogs",
"ip_type_basis": "asn",
"ip_type_version": "20261017-reviewed1-…",
"asn_country_code": "US",
"ip_country_code": "US",
"native_status": "COUNTRY_MATCH",
"native_basis": "ip_country_vs_asn_country"
}
}
ASN source:IPinfo Lite · CC BY-SA 4.0
/api/myip · /api/ip · /api/lookup · /api/echo · /ip
asn / as_name / as_domain / network /
range_start / range_end / asn_source / ip_type / ip_type_source / ip_type_basis / ip_type_version
代理检测字段包括 proxy_status、proxy_detected、vpn_detected、tor_detected、hosting_detected、anonymous_detected、proxy_risk、proxy_confidence、proxy_network_type、proxy_checked_at 和 proxy_expires_at。数据由首页或手动查询获取并存入数据库,公开接口只读取已有结果,不额外调用 ProxyCheck。FRESH 为有效记录,STALE 为过期历史记录,NOT_CHECKED / UNAVAILABLE 等表示暂无有效检测,布尔值为 null 时不能当作未检出。检测结果不保证原生或无代理。
ASN 区间优先使用 IPtoASN(PDDL,可商用),缺失时回退 IPinfo Lite;AS 域名按相同 ASN 从 IPinfo Lite 补充。类型来源为 IPLogs(CC BY 4.0,本站筛选)。DCH = 机房 / 云服务,CDN = 内容分发,UNKNOWN = 未知;未匹配不表示住宅或移动。分类依据为 ASN,不能证明具体 IP 使用代理。非单一 CIDR 区间的 network 为空,以 range_start / range_end 为准。asn_country_code 为 AS 关联国家代码,ip_country_code 为地理归属国家代码;native_status 为 COUNTRY_MATCH / COUNTRY_MISMATCH / UNKNOWN,native_basis 为 ip_country_vs_asn_country。此项仅比较地区,不能保证原生、住宅或无代理。
All IP lookups include these fields. Missing ASN or unmatched network values are empty strings. Network ranges come from IPinfo Lite and do not represent live BGP routes.
5. QR code generation
GET /qr/?data=TEXT
A GET request returns an image/png directly, ready to drop into an <img> tag.
Basic parameters
| th_param | th_desc | th_req |
|---|---|---|
| data | QR content. Required, URL-encoded, up to 1200 bytes. | req_yes |
| size | Image side length, 80–1200, default 320. The actual output is rounded down to a whole multiple of the module size, so it may come out a few pixels smaller — that keeps every module on whole pixels and scans more reliably. | req_no |
| level | Error correction: L (7%) / M (15%) / Q (25%) / H (30%), default H. Use H whenever there is a logo, or the covered centre may become unreadable. | req_no |
| p | Style ID. Either a preset template number (1–120) or your own personal ID (like u7) created while signed in. Omit for plain black & white. | req_no |
| format | png (default, returns the image) or base64 (returns JSON containing a data URI, handy for dropping straight into src). | req_no |
Style parameters (can be written straight into the URL)
| th_param | th_desc |
|---|---|
| fg | Foreground (module) colour, hex — e.g. %23e11d48 (# must be escaped as %23). |
| bg | Background colour, same format. |
| fg2 | Second gradient colour. Only applies when grad is not none. |
| grad | Gradient direction: none / h horizontal / v vertical / d diagonal. |
| shape | Module shape: square / dot / rounded. |
| eye | Shape of the three finder patterns: square / rounded / circle. |
| margin | Quiet zone in modules, 0–10, default 2. Too little margin hurts scan reliability. |
| text | Caption below the code, up to 30 characters. Pass it empty (&text=) to explicitly drop a caption stored in the style ID. |
| text_color | Caption colour, hex. |
Precedence: the URL overrides the style ID
The style behind p is the base; parameters given explicitly in the URL override it one by one, and anything you leave out keeps whatever the ID holds. So p=u7&size=600 means "the u7 style, resized to 600" — u7's colours, module shape and caption all survive. Without p the base is plain black & white.
The one exception is the logo: it is a file stored on the server, so it can only travel with a style ID and cannot be passed as a URL parameter. If you want a code with a logo, you need a personal ID.
Three ways to use it
- Direct call — no
p, every style option written into the URL. Good for one-off codes without signing up. - Preset templates —
p=1throughp=120, 120 ready-made colour and module styles, no sign-in needed. Templates cover colours and shapes only, not size, logo or caption. - Personal IDs — sign in, tune everything (logo and caption included) on the QR generator page and hit “Create API style ID” to get an ID like
u7. From then on?data=...&p=u7is all you need: change the style once under My QR styles and every place using that ID follows immediately, no code changes.
Domain binding: not even p is needed
Bind a domain to one of your IDs under My QR styles, and requests coming from that domain (matched by Referer) only need data — the bound style is applied automatically. Binding example.com also covers www.example.com.
Examples
<!-- plain black & white --> <img src="https://www.i5p.com/qr/?data=https%3A%2F%2Fwww.i5p.com"> <!-- styles inline: red dot modules with a diagonal gradient --> <img src="https://www.i5p.com/qr/?data=https%3A%2F%2Fwww.i5p.com&fg=%23e11d48&fg2=%23f59e0b&grad=d&shape=dot&eye=circle"> <!-- preset template 82, size 300 --> <img src="https://www.i5p.com/qr/?data=https%3A%2F%2Fwww.i5p.com&size=300&p=82"> <!-- a personal ID (size, colours, logo and caption all live in the ID) --> <img src="https://www.i5p.com/qr/?data=https%3A%2F%2Fwww.i5p.com&p=u7"> <!-- the same ID, but resized to 600 just this once --> <img src="https://www.i5p.com/qr/?data=https%3A%2F%2Fwww.i5p.com&p=u7&size=600"> <!-- base64 output, ready for front-end use --> curl "https://www.i5p.com/qr/?data=https%3A%2F%2Fwww.i5p.com&p=82&format=base64"
Notes
- The response is an image and does not follow the JSON error codes; on a bad parameter it returns a JSON explanation instead, which shows up as a broken image inside
<img>. Open the URL directly in a browser to see the reason. - Identical parameters always produce a byte-identical image, served with an
ETagandCache-Control: max-age=86400, so CDN and browser caching are safe. - Anonymous calls are rate limited per minute (adjustable in the admin panel, currently 1200/min). Exceeding it returns
429. - The longer the content and the higher the error correction, the denser the modules. For long URLs, shorten them first or drop the level to
M.
Full parameters and a live playground: QR Code
6. Barcode generation
GET /bar/?data=TEXT&type=ean13
A GET request returns an image/png directly. Seven 1D symbologies supported.
data barcode content (required); type one of code128 / ean13 / ean8 / upca / code39 / itf / codabar, default code128; w module width 1–8; h height 20–400; fg/bg colors; text=0 hides the caption.
<img src="https://www.i5p.com/bar/?data=6901234567892&type=ean13&w=3&h=140">
Full parameters and a live playground: Barcode
Request signing
Requests carrying a key must be signed. Your api_secret never appears in the URL, so a leaked link (logs, browser history) cannot be used to forge further requests.
key your API key; ts Unix timestamp in seconds (300s tolerance); nonce random string of 6–64 chars (single use within 300s); sign the signature. All four may instead be sent as X-Api-Key / X-Api-Ts / X-Api-Nonce / X-Api-Sign headers.
Algorithm: take every parameter except sign and callback, sort by parameter name ascending, join as k1=v1&k2=v2 (raw values, no URL encoding), then HMAC-SHA256 with your api_secret, lowercase hex.
// PHP
$key = 'a1b2c3d4e5';
$secret = '你的secret';
$p = ['ip' => '8.8.8.8', 'key' => $key, 'ts' => time(), 'nonce' => bin2hex(random_bytes(6))];
ksort($p);
$base = [];
foreach ($p as $k => $v) { $base[] = "$k=$v"; }
$p['sign'] = hash_hmac('sha256', implode('&', $base), $secret);
echo file_get_contents('https://www.i5p.com/api/ip?' . http_build_query($p));
// Node.js
const crypto = require('crypto');
const key = 'a1b2c3d4e5', secret = '你的secret';
const p = { ip: '8.8.8.8', key, ts: Math.floor(Date.now() / 1000),
nonce: crypto.randomBytes(6).toString('hex') };
const base = Object.keys(p).sort().map(k => `${k}=${p[k]}`).join('&');
p.sign = crypto.createHmac('sha256', secret).update(base).digest('hex');
const url = 'https://www.i5p.com/api/ip?' + new URLSearchParams(p);
fetch(url).then(r => r.json()).then(console.log);
#!/bin/bash KEY="a1b2c3d4e5"; SECRET="你的api_secret" IP="8.8.8.8"; TS=$(date +%s); NONCE=$(head -c6 /dev/urandom | xxd -p) BASE="ip=$IP&key=$KEY&nonce=$NONCE&ts=$TS" # already in ascending key order SIGN=$(printf '%s' "$BASE" | openssl dgst -sha256 -hmac "$SECRET" -r | cut -d' ' -f1) curl "https://www.i5p.com/api/ip?$BASE&sign=$SIGN"
Create keys in your dashboard. If the admin disables “require signing”, sending only key also works (not recommended).
CORS & JSONP
Every JSON endpoint sends Access-Control-Allow-Origin: *, so fetch/XHR works cross-origin. Add ?callback=fnName (or jsonp=) to get JSONP for direct <script> use.
<script src="https://www.i5p.com/api/myip?callback=showIp"></script>
<script>function showIp(r) { console.log(r.data.ip); }</script>
Notes
codeis 0 on success; non-zero is an error (400 bad parameter / 401 invalid key / 429 rate limited / 403 blocked).- Anonymous: 5 QPS, 200000 requests/day per IP. With an API key: 5 QPS, 5000000 requests/day.
- The QR and barcode endpoints return images and do not follow the JSON error codes above; on bad input they return a JSON error instead.
- For a higher quota, create an account and generate an API key in your dashboard.