numbersonline

API reference

v1.0.0OpenAPI 3.0

One REST API over a single E.164 primitive: parse & validate, single and bulk number lookup (line type, range carrier, CNAM, STIR/SHAKEN verstat and a supplementary spam signal), inbound caller-intelligence, identity match, do-not-call list scrubbing, prepaid accounts, a ClearIP-compatible SBC/SIP redirect decision for session border controllers, and an MCP server plus Vapi/Retell webhooks for AI voice agents. The core endpoints below are live-runnable; every endpoint — including the full machine-readable schema — is at /api/spec.

Authentication

Every endpoint requires an API key, sent as X-API-Key or Authorization: Bearer, scoped to its use cases — a self-service key covers parse, lookup, inbound caller-intelligence, match, scrub, MCP/voice-agent tools, SBC redirect, community reporting and pre-call. Tenant sub-keys are narrowed to lookup, SBC redirect and pre-call. Keys are issued self-service and shown exactly once — we store only a hash.

Get a free keyPOST /api/v1/account/signupthen send it as X-API-Key.
Base URL & limits
Base URLhttps://numbers.online
Per-key default60 requests/min (lookup, match, scrub, CID, MCP, SBC)
Free / unverified10 lookups/min · 50/day · 10 reports/day (pooled per account)
Per verified business #+60/min · +2,000/day lookups · +100/day reports
Standardprepaid per-dip above the pool
EnterpriseCustom

The pooled budgets cover inbound caller-intelligence, the outbound pre-call check and community reporting; all other endpoints use the per-key 60-requests/minute window. Pooled limits are shared across an account's keys and recomputed from live state. Verify a business number — POST /api/v1/account/verify-phone/start then /confirm — to raise them; personal verification does not.

Integration guides

Step-by-step recipes to wire numbers.online into a PBX, softphone, AI voice agent, or session border controller — FreePBX & Asterisk, FreeSWITCH / FusionPBX, 3CX, MicroSIP, an /api/v1/mcp Model Context Protocol server with Vapi & Retell webhooks, a ClearIP-compatible /api/v1/sbc/redirect for Kamailio / OpenSIPS / dSIPRouter, the outbound pre-call call-provenance flow, and the signed /api/v1/compliance/evidence robocall-mitigation bundle. Read the integration guides (ordered simplest first), or grab the copy-paste artifacts on the integrations page.

Every endpoint is listed below in onboarding order — from getting a key and parsing a number to operator-grade SBC and multi-tenant controls. The core ones carry a live Try it widget backed by a rate-limited, keyless public demo proxy, and the rest show a copy-paste curl. Get your own free key: POST /api/v1/account/signup. Full machine-readable schema at /api/spec.

Account & keys

Self-service signup, prepaid balance, and credit top-ups.
POST/api/v1/account/signupGet an API keyNO KEY

Self-service signup — no sales call. Submit an email and receive an account plus a freshly minted key (format nol_…), returned exactly once and stored only as a hash, so save it. New accounts start on the free tier with a zero balance; add credit with /api/v1/account/topup to use billed endpoints. No key required (rate-limited to 3/hour per IP).

Example request
curl -X POST https://numbers.online/api/v1/account/signup \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]"}'
GET/api/v1/accountCheck balance & usage

Returns the authenticated account: prepaid balance (microdollars), trailing-30-day usage, your keys (display fields only — never the raw key), and any MSP tenants. Use it to monitor spend and decide when to top up.

Example request
curl https://numbers.online/api/v1/account \
  -H "X-API-Key: YOUR_API_KEY"
POST/api/v1/account/topupAdd prepaid credit

Create a Stripe Checkout session to add prepaid credit. Amount is in US cents: $5 minimum (500) to $500 (50000) per checkout; credit applies when Stripe confirms payment. Standard-tier billed endpoints return 402 when the balance is exhausted — top up to resume.

Example request
curl -X POST https://numbers.online/api/v1/account/topup \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"amount_cents": 2000}'
POST/api/v1/account/verify-phone/startVerify a business number (step 1)

