> For complete lifecycle-event payload schemas and examples, use the canonical overview: Session /api/sessions; Room lifecycle, members, and room playback /api/rooms; Session playback /api/playback; Recording /api/recording; DTMF /api/keypad-input; Messages /api/messages; WebSocket Session /api/web-socket. Use /api/event-delivery for transport behavior. Endpoint pages name relevant events, but these overviews are the canonical references.

# Send DTMF sequence

POST https://api.vorbal.dev/v1/sessions/{uuid}/dtmf/send
Content-Type: application/json

**Rate limit: Per command** · **Burst:** 20 · **Refill:** 20 req/s

Send an ordered sequence of DTMF key presses and waits to the remote party during an answered phone session. Each action specifies its key-press duration or wait. The platform preserves action order, but a `wait.duration_ms` value is a minimum delay and the next action might start later.

The platform accepts only one active sequence per session. It does not accept this command for ringing calls or WebSocket sessions created with `POST /v1/sessions:connectWebsocket`.

A `202` response confirms that the platform durably admitted the sequence. It does not confirm that the remote party handled the keys, and the platform does not emit an acceptance webhook.

See [Keypad input lifecycle events](/api/keypad-input#lifecycle-events) for complete payload schemas and examples.

Reference: https://docs.vorbal.dev/api/keypad-input/send

## Authentication

- `Authorization` header (bearer token, required) — Application auth. Send `Authorization: Bearer <app_uuid>:<api_key>` using any active key in the app's collection. See [Authentication](https://voice-platform.docs.buildwithfern.com/api/authentication) for details.

## Request

### Path parameters

- `uuid` (string, required) — [Session](/api/sessions) identifier.

### Headers

- `Idempotency-Key` (string, optional) — Optional key for safely retrying mutating requests. See [Idempotency](https://voice-platform.docs.buildwithfern.com/idempotency) for details.
- `Operation-Id` (string, optional) — optional client-supplied lowercase RFC-4122 v4 UUID returned as operation_uuid; platform generates one when omitted; correlation metadata distinct from Idempotency-Key.

### Body (application/json)

- `sequence` (list of object or object, required) — Ordered key and wait actions. Waits may appear anywhere and consecutive waits are allowed. The total nominal duration may not exceed ten minutes, and the sequence must include at least one key action.
  - object
    - `digit` (string, required) — The DTMF key to send: `0`-`9`, `A`-`D`, `*`, or `#`.
    - `duration_ms` (integer, required) — Duration of this key press in milliseconds.
    - `type` ("key", required) — Send one DTMF key press.
  - object
    - `duration_ms` (integer, required) — Requested wait in whole milliseconds; arbitrary values such as `1375` are accepted.
    - `type` ("wait", required) — Wait before executing the next sequence action.

## Response

### 202

Command accepted for async execution

- `operation_uuid` (string, required)
- `status` (enum, required)
  - Allowed values: `in_progress`, `completed`
- `already_ended` (true, optional) — Optional. Set to `true` on idempotent terminal commands when the session was already in a terminal state at the time the request was received. Absent otherwise.

## Examples

**Request**

```json
{
  "sequence": [
    {
      "digit": "1",
      "duration_ms": 250,
      "type": "key"
    },
    {
      "duration_ms": 1375,
      "type": "wait"
    },
    {
      "digit": "#",
      "duration_ms": 400,
      "type": "key"
    }
  ]
}
```

**Response**

```json
{
  "operation_uuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "in_progress"
}
```

**SDK Code**

```python Keypad Input_sendDTMFDigits_example
import requests

url = "https://api.vorbal.dev/v1/sessions/uuid/dtmf/send"

payload = { "sequence": [
        {
            "digit": "1",
            "duration_ms": 250,
            "type": "key"
        },
        {
            "duration_ms": 1375,
            "type": "wait"
        },
        {
            "digit": "#",
            "duration_ms": 400,
            "type": "key"
        }
    ] }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Keypad Input_sendDTMFDigits_example
const url = 'https://api.vorbal.dev/v1/sessions/uuid/dtmf/send';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"sequence":[{"digit":"1","duration_ms":250,"type":"key"},{"duration_ms":1375,"type":"wait"},{"digit":"#","duration_ms":400,"type":"key"}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Keypad Input_sendDTMFDigits_example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.vorbal.dev/v1/sessions/uuid/dtmf/send"

	payload := strings.NewReader("{\n  \"sequence\": [\n    {\n      \"digit\": \"1\",\n      \"duration_ms\": 250,\n      \"type\": \"key\"\n    },\n    {\n      \"duration_ms\": 1375,\n      \"type\": \"wait\"\n    },\n    {\n      \"digit\": \"#\",\n      \"duration_ms\": 400,\n      \"type\": \"key\"\n    }\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Keypad Input_sendDTMFDigits_example
require 'uri'
require 'net/http'

url = URI("https://api.vorbal.dev/v1/sessions/uuid/dtmf/send")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"sequence\": [\n    {\n      \"digit\": \"1\",\n      \"duration_ms\": 250,\n      \"type\": \"key\"\n    },\n    {\n      \"duration_ms\": 1375,\n      \"type\": \"wait\"\n    },\n    {\n      \"digit\": \"#\",\n      \"duration_ms\": 400,\n      \"type\": \"key\"\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java Keypad Input_sendDTMFDigits_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.vorbal.dev/v1/sessions/uuid/dtmf/send")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"sequence\": [\n    {\n      \"digit\": \"1\",\n      \"duration_ms\": 250,\n      \"type\": \"key\"\n    },\n    {\n      \"duration_ms\": 1375,\n      \"type\": \"wait\"\n    },\n    {\n      \"digit\": \"#\",\n      \"duration_ms\": 400,\n      \"type\": \"key\"\n    }\n  ]\n}")
  .asString();
```

```php Keypad Input_sendDTMFDigits_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.vorbal.dev/v1/sessions/uuid/dtmf/send', [
  'body' => '{
  "sequence": [
    {
      "digit": "1",
      "duration_ms": 250,
      "type": "key"
    },
    {
      "duration_ms": 1375,
      "type": "wait"
    },
    {
      "digit": "#",
      "duration_ms": 400,
      "type": "key"
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Keypad Input_sendDTMFDigits_example
using RestSharp;

var client = new RestClient("https://api.vorbal.dev/v1/sessions/uuid/dtmf/send");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"sequence\": [\n    {\n      \"digit\": \"1\",\n      \"duration_ms\": 250,\n      \"type\": \"key\"\n    },\n    {\n      \"duration_ms\": 1375,\n      \"type\": \"wait\"\n    },\n    {\n      \"digit\": \"#\",\n      \"duration_ms\": 400,\n      \"type\": \"key\"\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Keypad Input_sendDTMFDigits_example
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["sequence": [
    [
      "digit": "1",
      "duration_ms": 250,
      "type": "key"
    ],
    [
      "duration_ms": 1375,
      "type": "wait"
    ],
    [
      "digit": "#",
      "duration_ms": 400,
      "type": "key"
    ]
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.vorbal.dev/v1/sessions/uuid/dtmf/send")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```