{"record":{"id":"7f5b64726e849220","repo":"zeroclaw-labs/zeroclaw","slug":"failed-to-initiate-call","errorCode":null,"errorMessage":"Failed to initiate call: {}","messagePattern":"Failed to initiate call: (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-channels/src/clawdtalk.rs","lineNumber":92,"sourceCode":"                mode: \"premium\".to_string(),\n            }),\n            webhook_url: None,\n            // AI voice settings via Telnyx Call Control\n            command_id: None,\n        };\n\n        let response = self\n            .client\n            .post(format!(\"{}/calls\", Self::TELNYX_API_URL))\n            .header(\"Authorization\", format!(\"Bearer {}\", self.api_key))\n            .header(\"Content-Type\", \"application/json\")\n            .json(&request)\n            .send()\n            .await?;\n\n        if !response.status().is_success() {\n            let error = response.text().await?;\n            anyhow::bail!(\"Failed to initiate call: {}\", error);\n        }\n\n        let call_response: CallResponse = response.json().await?;\n\n        Ok(CallSession {\n            call_control_id: call_response.call_control_id,\n            call_leg_id: call_response.call_leg_id,\n            call_session_id: call_response.call_session_id,\n        })\n    }\n\n    /// Send audio or TTS to an active call\n    pub async fn speak(&self, call_control_id: &str, text: &str) -> anyhow::Result<()> {\n        let request = SpeakRequest {\n            payload: text.to_string(),\n            payload_type: \"text\".to_string(),\n            service_level: \"premium\".to_string(),\n            voice: \"female\".to_string(),","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-channels/src/clawdtalk.rs#L74-L110","documentation":"initiate_call POSTs to Telnyx /v2/calls with the configured connection_id, from_number and Bearer api_key; any non-2xx response body is embedded verbatim in this error. The diagnosis (bad key, invalid connection_id, unprovisioned from_number, insufficient credit) lives in Telnyx's own JSON inside the braces. Transport-level failures (DNS, TLS, the client's 30s timeout) instead surface earlier as reqwest errors via the ? on send(), not as this message.","triggerScenarios":"401 from a revoked or mistyped api_key; 4xx from a connection_id that is not a valid Call Control SIP connection on that account; from_number not purchased or not E.164; `to` in a format the connection rejects; account out of credit or voice not enabled for the destination country.","commonSituations":"API key rotated in the Telnyx portal but not in [channels.clawdtalk.<alias>]; pasting the Telnyx public key instead of the API key; connection_id belonging to a different Telnyx project; from_number released back to the number pool; sandbox credentials pointed at production endpoints.","solutions":["Read the embedded Telnyx error body first — it names the exact rejected field or reason","Verify the V2 key by calling GET /v2/phone_numbers with the same Bearer token (this is what health_check does); it must return 200","Confirm connection_id is a Call Control SIP connection in the same Telnyx project as the key","Confirm from_number is purchased, E.164-formatted, and `to` is a dialable E.164 number","Check Telnyx account balance and voice enablement for the destination country"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Fail fast on bad credentials before any send:\nif !channel.health_check().await {\n    // GET /v2/phone_numbers rejected the key — fix [channels.clawdtalk.<alias>] first\n}","typeGuard":null,"tryCatchPattern":"match channel.send(&msg).await {\n    Err(e) if e.to_string().starts_with(\"Failed to initiate call\") => {\n        // Telnyx rejected POST /v2/calls — parse the embedded body; do not retry blindly\n    }\n    r => r?,\n}","preventionTips":["Run health_check() at channel startup to catch credential drift early","Keep api_key, connection_id and from_number from one Telnyx project in one config block","Always log the full error string — the Telnyx body inside the braces carries the diagnosis"],"tags":["clawdtalk","telnyx","voice","http","api"],"backgroundTag":"telnyx-api-error","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}