Step 1 of binding a business number to your account: send a one-time code by voice (default) or sms to a number your account controls. Account-level keys only. A verified business number is what raises your pooled rate limits (+60/min, +2,000/day lookups, +100/day reports), unlocks the accountable report lane, and enables pre-call enrollment. Returns 429 with Retry-After on cooldown/velocity.

Example request
curl -X POST https://numbers.online/api/v1/account/verify-phone/start \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"phone": "+14155550142", "channel": "voice"}'
POST/api/v1/account/verify-phone/confirmVerify a business number (step 2)

Step 2: submit the code to verify and bind the number to your account. Free accounts may bind exactly one number (402 if you already have one and none is paid); a number already claimed by another account returns 409 (the Sybil floor). On success the number counts toward your pooled limits and can be enrolled for call-provenance.

Example request
curl -X POST https://numbers.online/api/v1/account/verify-phone/confirm \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"phone": "+14155550142", "code": "123456"}'

Parsing

Phone number parsing and validation. Free on every tier.
POST/api/parseParse a phone number

Parse and validate a single number, returning format variants, country, line type, carrier and validity.

Example request
curl -X POST https://numbers.online/api/parse \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"phoneNumber": "+14155552671"}'
POST/api/parse/bulkParse multiple numbers

Parse up to 100 numbers in one request. Returns a result per number plus a summary.

Example request
curl -X POST https://numbers.online/api/parse/bulk \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"phoneNumbers": ["+14155552671", "+442071234567"]}'

Reference

Reference data and examples.
GET/api/countriesList supported countries

All supported countries with calling codes and example numbers.

Example request
curl https://numbers.online/api/countries \
  -H "X-API-Key: YOUR_API_KEY"

Lookup

Number lookup: line type, range carrier, CNAM, verstat, and a supplementary spam signal.
GET/api/v1/lookup/{e164}Look up a number

Single-number lookup: validity, formats, line type, range carrier (a supplementary signal — not porting-aware), country, CNAM, normalized STIR/SHAKEN verstat, and a low-confidence supplementary spam signal. Invalid numbers return 200 with valid:false and are not billed. Billed per dip: $0.004 with a fresh CNAM dip, $0.002 when served from cache or without a CNAM supplier; free tier is unbilled (rate-limited). Optional ?verstat= and ?max_cache_age= query params; Idempotency-Key header for at-most-once billing.

Example request
curl https://numbers.online/api/v1/lookup/+14155552671 \
  -H "X-API-Key: YOUR_API_KEY"
POST/api/v1/lookup/batchLook up multiple numbers

Bulk lookup for list processing: submit up to 100 numbers and receive the same shape as the single lookup per number (in input order) plus a billing summary. A list-processing surface, not a call-path surface — large batches dip suppliers with bounded concurrency and can take seconds. Billed per valid number ($0.004 fresh CNAM dip / $0.002 otherwise); invalid numbers are free. Optional verstat / max_cache_age; Idempotency-Key header for at-most-once billing.

Example request
curl -X POST https://numbers.online/api/v1/lookup/batch \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"numbers": ["+14155552671", "+442071234567"]}'
GET/api/v1/cid/{number}Plain-text caller-id for PBXs

Caller-name (CNAM) lookup that ALWAYS returns text/plain so a PBX can paste the body verbatim as the caller name — built for FreeSWITCH mod_cidlookup and similar header-less clients. The body is the resolved name (ACME CORP), the name prefixed with an operator-chosen tag when a spam_tag is set and the signal crosses spam_threshold (Spam? ACME CORP), or the literal UNAVAILABLE sentinel. This is the only endpoint that also accepts the key as a ?key= query param (use a dedicated, rotated key). Optional ?country, ?spam_tag, ?spam_threshold, ?max_cache_age. Billed like /api/v1/lookup; fail-open — a slow or failing supplier yields UNAVAILABLE, never an error on the call path. See the integrations page.

Example request
curl "https://numbers.online/api/v1/cid/12025550123?key=YOUR_API_KEY"

Trust

Identity match and contact-suppression preference lookups.
POST/api/matchMatch a name to a number

Privacy-preserving identity check. Returns match / no_match / not_verified — the stored name is never returned. Billed $0.004 per match on the standard tier (a no-match still resolves a result). Requires an API key.

