> ## 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.

# Set up voicemail boxes and greetings

> Create personal and shared department voicemail mailboxes, attach a greeting by upload or text-to-speech, wire a DID or queue overflow to the box, and retrieve messages with full-read fencing and MWI.

A voicemail mailbox captures a caller's recording when nobody picks up: at the end of an IVR flow, on a queue's overflow path, or as a DID's routed destination. Each capture stores the recording, a transcript, and per-user read state — so a shared mailbox works like a triage queue, not a forwarded audio file. This guide covers the operator loop end to end: create the box, set the greeting, route calls into it, and work the messages.

**Base path:** `/api/v1/voice`

**Authentication:** Clerk session (`Authorization: Bearer <token>`) or API key (`X-API-Key`).

**Scope:** `voice:read` for listings and playback; `voice:write` plus an owner, admin, or developer role for creating or changing a mailbox. Greetings are per-user — any authenticated user manages their own.

***

## 1. Mailbox concepts: personal vs. shared

Orbit keeps two mailbox shapes. Pick per audience, not per habit:

* **Personal mailbox** — every user already has one. A captured message lands on the assigned user's mailbox, and a queue whose `overflowAction` is `"voicemail"` captures against the assigned user when the queue falls through with no eligible agent. The per-user greeting (Section 3) plays to the caller; you never create this mailbox — it exists with the user.
* **Shared department mailbox** — a box you create (for example `support`, `sales`, `after-hours`). It carries a roster of member user ids; when an inbound route or flow targets the box, every captured message is visible to every member and invisible to non-members. Read state is tracked per member — one person marking a message read doesn't clear it for the rest.

Both shapes show up in the dashboard's voice → voicemails page; the API is what you wire into provisioning flows, migration scripts, and shared-inbox automation.

## 2. Create a shared mailbox and route calls into it

`POST /api/v1/voice/voicemail-boxes` creates the box. `name` is a lowercase slug unique within your organization; `label` is the human-readable display; `members` is the roster of user ids subscribed to the box (max 50 — every id must belong to your organization or the call returns 422 with the offending ids listed).

```bash cURL theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "support",
    "label": "Support shared inbox",
    "members": ["user_abc123", "user_def456"],
    "retention_days": 365
  }'
```

The response is the created box with an id of the form `vmbox_*`. `retention_days` (1–2555, about seven years) sets how long messages in this box are kept — omit it to inherit the organization default.

