# Dial

The `<Dial>` verb connects the caller to another phone number. PressOne bridges the two call legs together; once the dialed call ends, PressOne can request an `action` URL with the outcome.

## Attributes

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `action` | string (uri) | — | URL to request once the dialed call ends. When absent, execution continues with the next verb in the document. |
| `method` | string | `POST` | HTTP method used to request `action`. One of `GET` or `POST`. |
| `timeout` | integer | `30` | Seconds to wait for the dialed party to answer before giving up. |
| `callerId` | string | — | Number to present to the dialed party as the caller ID. Must be a number your account owns. PressOne fails the dial (`DialCallStatus` of `failed`) if it is not. When omitted, PressOne presents the original caller's number. |
| `answerOnBridge` | boolean | `false` | Whether to delay answering the caller's leg until the dialed party answers. When `true`, PressOne leaves the caller's leg unanswered until the dialed party picks up, so the caller hears actual ringing until the call connects. When `false`, PressOne answers the caller's leg immediately, before dialing, so the caller typically hears silence instead of ringback until the call connects. |
| `record` | string | `do-not-record` | Whether to record the dialed call. Accepts `do-not-record`, `record-from-answer`, `record-from-ringing`, `record-from-answer-dual`, `record-from-ringing-dual`, or `record-from-start`. Any value other than `do-not-record` records both parties of the bridged call into a single audio file. `record-from-answer` starts the recording when the dialed party answers; `record-from-ringing` and `record-from-start` begin before the dial, so ringback is captured. The dual-channel variants behave like their base mode but still produce a single mixed channel. When recording is on, the `action` request includes `RecordingUrl`, and `recordingStatusCallback` fires when the recording is ready. |
| `recordingStatusCallback` | string (uri) | — | URL to notify when the dialed call's recording finishes. PressOne requests this URL once, for the `completed` event only, with `RecordingSource` set to `DialVerb`. |
| `recordingStatusCallbackMethod` | string | `POST` | HTTP method used to request `recordingStatusCallback`. One of `GET` or `POST`. |
| `timeLimit` | integer | `14400` | Maximum duration of the dialed call, in seconds. When it expires, PressOne hangs up the dialed party; a call that connected reports a `DialCallStatus` of `completed`. Defaults to four hours. |
| `hangupOnStar` | boolean | `false` | Whether the caller can press `*` to hang up on the dialed party without ending their own call. The document then continues: the `action` URL is requested with a `DialCallStatus` of `completed`. The dialed party's `*` has no effect. |
| `ringTone` | string | — | Country code selecting the ringback tone the caller hears while the dialed party rings. One of `us`, `ca`, `uk`, `nz`, `au`, `de`, `it`, `br`, `mx`, `es`, `pt`, `fr`, `in`, `jp`, or `za`. Other values fall back to the carrier's own ringback. When the dialed party's network sends early media, that audio takes precedence over the selected tone. |
| `sequential` | boolean | `false` | Whether to dial multiple `<Number>` children one at a time instead of all at once. When `false`, PressOne rings every target simultaneously and bridges the caller to whichever answers first. When `true`, PressOne dials each target in order, moving to the next only if the previous one does not complete. |

## Nesting

`<Dial>` accepts a phone number as its text content, or one or more `<Number>` child elements.

### `<Number>`

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `sendDigits` | string | — | Accepted but not currently applied. PressOne does not send these DTMF tones to the dialed party after the call connects, regardless of this attribute. |

`<Number>` contains the phone number to dial as text content.

> **Note:** Conference, client, SIP, and queue targets are not available. See the [compatibility page](/voice/twilio-compatibility) for the full list of unsupported targets.

## Action parameters

| Name | Type | Description |
|------|------|-------------|
| `DialCallStatus` | string | Outcome of the dialed call. One of `completed`, `busy`, `no-answer`, `canceled`, or `failed`. |
| `DialCallDuration` | integer | Duration of the bridged call, in seconds. Present only when the call bridged. |
| `DialCallSid` | string | Unique identifier for the dialed call leg. Present only when the call bridged. |
| `RecordingUrl` | string (uri) | Public URL of the recorded audio file. Present only when `record` was enabled. Recording URLs are publicly readable; see the warning on [`<Record>`](/voice/oneml/record). |

## Examples

A simple forward to another number:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial callerId="+2341700000000">+2341800000001</Dial>
</Response>
```

Forwarding with an `action` fallback to voicemail when the call does not complete:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Dial action="/dial-complete" callerId="+2341700000000" timeout="20">
    <Number>+2341800000001</Number>
  </Dial>
</Response>
```

The `/dial-complete` handler, complete and runnable:

<CodeTabs syncKey="lang">

```javascript title="Node.js"
const express = require("express");
const app = express();
app.use(express.urlencoded({ extended: false }));

app.post("/dial-complete", (req, res) => {
  const status = req.body.DialCallStatus;
  let oneml;

  if (status === "completed") {
    oneml = `<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Hangup/>
</Response>`;
  } else {
    oneml = `<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Our team is unavailable right now. Please leave a message after the beep.</Say>
  <Record action="/voicemail-complete" maxLength="120"/>
  <Hangup/>
</Response>`;
  }

  res.type("text/xml").send(oneml);
});

app.listen(3000);
```

```python title="Python"
from flask import Flask, request, Response

app = Flask(__name__)

@app.route("/dial-complete", methods=["POST"])
def dial_complete():
    status = request.form.get("DialCallStatus")

    if status == "completed":
        oneml = """<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Hangup/>
</Response>"""
    else:
        oneml = """<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Our team is unavailable right now. Please leave a message after the beep.</Say>
  <Record action="/voicemail-complete" maxLength="120"/>
  <Hangup/>
</Response>"""

    return Response(oneml, mimetype="text/xml")

if __name__ == "__main__":
    app.run(port=3000)
```

</CodeTabs>

## See also

- [Record](/voice/oneml/record)
- [Redirect](/voice/oneml/redirect)
- [OneML overview](/voice/oneml/overview)
