SMS OTP verification

Send and verify one-time passcodes over SMS during an agent conversation using Twilio Verify.

Agent conversation collecting a phone number, OTP code, and verification success

Overview

This guide shows you how to integrate Twilio Verify with your ElevenLabs agent so you can send an OTP to a caller’s phone number and verify the code they read back during a live voice conversation.

You will learn how to:

  • Create a Twilio Verify service and Base64-encode your credentials for authentication.
  • Configure two webhook server tools (send_SMS_verification and check_SMS_verification) in the dashboard, with the Agents CLI, or using the ElevenLabs API.
  • Authenticate both webhook calls using an Authorization header with a secret value.
  • Enable the skip_turn system tool so the agent waits when the caller has not received the code yet.

Prerequisites

  • A Twilio account with Twilio Verify enabled. If Verify is not available in your Twilio Console, request access through Twilio support or your Twilio account team.
  • If your Twilio account is in trial mode, the destination phone number must be a verified caller ID in Twilio.
1

Log in to the Twilio Console

Open the Twilio Console.

2

Create an Authenticate (Verify) service

In the left sidebar, choose Add + and create an Authenticate (Verify) service.

3

Name the service

Give it a descriptive name (for example, ElevenLabs OTP).
4

Copy the Verify Service SID

Open the service Settings page and copy the Verify Service SID. It starts with VA and is different from your Account SID.

Common Mistake: Use your Verify Service SID (VA...) from the Authenticate (Verify) service in the tool URLs below. Do not put your Account SID (AC...) in the path. The Verify API expects the service SID in the URL; using the Account SID produces 4xx invalid-parameter errors.

You can use the Twilio API Explorer in the console to test requests before you attach them to your agent.

Encode credentials and configure webhook tools

1

Encode your Twilio credentials for Basic authentication

Twilio Verify uses HTTP Basic authentication with your Account SID as the username and Auth Token as the password. Find both under Account Info on the Twilio Console home page.

In your shell, Base64-encode ACCOUNT_SID:AUTH_TOKEN (colon-separated, no spaces):

$printf '%s' 'YOUR_ACCOUNT_SID:YOUR_AUTH_TOKEN' | base64

Copy the output. The full Authorization header value is the word Basic, a single space, and that Base64 string. Store it as a tool secret in the next steps.

Basic dkFDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==
2

Configure the send_SMS_verification and check_SMS_verification tools

send_SMS_verification calls Twilio Verify to send an SMS OTP. check_SMS_verification submits the digits the caller speaks. Both require the same Verify Service SID and the same Authorization secret.

send_SMS_verification

Agent conversation collecting a phone number, OTP code, and verification success

In the Agent section of your agent settings, choose Add Tool and select Webhook.

FieldValue
Namesend_SMS_verification
DescriptionSends an OTP verification code via SMS to the provided phone number
MethodPOST
URLhttps://verify.twilio.com/v2/Services/YOUR_VERIFY_SERVICE_SID/Verifications

Replace YOUR_VERIFY_SERVICE_SID with the VA... SID from the first step.

Authentication header: Under Headers, add Authorization as type Secret and paste the full value (Basic plus Base64). See Server tools.

Body parameters: Set Content type to URL-encoded (application/x-www-form-urlencoded). Add parameters with LLM Prompt as the value type:

Data typeIdentifierDescription
stringToCaller phone number in E.164 format (for example +14155552671)
stringChannelDelivery channel; use sms

check_SMS_verification

Add a second webhook tool:

FieldValue
Namecheck_SMS_verification
DescriptionChecks whether the OTP code provided by the caller is valid
MethodPOST
URLhttps://verify.twilio.com/v2/Services/YOUR_VERIFY_SERVICE_SID/VerificationCheck

Use the same Verify Service SID and the same Authorization secret as for send_SMS_verification.

Body parameters: URL-encoded. Add To (E.164) and Code (OTP digits) with LLM Prompt.

If you configure Channel as an LLM-filled field in the dashboard, add instructions in your system prompt so the model always passes sms. The CLI and API examples above pin sms with constant_value / constantValue, so the model does not choose the channel.

3

Enable the skip_turn system tool

Callers often need a moment to receive the SMS before they can read the code. Without skip_turn, the agent may talk over the pause or repeat prompts.

In Tools, choose Add Tool, select System tool, and enable Skip turn. No further configuration is required.

Add guidance to the system prompt so the model knows when to call it, for example:

When the caller indicates they are still waiting to receive the OTP code — for example,
"hold on", "I haven't received it yet", or "give me a second" — use the skip_turn tool
to wait silently rather than speaking. Do not repeat the prompt or ask for the code again
until the caller indicates they are ready.

See Skip turn for details.

4

Orchestrate the flow in the system prompt

Use a system prompt that sequences the tools clearly, for example:

You are a secure verification agent. When you need to verify a caller's identity:
1. Ask for their phone number if you do not already have it.
2. Standardize the number to E.164 for tool calls: a leading plus, country code, then digits only, no spaces (for example +14155552671).
3. Call send_SMS_verification with their number and Channel set to "sms".
4. Tell the caller: "I've sent a verification code to your phone. Please read it out when you're ready."
5. If the caller says they haven't received the code yet or asks for a moment, use skip_turn to wait silently.
6. Once the caller provides the code, call check_SMS_verification with their number and the code.
7. If the response status is "approved", proceed with the verified flow.
8. If the code is invalid, let the caller know and offer to resend.

Troubleshooting

Twilio 60200 — Invalid parameter (HTTP 400)

Twilio may return a body like this when the request URL or body does not match what the Verify API expects:

1{
2 "code": 60200,
3 "message": "Invalid parameter",
4 "more_info": "https://www.twilio.com/docs/errors/60200",
5 "status": 400
6}

What to check: The path must use your Verify Service SID (VA...) from the Authenticate (Verify) service settings. Putting your Account SID (AC...) in .../Services/{Sid}/... is a frequent cause of 60200. See Twilio’s 60200 documentation for other invalid-parameter cases.

Twilio 20003 — Authentication Error — No credentials provided (HTTP 401)

When the Authorization header is missing, malformed, or not sent, Twilio can respond with:

1{
2 "code": 20003,
3 "message": "Authentication Error - No credentials provided",
4 "more_info": "https://www.twilio.com/docs/errors/20003",
5 "status": 401
6}

What to check: The tool must send an Authorization header whose value is the full Basic <base64> string (including the word Basic and a single space before the Base64 output). The Base64 input must be exactly ACCOUNT_SID:AUTH_TOKEN with no extra spaces or newlines. Confirm the secret is attached to this header on both webhook tools. See 20003.

Other issues

  • Number rejected in trial mode: In the Twilio Console, open Verified phone numbers and ensure the destination number is listed before you test.
  • Agent talks over the caller: Confirm Skip turn is enabled and the system prompt tells the model to use skip_turn when the caller needs time.