> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Missed-call → SMS callback recipe

> Catch callers you couldn't answer: auto-text them back when a DID rings out or a queue is abandoned, validate the fallback edge in the simulator before publish, and keep the reply threading into your inbox.

An inbound DID rings unanswered — it times out, every agent is offline, or the caller hangs up in the queue before anyone picks up. Without a handler, that lead is gone. With one, the platform texts the caller back within seconds — "Sorry we missed you, reply and we'll help" — and the caller's reply threads into your normal SMS inbox like any other inbound text. This guide builds that fallback edge end to end: pick the routing intent, set the text-back copy, validate with the simulator, and wire the reply into a queue. A worked dental-clinic example walks the whole compose.

## 1. What a missed-call handler does

Two trigger points can fire the automatic text-back, and you can enable either or both per DID:

* **Ring-out (missed call).** The DID terminates as a genuine missed call — ring timeout, busy, or no agent online — with no voicemail left. If the number's route has the text-back opt-in, the caller gets the SMS immediately.
* **Queue abandon.** The caller reached an ACD queue but hung up before an agent answered. The queue's route config carries its own text-back opt-in, evaluated when the queue entry closes as abandoned.

The outbound text goes through the same billing, opt-out, and quiet-hours enforcement as an SMS your team sends by hand, and it exits via the Devotel wholesale softswitch like every other outbound leg. The caller's reply arrives on the DID the text came from, so the two-way thread lands in your existing inbox with no new surface to operate.

## 2. Pick the routing intent

Text-back is opt-in per DID, and the opt-in lives on the inbound route's `config`. Three route types accept it:

* `type: "voicemail"` — the caller rings out or declines to leave a voicemail; the text-back fires on the missed call. Ring-out goes to voicemail either way; enable it here when you want unanswered callers to get the text regardless of whether they left a message.
* `type: "queue"` — abandoned calls from this queue's entry trigger the text; the queue keeps its normal routing otherwise.
* `type: "dispatch_to_voicemail_box"` — a shared department box — same missed-call semantics as `voicemail`.

Set `config.textBackEnabled: true` on the route. The same `config` object accepts the other fields for that route type, so enabling text-back is one more key on the routing write you already make.

### IVR flows — the fallback edge

When the DID points at an IVR flow (`type: "ivr"`), the flow itself owns the fallback: an `offerSmsCallback` node is the in-flow equivalent of the text-back. At the point where the caller would otherwise dead-end — a menu's `timeout` or `nomatch` handle, or a queue you front with an SMS-deflection offer — branch to `offerSmsCallback`. The node is press-1-to-accept; an accept closes the flow as a callback offer accepted, so wire the `declined` (or `default`) edge back into the flow — typically the upstream queue the offer was deflecting from.

The ring-out case on an `ivr` route — nobody answers the flow's destination either — still resolves through the same missed-call detection; the text-back opt-ins above cover the `voicemail`/`queue`/`dispatch_to_voicemail_box` route types the flow hands off to.

## 3. Set the SMS copy

`config.textBackMessage` (1–480 characters) overrides the platform default:

> Sorry we missed you! Reply to this text and we'll get right back to you.

Write copy that tells the caller what to do next. Keep it under one segment where you can — the cap is 480 characters, and shorter texts read better from a number the caller didn't save. The sender is the DID the caller dialed, so "this is Riverton Dental" belongs in the text: the caller sees an unfamiliar number otherwise.

Business-hours windows belong on the route, not the message. A time-window guard on the DID (see step 7) decides *whether the missed call path applies at this hour*; the text-back itself fires immediately whenever it applies, and the platform's quiet-hours enforcement holds texts that would land outside the allowed window for the tenant's configured hours — no template logic needed.

## 4. Write the routing

Mirroring the full route PUT shape from [Build and ship your first IVR flow](/guides/build-ivr-flow) step 5 — same endpoint, one more config key:

```bash cURL theme={null}
curl -X PUT "https://api.orbit.devotel.io/api/v1/numbers/+14155550123/routing" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "voicemail",
    "config": {
      "textBackEnabled": true,
      "textBackMessage": "Sorry we missed you at Riverton Dental — reply with a good time and we will call you back within one business hour."
    }
  }'
```

