# Record

The `<Record>` verb records the caller's voice and, once recording ends, sends the result to your `action` URL.

## Attributes

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `action` | string (uri) | None | URL to send the result to. When absent, the next verb in the document runs once recording ends. |
| `method` | string | `POST` | HTTP method used to request `action`. `GET` or `POST`. |
| `timeout` | integer | `5` | Seconds of silence that end the recording. Set to `0` to disable the silence timeout. |
| `finishOnKey` | string | `#` | Key that ends the recording. A single character: a digit, `*` or `#`. Set to an empty string to disable it. |
| `maxLength` | integer | `3600` | Maximum recording length, in seconds. |
| `playBeep` | boolean | `true` | Whether to play a beep before recording starts. |
| `recordingStatusCallback` | string (uri) | None | URL to notify when the recording finishes. Signals requests it once, for the `completed` event only. |
| `recordingStatusCallbackMethod` | string | `POST` | HTTP method used to request `recordingStatusCallback`. `GET` or `POST`. |

:::note
`RecordingUrl` points at the recording audio on the Calls API. Downloading it requires your `AccountSid` and auth token. See [Download recording audio](/programmable-voice/recording-calls#download-recording-audio).
:::

## Nesting

`<Record>` is a self-closing element with no text content and no nested verbs.

## Action parameters

| Name | Type | Description |
|------|------|-------------|
| `RecordingSid` | string | Unique identifier for the recording. |
| `RecordingUrl` | string (uri) | URL of the recording audio, ending in `.wav`. |
| `RecordingDuration` | integer | Duration of the recording, in seconds. |

### Recording status callback parameters

When `recordingStatusCallback` is set, Signals posts these parameters to it once the recording completes:

| Name | Type | Description |
|------|------|-------------|
| `AccountSid` | string | Your Voice Account SID. |
| `CallSid` | string | Unique identifier for the call. |
| `RecordingSid` | string | Unique identifier for the recording. |
| `RecordingUrl` | string (uri) | URL of the recording audio, ending in `.wav`. |
| `RecordingStatus` | string | Always `completed`. |
| `RecordingDuration` | integer | Duration of the recording, in seconds. |
| `RecordingChannels` | integer | Number of audio channels in the recording. |
| `RecordingSource` | string | Always `RecordVerb` for `<Record>`. |

## Examples

A voicemail prompt that records a message and requests `action` when done:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Leave a message after the beep. Press the pound key when you are finished.</Say>
  <Record action="/voicemail-complete" maxLength="120" finishOnKey="#"/>
  <Say>We did not receive a recording. Goodbye.</Say>
  <Hangup/>
</Response>
```

The `/voicemail-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("/voicemail-complete", (req, res) => {
  console.log("Voicemail received:", {
    recordingSid: req.body.RecordingSid,
    recordingUrl: req.body.RecordingUrl,
    durationSeconds: req.body.RecordingDuration,
  });

  res.type("text/xml").send(`<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Thank you. Your message has been recorded. Goodbye.</Say>
  <Hangup/>
</Response>`);
});

app.listen(3000);
```

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

app = Flask(__name__)

@app.route("/voicemail-complete", methods=["POST"])
def voicemail_complete():
    print("Voicemail received:", {
        "recordingSid": request.form.get("RecordingSid"),
        "recordingUrl": request.form.get("RecordingUrl"),
        "durationSeconds": request.form.get("RecordingDuration"),
    })

    oneml = """<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Thank you. Your message has been recorded. Goodbye.</Say>
  <Hangup/>
</Response>"""

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

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

</CodeTabs>

A silent recording of the rest of the call, reported through `recordingStatusCallback` instead of `action`:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>This call may be recorded for quality purposes.</Say>
  <Record playBeep="false" timeout="0" maxLength="3600" recordingStatusCallback="/recording-status"/>
  <Hangup/>
</Response>
```

See [Recording calls](/programmable-voice/recording-calls) for a complete `/recording-status` receiver and for downloading the audio.

## See also

- [Say](/programmable-voice/oneml/say)
- [Gather](/programmable-voice/oneml/gather)
- [OneML overview](/programmable-voice/oneml/overview)
