# Routing Twilio Calls into Spoke

When you activate a phone number from your Twilio account on Spoke, the Spoke platform automatically attaches Spoke's standard inbound TwiML application to the phone number. From that point forward, all routing and call handling is taken care of by Spoke.

If you want greater control over a call, including the ability to send a call to Spoke and have Spoke send the call back to your application if the call goes unanswered, then there are two ways to route the call into Spoke:

1. [Spoke's Redirect Handler](#using-spokes-redirect-handler)
2. [Twilio Voice Application Connect](#using-twilio-voice-application-connect).

Both methods enable you to programmatically connect incoming calls that have been processed with other Twilio applications (such as Studio, Flex or your own application) to Spoke.

## Using Spoke's Redirect Handler

The redirect handler url has the following form:

```
https://api.spokephone.com/telephony/redirect?extension={EXTENSION}&organisationId={YOUR_ORGANISATION_ID}
```

The handler accepts the following parameters in the query string of that url:

> Note: **The parameter order listed below is important** as all requests to the handler are signature validated.

| # | Parameter                  | Required | Description                                                                                                                          |
|---|----------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------|
| 1 | `extension`                | Yes      | The extension you are redirecting the call to                                                                                        |
| 2 | `nextOfferTimeout`         | No       | The number of seconds to wait before offering the call to the next available user(s) in a call group, see the supported range below. |
| 3 | `organisationId`           | Yes      | Your unique Spoke account identifier                                                                                                 |
| 4 | `priority`                 | No       | The priority of the call, see the supported range below.                                                                             |
| 5 | `returnTo`                 | No       | One of `flow` or `taskQueue` or `postEndpoint` or `application`.                                                                     |
| 6 | `returnToId`               | No       | The identifier of the `returnTo` destination, see the expected value below.                                                          |
| 7 | `sendToVoicemail`          | No       | If `true`, force the call to be sent to voicemail                                                                                    |
| 8 | `timeout`                  | No       | The number of seconds to wait for a user or anyone in a call group to answer, see the supported range below.                         |
| 9 | `x-<passthroughParameter>` | No       | Passthrough parameter to store against the call. See below for more details on how to set passthrough parameters.                    |

> Note: The Spoke Directory API provides a pre-formed `twimlRedirectUrl` for each directory entry that includes the correct `extension` and `organisationId` parameters.

To connect an incoming Twilio call with a Spoke directory entry using Spoke's Redirect Handler, simply update the call using Twilio's REST API as follows:

```javascript
const client = require('twilio')();

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({
    method: 'POST',
    url: 'https://api.spokephone.com/telephony/redirect?extension={EXTENSION}&organisationId={SPOKE_ORG_ID}'
  });
```

This will connect the incoming call to Spoke and follow the dial rules outlined in the `Spoke Directory` section above.

## Using Twilio Voice Application Connect

[Twilio Voice Application Connect](https://www.twilio.com/en-us/blog/products/launches/introducing-twilio-application-connect-programmable-voice) allows connecting a call to a TwiML application in another Twilio account. Spoke enables it on a TwiML application dedicated to your organisation, so you can route a call into Spoke by dialling that application from a separate Twilio account.

You can view your organisation's Voice Application Connect application SID from the [Spoke Account Portal](https://account.spokephone.com/advanced/byot).

When [dialling the application](https://www.twilio.com/docs/voice/twiml/dial/application), your organisation's Voice Application Connect application SID must be supplied as the `ApplicationSid`, along with `extension` and `sourceAccountSid` as application parameters.

The following custom parameters can be provided when dialling the application:

| # | Parameter                  | Required | Description                                                                                                                          |
|---|----------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------|
| 1 | `extension`                | Yes      | The extension you are routing the call to                                                                                            |
| 2 | `nextOfferTimeout`         | No       | The number of seconds to wait before offering the call to the next available user(s) in a call group, see the supported range below. |
| 3 | `priority`                 | No       | The priority of the call, see the supported range below.                                                                             |
| 4 | `returnTo`                 | No       | One of `taskQueue`, `postEndpoint` or `application`.                                                                                 |
| 5 | `returnToId`               | No       | The identifier of the `returnTo` destination, see the expected value below.                                                          |
| 6 | `sendToVoicemail`          | No       | If `true`, force the call to be sent to voicemail                                                                                    |
| 7 | `sourceAccountSid`         | Yes      | The account SID of the Twilio account the call is coming from                                                                        |
| 8 | `timeout`                  | No       | The number of seconds to wait for a user or anyone in a call group to answer, see the supported range below.                         |
| 9 | `x-<passthroughParameter>` | No       | Passthrough parameter to store against the call. See below for more details on how to set passthrough parameters.                    |

To connect an incoming Twilio call with a Spoke directory entry using Twilio Voice Application Connect, update the call with a `<Dial><Application>` TwiML using Twilio's REST API as follows:

```javascript
const client = require('twilio')();
const VoiceResponse = require('twilio').twiml.VoiceResponse;

const response = new VoiceResponse();
const dial = response.dial();
const application = dial.application();
application.applicationSid('{SPOKE_VOICE_APPLICATION_CONNECT_APP_SID}');
application.parameter({ name: 'extension', value: '{EXTENSION}' });
application.parameter({ name: 'sourceAccountSid', value: client.accountSid });

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({ twiml: response.toString() });
```

This will connect the incoming call to Spoke and follow the dial rules outlined in the `Spoke Directory` section above.

## Returning unanswered calls

If you route a call into Spoke, then Spoke's standard business rules kick in.  This means that if the target extension is unavailable or does not answer, then Spoke's standard "unanswered call" rules apply:

* For calls to a `User` extension, the call will go the user's voicemail
* For calls to a `Team` extension, the call will follow the call group's "unanswered" call flow configuration - which could send the call to another call group, the group's voicemail or to an external PSTN number

To override this behaviour and return control of the call back to your application, you have four options:

### 1. Return to a Studio Flow

#### Using Spoke's Redirect Handler

Add `&returnTo=flow&returnToId={FLOW_SID}` to the `url` parameter when updating the call:

```javascript
const client = require('twilio')();

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({
    method: 'POST',
    url: 'https://api.spokephone.com/telephony/redirect?extension={EXTENSION}&organisationId={SPOKE_ORG_ID}&returnTo=flow&returnToId={STUDIO_FLOW_SID}'
  });
```

This will return the call to a Twilio Studio flow.  If you have sent the call from the same flow by using the redirect widget, then you can control what happens next to the call by connecting a new widget to the `return` output of the redirect widget.

> Note: Returning the call to a Studio Flow is not supported when using Twilio Voice Application Connect. Use Spoke's Redirect Handler when the call must be returnable to your Flow.

### 2. Send the call to a TaskRouter Workflow

Unanswered calls can be sent to a Twilio TaskRouter Workflow, which could be attached to Flex, or a workflow/task queue that your own application listens to.

#### Using Spoke's Redirect Handler

Add `&returnTo=taskQueue&returnToId={WORKFLOW_SID}` to the `url` parameter when updating the call:

```javascript
const client = require('twilio')();

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({
    method: 'POST',
    url: 'https://api.spokephone.com/telephony/redirect?extension={EXTENSION}&organisationId={SPOKE_ORG_ID}&returnTo=taskQueue&returnToId={WORKFLOW_SID}'
  });
```

#### Using Twilio Voice Application Connect

Add `returnTo` and `returnToId` parameters to the `<Application>` noun when updating the call:

```javascript
const client = require('twilio')();
const VoiceResponse = require('twilio').twiml.VoiceResponse;

const response = new VoiceResponse();
const dial = response.dial();
const application = dial.application();
application.applicationSid('{SPOKE_VOICE_APPLICATION_CONNECT_APP_SID}');
application.parameter({ name: 'extension', value: '{EXTENSION}' });
application.parameter({ name: 'sourceAccountSid', value: client.accountSid });
application.parameter({ name: 'returnTo', value: 'taskQueue' });
application.parameter({ name: 'returnToId', value: '{WORKFLOW_SID}' });

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({ twiml: response.toString() });
```

> Note: When using Twilio Voice Application Connect to send an unanswered call to a TaskRouter Workflow, the workflow must be in the Twilio account associated with Spoke.

### 3. Send the call to an HTTPS endpoint

Unanswered calls can be sent to a Twilio Function or any HTTPS endpoint that accepts a POST request.

Details about the request body sent by Twilio can be found [here](https://www.twilio.com/docs/voice/twiml#twilios-request-to-your-application).

> Note: The POST request will be sent by Twilio with an `X-Twilio-Signature` header.
> We recommend you secure the endpoint by [validating that the request is coming from Twilio](https://www.twilio.com/docs/usage/security#validating-requests).
> For redirects to a Twilio Function, this can be done by [setting the visibility of the Function to Protected](https://www.twilio.com/docs/serverless/functions-assets/visibility#protected).

Invalid URLs will be ignored and unanswered calls will not be returned.

#### Using Spoke's Redirect Handler

Add `&returnTo=postEndpoint&returnToId={ENCODED_HTTPS_URL}` to the `url` parameter when updating the call:

```javascript
const client = require('twilio')();

const returnToPostEndpoint = encodeURIComponent("https://example.com/return-post-endpoint");

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({
    method: 'POST',
    url: `https://api.spokephone.com/telephony/redirect?extension={EXTENSION}&organisationId={SPOKE_ORG_ID}&returnTo=postEndpoint&returnToId=${returnToPostEndpoint}`
  });
```

#### Using Twilio Voice Application Connect

Add `returnTo` and `returnToId` parameters to the `<Application>` verb when updating the call:

```javascript
const client = require('twilio')();
const VoiceResponse = require('twilio').twiml.VoiceResponse;

const returnToPostEndpoint = encodeURIComponent("https://example.com/return-post-endpoint");

const response = new VoiceResponse();
const dial = response.dial();
const application = dial.application();
application.applicationSid('{SPOKE_VOICE_APPLICATION_CONNECT_APP_SID}');
application.parameter({ name: 'extension', value: '{EXTENSION}' });
application.parameter({ name: 'sourceAccountSid', value: client.accountSid });
application.parameter({ name: 'returnTo', value: 'postEndpoint' });
application.parameter({ name: 'returnToId', value: returnToPostEndpoint });

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({ twiml: response.toString() });
```

### 4. Send the call to a TwiML application

Unanswered calls can be sent to a TwiML application of any Twilio account.

If the application belongs to a different Twilio account than the one associated with Spoke, the application must be opted in to being dialled from other accounts by setting `PublicApplicationConnectEnabled` to true on its Application Resource. See Twilio's [`<Application>` usage documentation](https://www.twilio.com/docs/voice/twiml/dial/application/usage#accept-calls-from-a-different-twilio-account) for more details.

#### Using Spoke's Redirect Handler

Add `&returnTo=application&returnToId={APPLICATION_SID}` to the `url` parameter when updating the call:

```javascript
const client = require('twilio')();

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({
    method: 'POST',
    url: 'https://api.spokephone.com/telephony/redirect?extension={EXTENSION}&organisationId={SPOKE_ORG_ID}&returnTo=application&returnToId={APPLICATION_SID}'
  });
```

#### Using Twilio Voice Application Connect

Add `returnTo` and `returnToId` parameters to the `<Application>` noun when updating the call:

```javascript
const client = require('twilio')();
const VoiceResponse = require('twilio').twiml.VoiceResponse;

const response = new VoiceResponse();
const dial = response.dial();
const application = dial.application();
application.applicationSid('{SPOKE_VOICE_APPLICATION_CONNECT_APP_SID}');
application.parameter({ name: 'extension', value: '{EXTENSION}' });
application.parameter({ name: 'sourceAccountSid', value: client.accountSid });
application.parameter({ name: 'returnTo', value: 'application' });
application.parameter({ name: 'returnToId', value: '{APPLICATION_SID}' });

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({ twiml: response.toString() });
```

## Sending the call to voicemail

If the `sendToVoicemail` parameter is `true`, then Spoke will send the call to the target extension's voicemail, *if* that extension is a type that supports
voicemail. Once the external contact leaves a voicemail, the call ends. `User` and `Team` extensions will always have a voicemail, however other directory entry types do not currently support voicemail.  In the case of extensions that do not support voicemail, there are two possible scenarios:

* If `returnTo`/`returnToId` are provided, then the call will be returned to the target defined by `returnToId` as described in the section [Returning unanswered calls](#returning-unanswered-calls) above
* If `returnTo`/`returnToId` are *not* provided, the call will silently end. Due to this behaviour, we recommend that `returnTo` and `returnToId` are always provided

It is important to note that if `sendToVoicemail` is `true` then Spoke will **never** ring the target extension. Instead, this forces Spoke's call flows to bypass availability checks and assume the target entry has no availability.
In the case of a `Team`, it also bypasses unanswered call roll-over rules.  The call will be sent directly to the target entry's
voicemail.  The target entry will:

* Receive a standard missed call/voicemail notification
* See a missed call in their call history
* Receive a voicemail email including transcript (if that option is enabled)

> Note : As noted above, only `User` and `Team` extensions currently support voicemail.

#### Using Spoke's Redirect Handler

Add `&sendToVoicemail=true` to the `url` parameter when updating the call:

```javascript
const client = require('twilio')();

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({
    method: 'POST',
    url: 'https://api.spokephone.com/telephony/redirect?extension={EXTENSION}&organisationId={SPOKE_ORG_ID}&sendToVoicemail=true'
  });
```

#### Using Twilio Voice Application Connect

Add a `sendToVoicemail` parameter to the `<Application>` noun when updating the call:

```javascript
const client = require('twilio')();
const VoiceResponse = require('twilio').twiml.VoiceResponse;

const response = new VoiceResponse();
const dial = response.dial();
const application = dial.application();
application.applicationSid('{SPOKE_VOICE_APPLICATION_CONNECT_APP_SID}');
application.parameter({ name: 'extension', value: '{EXTENSION}' });
application.parameter({ name: 'sourceAccountSid', value: client.accountSid });
application.parameter({ name: 'sendToVoicemail', value: 'true' });

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({ twiml: response.toString() });
```

## Overriding call timeouts

If a valid number is provided as the `timeout`, then Spoke will use it as the number of seconds to wait for someone to answer the call before returning the call or sending it to voicemail.

* For calls to a `User` or a `Device`, this is the number of seconds Spoke will ring the user or the device.
  * The supported range of values for `timeout` when calling a user or a device is from 10 to 70 seconds. If the provided parameter falls outside the range, it will be rounded to the nearest supported value.
* For calls to a `Team`, this is the number of the seconds Spoke will wait for someone to answer the call before returning or forwarding the call.
  * The supported range of values for `timeout` when calling a team is from 10 to 300 seconds. If the provided parameter falls outside the range, it will be rounded to the nearest supported value.

If a valid number is provided as the `nextOfferTimeout`, then Spoke will use it as the number of seconds to wait for calls to a `Team` before offering the call to the next available user(s). The supported range of values for `nextOfferTimeout` is from 5 to 60 seconds. If the provided parameter falls outside the range, it will be rounded to the nearest supported value.

> Note : The asynchronous nature of API calls between Spoke and Twilio coupled with the overhead of setting up and tearing down call legs means that timeout values are indicative only, and the follow on action may occur some number of seconds after the timeout expires.

## Setting call priority

If a valid value is provided as the `priority`, then Spoke will use it to:

* Determine which calls take priority when selecting the next call to queue for a user.
* Determine the order in which calls are offered to a user.

The supported range of values for `priority` is an integer value between 1 and 9, where 1 is the highest priority and 9 is the lowest. If the provided parameter falls outside the range, the call will be assigned a default value of 5.

## Setting passthrough parameters

Passthrough parameters are stored against the call record and are then included in the call's [webhook events](/webhook-events). These parameters can also be retrieved when [getting the call resource through the Spoke API](/api/calls#get-a-call).

Use passthrough parameters to track calls that have been initially handled by other Twilio applications (such as Studio, Flex or your own custom application), ensuring that the outcome of the call can be associated correctly with your external applications (such as CRM or in-house systems).

Examples of passthrough parameters include caller verification, IVR selections or other data collected from external systems during the initial phase of the call.

See [Passthrough Parameters](/passthrough-parameters) for every mechanism that can set them and everywhere they are returned.

To attach passthrough parameters to a call, prefix each parameter name with `x-`.

* Size Limit: The total length of all passthrough parameters (including parameter names and values) must not exceed 1000 bytes. If this limit is exceeded, all passthrough parameters will be discarded.
* Processing: Parameter names and values are URL-decoded, validated for safety, and stored as-is upon input. No additional processing is performed.

#### Using Spoke's Redirect Handler

Add the passthrough parameters to the `url` parameter when updating the call:

```javascript
const client = require('twilio')();

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({
      method: 'POST',
      url: 'https://api.spokephone.com/telephony/redirect?extension={EXTENSION}&organisationId={SPOKE_ORG_ID}&x-contactId=HS12345&x-orderId=OR12345'
  });
```

**Important**: All the query parameters of the redirect handler `url` must be in alphabetical order. In the example above `x-contactId` must come before `x-orderId`.

#### Using Twilio Voice Application Connect

Add each passthrough parameter to the `<Application>` noun:

```javascript
const client = require('twilio')();
const VoiceResponse = require('twilio').twiml.VoiceResponse;

const response = new VoiceResponse();
const dial = response.dial();
const application = dial.application();
application.applicationSid('{SPOKE_VOICE_APPLICATION_CONNECT_APP_SID}');
application.parameter({ name: 'extension', value: '{EXTENSION}' });
application.parameter({ name: 'sourceAccountSid', value: client.accountSid });
application.parameter({ name: 'x-contactId', value: 'HS12345' });
application.parameter({ name: 'x-orderId', value: 'OR12345' });

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
  .update({ twiml: response.toString() });
```
