Skip to main content
Languages: every operation supports cURL, Node.js (TypeScript), Python, Go, Ruby, and PHP. The first 15 operations on this page show all six languages; the remaining 7 show cURL and TypeScript — the two most-used.

Jambonz API

Jambonz endpoints exposed by the Devotel CPaaS API Base path: /api/v1/jambonz Endpoint count: 22

What Jambonz is here for

Devotel Orbit hosts a Jambonz instance for BYO-CPaaS voice: you bring your telephony stack (your SIP trunks, extensions, and voice webhooks), and Orbit runs the media server, the SIP edge, and the REST control plane that ties them together. This page is the wire contract of that hosted Jambonz. It is distinct from the native Voice API reference, which is Orbit’s own programmable-voice surface; the two share billing, numbers, and analytics, but they expose different models. The Jambonz model assumes you already know what an application, a carrier, and a verb hook are, so this overlay walks one tenant from registration to a first call before the per-operation reference below takes over. The SDKs do not ship a typed helper for this surface, so the worked samples use raw cURL plus a six-language CodeGroup where the call is one you make yourself. Every envelope below is what arrives on the wire in the softswitch → Orbit webhooks direction or on the control plane; field names are the public contract.

Bootstrap the tenant

Register your tenant with the hosted Jambonz control plane. The response carries the tenant credentials and the JWT you present on every subsequent control-plane call; store the JWT (it is short-lived; re-register or refresh before it expires rather than caching it in code).
201
The webhook_base_url is the address you configure on the switch: every hook on this page lives under it. The SIP-side bootstrap happens on the same call path. When the edge forwards a REGISTER, POST /api/v1/jambonz/auth/register answers with the digest verdict the registrar needs; a softphone credential returns the A1 hash, a trunk credential returns the stored password so the SBC can verify the digest itself:
200
A credential that has no password configured on the tenant is rejected with a fail verdict, never a silent drop:
401

Provision an application

An application binds a voice webhook URL to the tenant; a carrier tells the tenant where your SIP traffic enters. Create both with the JWT from the bootstrap step, then read the account’s application list to confirm the binding before you place a call.
cURL
201
cURL
201
cURL
200
The list entry showing your voice_url next to the carrier sid is the confirmation that inbound calls will arrive at your webhook.

Place a call

A placed call is one REST call against the tenant, then a conversation between the switch and your webhooks. The REST shape:
201
From there Orbit posts back to the URLs on the application. Two payloads cover most of what you will parse on your side. The call-status webhook reports each lifecycle transition (ringing, answered, completed):
call-status webhook payload
The verb webhook is the other direction of the same conversation: your voice_url receives the session and answers with a Jambonz verb array the switch executes in order. This one plays a greeting and dials a phone number:
verb webhook payload
The per-operation sections below document every hook the switch can fire while that call runs, chain by chain.

The webhook contract, chain by chain

Chain 1 — SIP trunk auth

POST /api/v1/jambonz/auth/register
Covered end to end in Bootstrap the tenant above: the control-plane register returns the JWT, and the SIP-side register answers the digest challenge with the A1 hash (or the fail verdict). The edge re-authorizes every REGISTER and INVITE this way; there is nothing long-lived to rotate on the SIP side.
200
POST /api/v1/jambonz/customer-trunk-auth
When your PBX INVITEs or REGISTERs through a customer-trunk carrier, this hook verifies the digest claim against the trunk’s stored credentials and records the attempt either way. A negative verdict can carry a blacklist window so the edge drops persistent unauthenticated callers:
200
POST /api/v1/jambonz/lookup
Fired once per inbound INVITE to resolve the route. The body is the session state, including the custom SIP headers the edge preserves:
Request
200
POST /api/v1/jambonz/lookup-next
When a route resolves to more than one page of candidates, the Lookup-next hook walks the next page with the same body and the same verb-array answer:
200

Chain 2 — inbound routing

POST /api/v1/jambonz/dial-confirm
Before the switch commits to a resolved dial target, it asks this hook to confirm. Answer with the dial as-is, rewrite it, or decline it:
200
POST /api/v1/jambonz/callback-answer
When a virtual-hold callback reaches the customer, the answered leg posts here and receives the same enqueue verbs a fresh inbound caller would get, re- placing the customer into their original queue:
200
POST /api/v1/jambonz/feature-code
Star-code presses (hold, transfer, record) land here; the response is the verb sequence that implements the feature:
200
POST /api/v1/jambonz/queue-wait
While a caller holds, the switch re-posts this hook and plays what you answer, typically a position and estimated-wait announcement:
200
POST /api/v1/jambonz/queue-action
Queue-action fires when a queued caller leaves the queue for any reason. On timeout the answer is the fallback verbs; on bridged or leave it is an empty array, and re-posting an outcome is safe because both are no-ops:
200
POST /api/v1/jambonz/queue-overflow
Queue-overflow fires when the queue crosses its cap; answer with the overflow route, usually a dial to a backup destination:
200
POST /api/v1/jambonz/conference-wait-music
Conference-wait-music loops hold audio for a waiting conference participant; the music URL arrives as a query parameter:
200
POST /api/v1/jambonz/mid-queue-voicemail
Mid-queue-voicemail offers a holding caller the escape hatch to voicemail; the gather’s actionHook points at the mailbox store:
200
POST /api/v1/jambonz/ivr-step
Each IVR node posts its gathered digits here and receives the next node’s verbs:
200
POST /api/v1/jambonz/ivr-record-finalize
When a recording leg ends, this hook confirms storage; an empty array ends the leg cleanly:
200
POST /api/v1/jambonz/call-status
Every lifecycle transition (ringing, answered, completed, failed) posts here; the ack is deliberately empty and fail-open, so a wobble on your side is never a 5xx that drops the call:
200
POST /api/v1/jambonz/dial-status
Per-leg dial outcomes post here with the same fail-open ack:
200

