Twilio Integration¶
Phone call integration for ElevenLabs conversational AI agents.
v0.13.0 API Change
As of v0.13.0, Twilio and Phone Number methods are accessed via client.Telephony() instead of client.Twilio() and client.PhoneNumbers().
Overview¶
The Twilio integration enables:
- Incoming Calls: Route Twilio calls to ElevenLabs agents
- Outbound Calls: Initiate calls from ElevenLabs agents
- SIP Trunks: Connect via SIP infrastructure
- Phone Number Management: Manage agent phone numbers
Registering Incoming Calls¶
When Twilio receives a call, register it with ElevenLabs:
import "github.com/plexusone/elevenlabs-go/telephony"
// In your Twilio webhook handler
func handleIncomingCall(w http.ResponseWriter, r *http.Request) {
resp, err := client.Telephony().RegisterTwilioCall(ctx, &telephony.TwilioRegisterCallRequest{
AgentID: "your-agent-id",
})
if err != nil {
http.Error(w, err.Error(), 500)
return
}
// Return TwiML to Twilio
w.Header().Set("Content-Type", "application/xml")
w.Write([]byte(resp.TwiML))
}
With Dynamic Variables¶
Inject context into the agent conversation:
resp, err := client.Telephony().RegisterTwilioCall(ctx, &telephony.TwilioRegisterCallRequest{
AgentID: "your-agent-id",
// Dynamic variables for prompt injection
DynamicVariables: map[string]string{
"caller_name": callerInfo.Name,
"account_number": callerInfo.AccountNumber,
"call_reason": "support",
},
// Override first message
FirstMessage: fmt.Sprintf("Hello %s, how can I help you today?", callerInfo.Name),
// Override system prompt
SystemPrompt: "You are a helpful customer support agent...",
})
Making Outbound Calls¶
Initiate calls from your ElevenLabs agent:
call, err := client.Telephony().TwilioOutboundCall(ctx, &telephony.TwilioOutboundCallRequest{
// Required fields
AgentID: "your-agent-id",
AgentPhoneNumberID: "phone-number-id",
ToNumber: "+1234567890",
// Optional overrides
FirstMessage: "Hi, this is a call from your service.",
DynamicVariables: map[string]string{
"customer_name": "John",
"order_id": "12345",
},
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Call SID: %s\n", call.CallSID)
fmt.Printf("Conversation ID: %s\n", call.ConversationID)
SIP Trunk Outbound Calls¶
For SIP-based infrastructure:
call, err := client.Telephony().SIPOutboundCall(ctx, &telephony.SIPOutboundCallRequest{
AgentID: "your-agent-id",
SIPTrunkID: "sip-trunk-id",
ToNumber: "+1234567890",
FromNumber: "+0987654321", // Verified caller ID
DynamicVariables: map[string]string{
"context": "outbound_campaign",
},
})
Phone Number Management¶
List Phone Numbers¶
numbers, err := client.Telephony().ListPhoneNumbers(ctx)
if err != nil {
log.Fatal(err)
}
for _, num := range numbers {
fmt.Printf("%s: %s (%s)\n", num.Label, num.PhoneNumber, num.Status)
}
Get Phone Number Details¶
number, err := client.Telephony().GetPhoneNumber(ctx, "phone-number-id")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Number: %s\n", number.PhoneNumber)
fmt.Printf("Agent: %s\n", number.AgentID)
fmt.Printf("Provider: %s\n", number.Provider)
Update Phone Number¶
updated, err := client.Telephony().UpdatePhoneNumber(ctx, "phone-number-id",
&telephony.UpdatePhoneNumberRequest{
Label: "Customer Support Line",
AgentID: "new-agent-id",
})
Delete Phone Number¶
Request Types¶
TwilioRegisterCallRequest¶
| Field | Type | Required | Description |
|---|---|---|---|
AgentID |
string | Yes | ElevenLabs agent ID |
AgentPhoneNumberID |
string | No | Phone number ID |
DynamicVariables |
map[string]string | No | Prompt variables |
FirstMessage |
string | No | Override first message |
SystemPrompt |
string | No | Override system prompt |
CustomLLMExtraBody |
map[string]any | No | Extra LLM data |
TwilioOutboundCallRequest¶
| Field | Type | Required | Description |
|---|---|---|---|
AgentID |
string | Yes | ElevenLabs agent ID |
AgentPhoneNumberID |
string | Yes | From phone number ID |
ToNumber |
string | Yes | Destination (E.164 format) |
DynamicVariables |
map[string]string | No | Prompt variables |
FirstMessage |
string | No | Override first message |
SystemPrompt |
string | No | Override system prompt |
SIPOutboundCallRequest¶
| Field | Type | Required | Description |
|---|---|---|---|
AgentID |
string | Yes | ElevenLabs agent ID |
SIPTrunkID |
string | Yes | SIP trunk ID |
ToNumber |
string | Yes | Destination (E.164 format) |
FromNumber |
string | No | Caller ID (must be verified) |
DynamicVariables |
map[string]string | No | Prompt variables |
Example: Full Integration¶
package main
import (
"context"
"log"
"net/http"
elevenlabs "github.com/plexusone/elevenlabs-go"
"github.com/plexusone/elevenlabs-go/telephony"
)
var client *elevenlabs.Client
func main() {
var err error
client, err = elevenlabs.NewClient()
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/twilio/incoming", handleIncoming)
http.HandleFunc("/api/call", handleOutbound)
log.Println("Starting server on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handleIncoming(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Get caller info from Twilio parameters
callerNumber := r.FormValue("From")
resp, err := client.Telephony().RegisterTwilioCall(ctx, &telephony.TwilioRegisterCallRequest{
AgentID: "your-agent-id",
DynamicVariables: map[string]string{
"caller_number": callerNumber,
},
})
if err != nil {
log.Printf("register call error: %v", err)
http.Error(w, "error", 500)
return
}
w.Header().Set("Content-Type", "application/xml")
w.Write([]byte(resp.TwiML))
}
func handleOutbound(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
toNumber := r.URL.Query().Get("to")
call, err := client.Telephony().TwilioOutboundCall(ctx, &telephony.TwilioOutboundCallRequest{
AgentID: "your-agent-id",
AgentPhoneNumberID: "phone-number-id",
ToNumber: toNumber,
})
if err != nil {
http.Error(w, err.Error(), 500)
return
}
w.Write([]byte("Call initiated: " + call.CallSID))
}