Worked request and response samples
Copy a request body as written, substitute your own number, and compare the response envelope. Every sample pairs a plain E.164 number — Devotel Orbit forwards it as the CAMARA subject — against adv_test_sk_* sandbox key, so no operator is contacted, no credits are deducted, and the response carries meta.test_mode: true. X-Test-Mode: true behaves the same way on a dashboard-session-authenticated call; a live key (dv_live_sk_*) always reaches the operator.
Authentication, per-service subscription, and the response envelope
Two things gate every call on this page. First, your Orbit API key in theX-API-Key header: dv_live_sk_* for live traffic, dv_test_sk_* for the zero-charge sandbox. Second, a per-CAMARA-service subscription with the operator behind your deployment — Number Verification, SIM Swap, Device Location, Quality-on-Demand, Carrier Billing, KYC Match, and Connectivity Insights are each enabled per deployment as the operator contract covers them.
Read that enrollment back before you gate live traffic: GET /api/v1/numbers/network-apis/status answers { "data": { "enabled": true } } when a CAMARA operator is configured, and any signal dip on an unenrolled deployment fails closed with a 503 instead of a fabricated result (catalogued below).
Every 2xx response arrives in the same { data, meta } envelope. data carries the operator’s answer with CAMARA field names preserved; meta carries request_id, timestamp, and test_mode. Errors invert the envelope: error.code, error.status, error.message, plus error.details when a field-level or upstream cause is available.
The 38 operations in five families
- Silent identity proof —
number-verification:verify(possession),sim-swap:check+sim-swap:retrieve-date+sim-swap/subscriptions(recency + continuous monitoring),device-swap:check(handset change),device-roaming-status:retrieve+device-roaming-status/subscriptions(visited country),device-status:reachability,device-location:verify,number-recycling:check(tenure),scam-signal:assess(active-call / forwarding / swap dip),kyc-match:match(operator KYC),age-verification:verify(age gate),carrier-billing:charge(direct carrier billing). - Unified risk fusion —
risk:scorereturns the weighted 0–100 composite with reason codes;identity:gatereturns the same composite as anallow | review | denydecision plusreview_or_blockfor a funnel. - Quality-on-Demand — create/read/extend/delete
qod-sessionsfor an on-demand QoS data bearer. - Network slices + connectivity — book/read/delete
network-slicesreservations; check or subscribe toconnectivity-insights:check-network-qualitycongestion verdicts. - Bring-your-own-prefix routing —
internet-access/announcements(announce / list / withdraw),route-holds:assess(is a failover switch safe now), andfailover-events(the audit feed).
{ data, meta } envelope.
E.164 or hashed subject — exactly one. Every operation that takes a subscriber subject accepts
"phoneNumber" in E.164, or its SHA-256 equivalent "hashedPhoneNumber" — never both in one body. Send the plain E.164 form; Orbit forwards it to the operator as the CAMARA subject and masks it in every error detail. Devotel Orbit itself only ever speaks JSON toward the operator — an XML body shape appears only on operators that still run a legacy XML HLR endpoint, and even then it is the operator-facing contract, never yours.1. Number Verification (Silent Auth)
POST /api/v1/numbers/network-apis/number-verification:verify"phoneNumber" (E.164) or its SHA-256 equivalent "hashedPhoneNumber" — exactly one. Add accessToken when your device already completed the three-legged operator flow; without it the call still runs, but server-context possession is only as strong as the operator deployment allows.
devicePhoneNumberVerified: false means not confirmed — treat it as no assertion, never as proof of absence.
2. SIM Swap check
POST /api/v1/numbers/network-apis/sim-swap:checkmaxAge is the look-back in hours (1..2400, default 240). A swapped: true inside the window is a strong account-takeover signal — step up before you accept the session.
POST /sim-swap:retrieve-date returns the operator’s last SIM-change time under the same envelope. For continuous monitoring, POST /sim-swap/subscriptions enrolls the number and the operator POSTs a CloudEvent to your notificationUrl the moment a swap occurs — see section 7 for that round trip.
2b. SIM Swap subscription — create + the webhook it triggers
POST /api/v1/numbers/network-apis/sim-swap/subscriptionsnotificationUrl must be HTTPS; notificationAuthToken is sent to your sink as a bearer token on every delivery so you can authenticate the operator’s call.
notificationUrl. Your endpoint receives this exact envelope — switch on type and read the subject from data.subscriptionDetail.device.phoneNumber:
Webhook (POST to your notificationUrl)
3. Device Location verification
POST /api/v1/numbers/network-apis/device-location:verifylatitude, longitude) and radius in metres (2,000..200,000) — and the operator answers whether the device is inside it without revealing where it actually is. verificationResult is TRUE, FALSE, PARTIAL (coverage overlap, not a clean hit), or UNKNOWN (no fix inside maxAge seconds, 60..3600).
PARTIAL with the estimated matchRate — the verification-area read you treat as “probable, step up” rather than a clean pass:
200 (PARTIAL)
4. Device reachability + roaming status
POST /api/v1/numbers/network-apis/device-status:reachabilityCONNECTED_DATA, CONNECTED_SMS, or NOT_CONNECTED) for a device, without contacting it. A NOT_CONNECTED read is a corroborating fraud signal; CONNECTED_SMS tells you SMS delivery alone is still possible.
NOT_CONNECTED — nothing is dispatched to the handset; the verdict comes straight from the operator’s registration state:
200 (NOT_CONNECTED)
POST /api/v1/numbers/network-apis/device-roaming-status:retrieve{ phoneNumber } in, one verdict out:
5. Unified Identity Risk score
POST /api/v1/numbers/network-apis/risk:scoreroaming, reputationRiskLevel, callForwardingUnconditional) into ONE weighted 0–100 composite. Each live signal is fetched fail-soft — an unavailable operator is reported under signals_unavailable and contributes nothing, never a fabricated mid-score.
identity:gate is the funnel variant of the same scoring: same inputs (plus portedRecently and a claimed geofence), same composite, but the envelope is shaped for a gate — { decision, review_or_block, risk_score, risk_level, reasons } — so a live funnel can branch without re-interpreting the numeric score.
6. Scam Signal assessment
POST /api/v1/numbers/network-apis/scam-signal:assessrisk_level, and a scam_signal_detected boolean. No call content is accessed; the consuming app still makes the final allow/review/block decision.
200 (escalated)
7. Quality-on-Demand session
POST /api/v1/numbers/network-apis/qod-sessionsdevice (phone Number or IPv4), the applicationServer (IPv4), a qosProfile the operator offers, and duration in seconds (60..86400). Returns the operator-issued sessionId, qosStatus (REQUESTED → AVAILABLE / UNAVAILABLE), and expiry. GET reads a session’s current status, POST .../extend adds seconds, DELETE releases it early.
POST .../extend takes requestedAdditionalDuration in seconds and answers 200 with the widened record; DELETE answers 204 with an empty body.
DELETE returns 204 No Content with no body — treat the 2xx status alone as confirmation the session is gone; GET on the id afterward answers 404.
8. Continuous monitoring — subscription round trip
POST /api/v1/numbers/network-apis/sim-swap/subscriptionsnotificationUrl the moment the watched number’s signal changes (roaming-on / roaming-off, a swap event, a congestion transition, a slice state change). The same pattern applies to device-roaming-status/subscriptions and connectivity-insights/subscriptions — create reads, read state, then DELETE to stop.
sub_1b3d5f7a9c2e4g6h8i0j is the same id GET /sim-swap/subscriptions/{subscriptionId} reads back in the subscription-state reads below — create and read are one flow: create, handle the CloudEvent (or poll), then DELETE the same id to stop.
Remaining envelopes by family
The eight walkthrough sections above cover ten of the thirty-two create/read/update operations this page lists; the page renders thirty-eight endpoints in total — those thirty-two plus six teardown calls, which answer 204 with no body and are documented in the closing teardown subsection so the page’s worked sequencing stays in family order. The remaining operations follow the same envelope conventions — a{ data, meta } wrapper, operator fields carried verbatim under data, and the sandbox flag in meta.test_mode when a test-prefixed key is used. Each envelope below sits under the METHOD /path callout of the exact operation it documents, so the generated page splices it into that operation’s response slot; copy any pair straight into a pre-send risk check or a number-intelligence read without a trip to the sandbox.
Operator status — is a live operator configured?
GET /api/v1/numbers/network-apis/status200 (operator enrolled)
{ "data": { "enabled": false } } — the same shape as section 503’s fail-closed gate.
Bring-your-own-prefix routing — announcements and failover
POST /api/v1/numbers/network-apis/internet-access/announcements{ prefix, asn, proofOfOwnershipToken } body also drives the withdraw call (DELETE on the same path) — documented in the teardown subsection below.
GET /api/v1/numbers/network-apis/internet-access/announcementsfamily echoes the optional ipv4 | ipv6 filter, or both when unfiltered.
POST /api/v1/numbers/network-apis/internet-access/failover-eventsnext when more rows exist. Both filters are optional: prefix restricts the feed to one announced CIDR, limit (1..500) caps the most-recent-first page.
POST /api/v1/numbers/network-apis/internet-access/route-holds:assessswitch_safe: true; a pending or missing hold read resolves unsafe. parent_prefix_hint carries the operator’s covering-route hint when it offers one; active_holds counts the holds evaluated.
Carrier billing, age verification, and device swap — request + response pairs
The remaining pair-of-hands operations the walkthroughs skip, shown end to end with the exact body you send and the envelope you get back.Carrier Billing charge
POST /api/v1/numbers/network-apis/carrier-billing:chargeamount in major currency units (2 decimal places max), currency (ISO 4217), a 1..140-char description, plus optional merchantReference (echoed to the operator as referenceCode) and idempotencyKey so a retry can never double-bill. The route rejects any amount above the per-deployment cap before the call reaches the operator, and the live handler answers 201 with the operator’s payment record. The wallet-spend failure you can hit is a 402 INSUFFICIENT_BALANCE — the same balance gate the INSUFFICIENT_BALANCE troubleshooting page walks for every paid surface.
402
422 Over cap
Age Verification
POST /api/v1/numbers/network-apis/age-verification:verifyageThreshold is an integer 13..120. The response carries the fail-closed ageVerified boolean plus the operator’s raw ageCheck marker (and identityMatchScore when the operator supplies it) for your audit trail — branch on ageVerified, never on the raw token.
Device Swap check
POST /api/v1/numbers/network-apis/device-swap:checkmaxAge is the look-back in hours (1..2400, default 240). The response tells you whether the SIM started answering from a different IMEI inside the window, and when the most recent change happened.
- Age Verification answers a verdict, never a birthdate. Anything but an explicit affirmative from the operator (a
false, a missing field, an error shape leaking through a 2xx) resolvesageVerified: false— the fail-closed rule the buyer’s age gate must inherit. - Carrier Billing is the one operation on this page that moves money. The
amountcap is server-side per deployment, and the 402 / 422 failure envelopes above are the two rejection shapes a production integrator must branch on before retrying.
Identity signals beyond the walkthroughs
POST /api/v1/numbers/network-apis/number-recycling:checkPOST /api/v1/numbers/network-apis/kyc-match:matchtrue, false, or not_available per field, with an optional numeric score per attribute — never the underlying PII. Send the subscriber’s claimed identity alongside the number; the worked body below submits a full KYC document and gets one mostly-clean match back with a single mismatch to branch on.
POST /api/v1/numbers/network-apis/sim-swap:retrieve-datemaxAge so a stale SIM answers swapped: false while still returning the raw date for your audit trail.
POST /api/v1/numbers/network-apis/identity:gaterisk:score: same composite score, but the envelope carries the explicit decision plus review_or_block so a funnel can branch without re-interpreting the number.
Connectivity insights, slices, and QoD reads
POST /api/v1/numbers/network-apis/connectivity-insights:check-network-qualitymeets the application requirements or unable to meet the application requirements; the derived read adds the congestion verdict, the normalized congestionBand, and whether that verdict describes the current or a predicted horizon.
POST /api/v1/numbers/network-apis/connectivity-insights/subscriptionsci-sub-01), so the create → read pair reads as one flow.
GET /api/v1/numbers/network-apis/connectivity-insights/subscriptions/{subscriptionId}ci-sub-01 record above — plus the last congestion verdict the operator recorded for the watched number while the subscription is ACTIVE.
lastObservation mirrors the congestion payload the one-shot check-network-quality call returns (congestion + congestionBand + horizon); it is absent until the operator records a first verdict, and the webhook above remains the real-time feed.
The webhook round trip. Create a Connectivity Insights subscription the same way you create a SIM-swap one: one POST carrying the watched number and your HTTPS sink. The worked body below enrolls the same +14155552671 used throughout this page and takes back the ci-sub-01 record above.
cURL
ACTIVE, every congestion transition the operator detects is POSTed to your notificationUrl as a CloudEvent. notificationAuthToken comes back as the Authorization: Bearer header on each delivery — check it before you trust the body:
Webhook (POST to your notificationUrl)
Node.js (Express receiver)
DELETE /connectivity-insights/subscriptions/{subscriptionId} — the teardown answers 204 and the operator stops POSTing.
POST /api/v1/numbers/network-apis/network-slicesbookingId plus its state (REQUESTED on creation, then ACTIVE once the operator confirms), echoed back with the window and device cap you booked.
GET /api/v1/numbers/network-apis/network-slicesGET /api/v1/numbers/network-apis/network-slices/{bookingId}qos descriptor is the operator’s live assertion for the slice, not the profile you requested at booking — treat a mismatch against your booking as the operator’s current offer for this reservation.
GET /api/v1/numbers/network-apis/qod-sessions/{sessionId}REQUESTED until the operator confirms AVAILABLE or UNAVAILABLE), the profile, the lifetime window, and the measured throughput while the bearer is up.
throughput appears once qosStatus reaches AVAILABLE; while the session is still REQUESTED the record carries the status, profile, and window only.
POST /api/v1/numbers/network-apis/qod-sessions/{sessionId}/extendduration and pushed-back expiresAt.
9. Python goose — SDK escape hatch for a one-off read
The typed SDKs mirror the most-used operations; for the long tail, every SDK exposes a genericrequest() escape hatch that sends any path on this page with the client’s auth already applied. This goose client polls device-status:reachability for the worked number:
Python
cURL
200
10. Caller-correctable 4xx — operator rejection, expired subscription, QoD conflict
The 422 / 502 / 503 table above covers validation and operator-availability failures. Three more 4xx shapes are caller-correctable and worth branching on explicitly: an operation your operator deployment does not offer, a subscription you keep using past expiry, and a QoD session you try to create twice.operator_not_supported — the deployment’s operator does not offer this CAMARA service (distinct from the no-operator 503): the service is configured but not served. Reroute to a fallback or gate the feature until the operator enrollment covers it.
422
subscription_not_found — a read or delete against a subscriptionId, sessionId, or bookingId the operator no longer knows (never enrolled on this deployment, already deleted, or purged after expiry). Re-read your create response for the id that call returned; do not cache ids across deployments.
404
subscription_expired — a read or delete against a subscription whose expiresAt has passed. Renew by creating a fresh subscription and retry once with the new id rather than reusing the stale one.
410
qod_session_conflict — one active QoD session per device and application server. Either extend the live session (POST .../extend) or DELETE it before creating a replacement.
409
Polling a subscription. Prefer the CloudEvent webhooks — polling is the fallback when your sink missed a delivery. A poll loop treats 200 as “still live unless
REVOKED”, 404 as “gone, stop”, and 410 as “renew”:
cURL (poll until terminal)
device-roaming-status/subscriptions/{subscriptionId} and connectivity-insights/subscriptions/{subscriptionId} by swapping the path; QoD sessions and slice bookings terminate on qosStatus/state instead of status.
Subscription state reads and teardowns
Every subscription read on this page answers the same lifecycle instatus: ACTIVE while the operator monitors the number, EXPIRED once expiresAt has passed (reads then answer the subscription_expired 410 below), and REVOKED when the operator withdrew the subscription server-side before expiry — treats it as terminal, re-enroll with a fresh POST /subscriptions rather than polling.
POST /api/v1/numbers/network-apis/device-roaming-status/subscriptionsroaming-on / roaming-off CloudEvents to your notificationUrl.
GET /api/v1/numbers/network-apis/sim-swap/subscriptions/{subscriptionId}lastSimSwapDate is truncated to day precision (T00:00:00.000Z) and lastSimSwapDateMasked is always true on this read, so you can rank the subscription’s recency without the operator exposing a privacy-sensitive exact instant. When the last swap predates the operator’s retention window, both fields are omitted; for the precise date your fraud flow wants, call POST /sim-swap:retrieve-date with the subject for each check.
GET /api/v1/numbers/network-apis/device-roaming-status/subscriptions/{subscriptionId}roaming/countryCode/countryName carry the same visited-country answer the one-shot device-roaming-status:retrieve returns — checkedAt stamps when the operator last asserted it. When the device is home, roaming is false and the country fields are omitted.
Subscription, session, slice, and announcement teardowns — 204 No Content
DELETE /api/v1/numbers/network-apis/sim-swap/subscriptions/{subscriptionId}DELETE /api/v1/numbers/network-apis/device-roaming-status/subscriptions/{subscriptionId}, that of DELETE /api/v1/numbers/network-apis/connectivity-insights/subscriptions/{subscriptionId}, that of DELETE /api/v1/numbers/network-apis/qod-sessions/{sessionId}, that of DELETE /api/v1/numbers/network-apis/network-slices/{bookingId}, and that of DELETE /api/v1/numbers/network-apis/internet-access/announcements. All six answer 204 No Content with no body — the 2xx status alone confirms the operator stopped the subscription, released the session, freed the slice, or withdrew the prefix; a GET on the same id afterward answers 404.
The one body in the family. Withdrawing a prefix announcement is the exception: it carries the same fenced { prefix, asn, proofOfOwnershipToken } body its POST create takes — the operator honors a withdrawal only against a live enrollment fence, so mirror your announce call verbatim:
Error envelope — operator-side rejection
An off-spec body (a non-E.164 number, an out-of-rangeradius, a missing subject field) is rejected before any operator sees it, so the 422 with VALIDATION_ERROR costs you nothing and carries the offending field in error.details.issues. When the operator itself rejects the request (an unknown subscriber, an out-of-range window) the rejection is mapped to a caller-correctable 422 with the operator’s own code preserved in details.upstream_code; when the operator cannot be reached at all, the call surfaces as a 502 UPSTREAM_ERROR rather than a false result. Sandbox keys never reach an operator, so you see the upstream shapes only with a live key.
422
phoneNumber in every error detail is masked — a rejection never echoes the full E.164 subject back.
Error envelope — 503 fails closed with no operator
Call any live signal dip before a CAMARA operator is enrolled for the deployment and the route fails closed: no signal is fabricated, no low-risk answer is invented, and the caller gets a single, explicit 503. Every operation on this page raises the identical body, so aGET /status-gated client should treat enabled: false as “this is what any call would return”.
503
Auth failure — missing or invalid key
Every operation on this page first passes the platform’s API-key gate. A missing, malformed, or revokedX-API-Key fails with a 401 before the network-apis layer runs: no operator contact, no credits deducted. This is the client-credentials failure mode for server-to-server callers — confirm the header carries the raw key (no Bearer wrapper) and the right prefix for the environment (dv_test_sk_* for sandbox, dv_live_sk_* for live).
401
Worked sequence: confirm reachability, then subscribe to roaming events
The pre-send check a high-value transaction actually runs, end to end: prove the device answers, read where it roams, enroll continuous roaming monitoring, and book the QoS bearer when the “send” is a live session rather than a message. Which signals to combine for account-takeover vs. delivery-risk decisions is the strategy side, covered in Network signals with GSMA Open Gateway; this section is the wire format, with every response body shown as the sandbox returns it.GSMA Open Gateway surface, three flows
The thirty-eight operations on this page do three jobs:- Prove the subscriber — Number Verification, SIM Swap, KYC Match, Age Verification: is this person who they claim, right now?
- Place the device — Device Status reachability, Device Roaming Status, Device Location: where is it, and can it hear from you?
- Shape the bearer — Quality-on-Demand sessions and network slices: give the traffic the latency or throughput it needs while the session lasts.
X-API-Key and returns the same { data, meta } envelope. A dv_test_sk_* key answers from the sandbox with meta.test_mode: true and never contacts an operator, so you can wire and replay the whole sequence below at zero charge.
Number Verification silent auth
POST /api/v1/numbers/network-apis/number-verification:verifyphoneNumber in E.164, or its SHA-256 hashedPhoneNumber. When the device has already completed the operator’s three-legged redirect, add the accessToken it brought back — the operator then matches the redirected session against the MSISDN it sees on the bearer. That redirect-then-confirm pair is the silent-auth alternative to an SMS OTP: the device proves possession over the operator flow, your backend confirms with this call.
true is the network asserting possession of the number. false is no assertion, not proof of absence — fall back to OTP rather than rejecting the user.
SIM-swap gate
POST /api/v1/numbers/network-apis/sim-swap:checkmaxAge is hours (1..2400, default 240).
POST /api/v1/numbers/network-apis/sim-swap:retrieve-datePOST /api/v1/numbers/network-apis/sim-swap/subscriptionsGET /api/v1/numbers/network-apis/sim-swap/subscriptions/{subscriptionId}notificationUrl; the delivery envelope and the bearer-token check for your receiver are shown in section 2b above. Stop the feed with DELETE on the same id (204, no body).
Roaming + QoD for high-value sends
Confirm the device can hear from you, then read where it sits. ANOT_CONNECTED reachability read before an OTP send is a wasted-send gate; a roaming read that puts the device in a country you do not serve is a funnel gate.
POST /api/v1/numbers/network-apis/device-status:reachabilityroaming plus the visited country when the operator supplies it:
POST /api/v1/numbers/network-apis/device-roaming-status:retrieveroaming-on / roaming-off CloudEvents to your notificationUrl as the device crosses borders:
POST /api/v1/numbers/network-apis/device-roaming-status/subscriptionsGET /api/v1/numbers/network-apis/device-roaming-status/subscriptions/{subscriptionId} reads the same record back; DELETE on the id stops the feed with 204.
When the high-value send is a live session — a video consult, a cloud-gaming stream — book the QoS bearer instead of trusting the default one. qosProfile names an offering the operator publishes for your deployment (the worked deployment’s low-latency profile is QOS_L); duration is seconds, 60..86400.
POST /api/v1/numbers/network-apis/qod-sessionsqosStatus moves REQUESTED → AVAILABLE (or UNAVAILABLE) once the operator confirms; poll with GET /qod-sessions/{sessionId}, add time with POST .../extend, release early with DELETE (204). The full extend/delete round trip is in section 7.
Tenant prefix announcements
If your tenant brings its own IP space, announce the prefix toward the Internet and keep the failover audit feed on hand. The create body carries the fence — the proof-of-ownership token the operator issued at enrollment — and your owning ASN:POST /api/v1/numbers/network-apis/internet-access/announcementsPOST with query filters (prefix restricts to one announced CIDR, limit 1..500 caps the page) — it answers who announced or withdrew which prefix, most recent first:
POST /api/v1/numbers/network-apis/internet-access/failover-eventsDELETE /internet-access/announcements and the same fenced body; re-read the list to confirm the prefix left your ACTIVE set. The strategy for combining these signals before a high-value send — which dips gate, which step up, which merely log — lives in Network signals with GSMA Open Gateway.