Chain 3 — AI voice agent

POST /api/v1/jambonz/bridge-to-lk
When a browser or mobile agent takes a call through LiveKit, the parked carrier leg redirects here; the response hands the leg to the room the client already joined, matched on the X-LK-Room SIP header:
200
POST /api/v1/jambonz/supervisor-bridge
A monitoring supervisor lands here; listen joins muted, whisper is audible only to the agent named by coachCallSid, and barge or conference join as an audible third party:
200
POST /api/v1/jambonz/quality-ingest
After the call, RTCP-XR metrics post here; the ack confirms acceptance:
200

Chain 4 — Mailbox fallback

POST /api/v1/jambonz/voicemail-pin
The PIN gather for a passcode-protected mailbox posts the digits here; a wrong PIN with attempts remaining returns a spoken re-challenge:
200
POST /api/v1/jambonz/voicemail-store
The recording leg posts the audio reference here; the empty ack confirms storage:
200
POST /api/v1/jambonz/pause-elapsed
When a paused leg resumes reporting, this hook answers what plays during the pause:
200

Errors worth branching on

Every hook authenticates with the jambonz-signature HMAC over the body; an unsigned or tampered request gets a 401 before any routing runs, and hook failures fail open or fail cleanly with a 4xx envelope, never a 5xx mid-call. Retry 429 and 5xx on the control plane; surface 4xx to the operator.
401
422
429
For the platform-wide decision table these branches plug into, see the error handling guide.

Sandbox

Sandbox vs live

Every call on this page honors X-Test-Mode: with a test-prefixed key (or the header on a session-authenticated request) the softswitch → Orbit webhooks pipeline runs without real provider delivery and without credit deduction, and responses carry meta.test_mode: true. Live keys ignore the header, so a sandbox run can never accidentally place a live call.
cURL

Register auth

POST /api/v1/jambonz/auth/register
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Bridge-to-lk jambonz

POST /api/v1/jambonz/bridge-to-lk
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Call-status jambonz

POST /api/v1/jambonz/call-status
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Callback-answer jambonz

POST /api/v1/jambonz/callback-answer
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Conference-wait-music jambonz

POST /api/v1/jambonz/conference-wait-music
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Customer-trunk-auth jambonz

POST /api/v1/jambonz/customer-trunk-auth
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Dial-confirm jambonz

POST /api/v1/jambonz/dial-confirm
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Dial-status jambonz

POST /api/v1/jambonz/dial-status
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Feature-code jambonz

POST /api/v1/jambonz/feature-code
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Ivr-record-finalize jambonz

POST /api/v1/jambonz/ivr-record-finalize
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Ivr-step jambonz

POST /api/v1/jambonz/ivr-step
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Lookup jambonz

POST /api/v1/jambonz/lookup
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Lookup-next jambonz

POST /api/v1/jambonz/lookup-next
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Mid-queue-voicemail jambonz

POST /api/v1/jambonz/mid-queue-voicemail
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Pause-elapsed jambonz

POST /api/v1/jambonz/pause-elapsed
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Quality-ingest jambonz

POST /api/v1/jambonz/quality-ingest
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Queue-action jambonz

POST /api/v1/jambonz/queue-action
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Queue-overflow jambonz

POST /api/v1/jambonz/queue-overflow
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Queue-wait jambonz

POST /api/v1/jambonz/queue-wait
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Supervisor-bridge jambonz

POST /api/v1/jambonz/supervisor-bridge
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Voicemail-pin jambonz

POST /api/v1/jambonz/voicemail-pin
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.

Voicemail-store jambonz

POST /api/v1/jambonz/voicemail-store
string
Stripe-style idempotency token. Pass a stable, client-generated value (1-255 chars) to dedupe retries on transient timeouts. The same key+credential+path replays the original response for 24h on 2xx (5min on 4xx, 30s on 5xx). Returns 409 if a concurrent request with the same key is already in flight; replayed responses include the Idempotency-Replay: true response header.
string (enum: true|false)
Sandbox opt-in for Clerk-session-authenticated requests. Set to true to route the call through the test-mode pipeline: no real provider delivery, no credits deducted, response meta.test_mode: true. Ignored for live API keys (dv_live_sk_*) — server-to-server clients must use a test-prefixed key (dv_test_sk_*) to exercise sandbox. Test-prefixed keys unconditionally enable sandbox regardless of this header.