Receiving Voice Calls
Answer incoming calls, build keypad menus, and connect callers to another number using TwiML.
Answer incoming calls with a greeting, collect keypad input, and connect callers to another phone number using TwiML instructions returned by your application.
1. Configure your phone number
Use a TextGrid number enabled for incoming voice calls. Configure its callbacks when purchasing the number or update them later:
POST https://api.textgrid.com/2010-04-01/Accounts/YOUR_ACCOUNT_SID/IncomingPhoneNumbers/YOUR_PHONE_NUMBER_SID.json
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer YOUR_BASE64_ENCODED_CREDENTIALSSupply these form fields:
| Field | Example value |
|---|---|
voiceUrl | https://example.com/voice/incoming |
voiceMethod | POST |
statusCallback | https://example.com/voice/status |
statusCallbackMethod | POST |
Replace the example URLs and identifiers with your own. Use voiceUrl for the endpoint that returns call instructions and statusCallback for final call notifications. These are separate requests with different response requirements.
See Managing Phone Numbers for configuration and Getting Started with TextGrid for authentication.
Check call forwarding
If call forwarding is enabled for the number, TextGrid forwards incoming calls to the configured destination instead of requesting instructions from voiceUrl. Your incoming voice instructions webhook will not be called, even if a voiceUrl is configured.
Disable call forwarding if you want your webhook to control incoming calls, including greetings, keypad menus, and routing through TwiML Dial instructions.
2. Verify the instruction request
When someone calls your number, TextGrid requests instructions from your voiceUrl using the configured method.
- POST requests contain
application/x-www-form-urlencodedfields. - GET requests contain query parameters and no request body.
Verify X-TextGrid-Signature with your account's Webhook Secret before processing the request. Preserve the raw POST body before parsing, or the exact public request URL and query string for GET. See Verifying Webhook Signatures.
The request includes CallSid, AccountSid, From, To, CallStatus, and Direction. For the initial incoming instruction request, Direction is inbound and CallStatus is ringing.
Save CallSid to associate subsequent instructions and status notifications with the same call. Keep phone numbers and identifiers as strings. See Voice Webhooks for the complete callback contract.
3. Answer with a greeting
Return HTTP 200 with Content-Type: application/xml and a TwiML response:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Thank you for calling Example Company. Our office is currently closed.</Say>
</Response>TextGrid speaks the message. When there are no more TwiML instructions to process, the call hangs up automatically.
4. Build a keypad menu
To collect a menu selection, return a Gather instruction:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather action="https://example.com/voice/menu" method="POST" numDigits="1" timeout="5">
<Say>For sales, press 1. For support, press 2.</Say>
</Gather>
</Response>Replace the action URL with your menu endpoint. This example collects one keypad character with a five-second capture timeout. The supported Gather implementation collects DTMF input; do not assume speech recognition is available.
Gather supports no child prompt or one child prompt consisting of Say or Play. Do not place multiple prompt elements inside it; combine spoken instructions into one Say when needed.
Process the selection
The action endpoint receives the call fields plus Digits, with CallStatus=in-progress. Verify the request signature and read Digits as a string, preserving leading zeros and keypad characters.
Return the next TwiML response based on the selection. For example:
| Selection | Your application returns |
|---|---|
1 | A greeting and Dial instruction for your sales number. |
2 | A greeting and Dial instruction for your support number. |
| Missing or unrecognized input | Another menu prompt or a closing message, according to your call flow. |
Use an explicit Gather action and method to route menu responses clearly. If no action URL is supplied, TextGrid uses the call's instruction URL.
5. Connect the caller to another number
To connect the caller to a phone number, return:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Please hold while we connect you to support.</Say>
<Dial>+12025550102</Dial>
</Response>The number above is fictitious; replace it with the destination you want to reach. Dial creates an outgoing leg and connects it to the existing call. Applicable voice charges apply.
Use phone-number destinations for this workflow. The current implementation does not establish support for every Twilio Dial target or attribute. In particular, do not assume Client, SIP, or named Conference targets are supported merely because the XML resembles TwiML.
If you explicitly use Hangup on a call that belongs to a conference, it ends the entire conference. Do not add it as a routine step after Dial.
6. Receive the final status
TextGrid sends the incoming call's final notification to the phone number's statusCallback. Match CallSid to your saved call record.
The notification uses Direction=inbound and a CallStatus of completed, busy, no-answer, or failed. Verify its signature, record the result, and return HTTP 200; an empty response body is sufficient. Do not return call instructions to this endpoint.
Duration fields are conditional: where present, CallDuration reports seconds and Duration reports minutes rounded up. See Voice Webhooks for all fields and delivery behavior.
The final-status sender makes one request without an automatic retry loop. Events can repeat, so make processing idempotent. Specialized integrations can handle events separately; do not assume a generic notification for every call leg.
Test your call flow
Call your TextGrid number and confirm the greeting, each menu option, and the connection to your destination numbers. Test unanswered destinations and missing or unexpected keypad input as well.
Confirm your endpoints verify signatures, return valid XML for instruction requests, and acknowledge final status notifications. Escape dynamic XML text correctly, including characters such as & and <.
For initiating calls from your application, see Making Voice Calls.
Updated 2 minutes ago