Skip to content
Menu

Connect Twilio

Connect Twilio to EspoCRM for texts (SMS/MMS) and, if Twilio is your phone system, for calls with a softphone or the browser phone.

Updated October 15, 2026 View as Markdown

Texts always go through Twilio. Calls can go through Twilio too, if you don't use 3CX. In the addresses below, replace https://crm.example.com with your Site URL.

Connect the account

  1. Open Administration → Integrations → S+M EspoCRM VOIP · Twilio and tick the box to turn it on.
  2. Fill in Twilio Account SID and Twilio Auth Token (Twilio console → Account → API keys & tokens), and the Default country code (1 for the US and Canada).
  3. Save. Your Twilio numbers are added under Administration → S+M EspoCRM VOIP → Twilio Numbers.

Texts (SMS/MMS)

Choose who uses each number

Open Twilio Numbers. Numbers are added automatically when you save the Twilio settings and once a day; nothing you set is overwritten. For each number:

  • Status: Inactive for a number this CRM shouldn't use (its texts are ignored and nobody can send from it).
  • Default number for new texts.
  • Users who can send texts and Teams who can send texts. Administrators can always send. Everyone who can see a Contact, Lead or Account can still read its texts.
  • Alert first (no assigned user) and Also alert on every text (see Daily use).
  • Twilio Messaging Service SID (optional, MG…): send this number's texts through that service.

Important

Everyone allowed to send from a number sees all conversations through it, including with people who aren't in the CRM. Choose each number's users and teams with that in mind.

Point the number at EspoCRM

  1. In the Twilio console, open Phone Numbers → Manage → Active numbers → your number → Messaging configuration. Note where its texts go today: a number sends its texts to one place only.
  2. Set A message comes in to Webhook https://crm.example.com/api/v1/SmVoip/twilio/sms, HTTP POST. Save.

Delivery reports need nothing more: EspoCRM sends their address with each text.

Opt-outs

When someone replies STOP (or STOPALL, UNSUBSCRIBE, CANCEL, END, QUIT, REVOKE, OPTOUT), Twilio answers them and EspoCRM marks the number Opted out: no texts can be sent to it until they reply START (or YES, UNSTOP). HELP and INFO are answered by Twilio.

Texts from workflows

Under Administration → SMS, choose the SMS provider S+M EspoCRM VOIP (Twilio) so EspoCRM workflows can send texts, from the default number.

Calls through Twilio

Skip this part if your calls run on 3CX.

1. A SIP domain for the softphones

  1. In the Twilio console, Voice → SIP domains → Credential lists: create a list (for example Company phones) with a username and a strong password for each person, for example jsmith.
  2. SIP domains → Create SIP Domain, for example yourcompany.sip.twilio.com:
    • Voice Authentication → Credential lists: your list.
    • SIP Registration: Enabled, with the same list.
    • A call comes in: the outgoing Studio flow (step 3), once it exists.
    • Call status changes: https://crm.example.com/api/v1/SmVoip/twilio/status, POST.
  3. If 911 must work from the softphones, set an emergency address in Twilio.

In EspoCRM's Twilio settings, fill in SIP domain and Caller ID for the Call button (your Twilio number, for example +18885551234), and optionally Record calls made with the Call button. On each User, set SIP Username to their username on the SIP domain (jsmith).

2. Incoming calls: a Studio flow

In Studio → Flows, create a flow (for example Incoming) from scratch. From the trigger's Incoming Call exit:

  1. Make HTTP Request crm_ringing: POST, Form URL Encoded, URL https://crm.example.com/api/v1/SmVoip/twilio/ringing, with the parameters CallSid = {{trigger.call.CallSid}}, From = {{trigger.call.From}}, To = {{trigger.call.To}} and SipUser = jsmith. Connect both Success and Fail to the next widget, so calls still ring if the CRM is down.
  2. Connect Call To ring_user: SIP Endpoint sip:jsmith@yourcompany.sip.twilio.com (username and password empty), Caller ID {{trigger.call.From}}, a timeout such as 30 seconds, and Record Call on if you want recordings.
  3. Split Based On answered, from Connected Call Ended, on {{widgets.ring_user.DialCallStatus}}: if Equal To completed, a Say/Play goodbye; otherwise a Say/Play greeting, then Record Voicemail (maximum length 120 seconds).
  4. Publish.

Then, on the number's Voice configuration: A call comes in → Studio Flow → your flow, and Call status changes → https://crm.example.com/api/v1/SmVoip/twilio/status, HTTP POST.

3. Outgoing calls: a second Studio flow

Create a flow (for example Outgoing). From the trigger's Incoming Call exit (a call from a softphone arrives at the SIP domain as an incoming call):

  1. Make HTTP Request like crm_ringing above, without SipUser. Success and Fail → next.
  2. Connect Call To: Single Number with the value below, and your Twilio number as Caller ID.
  3. Publish, and choose this flow as the SIP domain's A call comes in.
{{trigger.call.To | remove: "sip:" | split: "@" | first}}

Dial numbers from the softphone as +1XXXXXXXXXX. Twilio's call log shows two rows per call; EspoCRM logs one Call.

4. The softphone

In Zoiper (or any SIP softphone), add a SIP account: domain yourcompany.sip.twilio.com, the person's username and password, transport UDP. It must show Registered. On a computer, make it the default app for phone links.

Warning

On a mobile phone, use a softphone with push notifications (for example Zoiper Pro). Free apps fall asleep in the background and calls go straight to voicemail.

5. The browser phone (optional)

Answer and make calls inside EspoCRM with the computer's microphone.

  1. Twilio console → Account → API keys & tokens → Create API key (type Standard). Copy the SID (SK…) and the Secret (shown once) into API Key SID (browser phone) and API Key Secret (browser phone).
  2. Voice → Manage → TwiML apps → Create: Voice Request URL = your outgoing flow's webhook URL (click the flow's trigger to see it), POST; Status callback URL = https://crm.example.com/api/v1/SmVoip/twilio/status. Copy its SID (AP…) into TwiML App SID (browser phone).
  3. To ring the browser and the softphone together: in the incoming flow, add a TwiML Redirect widget, POST, URL https://crm.example.com/api/v1/SmVoip/twilio/dial?user=jsmith&timeout=30&record=1&flow=FW… (FW… is the flow's SID; record=0 not to record). Connect crm_ringing to it instead of ring_user, connect its Return exit to the answered split, and change the split to {{widgets.<redirect widget name>.DialCallStatus}}. Publish.

Each person then turns it on in EspoCRM: Calls in the top bar → Turn on the browser phone, and allows the microphone.

Test

  1. Text the Twilio number from your mobile: within seconds a New text from … pop-up appears. Reply from EspoCRM.
  2. Reply STOP: EspoCRM shows Opted out. Reply START to undo.
  3. With Twilio calls: call the number from a phone that's in the CRM; the softphone rings and the pop-up shows the record. Hang up: a held "Inbound call" is logged.

If nothing happens, see Troubleshooting.

Was this page helpful?

Add a comment (optional)

We keep your answer and comment, nothing about who sent them.