Example request
curl -X POST https://numbers.online/api/match \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"number": "+16285550177", "name": "Maria Chen"}'
POST/api/scrubScrub a calling list

For each number, returns SUPPRESS (verified owner has a suppression preference — remove it), NO_MATCH (no suppression preference on record), or UNKNOWN (not resolvable). Optional channel: voice (default) | sms | whatsapp. Up to 1,000 per request. Billed $0.001 per number on the standard tier. A compliance aid, not a legal determination — requires an API key.

Example request
curl -X POST https://numbers.online/api/scrub \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"numbers": ["+16285550177", "+12135559988"], "channel": "voice"}'

Inbound & AI voice agents

Signed inbound caller-intelligence, an MCP server, and Vapi/Retell webhooks. Fail-open on the call path.
POST/api/v1/inbound/lookupInbound caller intelligence (signed)

The flagship inbound endpoint: signed, privacy-safe caller intelligence for an inbound call/message event — identity type, a 0-100 risk score (higher = worse), PII-free evidence signals, and a recommended action, with a signed receipt id. The receipt id is a single-use, anti-replay nonce you can later spend once via POST /api/v1/report to attach a community report to this number — it is not proof the call occurred. A verified individual returns only "Verified & online" — never a name. Optional STIR/SHAKEN verstat / attestation folds into the score. Requires an API key with the inbound_lookup use case. Billed $0.004 per dip on the standard tier; free tier rate-limited. Known and unknown numbers return the same 200 shape (anti-enumeration).

Example request
curl -X POST https://numbers.online/api/v1/inbound/lookup \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"number": "+14155551212", "context": "inbound_voice"}'
POST/api/v1/mcpMCP server for AI voice agents

Model Context Protocol over Streamable HTTP (JSON-RPC 2.0). Stateless and read-only. Methods: initialize, ping, tools/list (public discovery) and tools/call (requires a key with the "mcp" use case). Five tools: phone_lookup, line_type, caller_risk, dnc_check, reassigned_check. dnc_check and reassigned_check return "unknown" (and are unbilled) until a licensed data partner is configured. Each billable call meters the bundled mcp_call rate ($0.015). All output is a supplementary, low-confidence signal — the agent keeps every routing and dialing decision. GET returns 405 (response-only, no server-initiated SSE).

Example request
curl -X POST https://numbers.online/api/v1/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/call",
       "params": {"name": "phone_lookup", "arguments": {"number": "+14155552671"}}}'
POST/api/v1/integrations/retell/inboundRetell call_inbound webhook

Adapter for Retell’s call_inbound webhook: resolves the inbound caller and returns dynamic_variables (caller_name, caller_line_type, caller_spam_score, caller_risk, caller_on_dnc, caller_reassigned, caller_signal) for the agent prompt, plus a receipt_id. ALWAYS returns HTTP 200 with a (possibly empty) variables block — a non-2xx would keep the caller ringing — so auth failure or a supplier timeout degrade to neutral variables (fail-open). Authenticate via Authorization: Bearer or ?key= on the webhook URL.

Example request
curl -X POST "https://numbers.online/api/v1/integrations/retell/inbound?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event": "call_inbound",
       "call_inbound": {"from_number": "+14155552671", "to_number": "+14155550100"}}'
POST/api/v1/integrations/vapi/toolVapi custom tool webhook

Adapter for a Vapi custom function tool (an alternative to pointing Vapi at /api/v1/mcp). Accepts Vapi’s tool-calls payload and returns the phone_lookup bundle as a JSON-stringified result per toolCallId, with a signed receipt id. Each call meters the bundled mcp_call rate. Fail-open: a bad argument or supplier hiccup yields a graceful result string. Authenticate via Authorization: Bearer or ?key=.

Example request
curl -X POST https://numbers.online/api/v1/integrations/vapi/tool \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"message": {"type": "tool-calls",
       "toolCallList": [{"id": "call_1", "arguments": {"number": "+14155552671"}}]}}'

Outbound & call-provenance

