Location, network and abuse information for any IP address in one offline file.
No API, no rate limit, no lookup leaving the machine.
Python · JavaScript · Builder · Lookup page · API
pip install "plevin[db,full]" # Python
npm install plevinjs # Node, Deno, Bun, Workers, browsers
curl https://plevin.tn3w.dev/api/1.1.1.1 # HTTP, nothing to install>>> import plevin
>>> found = plevin.lookup("1.1.1.1")
>>> found.place.city.name, found.network.operator.brand, found.network.cidr
('Brisbane', 'Cloudflare', '1.1.1.0/24')
>>> plevin.lookup("185.220.101.1").abuse.service
'tor_exit_node'import { open } from "plevinjs";
const db = await open("https://plevin.tn3w.dev/db/plevin.plv");
db.lookup("1.1.1.1").network.operator.brand; // 'Cloudflare'One file per build, rebuilt daily. Pick the smallest one that answers your question.
| build | pip extra | size | carries |
|---|---|---|---|
| full | plevin[db] |
18.7 MB | every field |
| place | plevin[place] |
6.3 MB | city, region, postal, coordinates, metro |
| network | plevin[network] |
7.4 MB | ASN, operator, routing, registry |
| abuse | plevin[abuse] |
4.1 MB | abuse level, service and provider |
| country | plevin[country] |
378 KB | country code |
Download from the latest release, or
from plevin.tn3w.dev/db with open CORS. Need another
cut? plevinjs/slim rebuilds any selection in
JavaScript from plevin.raw, 30 MB, with the sections
the builder would write.
| group | answers |
|---|---|
place |
coordinates, accuracy, city, region, district, metro, local time, country with currency, calling code, languages |
network |
ASN, handle, CIDR, registry with its country and year, RPKI, operator with address, mobile carrier |
abuse |
risk, level, service (Tor, VPN, proxy, relay), threat, evidence, provider, crawler and other flags |
| address | spellings, special ranges, tunnels, embedded IPv4, no database needed |
dns |
PTR, forward-confirmed name, SOA, DNSSEC, only when asked |
A missing value is None/null, never "" or 0. Reserved space (private, loopback,
documentation, …) answers from the address alone: no place, network or abuse. A point
known only to a region or country names no town. Full reference with every field:
Python · JavaScript.
blocklist.netset
holds 542k CIDRs, 8.2 MB: every address feeds reported at 40 or above, plus every address a
current list names as an anonymising service. Per-address only: no ASN-wide scores, no
reserved space.
ipset create plevin hash:net
awk '!/^#/' blocklist.netset | xargs -n1 ipset add plevinplevin.tn3w.dev runs the database inside the browser tab.
Type an address, a hostname, an ASN (AS13335) or a network name. Only your own
address and DNS questions leave the tab. Source: site/.
worker/ is a Cloudflare Worker answering the same JSON as the readers:
curl https://plevin.tn3w.dev/api/1.1.1.1 # any address
curl https://plevin.tn3w.dev/api/me # the caller
curl https://plevin.tn3w.dev/api/about # build and fields
curl "https://plevin.tn3w.dev/api/1.1.1.1?dns=1" # with DNS- CORS open, no key.
- Cached 5 min, 1 min with DNS.
400for a bad or missing address,503without a database.
Deploy your own
cd worker && npm install
npx wrangler kv namespace create PLEVIN # id → KV_NAMESPACE_ID secret
npx wrangler kv key put --binding PLEVIN --remote plevin.plv --path ../plevin.plv
npx wrangler deploydeploy-worker.yml deploys on a push to
worker/ or js/ and refreshes KV on every release.
- Secrets:
KV_NAMESPACE_ID,ZONE_ID,CLOUDFLARE_ACCOUNT_ID,CLOUDFLARE_API_TOKEN. - Variable:
WORKER_ROUTE. - Token needs: Workers Scripts, Workers KV Storage and Workers Routes edit rights.
- Smaller build: set
DATABASEto a file other thanplevin.plv.
plevin_mini.py: the lookup without the package. 280 lines, standard
library only. Plain dictionaries, no derived fields.
python plevin_mini.py plevin.plv 8.8.8.8golf/: the same reader ported, one file each, standard library only. C, C++, Rust,
Go, Java, Kotlin, C#, PHP, Ruby and Perl so far, with Lua and Elixir still to come.
| rows | count |
|---|---|
| v4 boundaries | 3,154,886, plus 4,513,257 host overrides |
| v6 boundaries | 896,909 |
| cities | 81,672 in 3,220 regions |
| districts, metros | 20,591 and 210 |
| ASNs, networks | 86,164 and 148,809 (registry holders included) |
| timezones | 394 |
| abuse records | 5,576 from 209 feeds |
Sources: MaxMind GeoLite2, IP2Location LITE, DB-IP Lite, GeoNames, Natural Earth, RIPE RIS, RPKI, NRO, RIPE/APNIC/AFRINIC/LACNIC whois, operator geofeeds, CAIDA, PeeringDB, asn-abuse and 209 feeds. Readers derive country facts from pycountry, Babel and phonenumbers.
cd python && uv run pytest && uv run mypy && uv run basedpyright
uvx ruff check . ../plevin_mini.py --config pyproject.toml
cd ../js && npm ci && npm test && npm run lint && npm run typecheck
cd ../builder && cargo fmt --check && cargo clippy && cargo testjs/test/compare.ts checks both readers field for field; js/test/blocks.ts checks
the JavaScript LZMA decoder against liblzma on every block. js/test/countries.py
regenerates js/src/countries.ts from the libraries the Python full extra uses.
Apache 2.0 for code (LICENSE). The database carries the licenses of its sources.