numbersonline
API reference/Integration guides/SBC / SIP redirect integration
SBC / SIP operators

SBC / SIP redirect integration

a ClearIP-compatible call-setup signal for Kamailio, OpenSIPS, dSIPRouter, Sansay, Oracle/Acme Packet & ProSBC

Add a supplementary call-screening signal to a session border controller using numbers.online. On an inbound INVITE your SBC asks for a low-confidence decision on the calling number and maps it to a standard SIP final response — 603 to decline, 302 to divert, 503/404 to allow — exactly the contract Sansay ERS, Oracle/Acme session agents, and ProSBC route-retry already speak.

Positioning. This is a low-confidence, supplementary signal — not a verdict, and not a compliance determination. Your SBC keeps every routing and blocking decision. numbers.online never asserts that a call is lawful, unlawful, safe, or spam. A 603 block is only ever returned for a deterministic fact (an invalid/unroutable calling number) or a government/licensed-authoritative one (a number that is DNC-listed or reassigned according to a configured data partner). The crowd/heuristic spam score can only ever raise an advisory flag or — if you explicitly opt in — a redirect; it can never drive a block.


1. Architecture — why a thin SIP shim

numbers.online is an HTTPS/JSON service behind Cloudflare; it is not a SIP endpoint, so your SBC cannot dial it directly over SIP. Instead you run a tiny Kamailio or OpenSIPS redirect-server shim (config below) inside your own network:

  SBC  ──INVITE──▶  numbers.online shim (Kamailio/OpenSIPS)  ──HTTPS──▶  /api/v1/sbc/redirect
   ▲                          │                                              │
   └────── 603 / 302 / 503 / 404 ◀───── maps the JSON decision to a SIP final response ◀┘

SIP stays entirely inside your network; only a single outbound HTTPS dip leaves. This is the same affordance ClearIP ships as its "In-Line Proxy" — your SBC points at the shim with zero SBC-vendor cooperation, because SIP redirect/route servers are a generic SBC feature.


2. The decision contract

POST https://numbers.online/api/v1/sbc/redirect

Request (JSON):

{
  "number": "+14155552671",
  "allow_code": 503,
  "spam_threshold": 80,
  "redirect_threshold": 90,
  "block_reassigned": false,
  "block_invalid": true
}
FieldDefaultMeaning
number (required)The calling number (E.164 recommended).
allow_code503SIP code for allow/route-advance: 503 (ClearIP default) or 404 (use for Oracle/Acme, Ribbon, Metaswitch — they re-INVITE on 503).
spam_threshold80spam_score at/above which the decision becomes flag (advisory).
redirect_threshold(off)Opt-in: spam_score at/above which the decision becomes redirect (302 auto-divert).
block_reassignedfalseTreat reassigned yes (from a configured partner) as a block.
block_invalidtrueBlock an unparseable/invalid calling number (deterministic).
verstat, called_numberOptional STIR/SHAKEN passthrough and dialed number (reserved).

Response (JSON, uniform shape for known/unknown/valid/invalid numbers):

{
  "schema_version": "2026-06-06",
  "e164": "+14155552671",
  "valid": true,
  "decision": "allow",
  "sip": { "code": 503, "reason": "Service Unavailable" },
  "redirect_target": null,
  "advisory": {
    "spam_score": 12,
    "confidence": "low",
    "line_type": "mobile",
    "verstat": "unknown",
    "dnc_status": "unknown",
    "reassigned_status": "unknown"
  },
  "signal": "supplementary",
  "provider": "numbers.online",
  "receipt_id": "nol_rec_8sd91kfh20aJ",
  "insufficient_balance": false,
  "as_of": "2026-06-06T00:00:00.000Z"
}
decisionsip.codeYour shim emits
block603603 Decline — drop the call.
redirect302302 Moved Temporarily with a Contact you set (your IVR/CAPTCHA/voicemail). numbers.online supplies no routing target.
flag503/404The allow code, plus an elevated advisory spam_score your own logic may screen on.
allow503/404The allow code — your SBC route-advances using its own table.

sip.code is authoritative — your shim can emit it directly. decision is the human-readable label.


3. Quick smoke test

curl -s https://numbers.online/api/v1/sbc/redirect \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"number":"+14155552671"}' | jq .decision

A key with the sbc_redirect use case is required — every lookup-entitled key has it (it is backfilled, and new keys get it by default).


4. Kamailio

