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_paramth_descth_req
dataQR content. Required, URL-encoded, up to 1200 bytes.req_yes
sizeImage 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
levelError 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
pStyle 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
formatpng (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_paramth_desc
fgForeground (module) colour, hex — e.g. %23e11d48 (# must be escaped as %23).
bgBackground colour, same format.
fg2Second gradient colour. Only applies when grad is not none.
gradGradient direction: none / h horizontal / v vertical / d diagonal.
shapeModule shape: square / dot / rounded.
eyeShape of the three finder patterns: square / rounded / circle.
marginQuiet zone in modules, 0–10, default 2. Too little margin hurts scan reliability.
textCaption below the code, up to 30 characters. Pass it empty (&text=) to explicitly drop a caption stored in the style ID.
text_colorCaption 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

  1. Direct call — no p, every style option written into the URL. Good for one-off codes without signing up.
  2. Preset templates — p=1 through p=120, 120 ready-made colour and module styles, no sign-in needed. Templates cover colours and shapes only, not size, logo or caption.
  3. 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=u7 is 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"

QR QR

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 ETag and Cache-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">

Barcode

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