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

# Operate the team voicemail inbox

> Run a shared voicemail queue across teammates: claim ownership, keep per-user read state independent, and wire the daily triage loop into callback queues.

A shared mailbox only pays off if the team around it has a system: who is handling each message, what has been seen and by whom, and where a return call goes. The team voicemail inbox is that system — one list every department member sees, with claim-based ownership so two people never chase the same caller, and read state tracked per teammate so nobody else's habits pollute your unread count. This guide is the operating manual; [set up the voicemail boxes themselves](/guides/voice-voicemail-boxes) first.

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

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

**Scope:** `voice:read` for the list; `voice:write` plus an owner, admin, or developer role for claim and read-state changes.

***

## 1. Where the shared inbox lives

Open **Voice → Voicemails → Team** in the dashboard (`/voice/voicemails/team`). The page sits behind a role gate: owner, admin, and developer roles see it; other members land on their personal voicemail inbox instead. Grant one of those roles — the built-in role ladder is documented in [Roles, teams, and permissions](/concepts/roles-teams-permissions) — before pointing anyone at the team view. A 403 here is the role, not the page.

The personal inbox (`/voice/voicemails`) links to the team inbox and back, so operators can move between the two without re-navigating the sidebar.

## 2. Reading the list

Every row is one captured message with the caller number, the captured number it landed on, and the absolute timestamp pinned to your timezone. Two independent flags sit on top:

* **Owned (claimed) messages** carry a `Claimed by <name>` badge so the queue shows who is handling the caller. The claimant name resolves from your team's roster.
* **Your read state** come from the `user_read_at` column — unread rows are highlighted for you, and a pithy "Unread by you" counter tracks only your progress. The legacy `is_read` flag is projected for older UI surfaces, but the team view keys off the per-user column.

Four stat tiles — Open, In progress, Unread by you, Total — plus four filter chips (Open, In progress, Mine, All) let you cut the queue the way a triage shift cuts it. A transcript search box searches caller numbers and transcript text over the loaded window; rows paginate 50 at a time behind a "Load more" button so a long window doesn't bury the page.

Filter over the API the same way: folder view, keyset cursor, and the per-user read field travel in one response:

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

Each row carries `claimed_by_user_id` / `claimed_at` (who owns it) and `user_read_at` (your state). Pass `folder=spam` or `folder=inbox` to scope the list; pass the previous page's `meta.pagination.cursor` as `cursor` for the next page.

## 3. Claim and release: triage ownership

Claiming pins a message to one person without touching anyone else's view. The API body is an `action` enum, not a boolean:

```bash cURL theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/voicemails/{id}/claim" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "action": "claim" }'
```

The semantics are explicit:

* **Claim an unclaimed message** — assigns it to you, stamps `claimed_at`, and shows your name to the rest of the team.
* **Claim a message you already hold** — a no-op; re-claiming is idempotent, so double-clicks and retry loops are safe.
* **Claim a message someone else holds** — `409 CONFLICT` with the current claimant's id in the error details. Refresh and you see their badge.
* **Release** (`{ "action": "release" }`) — drops ownership back to Open. Releasing someone else's claim is owner- and admin-only; a developer role hits the same 409 as a claim attempt.

The claim never touches read state — taking ownership doesn't mark the message read for you or anyone else.

## 4. Per-user read markers

Read state lives in a per-(message, user) row, so each teammate keeps an independent unread filter:

```bash cURL theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/voicemails/{id}/team-read" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "is_read": true }'
```

Send `is_read: false` to reopen a message for yourself — useful when a claim bounced back to Open and you want it back in your unread counter. Marking read never writes the legacy global `is_read` flag and never changes another member's `user_read_at`; that's what makes a five-person box workable instead of a first-to-open-wins race.

## 5. Workflow patterns

Claim semantics support a few operating modes; pick one and write it down.

**Solo operator** — one person owns the box. Skip claims and just work the Open filter; claim only when someone covers for you, so the coverage hand-off shows who accepted what.

**Rotating on-call** — each shift empties the Open chip before handoff. The incoming shift's first move is filtering to Open: anything still there was claimed and not resolved by the outgoing shift. Hand off cleanly by releasing instead of leaving stale claims.

**Department box coverage** — one shared mailbox, several members (up to 50 on the roster). The "Unread by you" tile is each member's personal backlog; "Open" is the team's. A healthy box keeps Open at zero more than it keeps any individual's unread at zero.

**Claim before you call back** — the etiquette that prevents double-calls: claim first, then ring the customer, then mark read. If two people phone the same customer, the message usually sat claimed-by-nobody for a while — treat a 409 as a save, not an error.

## 6. Wire it into the contact center

Triage is half the job; the return call is the other half. Play the message, claim it, then enqueue a callback on the right queue so the return call enters the same SLA tracking and agent pool as a live caller — the pattern in the [Queue SLA callback runbook](/guides/queue-sla-callback-runbook). Supervisors on owner or admin roles can force-release abandoned claims, so a stalled shift doesn't park messages; the audit ledger records who claimed, released, and toggled read on every row for regulated-content evidence.

On go-live, the [CCaaS go-live checklist](/guides/voice-ccaas-go-live-checklist) covers the voice cutover end to end — fold the box roster and this triage loop into that run rather than treating voicemail as an afterthought.

## 7. Troubleshoot

* **The shared list is empty but callers say they left messages** — the route points at a `vmbox_*` id whose roster you're not on, or the box itself is archived. Check the box and its roster with `GET /api/v1/voice/voicemail-boxes` and have an admin add you with `PUT /api/v1/voice/voicemail-boxes/{id}`. Non-members never see box messages.
* **403 on the dashboard Team tab** — your role is below developer. An owner or admin bumps it in Team settings.
* **409 on claim, repeatedly** — someone else holds the message and the badge tells you who. Releasing another member's claim is owner/admin-only, by design.
* **A claim was released accidentally** — re-claim it; the claim history lives in the audit ledger, and the claimant's per-user read state survives the release, so no read progress is lost.
* **One member's view shows everything read, another's shows unread** — working as intended. Read state is per user; the discrepancy means one person worked the queue and the other hasn't. Cross-account anomalies (a user marked read in a different org's data) are impossible by construction — every query is scoped to the caller's tenant.
* **Transcript looks masked for one colleague, raw for another** — transcript visibility follows the caller's voicemail-read permission, not the claim. Members lacking read permission see a fenced preview; grant the permission rather than forwarding the text by hand.

## See also

* [Set up voicemail boxes and greetings](/guides/voice-voicemail-boxes) — create the shared mailbox, the roster, and the greeting this inbox aggregates
* [Queue SLA forecast and callbacks](/guides/queue-sla-callback-runbook) — the callback path a returned voicemail should join
* [Voice CCaaS go-live checklist](/guides/voice-ccaas-go-live-checklist) — fold the triage loop into the go-live run
* [Voice API reference](/api-reference/endpoints/voice) — parameter and response detail for every endpoint used here
