Skip to main content

Number Masking (Proxy) API

Connect Party A to Party B via a third “proxy” number — both sides call or text the proxy and the platform forwards to the other end. Used by marketplaces and ride-share apps where the buyer and seller shouldn’t see each other’s real phone number. Base path: /api/v1/proxy Authentication: API key (X-API-Key) or session JWT. Session create/close requires the owner, admin, or developer role.

Using the SDKs

Python (same call via the SDK’s escape hatch):
The Python SDK is core-scope — it wraps the 8 core resources (messaging, voice, contacts, campaigns, verify, numbers) and reaches everything else through the generic client.request() escape hatch above. See the Python SDK. Returns the typed ApiResponse envelope. See the SDK index at SDK quickstart.

Sessions

A session is the active mapping. While the session is open, calls and SMS to the proxy number from either participant are forwarded to the other. ttl_minutes is optional (integer 1–1440, defaults to 60). When the TTL elapses the session expires, the proxy number is released back to the pool, and inbound traffic to it stops forwarding. Texting the proxy counts toward messaging usage; voice legs count toward voice usage.

Create a session

201 response — store session_id, proxy_number, and expires_at:

List sessions

status filters to active, closed, or expired. Pagination is cursor-based — pass next_cursor from meta.pagination back as cursor.

Get a session

Returns the session row: id, participant_a, participant_b, proxy_number, status, ttl_minutes, expires_at, closed_at, created_at, updated_at.

Close a session

Close early when the trip or transaction ends — this releases the number immediately rather than waiting for TTL expiry.
200 response:
Closing an already-closed or expired session returns 409 CONFLICT (see Errors below).

Webhooks

Register the proxy event types on your webhook endpoint to follow the session lifecycle. Every delivery carries an id (evt_…), type, and data — and an HMAC signature header for verification.

proxy.session.created

proxy.message.forwarded

Fired once per successful forward — this is what you listen for to mirror the ride-share conversation in your own UI (when Party A texts or calls the proxy, the platform forwards to Party B and fires this event):
The event fires only when the forward succeeded — an inbound message to an expired session, an unknown sender, or a delivery failure produces no event. Message bodies are not included in the payload.

proxy.session.closed

End-to-end sequence (ride-share)

  1. POST /proxy/sessions — rider and driver numbers, ttl_minutes: 90. Store session_id, proxy_number, expires_at.
  2. Show both parties the proxy number as the contact for the trip.
  3. The rider texts the proxy. The platform forwards the message to the driver from the proxy number and fires proxy.message.forwarded. The driver replies to the proxy; same flow in reverse.
  4. When the trip ends, DELETE /proxy/sessions/{id} to close the session and release the number. If you never close it, the session expires at expires_at, releases the number, and any later inbound traffic to it is ignored.
The carrier’s inbound traffic to the proxy number arrives at POST /api/v1/proxy/inbound — internal, signed for carrier use; do not call it from your integration.

SDKs

The Node SDK (@devotel/sdk-node) covers /proxy: orbit.proxy.createSession(...), orbit.proxy.listSessions({ status, limit, cursor }), orbit.proxy.getSession(id), orbit.proxy.closeSession(id), plus iterSessions() for auto-pagination. See the SDK reference for the exact doctype signatures — the API contract above is authoritative (participant_a, participant_b, ttl_minutes). If you need a straight-HTTP fallback:

Errors

All errors ship the same envelope:
Note: an expired session is not a 4xx — a GET on an expired session still returns 200 with status: "expired"; closing it after expiry is the 409 case. Inbound traffic to an expired (or released) proxy number is ignored after TTL, so the only signal that masking has lapsed is the expired status on the row.