Outbound pre-call check (scrub + a supplementary compliance signal) and owner enrollment for spoofing defence. Fail-open; bundled, not metered.
POST/api/v1/precall/lookupPre-call check (outbound)

Call right before you dial: returns an M1 scrub on the destination `to` number — SUPPRESS (a verified owner asked not to be marketed to), NO_MATCH (no suppression on record — NOT a consent grant), or UNKNOWN — plus a supplementary compliance signal. When the `from` is one of your own enrolled, OTP-verified business numbers, a hashed (from→to) call-provenance edge is recorded for 7 days; at report time it lets us attribute calls you actually placed and shield your number from reports about calls you did not (likely spoofing). Free/bundled, not metered. Account-pooled on its own pre-call budget. Requires a key with the precall use case. context is outbound_voice | outbound_sms. Fail-open.

Example request
curl -X POST https://numbers.online/api/v1/precall/lookup \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"from": "+14155550100", "to": "+14155552671", "context": "outbound_voice"}'
POST/api/v1/precall/enrollEnroll a number for call-provenance

Owner-only control: enroll (or revoke) one of your own OTP-verified business numbers for call-provenance. Enrolling attests that the number only ever places calls after a numbers.online pre-call check, so the absence of a recorded edge becomes meaningful evidence a reported call was not yours. Account-level keys only (a tenant sub-key returns 403); the number must be a verified number bound to your account (else 404). A supplementary signal — never a block or a verdict.

Example request
curl -X POST https://numbers.online/api/v1/precall/enroll \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"number": "+14155550100", "enrolled": true}'

Community reporting

Key-gated spam/scam reporting — the give-to-get half of the community sensor.
POST/api/v1/reportReport a number (community sensor)

Report a number with one or more tags using a single-use `receipt_id` from a prior POST /api/v1/inbound/lookup on the same number. Tags only — no free-text body. The receipt is an anti-replay nonce and rate control, not proof a call happened. Accounts with a verified business number report in the accountable lane (reporter-weighted, earns credibility); free/personal accounts report in the crowd lane (a bounded, deferring, credibility-firewalled supplementary signal that cannot sink a verified number on its own). You cannot report a number bound to your own account. Daily report quota is pooled per account: 10/day free, +100/day per verified business number. Returns { ok, lane, report_id }; a stale/used/mismatched receipt returns 409, an over-quota request 429.

Example request
curl -X POST https://numbers.online/api/v1/report \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"e164":"+14155552671","tags":["robocall"],"receipt_id":"nol_rec_…"}'

SBC / SIP operators

Call-setup decisions for session border controllers (ClearIP-compatible SIP 603/302/503-404), operator HMAC request signing, and a signed FCC robocall-mitigation evidence bundle.
POST/api/v1/sbc/redirectSBC / SIP redirect decision

Call-setup decision for a SIP redirect server / SBC (Kamailio, OpenSIPS, dSIPRouter, Sansay, Oracle/Acme Packet, ProSBC), consumed by the operator-run shim recipe on the integrations page. Given the calling number it returns a ClearIP-compatible decision (allow / flag / redirect / block) plus the exact SIP code the shim maps to: 603 Decline, 302 redirect (you supply the Contact), or your allow code (503 default, or 404 route-advance). Optional verstat, spam_threshold, redirect_threshold, allow_code, block_reassigned, block_invalid; X-SBC-Budget-Ms header. Requires a key with the sbc_redirect use case (every lookup-entitled key has it). Billed $0.010 per decision on the standard tier; free tier rate-limited. A 603 block only ever follows a deterministic or authoritative fact — the low-confidence spam signal can only raise a flag/redirect. Fail-open: a timeout or error returns decision=allow. Supports opt-in operator HMAC signing (X-Operator-* headers).

Example request
curl -X POST https://numbers.online/api/v1/sbc/redirect \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"number": "+14155552671"}'
GET/api/v1/account/signingOperator HMAC signing secret

Operator-grade HMAC request signing for the calling key. GET returns the key’s HKDF-derived signing secret (exposed only to the key holder — equivalent exposure to the key itself), the canonical scheme, and whether signing is currently required; the secret is never stored (re-derived on demand). POST /api/v1/account/signing {"enabled": true|false} toggles whether signed surfaces (e.g. /api/v1/sbc/redirect) require a valid X-Operator-Signature on this key. This management route is never itself signature-gated, so a key can always disable signing or re-fetch its secret.

