Register a webhook for operator SMS/voice events. At most one
registration per (account, operator, network) — eventType is not
part of that key, so registering a second event type for the same
operator+network replaces the first. Registering again for an existing
combination without update: true is a 409.
eventType: voice (or both) registers successfully as long as the
operator/network combination itself is valid — there is no
registration-time check that voice is actually enabled, unlike sms.
Voice events only fire for a line whose active plan includes voice
support; a line on a plan with no voice allowance won’t produce voice
events even with a registered webhook. This applies to voiceStreamUrl
too — there’s no separate “voice streaming” plan capability, it’s
gated by the same voice allowance as voiceUrl/callbackVoiceUrl.
voiceStreamUrl is delivered differently from every other field here:
instead of an HTTP POST, Spenza opens an outbound WebSocket connection
to it (accepts ws://, wss://, http://, or https://) whenever a
live voice call starts on that operator/network, sends a JSON
handshake frame, then streams binary PCM audio (8kHz, 16-bit, mono) in
real time for the duration of the call. It’s never used as a
POST .../webhooks/{id}/test target (see that operation).
signingSecret is returned only from this creation path (format
whsec_<64 hex chars>) — no read endpoint ever returns it again. Store
it immediately; losing it means re-registering. Use it to verify the
X-Spenza-Signature header on every delivery (see the Webhooks guide).
Credential your endpoint requires — Spenza presents it when calling you. This is not a payload-signing scheme (see signingSecret/X-Spenza-Signature for that).
Set true to overwrite an existing registration for this operator+network. Coerced via class-transformer — sending the string "false" is truthy and also overwrites; send a real JSON boolean.
Response
Registered (or updated, if update:true).
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Spenza Partner API","colors":{"primary":"#4A90E2","light":"#6BA7EA","dark":"#3A7BC8"},"logo":{"light":"https://mintcdn.com/spenza/GJzB73Y-B-hhARyI/logo/spenza.png?fit=max\u0026auto=format\u0026n=GJzB73Y-B-hhARyI\u0026q=85\u0026s=fbc1eb2578f28d2a746d4705efa218e1","dark":"https://mintcdn.com/spenza/Z5R2JpHgh3kjkBT1/logo/spenza-dark.png?fit=max\u0026auto=format\u0026n=Z5R2JpHgh3kjkBT1\u0026q=85\u0026s=9c5f62da35c95508b83e786be10cf4b7","href":"https://spenza.com/"},"favicon":"https://mintcdn.com/spenza/6rGuabM28__mWZpe/favicon.jpg?fit=max\u0026auto=format\u0026n=6rGuabM28__mWZpe\u0026q=85\u0026s=c7c9675b82abf1acd84122e31e933cfb","navbar":{"links":[{"href":"https://spenza.com/","label":"Home"},{"href":"https://spenza.com/support/","label":"Support"},{"href":"/postman-collection","label":"Postman"},{"href":"https://status.spenza.com","label":"Status"}],"primary":{"type":"button","label":"Login","href":"https://web.spenza.com/login"}},"footer":{"socials":{"website":"https://spenza.com/"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"spenza","hasAudioNarration":false,"actualSubdomain":"spenza","customDomains":["docs.spenza.com"],"gitSource":{"type":"github","owner":"isimplexityorg","repo":"api-backend","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"collectionId":"9f05c287-fff5-4ced-bfc1-a43e5cd9c20a","liveDeploymentHistoryId":"6ae2f8bd3ff06ac66ce60a8e","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae2f8bd3ff06ac66ce60a8e"},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6ae2f8bd3ff06ac66ce60a8e","clientVersion":"0.0.4045","searchFilterCounts":[{"language":"default","tag":"API Reference","count":85},{"language":"default","tag":"Webhooks","count":8},{"language":"default","tag":"Device Groups","count":7},{"language":"default","tag":"SIM Groups","count":7},{"language":"default","tag":"SIMs","count":7},{"language":"default","tag":"User Groups","count":7},{"language":"default","tag":"Overview","count":5},{"language":"default","tag":"Reference","count":5},{"language":"default","tag":"Billing","count":5},{"language":"default","tag":"Plans \u0026 Catalog","count":5}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/webhooks/register-or-update-a-webhook","slug":"/api-reference/webhooks/register-or-update-a-webhook","pageMetadata":{"title":"Register or update a webhook","description":"Register a webhook for operator SMS/voice events. At most **one\nregistration per (account, operator, network)** — `eventType` is not\npart of that key, so registering a second event type for the same\noperator+network replaces the first. Registering again for an existing\ncombination without `update: true` is a `409`.\n\n`eventType: voice` (or `both`) registers successfully as long as the\noperator/network combination itself is valid — there is no\nregistration-time check that voice is actually enabled, unlike `sms`.\nVoice events only fire for a line whose active plan includes voice\nsupport; a line on a plan with no voice allowance won't produce voice\nevents even with a registered webhook. This applies to `voiceStreamUrl`\ntoo — there's no separate \"voice streaming\" plan capability, it's\ngated by the same voice allowance as `voiceUrl`/`callbackVoiceUrl`.\n\n`voiceStreamUrl` is delivered differently from every other field here:\ninstead of an HTTP POST, Spenza opens an outbound WebSocket connection\nto it (accepts `ws://`, `wss://`, `http://`, or `https://`) whenever a\nlive voice call starts on that operator/network, sends a JSON\nhandshake frame, then streams binary PCM audio (8kHz, 16-bit, mono) in\nreal time for the duration of the call. It's never used as a\n`POST .../webhooks/{id}/test` target (see that operation).\n\n**`signingSecret` is returned only from this creation path** (format\n`whsec_\u003c64 hex chars>`) — no read endpoint ever returns it again. Store\nit immediately; losing it means re-registering. Use it to verify the\n`X-Spenza-Signature` header on every delivery (see the Webhooks guide).\n","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/webhooks","href":"/api-reference/webhooks/register-or-update-a-webhook","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n strong: \"strong\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"Register a webhook for operator SMS/voice events. At most \", _jsx(_components.strong, {\n children: \"one\\nregistration per (account, operator, network)\"\n }), \" — \", _jsx(_components.code, {\n children: \"eventType\"\n }), \" is not\\npart of that key, so registering a second event type for the same\\noperator+network replaces the first. Registering again for an existing\\ncombination without \", _jsx(_components.code, {\n children: \"update: true\"\n }), \" is a \", _jsx(_components.code, {\n children: \"409\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n children: \"eventType: voice\"\n }), \" (or \", _jsx(_components.code, {\n children: \"both\"\n }), \") registers successfully as long as the\\noperator/network combination itself is valid — there is no\\nregistration-time check that voice is actually enabled, unlike \", _jsx(_components.code, {\n children: \"sms\"\n }), \".\\nVoice events only fire for a line whose active plan includes voice\\nsupport; a line on a plan with no voice allowance won’t produce voice\\nevents even with a registered webhook. This applies to \", _jsx(_components.code, {\n children: \"voiceStreamUrl\"\n }), \"\\ntoo — there’s no separate “voice streaming” plan capability, it’s\\ngated by the same voice allowance as \", _jsx(_components.code, {\n children: \"voiceUrl\"\n }), \"/\", _jsx(_components.code, {\n children: \"callbackVoiceUrl\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n children: \"voiceStreamUrl\"\n }), \" is delivered differently from every other field here:\\ninstead of an HTTP POST, Spenza opens an outbound WebSocket connection\\nto it (accepts \", _jsx(_components.code, {\n children: \"ws://\"\n }), \", \", _jsx(_components.code, {\n children: \"wss://\"\n }), \", \", _jsx(_components.code, {\n children: \"http://\"\n }), \", or \", _jsx(_components.code, {\n children: \"https://\"\n }), \") whenever a\\nlive voice call starts on that operator/network, sends a JSON\\nhandshake frame, then streams binary PCM audio (8kHz, 16-bit, mono) in\\nreal time for the duration of the call. It’s never used as a\\n\", _jsx(_components.code, {\n children: \"POST .../webhooks/{id}/test\"\n }), \" target (see that operation).\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsxs(_components.strong, {\n children: [_jsx(_components.code, {\n children: \"signingSecret\"\n }), \" is returned only from this creation path\"]\n }), \" (format\\n\", _jsx(_components.code, {\n children: \"whsec_\u003c64 hex chars>\"\n }), \") — no read endpoint ever returns it again. Store\\nit immediately; losing it means re-registering. Use it to verify the\\n\", _jsx(_components.code, {\n children: \"X-Spenza-Signature\"\n }), \" header on every delivery (see the Webhooks guide).\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Register or update a webhook","description":"Register a webhook for operator SMS/voice events. At most **one\nregistration per (account, operator, network)** — `eventType` is not\npart of that key, so registering a second event type for the same\noperator+network replaces the first. Registering again for an existing\ncombination without `update: true` is a `409`.\n\n`eventType: voice` (or `both`) registers successfully as long as the\noperator/network combination itself is valid — there is no\nregistration-time check that voice is actually enabled, unlike `sms`.\nVoice events only fire for a line whose active plan includes voice\nsupport; a line on a plan with no voice allowance won't produce voice\nevents even with a registered webhook. This applies to `voiceStreamUrl`\ntoo — there's no separate \"voice streaming\" plan capability, it's\ngated by the same voice allowance as `voiceUrl`/`callbackVoiceUrl`.\n\n`voiceStreamUrl` is delivered differently from every other field here:\ninstead of an HTTP POST, Spenza opens an outbound WebSocket connection\nto it (accepts `ws://`, `wss://`, `http://`, or `https://`) whenever a\nlive voice call starts on that operator/network, sends a JSON\nhandshake frame, then streams binary PCM audio (8kHz, 16-bit, mono) in\nreal time for the duration of the call. It's never used as a\n`POST .../webhooks/{id}/test` target (see that operation).\n\n**`signingSecret` is returned only from this creation path** (format\n`whsec_\u003c64 hex chars>`) — no read endpoint ever returns it again. Store\nit immediately; losing it means re-registering. Use it to verify the\n`X-Spenza-Signature` header on every delivery (see the Webhooks guide).\n","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/webhooks","href":"/api-reference/webhooks/register-or-update-a-webhook","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"tags":["Webhooks"],"summary":"Register or update a webhook","operationId":"registerWebhook","description":"Register a webhook for operator SMS/voice events. At most **one\nregistration per (account, operator, network)** — `eventType` is not\npart of that key, so registering a second event type for the same\noperator+network replaces the first. Registering again for an existing\ncombination without `update: true` is a `409`.\n\n`eventType: voice` (or `both`) registers successfully as long as the\noperator/network combination itself is valid — there is no\nregistration-time check that voice is actually enabled, unlike `sms`.\nVoice events only fire for a line whose active plan includes voice\nsupport; a line on a plan with no voice allowance won't produce voice\nevents even with a registered webhook. This applies to `voiceStreamUrl`\ntoo — there's no separate \"voice streaming\" plan capability, it's\ngated by the same voice allowance as `voiceUrl`/`callbackVoiceUrl`.\n\n`voiceStreamUrl` is delivered differently from every other field here:\ninstead of an HTTP POST, Spenza opens an outbound WebSocket connection\nto it (accepts `ws://`, `wss://`, `http://`, or `https://`) whenever a\nlive voice call starts on that operator/network, sends a JSON\nhandshake frame, then streams binary PCM audio (8kHz, 16-bit, mono) in\nreal time for the duration of the call. It's never used as a\n`POST .../webhooks/{id}/test` target (see that operation).\n\n**`signingSecret` is returned only from this creation path** (format\n`whsec_\u003c64 hex chars>`) — no read endpoint ever returns it again. Store\nit immediately; losing it means re-registering. Use it to verify the\n`X-Spenza-Signature` header on every delivery (see the Webhooks guide).\n","requestBody":"d2fe907e-6553-4e75-ad2b-e00b5dec99b2","responses":{"201":"c5830904-41c1-44e7-82ed-caed49330d57","400":"0bf2b0c6-4b4a-43c0-a3dd-f6eb10b197e8","409":"7b2ac38a-3d1c-4491-80b8-4bf63142714e"},"method":"post","type":"path","servers":["9985245e-477a-47ad-977d-32b247cc3dad"],"security":["a92800d6-ea01-48e1-a0b5-d7f10c221d1a"],"path":"/api/v1.1/webhooks","baseUrlOptions":["https://api.spenza.com"],"title":"Register or update a webhook","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["operator","network","eventType","authentication","webhookUrls"],"properties":{"operator":{"type":"string","example":"SpenzaJ","isRequired":true,"uniqueKey":"operator","typeLabel":"string"},"network":{"type":"string","example":"T-Mobile","isRequired":true,"uniqueKey":"network","typeLabel":"string"},"eventType":{"type":"string","enum":["sms","voice","both"],"isRequired":true,"uniqueKey":"eventType","typeLabel":"enum\u003cstring>"},"authentication":{"type":"object","required":["type"],"description":"Credential your endpoint requires — Spenza presents it when calling you. This is not a payload-signing scheme (see `signingSecret`/`X-Spenza-Signature` for that).","properties":{"type":{"type":"string","enum":["basic","bearer","api_key","none"],"isRequired":true,"uniqueKey":"authentication.type","typeLabel":"enum\u003cstring>"},"username":{"type":"string","description":"Required when type=basic.","example":"partner-webhook","uniqueKey":"authentication.username","typeLabel":"string"},"password":{"type":"string","description":"Required when type=basic.","example":"a-secret-you-choose","uniqueKey":"authentication.password","typeLabel":"string"},"token":{"type":"string","description":"Required when type=bearer.","example":"a-secret-you-choose","uniqueKey":"authentication.token","typeLabel":"string"},"apiKey":{"type":"string","description":"Required when type=api_key.","example":"a-secret-you-choose","uniqueKey":"authentication.apiKey","typeLabel":"string"},"apiKeyHeader":{"type":"string","default":"X-API-Key","uniqueKey":"authentication.apiKeyHeader","typeLabel":"string"}},"isRequired":true,"uniqueKey":"authentication","typeLabel":"object"},"webhookUrls":{"type":"object","properties":{"messageUrl":{"type":"string","format":"uri","description":"Incoming SMS.","example":"https://partner.example.com/hooks/sms","uniqueKey":"webhookUrls.messageUrl","typeLabel":"string\u003curi>"},"callbackMessageUrl":{"type":"string","format":"uri","description":"SMS delivery-status callbacks.","example":"https://partner.example.com/hooks/sms-status","uniqueKey":"webhookUrls.callbackMessageUrl","typeLabel":"string\u003curi>"},"voiceUrl":{"type":"string","format":"uri","description":"Incoming voice events.","example":"https://partner.example.com/hooks/voice","uniqueKey":"webhookUrls.voiceUrl","typeLabel":"string\u003curi>"},"callbackVoiceUrl":{"type":"string","format":"uri","description":"Voice/trunk callbacks; payload includes a trunkType field.","example":"https://partner.example.com/hooks/voice-status","uniqueKey":"webhookUrls.callbackVoiceUrl","typeLabel":"string\u003curi>"},"voiceStreamUrl":{"type":"string","description":"WS/WSS/HTTP(S) URL for live voice media — Spenza opens an outbound WS, sends a JSON handshake, then binary 8kHz/16-bit/mono PCM frames.","example":"wss://partner.example.com/hooks/voice-stream","uniqueKey":"webhookUrls.voiceStreamUrl","typeLabel":"string"}},"isRequired":true,"uniqueKey":"webhookUrls","typeLabel":"object"},"retryPolicy":{"type":"object","properties":{"maxAttempts":{"type":"integer","minimum":1,"maximum":10,"default":3,"uniqueKey":"retryPolicy.maxAttempts","typeLabel":"integer"},"backoffStrategy":{"type":"string","enum":["fixed","exponential","linear"],"default":"exponential","uniqueKey":"retryPolicy.backoffStrategy","typeLabel":"enum\u003cstring>"},"initialDelaySeconds":{"type":"integer","minimum":1,"maximum":60,"default":5,"uniqueKey":"retryPolicy.initialDelaySeconds","typeLabel":"integer"},"maxDelaySeconds":{"type":"integer","minimum":60,"maximum":3600,"default":300,"uniqueKey":"retryPolicy.maxDelaySeconds","typeLabel":"integer"}},"uniqueKey":"retryPolicy","typeLabel":"object"},"status":{"type":"string","enum":["active","inactive"],"default":"active","uniqueKey":"status","typeLabel":"enum\u003cstring>"},"description":{"type":"string","example":"Primary SMS webhook for T-Mobile","uniqueKey":"description","typeLabel":"string"},"update":{"type":"boolean","default":false,"description":"Set true to overwrite an existing registration for this operator+network. Coerced via class-transformer — sending the string \"false\" is truthy and also overwrites; send a real JSON boolean.","uniqueKey":"update","typeLabel":"boolean"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"operator":"SpenzaJ","network":"T-Mobile","authentication":{"username":"partner-webhook","password":"a-secret-you-choose","token":"a-secret-you-choose","apiKey":"a-secret-you-choose","apiKeyHeader":"X-API-Key"},"webhookUrls":{"messageUrl":"https://partner.example.com/hooks/sms","callbackMessageUrl":"https://partner.example.com/hooks/sms-status","voiceUrl":"https://partner.example.com/hooks/voice","callbackVoiceUrl":"https://partner.example.com/hooks/voice-status","voiceStreamUrl":"wss://partner.example.com/hooks/voice-stream"},"retryPolicy":{"maxAttempts":3,"backoffStrategy":"exponential","initialDelaySeconds":5,"maxDelaySeconds":300},"status":"active","description":"Primary SMS webhook for T-Mobile","update":false}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"c5830904-41c1-44e7-82ed-caed49330d57":{"description":"Registered (or updated, if `update:true`).","content":{"application/json":{"example":{"success":true,"data":{"id":"wh_69146d70ed68","operator":"SpenzaJ","network":"T-Mobile","eventType":"sms","status":"active","authentication":{"type":"bearer","token":"***ENCRYPTED***"},"webhookUrls":{"messageUrl":"https://partner.example.com/hooks/sms","callbackMessageUrl":null,"voiceUrl":null,"callbackVoiceUrl":null,"voiceStreamUrl":null},"retryPolicy":{"maxAttempts":5,"backoffStrategy":"exponential","initialDelaySeconds":5,"maxDelaySeconds":300},"description":null,"createdAt":"2026-07-10T10:00:00.000Z","updatedAt":"2026-07-10T10:00:00.000Z","signingSecret":"whsec_9b1f8c2e7a4d6053b8e1f2a9c4d7e6053b8e1f2a9c4d7e6053b8e1f2a9c4d70"}},"examples":{"Example":{"title":"Example","value":{"success":true,"data":{"id":"wh_69146d70ed68","operator":"SpenzaJ","network":"T-Mobile","eventType":"sms","status":"active","authentication":{"type":"bearer","token":"***ENCRYPTED***"},"webhookUrls":{"messageUrl":"https://partner.example.com/hooks/sms","callbackMessageUrl":null,"voiceUrl":null,"callbackVoiceUrl":null,"voiceStreamUrl":null},"retryPolicy":{"maxAttempts":5,"backoffStrategy":"exponential","initialDelaySeconds":5,"maxDelaySeconds":300},"description":null,"createdAt":"2026-07-10T10:00:00.000Z","updatedAt":"2026-07-10T10:00:00.000Z","signingSecret":"whsec_9b1f8c2e7a4d6053b8e1f2a9c4d7e6053b8e1f2a9c4d7e6053b8e1f2a9c4d70"}}}},"exampleType":"examples"}},"exampleType":"examples"},"0bf2b0c6-4b4a-43c0-a3dd-f6eb10b197e8":{"description":"Missing fields, or an unsupported operator/network/event-type combination.","content":{"application/json":{"examples":{"missingFields":{"title":"missingFields","value":{"success":false,"error":{"code":"MISSING_FIELDS","message":"Please fill in all the required fields to register this webhook.","details":{"missingFields":["webhookUrls"]}}}},"badEventTypeOrAuth":{"title":"badEventTypeOrAuth","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"Please check the event type and authentication settings you provided.","details":{"field":"eventType","allowed":["sms","voice","both"]}}}},"unknownOperatorNetwork":{"title":"unknownOperatorNetwork","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"That operator and network combination does not exist."}}},"notConfiguredForWebhooks":{"title":"notConfiguredForWebhooks","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"That operator and network combination is not configured for webhooks."}}},"smsNotSupported":{"title":"smsNotSupported","value":{"success":false,"error":{"code":"VALIDATION_ERROR","message":"That operator and network combination does not currently support SMS webhooks."}}}},"exampleType":"examples"}},"exampleType":"examples"},"7b2ac38a-3d1c-4491-80b8-4bf63142714e":{"description":"A webhook is already registered for this carrier without `update:true`.","content":{"application/json":{"example":{"success":false,"error":{"code":"CONFLICT","message":"A webhook is already registered for this carrier and event type — set the update flag to change it."}},"examples":{"Example":{"title":"Example","value":{"success":false,"error":{"code":"CONFLICT","message":"A webhook is already registered for this carrier and event type — set the update flag to change it."}}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"a92800d6-ea01-48e1-a0b5-d7f10c221d1a":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Bearer token obtained from `POST /api/v1.1/auth/token`.","scopes":[],"schemeName":"bearerAuth"}}},"servers":{"9985245e-477a-47ad-977d-32b247cc3dad":{"url":"https://api.spenza.com","description":"Production"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Bearer token obtained from `POST /api/v1.1/auth/token`.","scopes":[],"schemeName":"bearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Bearer token obtained from `POST /api/v1.1/auth/token`.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"bearerAuth","name":"Authorization"}],"title":"bearerAuth"}]},"originalFileLocation":"openapi.yaml"},"subdomain":"spenza","siteName":"Spenza Partner API","title":"Register or update a webhook - Spenza Partner API","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-29T07:35:45.708Z","originalFileLocation":"api-reference/webhooks/register-or-update-a-webhook.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Register a webhook for operator SMS/voice events. At most one registration per (account, operator, network) — eventType is not part of that key, so registering a second event type for the same operator+network replaces the first. Registering again for an existing combination without update: true is a 409. eventType: voice (or both) registers successfully as long as the operator/network combination itself is valid — there is no registration-time check that voice is actually enabled, unlike sms. Voice events only fire for a line whose active plan includes voice support; a line on a plan with no voice allowance won\u0026#x27;t produce voice events even with a registered webhook. This applies to voiceStreamUrl too — there\u0026#x27;s no separate \u0026quot;voice streaming\u0026quot; plan capability, it\u0026#x27;s gated by the same voice allowance as voiceUrl/callbackVoiceUrl. voiceStreamUrl is delivered differently from every other field here: instead of an HTTP POST, Spenza opens an outbound WebSocket connection to it (accepts ws://, wss://, http://, or https://) whenever a live voice call starts on that operator/network, sends a JSON handshake frame, then streams binary PCM audio (8kHz, 16-bit, mono) in real time for the duration of the call. It\u0026#x27;s never used as a POST .../webhooks/{id}/test target (see that operation). signingSecret is returned only from this creation path (format whsec_\u0026lt;64 hex chars\u0026gt;) — no read endpoint ever returns it again. Store it immediately; losing it means re-registering. Use it to verify the X-Spenza-Signature header on every delivery (see the Webhooks guide).\">\u003cmeta data-mint-head name=\"application-name\" content=\"Spenza Partner API\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/spenza/a8hAv7eroJmUmmEz/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/spenza/a8hAv7eroJmUmmEz/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/spenza/a8hAv7eroJmUmmEz/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/spenza/a8hAv7eroJmUmmEz/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/spenza/a8hAv7eroJmUmmEz/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/spenza/a8hAv7eroJmUmmEz/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/spenza/a8hAv7eroJmUmmEz/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/spenza/a8hAv7eroJmUmmEz/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/spenza/a8hAv7eroJmUmmEz/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Register or update a webhook - Spenza Partner API\">\u003cmeta data-mint-head property=\"og:description\" content=\"Register a webhook for operator SMS/voice events. At most one registration per (account, operator, network) — eventType is not part of that key, so registering a second event type for the same operator+network replaces the first. Registering again for an existing combination without update: true is a 409. eventType: voice (or both) registers successfully as long as the operator/network combination itself is valid — there is no registration-time check that voice is actually enabled, unlike sms. Voice events only fire for a line whose active plan includes voice support; a line on a plan with no voice allowance won\u0026#x27;t produce voice events even with a registered webhook. This applies to voiceStreamUrl too — there\u0026#x27;s no separate \u0026quot;voice streaming\u0026quot; plan capability, it\u0026#x27;s gated by the same voice allowance as voiceUrl/callbackVoiceUrl. voiceStreamUrl is delivered differently from every other field here: instead of an HTTP POST, Spenza opens an outbound WebSocket connection to it (accepts ws://, wss://, http://, or https://) whenever a live voice call starts on that operator/network, sends a JSON handshake frame, then streams binary PCM audio (8kHz, 16-bit, mono) in real time for the duration of the call. It\u0026#x27;s never used as a POST .../webhooks/{id}/test target (see that operation). signingSecret is returned only from this creation path (format whsec_\u0026lt;64 hex chars\u0026gt;) — no read endpoint ever returns it again. Store it immediately; losing it means re-registering. Use it to verify the X-Spenza-Signature header on every delivery (see the Webhooks guide).\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Spenza Partner API\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.spenza.com/api-reference/webhooks/register-or-update-a-webhook\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://spenza.mintlify.app/_mintlify/api/og/v2?division=Webhooks\u0026amp;title=Register+or+update+a+webhook\u0026amp;description=Register+a+webhook+for+operator+SMS%2Fvoice+events.+At+most+**one%0Aregistration+per+%28account%2C+operator%2C+network%29**+%E2%80%94+%60eventType%60+is+not%0Apart+of+that+key%2C+so+regist\u0026amp;theme=d935d10a2668cab1092b6754\u0026amp;signature=b96661c4a8c5259a63c0c9466eb8e07fa6e3870ff816d25aa21b293aa23b6bf4\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Register or update a webhook - Spenza Partner API\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Register a webhook for operator SMS/voice events. At most one registration per (account, operator, network) — eventType is not part of that key, so registering a second event type for the same operator+network replaces the first. Registering again for an existing combination without update: true is a 409. eventType: voice (or both) registers successfully as long as the operator/network combination itself is valid — there is no registration-time check that voice is actually enabled, unlike sms. Voice events only fire for a line whose active plan includes voice support; a line on a plan with no voice allowance won\u0026#x27;t produce voice events even with a registered webhook. This applies to voiceStreamUrl too — there\u0026#x27;s no separate \u0026quot;voice streaming\u0026quot; plan capability, it\u0026#x27;s gated by the same voice allowance as voiceUrl/callbackVoiceUrl. voiceStreamUrl is delivered differently from every other field here: instead of an HTTP POST, Spenza opens an outbound WebSocket connection to it (accepts ws://, wss://, http://, or https://) whenever a live voice call starts on that operator/network, sends a JSON handshake frame, then streams binary PCM audio (8kHz, 16-bit, mono) in real time for the duration of the call. It\u0026#x27;s never used as a POST .../webhooks/{id}/test target (see that operation). signingSecret is returned only from this creation path (format whsec_\u0026lt;64 hex chars\u0026gt;) — no read endpoint ever returns it again. Store it immediately; losing it means re-registering. Use it to verify the X-Spenza-Signature header on every delivery (see the Webhooks guide).\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://spenza.mintlify.app/_mintlify/api/og/v2?division=Webhooks\u0026amp;title=Register+or+update+a+webhook\u0026amp;description=Register+a+webhook+for+operator+SMS%2Fvoice+events.+At+most+**one%0Aregistration+per+%28account%2C+operator%2C+network%29**+%E2%80%94+%60eventType%60+is+not%0Apart+of+that+key%2C+so+regist\u0026amp;theme=d935d10a2668cab1092b6754\u0026amp;signature=b96661c4a8c5259a63c0c9466eb8e07fa6e3870ff816d25aa21b293aa23b6bf4\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/spenza/a8hAv7eroJmUmmEz/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Spenza Partner API\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#4A90E2\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.spenza.com/api-reference/webhooks/register-or-update-a-webhook\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/webhooks/register-or-update-a-webhook.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.spenza.com/#organization\",\"name\":\"Spenza Partner API\",\"url\":\"https://docs.spenza.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/spenza/GJzB73Y-B-hhARyI/logo/spenza.png?fit=max\u0026auto=format\u0026n=GJzB73Y-B-hhARyI\u0026q=85\u0026s=fbc1eb2578f28d2a746d4705efa218e1\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.spenza.com#website\",\"name\":\"Spenza Partner API\",\"url\":\"https://docs.spenza.com\",\"publisher\":{\"@id\":\"https://docs.spenza.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.spenza.com/api-reference/webhooks/register-or-update-a-webhook#webpage\",\"url\":\"https://docs.spenza.com/api-reference/webhooks/register-or-update-a-webhook\",\"name\":\"Register or update a webhook\",\"description\":\"Register a webhook for operator SMS/voice events. At most one registration per (account, operator, network) — eventType is not part of that key, so registering a second event type for the same operator+network replaces the first. Registering again for an existing combination without update: true is a 409. eventType: voice (or both) registers successfully as long as the operator/network combination itself is valid — there is no registration-time check that voice is actually enabled, unlike sms. Voice events only fire for a line whose active plan includes voice support; a line on a plan with no voice allowance won't produce voice events even with a registered webhook. This applies to voiceStreamUrl too — there's no separate \\\"voice streaming\\\" plan capability, it's gated by the same voice allowance as voiceUrl/callbackVoiceUrl. voiceStreamUrl is delivered differently from every other field here: instead of an HTTP POST, Spenza opens an outbound WebSocket connection to it (accepts ws://, wss://, http://, or https://) whenever a live voice call starts on that operator/network, sends a JSON handshake frame, then streams binary PCM audio (8kHz, 16-bit, mono) in real time for the duration of the call. It's never used as a POST .../webhooks/{id}/test target (see that operation). signingSecret is returned only from this creation path (format whsec_\\u003c64 hex chars>) — no read endpoint ever returns it again. Store it immediately; losing it means re-registering. Use it to verify the X-Spenza-Signature header on every delivery (see the Webhooks guide).\",\"dateModified\":\"2026-10-29T07:35:45.708Z\",\"isPartOf\":{\"@id\":\"https://docs.spenza.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.spenza.com/api-reference/webhooks/register-or-update-a-webhook#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.spenza.com/api-reference/webhooks/register-or-update-a-webhook#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"API Reference\",\"item\":\"https://docs.spenza.com/api-reference/authentication/exchange-credentials-for-a-token\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Webhooks\",\"item\":\"https://docs.spenza.com/api-reference/webhooks/list-webhook-registrations\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Register or update a webhook\",\"item\":\"https://docs.spenza.com/api-reference/webhooks/register-or-update-a-webhook\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.spenza.com/api-reference/webhooks/register-or-update-a-webhook#apireference\",\"headline\":\"Register or update a webhook\",\"name\":\"Register or update a webhook\",\"description\":\"Register a webhook for operator SMS/voice events. At most one registration per (account, operator, network) — eventType is not part of that key, so registering a second event type for the same operator+network replaces the first. Registering again for an existing combination without update: true is a 409. eventType: voice (or both) registers successfully as long as the operator/network combination itself is valid — there is no registration-time check that voice is actually enabled, unlike sms. Voice events only fire for a line whose active plan includes voice support; a line on a plan with no voice allowance won't produce voice events even with a registered webhook. This applies to voiceStreamUrl too — there's no separate \\\"voice streaming\\\" plan capability, it's gated by the same voice allowance as voiceUrl/callbackVoiceUrl. voiceStreamUrl is delivered differently from every other field here: instead of an HTTP POST, Spenza opens an outbound WebSocket connection to it (accepts ws://, wss://, http://, or https://) whenever a live voice call starts on that operator/network, sends a JSON handshake frame, then streams binary PCM audio (8kHz, 16-bit, mono) in real time for the duration of the call. It's never used as a POST .../webhooks/{id}/test target (see that operation). signingSecret is returned only from this creation path (format whsec_\\u003c64 hex chars>) — no read endpoint ever returns it again. Store it immediately; losing it means re-registering. Use it to verify the X-Spenza-Signature header on every delivery (see the Webhooks guide).\",\"url\":\"https://docs.spenza.com/api-reference/webhooks/register-or-update-a-webhook\",\"mainEntityOfPage\":{\"@id\":\"https://docs.spenza.com/api-reference/webhooks/register-or-update-a-webhook#webpage\"},\"dateModified\":\"2026-10-29T07:35:45.708Z\",\"publisher\":{\"@id\":\"https://docs.spenza.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.spenza.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Spenza Partner API\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Spenza Partner API","nav":{"global":null,"groups":[{"group":"Overview","pages":[{"title":"Introduction","href":"/introduction"},{"title":"Getting Started","href":"/getting-started"},{"title":"Core Concepts","href":"/core-concepts"},{"title":"Authentication","href":"/authentication"},{"title":"Quickstart","href":"/quickstart"}]},{"group":"Build","pages":[{"title":"Guides","href":"/guides"},{"title":"Webhooks","href":"/webhooks"},{"title":"Postman Collection","href":"/postman-collection"}]},{"group":"Reference","pages":[{"title":"Errors","href":"/errors"},{"title":"Rate Limits","href":"/rate-limits"},{"title":"Environments \u0026 Versioning","href":"/environments-versioning"},{"title":"Security \u0026 Best Practices","href":"/security"},{"title":"SDKs \u0026 Code Examples","href":"/sdks"}]},{"group":"Help","pages":[{"title":"API Status \u0026 Maintenance","href":"/status"},{"title":"FAQ \u0026 Troubleshooting","href":"/faq"},{"title":"Support","href":"/support"}]},{"group":"API Reference","pages":[{"group":"Authentication","pages":[{"title":"Exchange credentials for a token","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/auth/token","href":"/api-reference/authentication/exchange-credentials-for-a-token"}]},{"group":"SIMs","pages":[{"title":"List SIMs","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/sims","href":"/api-reference/sims/list-sims"},{"title":"Get a SIM by ICCID","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/sims/{iccid}","href":"/api-reference/sims/get-a-sim-by-iccid"},{"title":"Get SIM usage","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/sims/{iccid}/usage","href":"/api-reference/sims/get-sim-usage"},{"title":"Assign a SIM to a user","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/sims/{iccid}/assign","href":"/api-reference/sims/assign-a-sim-to-a-user"},{"title":"Request a new phone number","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/sims/{iccid}/renew-number","href":"/api-reference/sims/request-a-new-phone-number"},{"title":"Get a SIM's current service state","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/sims/{iccid}/service-state","href":"/api-reference/sims/get-a-sims-current-service-state"},{"title":"Enable or disable voice, SMS, and/or data on a SIM","deprecated":null,"version":null,"openapi":"/openapi.yaml patch /api/v1.1/sims/{iccid}/service-state","href":"/api-reference/sims/enable-or-disable-voice-sms-andor-data-on-a-sim"}]},{"group":"Subscriptions","pages":[{"title":"List subscriptions","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/subscriptions","href":"/api-reference/subscriptions/list-subscriptions"},{"title":"Get a SIM's subscription","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/sims/{iccid}/subscription","href":"/api-reference/subscriptions/get-a-sims-subscription"},{"title":"Cancel a subscription","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/subscriptions/{iccid}/cancel","href":"/api-reference/subscriptions/cancel-a-subscription"}]},{"group":"Plans \u0026 Catalog","pages":[{"title":"List plans","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/plans","href":"/api-reference/plans-\u0026-catalog/list-plans"},{"title":"Get a plan","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/plans/{planId}","href":"/api-reference/plans-\u0026-catalog/get-a-plan"},{"title":"List SIM products","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/sim-products","href":"/api-reference/plans-\u0026-catalog/list-sim-products"},{"title":"Purchase a plan (synchronous)","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/plans/purchase","href":"/api-reference/plans-\u0026-catalog/purchase-a-plan-synchronous"},{"title":"Purchase a plan (asynchronous)","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v3/plans/purchase","href":"/api-reference/plans-\u0026-catalog/purchase-a-plan-asynchronous"}]},{"group":"eSIM","pages":[{"title":"Provision an eSIM, optionally with a plan","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/esim","href":"/api-reference/esim/provision-an-esim-optionally-with-a-plan"},{"title":"Get eSIM activation QR","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/esim/{iccid}/qr","href":"/api-reference/esim/get-esim-activation-qr"}]},{"group":"Billing","pages":[{"title":"List invoices","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/invoices","href":"/api-reference/billing/list-invoices"},{"title":"Get an invoice","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/invoices/{id}","href":"/api-reference/billing/get-an-invoice"},{"title":"Download invoice PDF","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/invoices/{id}/pdf","href":"/api-reference/billing/download-invoice-pdf"},{"title":"Get credit balance","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/credit-balance","href":"/api-reference/billing/get-credit-balance"},{"title":"Add prepaid credit","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/top-up","href":"/api-reference/billing/add-prepaid-credit"}]},{"group":"Users","pages":[{"title":"List users","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/users","href":"/api-reference/users/list-users"},{"title":"Create a user","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/users","href":"/api-reference/users/create-a-user"},{"title":"Get a user","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/users/{email}","href":"/api-reference/users/get-a-user"},{"title":"Update a user","deprecated":null,"version":null,"openapi":"/openapi.yaml put /api/v1.1/users/{email}","href":"/api-reference/users/update-a-user"},{"title":"Delete a user","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1.1/users/{email}","href":"/api-reference/users/delete-a-user"}]},{"group":"Orders \u0026 Transactions","pages":[{"title":"List orders","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/orders","href":"/api-reference/orders-\u0026-transactions/list-orders"},{"title":"Get an order","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/orders/{id}","href":"/api-reference/orders-\u0026-transactions/get-an-order"},{"title":"List transactions","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/transactions","href":"/api-reference/orders-\u0026-transactions/list-transactions"}]},{"group":"Numbers \u0026 Port-in","pages":[{"title":"List port-in requests","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/port-ins","href":"/api-reference/numbers-\u0026-port-in/list-port-in-requests"},{"title":"Check port-in eligibility","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/port-in/eligibility","href":"/api-reference/numbers-\u0026-port-in/check-port-in-eligibility"},{"title":"Submit a port-in","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v3/port-in","href":"/api-reference/numbers-\u0026-port-in/submit-a-port-in"}]},{"group":"Messaging","pages":[{"title":"Send an SMS","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/sms","href":"/api-reference/messaging/send-an-sms"}]},{"group":"Webhooks","pages":[{"title":"List webhook registrations","description":"List webhook registrations, paginated in memory.","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/webhooks","href":"/api-reference/webhooks/list-webhook-registrations"},{"title":"Register or update a webhook","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/webhooks","href":"/api-reference/webhooks/register-or-update-a-webhook"},{"title":"Get a webhook registration","description":null,"deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/webhooks/{id}","href":"/api-reference/webhooks/get-a-webhook-registration"},{"title":"Update a webhook registration","deprecated":null,"version":null,"openapi":"/openapi.yaml put /api/v1.1/webhooks/{id}","href":"/api-reference/webhooks/update-a-webhook-registration"},{"title":"Delete a webhook registration","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1.1/webhooks/{id}","href":"/api-reference/webhooks/delete-a-webhook-registration"},{"title":"Send a test event","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/webhooks/{id}/test","href":"/api-reference/webhooks/send-a-test-event"},{"title":"List webhook deliveries","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/webhook-deliveries","href":"/api-reference/webhooks/list-webhook-deliveries"},{"title":"Redeliver a webhook event","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/webhook-deliveries/{id}/redeliver","href":"/api-reference/webhooks/redeliver-a-webhook-event"}]},{"group":"Voice Quality","pages":[{"title":"List voice quality webhooks","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/voice-quality/webhooks","href":"/api-reference/voice-quality/list-voice-quality-webhooks"},{"title":"Register a voice quality webhook","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/voice-quality/webhooks","href":"/api-reference/voice-quality/register-a-voice-quality-webhook"},{"title":"Get a voice quality webhook","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/voice-quality/webhooks/{id}","href":"/api-reference/voice-quality/get-a-voice-quality-webhook"},{"title":"Delete a voice quality webhook","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1.1/voice-quality/webhooks/{id}","href":"/api-reference/voice-quality/delete-a-voice-quality-webhook"},{"title":"Voicetestcompleted","version":null,"deprecated":null,"openapi":"/openapi.yaml webhook voice.test.completed","href":"/api-reference/voice-quality/voicetestcompleted"}]},{"group":"SIP Gateway","pages":[{"title":"Get your SIP gateway configuration","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1/customer/register-sip","href":"/api-reference/sip-gateway/get-your-sip-gateway-configuration"},{"title":"Register or update your SIP gateway","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1/customer/register-sip","href":"/api-reference/sip-gateway/register-or-update-your-sip-gateway"},{"title":"Delete your SIP gateway configuration","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1/customer/register-sip","href":"/api-reference/sip-gateway/delete-your-sip-gateway-configuration"}]},{"group":"Notifications","pages":[{"title":"List notifications","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/notifications","href":"/api-reference/notifications/list-notifications"},{"title":"Get notification preferences","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/notification-preferences","href":"/api-reference/notifications/get-notification-preferences"},{"title":"Update a notification preference","deprecated":null,"version":null,"openapi":"/openapi.yaml put /api/v1.1/notification-preferences","href":"/api-reference/notifications/update-a-notification-preference"}]},{"group":"Device Groups","pages":[{"title":"List device-groups","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/device-groups","href":"/api-reference/device-groups/list-device-groups"},{"title":"Create a device-group","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/device-groups","href":"/api-reference/device-groups/create-a-device-group"},{"title":"Get a device-group","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/device-groups/{name}","href":"/api-reference/device-groups/get-a-device-group"},{"title":"Update a device-group","deprecated":null,"version":null,"openapi":"/openapi.yaml put /api/v1.1/device-groups/{name}","href":"/api-reference/device-groups/update-a-device-group"},{"title":"Delete a device-group","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1.1/device-groups/{name}","href":"/api-reference/device-groups/delete-a-device-group"},{"title":"Move a device into this group","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/device-groups/{name}/devices","href":"/api-reference/device-groups/move-a-device-into-this-group"},{"title":"Remove a device from this group","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1.1/device-groups/{name}/devices/{meid}","href":"/api-reference/device-groups/remove-a-device-from-this-group"}]},{"group":"SIM Groups","pages":[{"title":"List sim-groups","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/sim-groups","href":"/api-reference/sim-groups/list-sim-groups"},{"title":"Create a sim-group","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/sim-groups","href":"/api-reference/sim-groups/create-a-sim-group"},{"title":"Get a sim-group","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/sim-groups/{name}","href":"/api-reference/sim-groups/get-a-sim-group"},{"title":"Update a sim-group","deprecated":null,"version":null,"openapi":"/openapi.yaml put /api/v1.1/sim-groups/{name}","href":"/api-reference/sim-groups/update-a-sim-group"},{"title":"Delete a sim-group","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1.1/sim-groups/{name}","href":"/api-reference/sim-groups/delete-a-sim-group"},{"title":"Move a SIM into this group","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/sim-groups/{name}/sims","href":"/api-reference/sim-groups/move-a-sim-into-this-group"},{"title":"Remove a SIM from this group","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1.1/sim-groups/{name}/sims/{iccid}","href":"/api-reference/sim-groups/remove-a-sim-from-this-group"}]},{"group":"User Groups","pages":[{"title":"List user-groups","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/user-groups","href":"/api-reference/user-groups/list-user-groups"},{"title":"Create a user-group","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/user-groups","href":"/api-reference/user-groups/create-a-user-group"},{"title":"Get a user-group","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/user-groups/{name}","href":"/api-reference/user-groups/get-a-user-group"},{"title":"Update a user-group","deprecated":null,"version":null,"openapi":"/openapi.yaml put /api/v1.1/user-groups/{name}","href":"/api-reference/user-groups/update-a-user-group"},{"title":"Delete a user-group","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1.1/user-groups/{name}","href":"/api-reference/user-groups/delete-a-user-group"},{"title":"Move a user into this group","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/user-groups/{name}/members","href":"/api-reference/user-groups/move-a-user-into-this-group"},{"title":"Remove a user from this group","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1.1/user-groups/{name}/members/{email}","href":"/api-reference/user-groups/remove-a-user-from-this-group"}]},{"group":"Devices","pages":[{"title":"List devices in your catalog","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/team-devices","href":"/api-reference/devices/list-devices-in-your-catalog"},{"title":"Get a device","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/devices/{imei}","href":"/api-reference/devices/get-a-device"},{"title":"Assign a device to a user","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/devices/{imei}/assign","href":"/api-reference/devices/assign-a-device-to-a-user"},{"title":"Unassign a device","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/devices/{imei}/unassign","href":"/api-reference/devices/unassign-a-device"}]},{"group":"Team Members","pages":[{"title":"List team members","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/team-members","href":"/api-reference/team-members/list-team-members"},{"title":"Invite a teammate as an admin","deprecated":null,"version":null,"openapi":"/openapi.yaml post /api/v1.1/team-members","href":"/api-reference/team-members/invite-a-teammate-as-an-admin"},{"title":"Get a team member","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v1.1/team-members/{email}","href":"/api-reference/team-members/get-a-team-member"},{"title":"Update a team member","deprecated":null,"version":null,"openapi":"/openapi.yaml put /api/v1.1/team-members/{email}","href":"/api-reference/team-members/update-a-team-member"},{"title":"Remove a team member","deprecated":null,"version":null,"openapi":"/openapi.yaml delete /api/v1.1/team-members/{email}","href":"/api-reference/team-members/remove-a-team-member"}]},{"group":"Async Status","pages":[{"title":"Poll the status of any v3 async operation","deprecated":null,"version":null,"openapi":"/openapi.yaml get /api/v3/transactions/{transactionId}","href":"/api-reference/async-status/poll-the-status-of-any-v3-async-operation"}]}]}]},"basePath":"","title":"Register or update a webhook - Spenza Partner API","buildId":"dpl_36EDyZCDfRuoUD9af5CH4M1bqY2h","deploymentId":"dpl_36EDyZCDfRuoUD9af5CH4M1bqY2h","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-DCDCdBVX.js","utils-ME8dDnLe.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-0e84ACsd.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-wgRBj-ia.js","snippetPresets-C11Sgb-o.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-C0lapOpP.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-ZeRQV8fF.js","shallow-BupWh095.js","getApiPlaygroundDisplay-BnYQO2Ss.js","CodeSnippet-RKKOc8c_.js","CodeSnippets-Drf_m8wS.js","Page-Bevw23-4.js","getPastedJson-u6QiPzNZ.js","icon-Bb-CBSxO.js","MethodPill-F7l5AI7V.js","DuplicateIcon-IiAXkdSg.js","createIcon-FliI8EBc.js","DynamicMarkdown-B62XqCSI.js","SectionHeading-Dj31pT03.js","axios-vUo_bRtp.js","Markdown-BOgQCTwD.js","clsx-BIWXJmsZ.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-DKZWslLH.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-UDqbR6xh.js"]}