# OneML overview

OneML is the XML markup you return from your server to control a live call. When Signals needs instructions for a call, it requests your URL and runs the OneML document your server returns, verb by verb, until the document runs out or a verb ends the call. OneML is compatible with TwiML, so most existing TwiML documents run unchanged.

## Document rules

Every OneML document follows the same rules:

- The root element must be `<Response>`. Signals rejects any document with another root element.
- Verbs run top to bottom, in document order.
- Unknown verbs and unknown attributes are rejected. Parsing is strict: a typo in a verb or attribute name fails the whole document instead of being ignored.

## Fetching OneML documents

Signals fetches OneML documents from the URLs you configure: a voice application's voice URL, the `Url` on a created call, and `action` or `<Redirect>` URLs inside a document. A relative `action` or `<Redirect>` URL resolves against the URL of the current document. For a `GET` request, call parameters are sent in the query string. For a `POST` request (the default), they are sent as an `application/x-www-form-urlencoded` body.

Signals waits at most 10 seconds for your server to respond and follows at most 5 redirects. See [Webhooks](/programmable-voice/webhooks) for every parameter and limit.

## Verbs

| Verb | Description |
|------|-------------|
| [Say](/programmable-voice/oneml/say) | Speaks text to the caller using text-to-speech. |
| [Play](/programmable-voice/oneml/play) | Plays an audio file, or sends DTMF tones, to the caller. |
| [Gather](/programmable-voice/oneml/gather) | Collects DTMF digits or speech from the caller. |
| [Record](/programmable-voice/oneml/record) | Records the caller's voice. |
| [Dial](/programmable-voice/oneml/dial) | Connects the call to another phone number. |
| [Redirect](/programmable-voice/oneml/redirect) | Fetches and runs a new OneML document. |
| [Pause](/programmable-voice/oneml/pause) | Waits silently for a set duration. |
| [Hangup](/programmable-voice/oneml/hangup) | Ends the call. |
| [Reject](/programmable-voice/oneml/reject) | Rejects an incoming call before it is answered. |
| [Stream](/programmable-voice/oneml/stream) | Streams call audio to a WebSocket endpoint. |
| [Disconnect](/programmable-voice/oneml/disconnect) | Ends OneML control of the call without a hangup. |

## Limits

| Limit | Value |
|-------|-------|
| Inline OneML document size (`Twiml` on create-call) | 4,000 characters |
| Redirect loop cap | 10 consecutive redirects without new caller input |
| `loop="0"` repeat cap | 1,000 iterations |
| Webhook fetch timeout | 10 seconds |

## Check a document before you deploy it

The Signals console includes a OneML checker. Switch the console to **Programmable Voice** and open **OneML** to paste a document, or fetch one from a voice application's URL, and review the problems it finds and the steps the document would run.

## Minimal example

The following document speaks a greeting and hangs up:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Welcome to Acme Delivery.</Say>
  <Hangup/>
</Response>
```

A spoken one-time passcode is the same idea, passed inline when you create a call so no server is needed. Separate the digits with spaces so they are read one at a time:

```bash
curl -X POST "https://api.signals.pressone.africa/2010-04-01/Accounts/ACCOUNT_SID/Calls.json" \
  -u "ACCOUNT_SID:AUTH_TOKEN" \
  --data-urlencode "To=+2348031234567" \
  --data-urlencode "From=+2342013300100" \
  --data-urlencode "Twiml=<Response><Say loop=\"2\">Your Acme verification code is 4 8 2 9 1 6.</Say></Response>"
```

## Next steps

- [Receiving calls](/programmable-voice/receiving-calls): point a number at your server.
- [Webhooks](/programmable-voice/webhooks): the parameters every request carries.
- [Moving from Twilio](/programmable-voice/twilio-compatibility): TwiML features OneML does not support.