Download /integrations/kamailio/numbers_online_sbc.cfg. It loads http_async_client + jansson, queries the endpoint with a sub-second $http_req(timeout), and maps the decision to sl_send_reply. Set your API key from a #!define/AVP loaded from the environment — never a committed literal. Kamailio is the recommended path when you need a tight (sub-500ms) call-setup budget.

5. OpenSIPS

Download /integrations/opensips/numbers_online_sbc.cfg. It uses rest_client (async(rest_post(...), resume)) + the json module. Note: rest_client timeouts are integer-seconds, so the OpenSIPS path's worst case is ~1s, not sub-500ms — size your SBC budget accordingly or use Kamailio for tighter budgets.

6. dSIPRouter

dSIPRouter is Kamailio underneath — apply the Kamailio recipe to its managed config. See /integrations/dsiprouter/README.md. Multi-tenant deployments mint a per-tenant sub-key through the MSP control plane so usage rolls up per customer.

7. Sansay, Oracle/Acme Packet, ProSBC (native SIP redirect)

These SBCs query a redirect server natively — point them at your shim:

  • Sansay VSXiApp Servers → External Routing Server (ERS). VSXi sends the INVITE and routes on the returned 302 Contact, or drops on 603.
  • Oracle / Acme Packet — a session-agent + local-policy with redirect-action recurse; 302 recurses to Contact, 603 drops, 404 route-advances (set allow_code: 404).
  • ProSBC (TelcoBridges) — a NAP + Route with per-response-code retry actions: 302 reroutes to the Contact list, 404/503Continue call (route advance), 603Stop call. Set allow_code: 404.

8. Latency, fail-open & idempotency

  • Fail-open is mandatory on the call path. Every shim recipe treats a transport error, non-200, timeout, or unparseable body as allow (route-advance). A numbers.online outage must never drop a call. The server itself returns decision: "allow" (never a 5xx) on its own timeout or error.
  • Tell us your deadline. Send your shim's call-setup budget as the X-SBC-Budget-Ms header (or budget_ms in the body, capped at 5000). We never bill a decision that overran your budget.
  • Idempotency. Send an Idempotency-Key header so retries bill at most once.
  • Insufficient balance still allows. A depleted prepaid balance returns insufficient_balance: true and still allows the call on the deterministic fields (no fresh CNAM dip). Top up to restore the full signal.

9. Operator HMAC request signing (optional, Phase 4.3)

For operator-grade auth you can require a signed request per key. Fetch the key's HMAC secret and toggle signing:

# Fetch the derived HMAC secret + scheme for the calling key
curl -s https://numbers.online/api/v1/account/signing -H "Authorization: Bearer YOUR_API_KEY" | jq .

# Require signed requests on this key
curl -s -X POST https://numbers.online/api/v1/account/signing \
  -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"enabled":true}'

Then sign each request with HMAC-SHA256 over the canonical string and send three headers:

canonical = METHOD \n PATH \n sha256(body)hex \n timestamp \n nonce

X-Operator-Signature: hmac-sha256:<base64(hmac)>
X-Operator-Timestamp: <unix seconds>          # must be within ±300s
X-Operator-Nonce:     <unique per request>    # single-use (replay defense)

The secret is HKDF-derived server-side from a deployment master + your immutable key id — nothing operator-specific is stored at rest, and it is re-derivable through your own key. The nonce is genuinely single-use for the full validity window, and the timestamp must be within ±300s. Auth fails closed: a missing/expired/replayed/invalid signature is a 401 (and your shim then fails open locally). RFC 9421 HTTP Message Signatures (alg="ed25519") is a documented future upgrade.

Path note for signed requests: the canonical PATH is the exact request path. Sign and send the full /api/v1/sbc/redirect path — not the /v1/sbc/redirect short form — so the signature matches what the server canonicalizes.


10. Compliance evidence

Every SBC decision on a valid number emits a signed, PII-free receipt (long-retained). Export them as a signed robocall-mitigation evidence bundle — see the FCC evidence-bundle guide.


Keys & billing

  • Use a key with the sbc_redirect use case (all lookup-entitled keys have it).
  • Free tier: rate-limited, not billed — good for testing.
  • Standard tier: billed $0.010 per decision (bundled validity + line type + risk + DNC/reassigned), volume-discounted below the AI-agent mcp_call bundle. Top up at POST /api/v1/account/topup.
  • The raw key is shown once at issuance and stored only as a hash. For the ?key= query-param fallback (where headers are impossible), use a dedicated, rotatable key.
  • Multi-tenant SBCs: mint per-tenant sub-keys via the MSP control plane so usage and billing attribute per customer.
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.
AI voice agentsOutbound pre-call check & call-provenance