For a queue-fronted DID, the same write with `"type": "queue"` and `"config": { "queueId": "queue_01h...", "textBackEnabled": true, "textBackMessage": "..." }`. Omitting `textBackMessage` sends the default copy. Set `textBackEnabled: false` (or omit it) and nothing changes for an existing route.

## 5. Validate with the simulator

Verify the edge before a caller hits it — no live minute burned. For an IVR flow that falls back to an SMS offer on no-input, drive the timeout branch in the simulator:

```bash cURL theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/ivr-flows/ivr_01h.../simulate" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "turns": [
      {},
      { "handle": "accepted" }
    ],
    "max_steps": 50
  }'
```

An empty turn (`{}`) advances a menu exactly as if the caller pressed nothing — the menu's `timeout` handle fires (falling back to `default` when no timeout edge exists) and the walk lands on the `offerSmsCallback` node. An offer is press-1-to-accept; a `{ "digits": "1" }` turn (or the explicit `handle: "accepted"`) accepts. Expect the walk to end at the offer with `termination_reason: "callback_accepted"`, `reached_nodes` spanning menu → offer, and a `gather` in `emitted_verbs`. Send the decline path too — a non-`1` digit takes the offer's `declined`/`default` edge back into the flow.

The ring-out text-back on `voicemail`/`queue` routes is config, not flow structure — there is no graph edge to walk — so the simulator validates the *flow* fallback (the offer node), and the routing write in step 4 is what arms the ring-out trigger. Validate both before publish.

## 6. Land the reply on a queue, not a list

The text-back's power is that the reply is a normal inbound SMS on the DID. Thread it to the team the same way the queue guide covers for human-handled threads — the [two-way conversation guide](/guides/sms-two-way-conversation) shows when a webhook-driven thread map is enough and when to move the thread into the Inbox. For a callback queue rather than an ad-hoc list, point the DID's inbound SMS route at the inbox or a webhook that creates a callback task; the [voice callback console guide](/guides/voice-callback-console) and the [callbacks scheduling page](/voice/callbacks-scheduling) cover the explicit callback-queue request path when the caller asks for a scheduled ring-back instead of texting.

## 7. Edge cases and compliance controls

Tenant-owned controls only; each is a guard your configuration sets, the same class of control the compliance docs document.

* **Spoof / non-dialable caller.** The text-back only fires for a valid E.164 caller id; an anonymous, restricted, or malformed caller is skipped and logged, not texted. If you additionally want to block nuisance callers before the missed-call handler at all, the route's caller-id filter's `block` list (E.164 entries) applies.
* **SMS floods.** Text-back is one SMS per missed/abandoned call and reuses the standard send path, so billing and quota enforcement cap it exactly like a manual send. An inbound call-flood guard on the route (`caller_id_filter.floodGuard`, a per-DID calls-per-second ceiling) throttles a caller hammering the DID before each attempt can trigger another text.
* **Quiet hours.** The send goes through the platform's quiet-hours enforcement, so an after-hours missed call never produces a text that violates the tenant's messaging window. Set the window in your compliance settings; the [TCPA quiet-hours guide](/guides/tcpa-quiet-hours-and-windows) covers the configuration.
* **Opt-outs.** Replies run through the same STOP handling as any thread message — a STOP on the thread suppresses further sends to that caller.

## Worked example: Riverton Dental

Riverton Dental's front desk answers the DID comfortably at off-peak, but peak drive-time (school-run mornings, lunch hour) floods the desk and callers ring out. The compose:

1. The DID's route is `type: "voicemail"` with `textBackEnabled: true` and the copy "Sorry we missed you at Riverton Dental — reply with a good time and we will call you back within one business hour."
2. The front-desk team watches the SMS inbox during the drive-time window; replies become callback tasks instead of lost leads.
3. A caller-id `block` list on the route keeps known robodialers from triggering text-backs, and the tenant's quiet-hours window keeps a 9 pm ring-out from texting a patient at night.

Off-peak, the desk answers and the text-back never fires — the opt-in only arms on a genuine missed or abandoned call. Peak, the missed caller reads the text in under a minute, replies "tomorrow at 10", and the desk books the callback from the inbox thread.
