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"
}
}
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.