# Kamailio & OpenSIPS SIP redirect call screening — a ClearIP-compatible SBC signal

- Category: SBC / SIP operators
- Published: June 3, 2026 · Updated: June 15, 2026
- Canonical: https://numbers.online/docs/integrations/sbc-sip-redirect

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):

```json
{
  "number": "+14155552671",
  "allow_code": 503,
  "spam_threshold": 80,
  "redirect_threshold": 90,
  "block_reassigned": false,
  "block_invalid": true
}
```

| Field | Default | Meaning |
|---|---|---|
| `number` (required) | — | The **calling** number (E.164 recommended). |
| `allow_code` | `503` | SIP code for allow/route-advance: `503` (ClearIP default) or `404` (use for Oracle/Acme, Ribbon, Metaswitch — they re-INVITE on 503). |
| `spam_threshold` | `80` | spam_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_reassigned` | `false` | Treat reassigned `yes` (from a configured partner) as a block. |
| `block_invalid` | `true` | Block an unparseable/invalid calling number (deterministic). |
| `verstat`, `called_number` | — | Optional STIR/SHAKEN passthrough and dialed number (reserved). |

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

```json
{
  "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"
}
```

| `decision` | `sip.code` | Your shim emits |
|---|---|---|
| `block` | `603` | **603 Decline** — drop the call. |
| `redirect` | `302` | **302 Moved Temporarily** with a `Contact` *you* set (your IVR/CAPTCHA/voicemail). Numbers Online supplies no routing target. |
| `flag` | `503`/`404` | The allow code, **plus** an elevated advisory `spam_score` your own logic may screen on. |
| `allow` | `503`/`404` | The 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

```bash
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`](/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`](/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`](/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 VSXi** — *App 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/503` → *Continue call* (route advance), `603` → *Stop 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:

```bash
# 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](/docs/integrations/fcc-evidence-bundle).

---

## 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.

## Keys & references

Keys are self-service at https://numbers.online/docs — shown once, stored only as a hash.
Machine-readable schema: https://numbers.online/api/spec · all guides: https://numbers.online/md/docs/integrations

- Previous guide: [AI voice agents](https://numbers.online/md/docs/integrations/ai-voice-agents-mcp)
- Next guide: [Outbound pre-call check & call-provenance](https://numbers.online/md/docs/integrations/precall-call-provenance)

---

Numbers Online — community-powered phone-number trust signals. Every figure on this
page is a supplementary, low-confidence signal — advisory, not a verdict on any number
or its owner.

- Canonical page (HTML): https://numbers.online/docs/integrations/sbc-sip-redirect
- Report a call: https://numbers.online/report · Listed in error? Request removal: https://numbers.online/opt-out
- Machine guide to the phone-intelligence API: https://numbers.online/llms.txt · OpenAPI: https://numbers.online/api/spec
