Liveliness API
Resolve any phone number to a real-time verdict: live, reachable, line type, carrier and risk. One endpoint, one API key.
New to phone data? Start with the guides or look up a term in the glossary.
Quickstart
- 1.Create a free account (500 lookups a month, no card).
- 2.In your dashboard, click Create key and copy it (shown once).
- 3.Send your first request:
curl https://qualmie.dev/v1/liveliness \
-H "Authorization: Bearer sk_live_1a2b3c..." \
-H "Content-Type: application/json" \
-d '{ "phone_number": "+12125550100" }'Authentication
Authenticate every request with your secret key in the Authorization header as a bearer token. Keep secret keys server-side — never ship them to a browser or mobile client. Rotate or revoke a key anytime from your dashboard.
Authorization: Bearer sk_live_1a2b3c...Endpoint reference
https://qualmie.dev/v1/livelinessBody parameters
phone_numberstring, required — the number to check, in E.164 or a local format we can normalize.
Response fields
| Field | Type | Description |
|---|---|---|
phone_number | string | Normalized E.164, e.g. +12125550100. |
valid | boolean | Number is well-formed and assigned. |
live | boolean | Active on a carrier network right now. |
reachable | boolean | Can currently receive a call or SMS. |
line_type | enum | mobile · landline · voip · toll_free · unknown. |
carrier | object | Current carrier: name, type, country, mcc, mnc. |
ported | boolean | Number has been ported to another carrier. |
risk | object | level, score (0–100) and fraud flags. |
checked_at | string | ISO-8601 timestamp of the lookup. |
latency_ms | number | Server-side resolution time. |
{
"phone_number": "+12125550100",
"valid": true,
"live": true,
"reachable": true,
"line_type": "mobile",
"carrier": {
"name": "Verizon Wireless",
"type": "mobile",
"country": "US",
"mcc": "310",
"mnc": "004"
},
"ported": false,
"risk": {
"level": "low",
"score": 8,
"voip": false,
"disposable": false,
"recently_ported": false,
"recently_disconnected": false
},
"checked_at": "2026-07-17T17:04:11Z",
"latency_ms": 187
}Response headers
Every response carries your current limits so you can throttle and plan ahead without a separate call.
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests/second allowed on your plan. |
X-RateLimit-Remaining | Requests left in the current second. |
X-Quota-Limit | Lookups included in your plan this month. |
X-Quota-Remaining | Plan lookups left this month. |
X-Credits-Remaining | Prepaid lookups left (used after the monthly quota). |
Code examples
Plain HTTP — no SDK required.
const res = await fetch("https://qualmie.dev/v1/liveliness", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.QUALMIE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ phone_number: "+12125550100" }),
});
const result = await res.json();
if (result.live && result.reachable) {
// safe to send
}import os, requests
res = requests.post(
"https://qualmie.dev/v1/liveliness",
headers={"Authorization": f"Bearer {os.environ['QUALMIE_API_KEY']}"},
json={"phone_number": "+12125550100"},
)
result = res.json()
if result["live"] and result["reachable"]:
... # safe to sendErrors
Errors return a JSON body with an error message and a conventional status code.
| Status | Meaning |
|---|---|
400 | Invalid or missing phone_number. |
401 | Missing, invalid, or revoked API key. |
402 | Monthly quota reached and no prepaid lookups left — upgrade or buy a pack. |
429 | Rate limit exceeded. Back off (see Retry-After) and retry. |
5xx | Temporary error. Safe to retry with backoff. |
Rate limits & quotas
Two limits apply: a per-second rate limit (abuse protection) and a monthly quota (your plan allowance). Past the monthly quota, prepaid lookup packs are consumed automatically; a 402 only comes back when both are exhausted.
| Plan | Rate limit | Monthly quota |
|---|---|---|
| Free | 5 / sec | 500 / month |
| Pro | 25 / sec | 50,000 / month |
| Scale | 100 / sec | Custom |
Ready to build? Grab a key and make your first call.
Get your free API key