numbersonline
API reference/Integration guides/Outbound pre-call check & call-provenance
Outbound & compliance

Outbound pre-call check & call-provenance

a do-not-call scrub before you dial, and a spoofing shield for your own number

Two endpoints for outbound voice/SMS senders — dialers, SBCs, and AI voice agents. Run a pre-call scrub on the number you are about to dial, and enrol your own verified business numbers so that calls spoofing your caller ID don't get charged to your reputation.

Positioning — read this first. The pre-call check is a supplementary signal, never a consent grant: a NO_MATCH result is not permission to call — you remain responsible for your own lawful basis. Enrolment records who you actually dialled so the absence of a record becomes evidence a reported call wasn't yours; it is not a compliance determination, a block, or a verdict on any call.


1. What it is for

  • Pre-call scrub (POST /api/v1/precall/lookup) — right before you dial a number, check whether its verified owner has asked not to be marketed to, and read a supplementary compliance signal. Free, bundled, fail-open.
  • Call-provenance — when the calling number (from) is one of your own enrolled verified business numbers, the pre-call check records a short-lived, hashed (from → to) edge. If a complaint later arrives about a call you never placed (because someone spoofed your number), the missing edge distinguishes your real, attested calls from the spoofed ones. The spoofed-call report is then treated as a supplementary signal about the spoofing and withheld from your own risk read — so the business whose identity was forged isn't the one penalised.

Both endpoints require an API key with the precall use case. Every self-service key has it by default.


2. Pre-call check

POST /api/v1/precall/lookup
X-API-Key: <your key>
Content-Type: application/json

{
  "from": "+14155550100",            # your calling number (E.164)
  "to":   "+14155552671",            # the number you are about to dial (E.164)
  "context": "outbound_voice"        # outbound_voice | outbound_sms
}

Response:

{
  "schema_version": "2026-06-08",
  "to": "+14155552671",
  "dnc": "NO_MATCH",                  // SUPPRESS | NO_MATCH | UNKNOWN
  "dnc_note": "Supplementary signal only. NO_MATCH is not consent; you remain responsible for your own lawful basis to call.",
  "compliance": { /* supplementary compliance signal, where a licensed provider is configured */ },
  "enrolled": true,                   // is `from` an enrolled number of yours?
  "provenance_recorded": true,        // was a provenance edge written for this call?
  "provenance_note": "…",
  "edge_id": "nol_edge_…",            // present only when an edge was recorded
  "ttl_seconds": 604800               // edge lifetime (7 days)
}
  • dncSUPPRESS (the verified owner asked not to be marketed to — remove them), NO_MATCH (no suppression on record — not consent), or UNKNOWN (not resolvable).
  • Fail-open. A slow or failing lookup never blocks your dialer — treat any error as UNKNOWN and proceed under your own lawful basis.
  • Free / bundled. The pre-call check is not metered.

3. Enrol your own number for call-provenance

Enrol once per number you own; thereafter every pre-call check from that number records a provenance edge.

POST /api/v1/precall/enroll
X-API-Key: <your key>
Content-Type: application/json

{
  "number": "+14155550100",          # one of YOUR verified business numbers
  "enrolled": true                   # false to revoke
}

Response:

{
  "ok": true,
  "number": "+14155550100",
  "enrolled": true,
  "attestation": "By enrolling, you attest that this number only places calls after a numbers.online outbound pre-call lookup. We treat the absence of a matching pre-call edge as a supplementary signal that a complaint may concern a spoofed call, not one you placed. Enrollment is revocable and abuse-monitored. Supplementary signal only — not a compliance determination."
}

Requirements:

  • Account-level key only. A tenant sub-key cannot enrol (403).
  • Your own verified number only. The number must be OTP-verified and bound to your account (404 otherwise). Verify a business number first via POST /api/v1/account/verify-phone/start/confirm.
  • Revocable. Send "enrolled": false to stop recording edges.

4. How the shield works (and its limits)

  • Base-rate firewall. Only enrolled numbers record edges. A non-enrolled number gets the scrub but no provenance inference — so "no edge" is only meaningful for numbers you deliberately enrolled.
  • 7-day window. Edges live for 7 days, which is also the report-matching window. Hashes are byte-identical on both ends, so a report about a call you placed within the window matches your edge.
  • Report-time labels. A community report about an enrolled number is labelled matched (a pre-call edge confirms you dialled this receiver), mismatched (enrolled owner + known receiver but no edge → the complaint may concern a spoofed call → withheld from your read and feeds a bounded spoofing signal), or null (not applicable).
  • Always hedged. The shield only fires when there's an enrolled owner, a known receiver, and no matching edge. We never claim certainty — only that a reported call is unlikely to have been yours. It is a supplementary signal, never a block or a verdict, and it is corroboration-gated and abuse-monitored.

5. Privacy

Both ends of every edge are stored only as SHA-256 hashes of the canonical E.164; raw numbers are never logged or stored. Edges are server-only and expire after 7 days. The provenance label on a report is a supplementary signal — not proof — and is never surfaced to either party as a verdict.

Need a key? Get one self-service — it’s shown once and stored only as a hash. Browse the other guides, grab copy-paste artifacts on the integrations page, or read the full machine-readable schema at /api/spec.
SBC / SIP redirect integrationFCC robocall-mitigation evidence bundle