Update the roster, label, or retention with `PUT /api/v1/voice/voicemail-boxes/{id}` — supply only the fields you want to change; when `members` is supplied it replaces the roster rather than merging. List boxes (keyset-paginated, pass the previous page's `meta.pagination.cursor` as `cursor`) with `GET /api/v1/voice/voicemail-boxes`, and remove one with `DELETE /api/v1/voice/voicemail-boxes/{id}`. Deleting a box does not delete messages already captured against it — they remain visible, grouped under the archived-box view in the dashboard.

**Wire a DID or flow to the box.** In the [IVR flow builder](/guides/build-ivr-flow), set the destination node's action to route into a voicemail box and pass the `vmbox_*` id. The same target exists for a DID's inbound routing config — point the number's route at the box and every unanswered call captures against it, visible to the member roster. A queue's fallback works the same way from the queue side: set `overflowAction` when you [create or update the queue](/guides/voice-queues) so a queue with no eligible agents drops the caller into voicemail instead of ringing forever.

## 3. Set the greeting: upload or text-to-speech

Greetings are per-user. The assigned user's greeting plays on personal capture; a box with no explicit greeting plays the tenant-default message. Manage your own greeting under `/api/v1/voice/voicemail/greeting` — no admin role required.

**Author by text-to-speech** — the fastest path and the one most teams standardize on. Send the spoken text; the platform renders it to audio and stores it against your user:

```bash cURL theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/voicemail/greeting/tts" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "You have reached Devotel support. Leave your name, number, and a short description, and we will call you back within one business day.",
    "voice_id": "sapphire",
    "language": "en-US"
  }'
```

`text` is capped at 500 characters — at normal speaking pace that is roughly 30 seconds, which is already longer than callers tolerate before the beep. `voice_id` and `language` (a BCP-47 code like `en` or `en-US`) are optional; omit them to use the tenant's default voice.

**Upload a recorded file** — MP3 or WAV, 2 MB maximum, as multipart form data:

```bash cURL theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/voicemail/greeting" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -F "file=@support-greeting.mp3"
```

Read the current greeting with `GET /api/v1/voice/voicemail/greeting`; the response carries the playback URL and its upload timestamp. Revert to the tenant default with `DELETE /api/v1/voice/voicemail/greeting`.

For business-hours variation, keep the daytime flow's greeting prompt in the IVR itself (the `say`/`play` node before the voicemail node) and treat the greeting endpoint as the after-hours and overflow default — the flow's prompt wins whenever the flow runs, the mailbox greeting covers everything that lands without one.

## 4. Retrieve messages and keep the badge honest

List the newest messages first with cursor pagination:

```bash cURL theme={null}
curl "https://api.orbit.devotel.io/api/v1/voice/voicemails?limit=20" \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

Successful catches:

* `GET /api/v1/voice/voicemails/{id}` returns the message with a signed, short-lived recording URL and the transcript. Transcripts are fenced — a caller without voicemail-read permission receives a masked transcript, not the raw text.
* `GET /api/v1/voice/voicemails/search?q=<term>` runs full-text search across transcripts, so "find every message mentioning a refund" is one call.
* `PATCH /api/v1/voice/voicemails/{id}/read` with `{ "is_read": true }` toggles read state; `DELETE /api/v1/voice/voicemails/{id}` removes the message.
* `GET /api/v1/voice/voicemails/team` is the shared-inbox view: box-captured and unclaimed messages with the caller's own read state per message. `POST /api/v1/voice/voicemails/{id}/claim` with `{ "claim": true }` assigns the message to you (or releases it with `false`); `POST /api/v1/voice/voicemails/{id}/team-read` marks your read state without touching anyone else's.
* `POST /api/v1/voice/voicemails/{id}/forward` forwards the recording to colleague user ids, or to an external email address when the org allows it — the recipient gets the audio as an attachment.

**Notifications and MWI.** New captures raise an in-dashboard notification, and — for users who turn it on — a voicemail-to-email delivery with the audio attached, so an after-hours mailbox can land in the on-call inbox without anybody polling. The message-waiting indicator comes from `GET /api/v1/voice/mwi` (snapshot) and `GET /api/v1/voice/mwi/stream` (server-sent events): new/old message counts per mailbox, which is what backlights the softphone's voicemail badge and a SIP desk phone's lamp. Pipe the SSE stream into any wallboard or desktop app that needs a live unread count.

**Callback-in-queue link.** A message that needs a return call should not sit next to the queue it belongs to — send the caller back into it. Read the message, then enqueue a callback on the right queue ([queue callbacks](/voice/queue-sla-forecast-callback)) so the return call enters the same SLA tracking and agent pool as a live caller. Teams that skip this step end up with voicemails triaged fast but answered slow.

## 5. Verify and troubleshoot

Run this checklist after wiring a new box:

1. `GET /api/v1/voice/voicemail-boxes` — the box exists with the roster you expect.
2. Call the DID off-hours (or overflow the queue by signing every agent out) and leave a 10-second message.
3. `GET /api/v1/voice/voicemails?limit=1` — the message appears with a transcript and a signed recording URL that plays.
4. `GET /api/v1/voice/mwi` — the new-message count for the box is non-zero for each member.
5. Mark it read as one member; confirm another member's `/voicemails/team` still shows it unread.

Common failures:

* **422 on create, `members` field called out:** at least one user id is not in your organization or was deleted. The error lists the offending ids — fix the roster, not the call.
* **409 on create:** the `name` slug already exists in your organization. Names are unique per org; pick another slug or reuse the existing box.
* **Caller hears the default greeting after you uploaded a new one:** greetings attach to the *assigned user*, not the box. A route into a shared box plays the tenant default unless the flow plays its own prompt first — upload the greeting as the user the flow assigns, or move the prompt into the flow.
* **TTS returns 503:** text-to-speech is not configured for the tenant. Fall back to the multipart upload path.
* **413 on upload:** the greeting file exceeds 2 MB. Transcode to MP3 or trim the recording; voicemail intros past a minute lose callers anyway.
* **Plays for one member but is invisible to another:** read state is per member — a teammate marking a message read never clears it for you. Conversely, a non-member never sees box messages at all; check the roster with `GET /api/v1/voice/voicemail-boxes/{id}`.

## See also

* [Set up and run voice queues](/guides/voice-queues) — overflow action, SLA policies, and the queue a callback re-enters
* [Build and route an IVR flow](/guides/build-ivr-flow) — the destination node that targets a voicemail box
* [Queue SLA forecast and callbacks](/voice/queue-sla-forecast-callback) — the callback path a returned voicemail should join
* [Voice API reference](/api-reference/endpoints/voice) — parameter and response detail for every endpoint used here
