Official Python client for the CheckThatPhone phone validation API. Validate US and Canadian phone numbers in real time: carrier and line type from live carrier data, portability and deliverability, GeoIP and timezone, plus optional TCPA litigator screening and a free state do-not-call scrub — one call, one credit.
Zero dependencies (standard library only). Python 3.9+.
pip install checkthatphoneimport os
from checkthatphone import CheckThatPhone
client = CheckThatPhone(api_key=os.environ["CHECKTHATPHONE_API_KEY"])
result = client.lookup("8182925409")
print(result.data["nanpType"]) # "mobile"
print(result.data["dipCarrier"]) # "AT&T"
print(result.data["deliverable"]) # "true"
print(result.credits_used) # 1Get an API key at checkthatphone.com — the free tier includes 500 lookups per month.
Flag known serial TCPA plaintiffs before you call or text (+1 credit):
result = client.lookup("8182925409", litigator_filter=True)
if result.data.get("litigator") == "true":
# result.data["litigator_type"]: "litigator" | "plaintiff" | "agitator"
suppress(result.data["subscriber"])Screen state do-not-call registries (40 states) and a national complainer list at no extra credit:
result = client.lookup("8182925409", dnc_other=True)
result.data.get("dncStateResult") # "STATE DNC" or ""
result.data.get("dncComplainerResult") # "DNC COMPLAINER" or ""
result.data.get("dncStateCovered") # "false" = state not in the data; don't read "" as clearSome landlines can receive texts. Detect them instead of dropping them (+1 credit, charged only when the number is a landline):
result = client.lookup("5551234567", landline_sms_lookup=True)
if result.data.get("dipMessagingEnabled") == "true":
send_sms(...)Pass the contact's IP for city-level location and the IANA timezone (no extra charge) — useful for TCPA calling-hours compliance:
result = client.lookup("8182925409", ip="136.38.145.14")
result.data["timezone"] # "America/Los_Angeles"Non-2xx responses raise CheckThatPhoneError with status, code, detail, and a retryable hint. Failed and invalid requests are billed 0 credits.
from checkthatphone import CheckThatPhoneError
try:
client.lookup("not-a-number")
except CheckThatPhoneError as err:
if err.retryable:
retry_later()Every response field (carrier DIP, portability/LRN, deactivation, blacklist, and more) is documented at checkthatphone.com/docs.
MIT