{"openapi": "3.1.0", "info": {"title": "SautiPBX API", "version": "1.0", "description": "REST API for the SautiPBX voice platform."}, "paths": {"/api/calls/": {"get": {"operationId": "apps_api_routers_calls_list_calls", "summary": "List Calls", "parameters": [{"in": "query", "name": "direction", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Direction"}, "required": false}, {"in": "query", "name": "status", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Status"}, "required": false}, {"in": "query", "name": "search", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Search"}, "required": false}, {"in": "query", "name": "from_dt", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "From Dt"}, "required": false}, {"in": "query", "name": "to_dt", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "To Dt"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CallListOut"}}}}}, "description": "List CDRs for the authenticated account.", "tags": ["Calls"], "security": [{"BearerAuth": []}]}}, "/api/calls/originate": {"post": {"operationId": "apps_api_routers_calls_originate_call", "summary": "Originate Call", "parameters": [{"in": "header", "name": "Idempotency-Key", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Idempotency-Key"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CallOut"}}}}}, "description": "Place an outbound call (spec \u00a78.3). Dials `to` presenting `from` (a DID you\nown) as caller-id, and on answer hands the leg to the call-control document at\n`url`. Send an `Idempotency-Key` header so a retry never places a second call.", "tags": ["Calls"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/OriginateIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/calls/hangup": {"post": {"operationId": "apps_api_routers_calls_hangup_call", "summary": "Hangup Call", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CallOut"}}}}}, "description": "End a live call, passing the sid in the JSON body: `{\"sid\": \"call_abc\"}`.", "tags": ["Calls"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/HangupIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}, "get": {"operationId": "apps_api_routers_calls_hangup_call_by_query", "summary": "Hangup Call By Query", "parameters": [{"in": "query", "name": "sid", "schema": {"title": "Sid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CallOut"}}}}}, "description": "End a live call, passing the sid as a query argument: `/calls/hangup?sid=call_abc`.", "tags": ["Calls"], "security": [{"BearerAuth": []}]}}, "/api/calls/hangup/{sid}": {"get": {"operationId": "apps_api_routers_calls_hangup_call_by_path", "summary": "Hangup Call By Path", "parameters": [{"in": "path", "name": "sid", "schema": {"title": "Sid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CallOut"}}}}}, "description": "End a live call, passing the sid in the URL path: `/calls/hangup/call_abc`.", "tags": ["Calls"], "security": [{"BearerAuth": []}]}}, "/api/calls/{call_uuid}": {"get": {"operationId": "apps_api_routers_calls_get_call", "summary": "Get Call", "parameters": [{"in": "path", "name": "call_uuid", "schema": {"title": "Call Uuid", "type": "string"}, "required": true}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CallOut"}}}}}, "description": "Retrieve a single CDR by its uuid.", "tags": ["Calls"], "security": [{"BearerAuth": []}]}}, "/api/numbers/": {"get": {"operationId": "apps_api_routers_numbers_list_numbers", "summary": "List Numbers", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/DIDOut"}, "title": "Response", "type": "array"}}}}}, "description": "List DIDs owned by the authenticated account.", "tags": ["Numbers"], "security": [{"BearerAuth": []}]}}, "/api/numbers/available": {"get": {"operationId": "apps_api_routers_numbers_available", "summary": "Available", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/AvailableDIDOut"}, "title": "Response", "type": "array"}}}}}, "description": "List DIDs in the pool that can be acquired.", "tags": ["Numbers"], "security": [{"BearerAuth": []}]}}, "/api/numbers/acquire": {"post": {"operationId": "apps_api_routers_numbers_acquire", "summary": "Acquire", "parameters": [{"in": "header", "name": "Idempotency-Key", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Idempotency-Key"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DIDOut"}}}}}, "description": "Acquire a pool DID \u2014 charges the one-time `did_setup` fee. Send an\n`Idempotency-Key` header so a retry (network blip, timeout) never charges the\nfee twice; the retry replays the original response instead of re-acquiring.", "tags": ["Numbers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/AcquireIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/numbers/release": {"post": {"operationId": "apps_api_routers_numbers_release", "summary": "Release", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Release a DID back to the pool.", "tags": ["Numbers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReleaseIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/numbers/configure": {"post": {"operationId": "apps_api_routers_numbers_configure", "summary": "Configure", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DIDOut"}}}}}, "description": "Update a DID's per-purpose webhook overrides and/or friendly name.", "tags": ["Numbers"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/ConfigureIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/recordings/": {"get": {"operationId": "apps_api_routers_recordings_list_recordings", "summary": "List Recordings", "parameters": [{"in": "query", "name": "call_uuid", "schema": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Call Uuid"}, "required": false}, {"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/RecordingOut"}, "title": "Response", "type": "array"}}}}}, "description": "List recordings for the authenticated account.", "tags": ["Recordings"], "security": [{"BearerAuth": []}]}}, "/api/recordings/download": {"post": {"operationId": "apps_api_routers_recordings_download_url", "summary": "Download Url", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Get a time-limited download URL for a recording.", "tags": ["Recordings"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DownloadIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/recordings/delete": {"post": {"operationId": "apps_api_routers_recordings_delete_recording", "summary": "Delete Recording", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Soft-delete a recording.", "tags": ["Recordings"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DeleteIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/phone-tokens/mint": {"post": {"operationId": "apps_api_routers_phone_tokens_mint_token", "summary": "Mint Token", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Mint a phone token for an end-user.", "tags": ["Phone Tokens"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/MintIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/phone-tokens/revoke": {"post": {"operationId": "apps_api_routers_phone_tokens_revoke_token", "summary": "Revoke Token", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Revoke a phone token immediately.", "tags": ["Phone Tokens"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RevokeIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/account/": {"get": {"operationId": "apps_api_routers_account_get_account", "summary": "Get Account", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AccountOut"}}}}}, "description": "Return the authenticated account's profile.", "tags": ["Account"], "security": [{"BearerAuth": []}]}}, "/api/account/webhooks": {"get": {"operationId": "apps_api_routers_account_get_webhooks", "summary": "Get Webhooks", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WebhookConfigOut"}}}}}, "description": "The account's webhook configuration (per-purpose default URLs, fallback,\nper-number overrides).", "tags": ["Account"], "security": [{"BearerAuth": []}]}, "post": {"operationId": "apps_api_routers_account_set_webhooks", "summary": "Set Webhooks", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/WebhookConfigOut"}}}}}, "description": "Set an account-default webhook URL (for one purpose) and/or the fallback\nbehaviour. Only the fields you send are changed.", "tags": ["Account"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/WebhookConfigIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/account/webhooks/secret": {"get": {"operationId": "apps_api_routers_account_get_webhook_secret", "summary": "Get Webhook Secret", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SecretOut"}}}}}, "description": "Reveal the account's single webhook signing secret.", "tags": ["Account"], "security": [{"BearerAuth": []}]}}, "/api/account/webhooks/secret/rotate": {"post": {"operationId": "apps_api_routers_account_rotate_webhook_secret", "summary": "Rotate Webhook Secret", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SecretOut"}}}}}, "description": "Rotate the signing secret \u2014 the old one stops verifying immediately.", "tags": ["Account"], "security": [{"BearerAuth": []}]}}, "/api/keys/": {"get": {"operationId": "apps_api_routers_keys_list_keys", "summary": "List Keys", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/KeyOut"}, "title": "Response", "type": "array"}}}}}, "description": "List API keys for the authenticated account.", "tags": ["API Keys"], "security": [{"BearerAuth": []}]}}, "/api/keys/create": {"post": {"operationId": "apps_api_routers_keys_create_key", "summary": "Create Key", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Create a new API key (plaintext shown once).", "tags": ["API Keys"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateKeyIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/keys/revoke": {"post": {"operationId": "apps_api_routers_keys_revoke_key", "summary": "Revoke Key", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Revoke an API key.", "tags": ["API Keys"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/RevokeKeyIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/wallet/balance": {"get": {"operationId": "apps_api_routers_wallet_get_balance", "summary": "Get Balance", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BalanceOut"}}}}}, "description": "Return the current wallet balance.", "tags": ["Wallet"], "security": [{"BearerAuth": []}]}}, "/api/wallet/transactions": {"get": {"operationId": "apps_api_routers_wallet_list_transactions", "summary": "List Transactions", "parameters": [{"in": "query", "name": "limit", "schema": {"default": 50, "title": "Limit", "type": "integer"}, "required": false}, {"in": "query", "name": "offset", "schema": {"default": 0, "title": "Offset", "type": "integer"}, "required": false}], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/TxnOut"}, "title": "Response", "type": "array"}}}}}, "description": "List wallet transactions (newest first).", "tags": ["Wallet"], "security": [{"BearerAuth": []}]}}, "/api/users/": {"get": {"operationId": "apps_api_routers_endusers_list_endusers", "summary": "List Endusers", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"items": {"$ref": "#/components/schemas/EndUserOut"}, "title": "Response", "type": "array"}}}}}, "description": "List end-users for the authenticated account.", "tags": ["End-users"], "security": [{"BearerAuth": []}]}}, "/api/users/create": {"post": {"operationId": "apps_api_routers_endusers_create_enduser", "summary": "Create Enduser", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EndUserOut"}}}}}, "description": "Create a new end-user (softphone identity).", "tags": ["End-users"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateEndUserIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/users/update": {"post": {"operationId": "apps_api_routers_endusers_update_enduser", "summary": "Update Enduser", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EndUserOut"}}}}}, "description": "Update an end-user's display name or active state.", "tags": ["End-users"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateEndUserIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/users/delete": {"post": {"operationId": "apps_api_routers_endusers_delete_enduser", "summary": "Delete Enduser", "parameters": [], "responses": {"200": {"description": "OK"}}, "description": "Delete an end-user.", "tags": ["End-users"], "requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DeleteEndUserIn"}}}, "required": true}, "security": [{"BearerAuth": []}]}}, "/api/stream/token": {"post": {"operationId": "apps_api_routers_stream_mint_token", "summary": "Mint Token", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/StreamTokenOut"}}}}}, "description": "Mint a short-lived token for the `/api/stream` WebSocket.\n\nThe developer's backend calls this with its secret API key, then hands the\nreturned token to the browser \u2014 the API key itself never reaches the client.\nThe token lasts only long enough to open the socket (see `ttl_seconds`).", "tags": ["Stream"], "security": [{"BearerAuth": []}]}}, "/api/health/": {"get": {"operationId": "apps_api_routers_health_health", "summary": "Health", "parameters": [], "responses": {"200": {"description": "OK", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/StatusOut"}}}}, "503": {"description": "Service Unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/StatusOut"}}}}}, "description": "Service status probe \u2014 200 `{\"status\": \"ok\"}` or 503 `{\"status\": \"degraded\"}`.", "tags": ["Health"]}}}, "components": {"schemas": {"CallListOut": {"properties": {"calls": {"items": {"$ref": "#/components/schemas/CallOut"}, "title": "Calls", "type": "array"}, "total": {"title": "Total", "type": "integer"}, "limit": {"title": "Limit", "type": "integer"}, "offset": {"title": "Offset", "type": "integer"}}, "required": ["calls", "total", "limit", "offset"], "title": "CallListOut", "type": "object"}, "CallOut": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "sid": {"title": "Sid", "type": "string"}, "direction": {"title": "Direction", "type": "string"}, "from_number": {"title": "From Number", "type": "string"}, "to_number": {"title": "To Number", "type": "string"}, "status": {"title": "Status", "type": "string"}, "reason_code": {"title": "Reason Code", "type": "string"}, "reason_label": {"title": "Reason Label", "type": "string"}, "duration_seconds": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duration Seconds"}, "talk_seconds": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Talk Seconds"}, "cost": {"title": "Cost", "type": "string"}, "tts_seconds": {"title": "Tts Seconds", "type": "integer"}, "custom_payload": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Custom Payload"}, "started_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Started At"}, "answered_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Answered At"}, "ended_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Ended At"}, "created_at": {"title": "Created At", "type": "string"}}, "required": ["uuid", "sid", "direction", "from_number", "to_number", "status", "reason_code", "reason_label", "duration_seconds", "talk_seconds", "cost", "tts_seconds", "started_at", "answered_at", "ended_at", "created_at"], "title": "CallOut", "type": "object"}, "OriginateIn": {"properties": {"to": {"title": "To", "type": "string"}, "from": {"title": "From", "type": "string"}, "url": {"title": "Url", "type": "string"}, "timeout": {"default": 30, "title": "Timeout", "type": "integer"}, "customPayload": {"anyOf": [{"additionalProperties": true, "type": "object"}, {"type": "null"}], "title": "Custompayload"}}, "required": ["to", "from", "url"], "title": "OriginateIn", "type": "object"}, "HangupIn": {"properties": {"sid": {"title": "Sid", "type": "string"}}, "required": ["sid"], "title": "HangupIn", "type": "object"}, "DIDOut": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "number": {"title": "Number", "type": "string"}, "friendly_name": {"title": "Friendly Name", "type": "string"}, "webhook_urls": {"additionalProperties": {"type": "string"}, "title": "Webhook Urls", "type": "object"}, "webhook_inbound": {"$ref": "#/components/schemas/WebhookInbound"}, "is_active": {"title": "Is Active", "type": "boolean"}, "acquired_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Acquired At"}}, "required": ["uuid", "number", "friendly_name", "webhook_urls", "webhook_inbound", "is_active", "acquired_at"], "title": "DIDOut", "type": "object"}, "WebhookInbound": {"properties": {"url": {"title": "Url", "type": "string"}, "source": {"title": "Source", "type": "string"}}, "required": ["url", "source"], "title": "WebhookInbound", "type": "object"}, "AvailableDIDOut": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "number": {"title": "Number", "type": "string"}}, "required": ["uuid", "number"], "title": "AvailableDIDOut", "type": "object"}, "AcquireIn": {"properties": {"uuid": {"title": "Uuid", "type": "string"}}, "required": ["uuid"], "title": "AcquireIn", "type": "object"}, "ReleaseIn": {"properties": {"uuid": {"title": "Uuid", "type": "string"}}, "required": ["uuid"], "title": "ReleaseIn", "type": "object"}, "ConfigureIn": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "webhook_urls": {"anyOf": [{"additionalProperties": {"type": "string"}, "type": "object"}, {"type": "null"}], "title": "Webhook Urls"}, "friendly_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Friendly Name"}}, "required": ["uuid"], "title": "ConfigureIn", "type": "object"}, "RecordingOut": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "call_uuid": {"title": "Call Uuid", "type": "string"}, "call_sid": {"title": "Call Sid", "type": "string"}, "duration_seconds": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Duration Seconds"}, "size_bytes": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Size Bytes"}, "media_format": {"title": "Media Format", "type": "string"}, "storage_backend": {"title": "Storage Backend", "type": "string"}, "expires_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Expires At"}, "created_at": {"title": "Created At", "type": "string"}}, "required": ["uuid", "call_uuid", "call_sid", "duration_seconds", "size_bytes", "media_format", "storage_backend", "expires_at", "created_at"], "title": "RecordingOut", "type": "object"}, "DownloadIn": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "ttl_seconds": {"default": 300, "title": "Ttl Seconds", "type": "integer"}}, "required": ["uuid"], "title": "DownloadIn", "type": "object"}, "DeleteIn": {"properties": {"uuid": {"title": "Uuid", "type": "string"}}, "required": ["uuid"], "title": "DeleteIn", "type": "object"}, "MintIn": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "ttl_seconds": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Ttl Seconds"}, "max_concurrent": {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "Max Concurrent"}}, "required": ["uuid"], "title": "MintIn", "type": "object"}, "RevokeIn": {"properties": {"uuid": {"title": "Uuid", "type": "string"}}, "required": ["uuid"], "title": "RevokeIn", "type": "object"}, "AccountOut": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "name": {"title": "Name", "type": "string"}, "wallet_balance": {"title": "Wallet Balance", "type": "string"}, "status": {"title": "Status", "type": "string"}}, "required": ["uuid", "name", "wallet_balance", "status"], "title": "AccountOut", "type": "object"}, "NumberWebhookOut": {"properties": {"number": {"title": "Number", "type": "string"}, "purpose": {"title": "Purpose", "type": "string"}, "url": {"title": "Url", "type": "string"}}, "required": ["number", "purpose", "url"], "title": "NumberWebhookOut", "type": "object"}, "WebhookConfigOut": {"properties": {"endpoints": {"additionalProperties": {"type": "string"}, "title": "Endpoints", "type": "object"}, "fallback_mode": {"title": "Fallback Mode", "type": "string"}, "fallback_value": {"title": "Fallback Value", "type": "string"}, "numbers": {"items": {"$ref": "#/components/schemas/NumberWebhookOut"}, "title": "Numbers", "type": "array"}}, "required": ["endpoints", "fallback_mode", "fallback_value", "numbers"], "title": "WebhookConfigOut", "type": "object"}, "WebhookConfigIn": {"properties": {"purpose": {"default": "voice_inbound", "title": "Purpose", "type": "string"}, "url": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Url"}, "fallback_mode": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Fallback Mode"}, "fallback_value": {"default": "", "title": "Fallback Value", "type": "string"}}, "title": "WebhookConfigIn", "type": "object"}, "SecretOut": {"properties": {"signing_secret": {"title": "Signing Secret", "type": "string"}}, "required": ["signing_secret"], "title": "SecretOut", "type": "object"}, "KeyOut": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "name": {"title": "Name", "type": "string"}, "prefix": {"title": "Prefix", "type": "string"}, "is_active": {"title": "Is Active", "type": "boolean"}, "last_used_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Used At"}, "created_at": {"title": "Created At", "type": "string"}}, "required": ["uuid", "name", "prefix", "is_active", "last_used_at", "created_at"], "title": "KeyOut", "type": "object"}, "CreateKeyIn": {"properties": {"name": {"title": "Name", "type": "string"}}, "required": ["name"], "title": "CreateKeyIn", "type": "object"}, "RevokeKeyIn": {"properties": {"uuid": {"title": "Uuid", "type": "string"}}, "required": ["uuid"], "title": "RevokeKeyIn", "type": "object"}, "BalanceOut": {"properties": {"balance": {"title": "Balance", "type": "string"}, "currency": {"title": "Currency", "type": "string"}}, "required": ["balance", "currency"], "title": "BalanceOut", "type": "object"}, "TxnOut": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "direction": {"title": "Direction", "type": "string"}, "kind": {"title": "Kind", "type": "string"}, "amount": {"title": "Amount", "type": "string"}, "balance_before": {"title": "Balance Before", "type": "string"}, "created_at": {"title": "Created At", "type": "string"}}, "required": ["uuid", "direction", "kind", "amount", "balance_before", "created_at"], "title": "TxnOut", "type": "object"}, "EndUserOut": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "email": {"title": "Email", "type": "string"}, "display_name": {"title": "Display Name", "type": "string"}, "extension_number": {"title": "Extension Number", "type": "string"}, "registration_state": {"title": "Registration State", "type": "string"}, "is_active": {"title": "Is Active", "type": "boolean"}, "last_registered_at": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Last Registered At"}, "created_at": {"title": "Created At", "type": "string"}}, "required": ["uuid", "email", "display_name", "extension_number", "registration_state", "is_active", "last_registered_at", "created_at"], "title": "EndUserOut", "type": "object"}, "CreateEndUserIn": {"properties": {"email": {"title": "Email", "type": "string"}, "display_name": {"default": "", "title": "Display Name", "type": "string"}}, "required": ["email"], "title": "CreateEndUserIn", "type": "object"}, "UpdateEndUserIn": {"properties": {"uuid": {"title": "Uuid", "type": "string"}, "display_name": {"anyOf": [{"type": "string"}, {"type": "null"}], "title": "Display Name"}, "is_active": {"anyOf": [{"type": "boolean"}, {"type": "null"}], "title": "Is Active"}}, "required": ["uuid"], "title": "UpdateEndUserIn", "type": "object"}, "DeleteEndUserIn": {"properties": {"uuid": {"title": "Uuid", "type": "string"}}, "required": ["uuid"], "title": "DeleteEndUserIn", "type": "object"}, "StreamTokenOut": {"properties": {"token": {"title": "Token", "type": "string"}, "ttl_seconds": {"title": "Ttl Seconds", "type": "integer"}}, "required": ["token", "ttl_seconds"], "title": "StreamTokenOut", "type": "object"}, "StatusOut": {"properties": {"status": {"title": "Status", "type": "string"}}, "required": ["status"], "title": "StatusOut", "type": "object"}}, "securitySchemes": {"BearerAuth": {"type": "http", "scheme": "bearer"}}}, "servers": []}