boundstone (Python)
Official Python client for Boundstone — phone, email & IP validation you can actually verify.
Zero dependencies (standard library only). Python 3.8+.
pip install boundstone
Quickstart
from boundstone import Boundstone
bs = Boundstone("bs_live_YOUR_KEY") # create a key at https://app.boundstone.io
r = bs.verify_email("you@example.com")
print(r.valid_syntax, r.mx_found, r.disposable, r.role_account)
The honesty contract
Every result carries a checks object with two lists — what was checked, and what
was not. That second list is the whole point: you always know exactly what a
valid is based on, and Boundstone never implies a check it didn't run.
r = bs.verify_email("you@example.com")
print(r.checks.performed) # ['syntax', 'mx', 'disposable_list', 'role_list']
print(r.checks.not_performed) # ['smtp_mailbox', 'catch_all']
smtp_mailbox and catch_all sit in not_performed because confirming a specific
mailbox exists needs an SMTP probe that many servers answer dishonestly. Boundstone
tells you it didn't run that, rather than dressing up a guess as a verdict.
Phone
p = bs.verify_phone("+16504472983")
print(p.valid, p.country, p.line_type, p.e164) # True US fixed_line_or_mobile +16504472983
print(p.checks.not_performed) # ['carrier_lookup', 'ported_status', 'hlr_liveness']
# NANP numbers also carry an allocation verdict: a phone library can tell you the
# digits parse and the area code is real, but not whether a carrier actually holds
# that exchange. So a library alone accepts unallocated blocks and the reserved
# 555-01XX range used in films — numbers that pass a cheap check and then get dialled.
print(p.allocation.allocated, p.allocation.snapshot) # True 2026-07-30
dead = bs.verify_phone("+14155550184") # reserved fictional range
print(dead.valid, dead.allocation.reason) # False reserved_fictional
# allocation is None for non-NANP numbers — we hold no allocation data for other
# numbering plans, and saying nothing beats implying coverage we don't have.
print(bs.verify_phone("+442071838750").allocation) # None
# For a national number without a country code, pass a default region:
bs.verify_phone("07911 123456", country="GB")
Carrier, ported-status and live-reachability (HLR) checks are not_performed today —
metadata can't see the live network, and Boundstone won't pretend it can.
IP
ip = bs.verify_ip("10.0.0.1")
print(ip.valid, ip.version, ip.classification, ip.is_public, ip.is_bogon)
print(ip.checks.not_performed) # ['geolocation', 'asn', 'hosting_datacenter', 'proxy_vpn_tor', 'reputation']
IP validation and classification (public / private / bogon…) is live and free.
IP intelligence (geolocation, proxy/VPN) needs licensed data and is not_performed.
Account
acct = bs.account()
print(acct.plan, acct.balance)
Errors
Any non-2xx response raises BoundstoneError with the status and the API's error code:
from boundstone import Boundstone, BoundstoneError
try:
bs.verify_email("you@example.com")
except BoundstoneError as e:
print(e.status, e.code, e.message) # e.g. 402 insufficient_credits ...
Notes
- The free tier is 250 credits/month, no card, and credits never expire.
- Every result also exposes
.raw— the untouched JSON dict — if you need a field the typed result doesn't surface yet. - Full API reference: https://boundstone.io/docs · OpenAPI: https://api.boundstone.io/openapi.json
MIT licensed.
Metadata
Release files for boundstone 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| boundstone-0.2.0.tar.gz | 5.6 kB | Without provenance | Details for boundstone-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| boundstone-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for boundstone-0.2.0-py3-none-any.whl |
Total release size: 11.0 kB
Release files / boundstone-0.2.0.tar.gz
| Download URL | boundstone-0.2.0.tar.gz |
|---|---|
| Size | 5.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6d7704f0b818c87dbae39fcad09cc69df2b77bc0c2e268bdd45095ee4ba9b166
|
|
BLAKE2b-256 checksum How to use checksums |
00a80981377146bda9abdc613ce8f27e62bc5be9f39502ad9a55420d60553b75
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / boundstone-0.2.0-py3-none-any.whl
| Download URL | boundstone-0.2.0-py3-none-any.whl |
|---|---|
| Size | 5.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
975f3de4fb8acd5b703ebb7fef671e9a5e94c025fc3cc335b889f64f43d7463a
|
|
BLAKE2b-256 checksum How to use checksums |
19bfdd00fb83b93a23b4ceefccf741db92dce562bd1ce1274cb67a6b65c4b7b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Security for boundstone 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.