Example request
curl https://numbers.online/api/v1/account/signing \
  -H "X-API-Key: YOUR_API_KEY"
GET/api/v1/compliance/evidenceFCC robocall-mitigation evidence bundle

A signed, PII-free, independently-verifiable record of the supplementary number-status checks this account performed over a window (aggregated from signed lookup receipts; numbers appear only as hashes). An operator can reference it in their OWN robocall-mitigation program documentation (47 CFR 64.6305) — it is NOT an FCC certification and does not make anyone compliant; the operator signs their own attestation. Optional ?from / ?to (ISO 8601; window capped at 400 days). Account-level keys only. Verify each receipt signature, the bundle signature, and the Merkle root against /api/v1/publickey.

Example request
curl "https://numbers.online/api/v1/compliance/evidence?from=2025-06-01T00:00:00Z" \
  -H "X-API-Key: YOUR_API_KEY"

Multi-tenant (MSP)

For resellers and PBX operators: per-tenant sub-keys, usage rollups, and suppression lists under one prepaid balance. Account-level keys only.
GET/api/v1/account/tenantsList tenants

List the account’s tenants (downstream customers / sites), each with a trailing-30-day usage rollup and sub-key count. Only account-level keys may manage tenants — a tenant sub-key cannot.

Example request
curl https://numbers.online/api/v1/account/tenants \
  -H "X-API-Key: YOUR_API_KEY"
POST/api/v1/account/tenantsCreate a tenant

Create a tenant so per-customer usage, billing rollups, rate limits, and suppression lists are attributed separately while all spend draws on the one account balance. Read one tenant’s detail with GET /api/v1/account/tenants/{id}; enable/disable it with PATCH /api/v1/account/tenants/{id} {"status":"active"|"disabled"} (disabling also disables its sub-keys).

Example request
curl -X POST https://numbers.online/api/v1/account/tenants \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"name": "Dental office"}'
POST/api/v1/account/tenants/{id}/keysIssue a tenant sub-key

Mint an API key scoped to one tenant. The sub-key inherits the account’s tier and bills against the account’s single prepaid balance; it can perform lookups only (a PBX credential, not an account credential — it cannot manage tenants or top up). The raw key is returned exactly once.

Example request
curl -X POST https://numbers.online/api/v1/account/tenants/TENANT_ID/keys \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"name": "Front desk PBX"}'
POST/api/v1/account/tenants/{id}/suppressionsManage tenant suppressions

Add a number to a tenant’s suppression list (POST), list entries (GET — labels + timestamps only; numbers are stored as SHA-256 hashes and never returned), or remove one (DELETE the same number). A suppressed number gets no enrichment (no CNAM dip, no spam score) and no charge when looked up through that tenant’s sub-keys.

Example request
curl -X POST https://numbers.online/api/v1/account/tenants/TENANT_ID/suppressions \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"number": "+14155552671", "label": "front desk"}'

Receipts & verification

Signed, privacy-safe lookup receipts (Ed25519) and the public signing key. No key required.
GET/api/v1/receipts/{id}Retrieve a signed receiptNO KEY

Fetch a signed, privacy-safe lookup receipt by its unguessable id — the id is the capability, so no API key is needed and the evidence can be shared with counsel. PII-free: the number appears only as number_hash = sha256(E.164). Verify response_signature over signed_payload with the Ed25519 key from /api/v1/publickey, then recompute sha256(your number) and match number_hash. A supplementary signal, not a compliance assertion.

Example request
curl https://numbers.online/api/v1/receipts/nol_rec_8sd91kfh20aJ
GET/api/v1/publickeyEd25519 signing public keyNO KEY

The Ed25519 public key (SPKI PEM) used to sign inbound-lookup responses and lookup receipts, so any verifier can check a signature without out-of-band key exchange. public_key_pem is null when no signing key is configured (responses ship "unsigned"). No key required.

Example request
curl https://numbers.online/api/v1/publickey