Skip to content

Voicemail Administration

This page covers the operations an administrator reaches for when a mailbox needs intervention rather than day-to-day management: bulk message removal, counter/storage repair, and the recovery workflow for orphan boxes — mailboxes whose contents outlived their config entry. Routine operations (messages, greetings, PINs, options) are on Voicemail Box Management.

Conventions are the usual ones: $VSS, $TOKEN, $NSID for curl; an active vsscli profile with a namespace set. Voicemail commands live under vsscli realtime voicemail … (short form vsscli rt vm …).

Everything on this page needs vm:write except orphan destruction and rehoming, which are gated behind the stricter vm:admin:

Operation Action Held by
Wipe, repair vm:write partition-admin, namespace-admin, provisioner, operator, editor
Orphan listing / message reads vm:list / vm:read The same, plus viewer and system-auditor
Deleting single orphan messages vm:write As for wipe/repair
Rehome, purge, purge-all vm:admin partition-admin, namespace-admin, provisioner only

The split means operations staff can clean up message content, but destroying a mailbox’s remaining state (or moving it into another box) requires an admin-level credential.

Wipe deletes every message in an active box — recordings and metadata — and zeroes the counters, clearing the subscriber’s message lamp. The box itself is untouched: PIN, email, greetings, and preferences all survive. Typical uses: a mailbox handed to a new employee (paired with a PIN reset and greeting deletes), or a subscriber request to empty a flooded box.

Terminal window
curl -s -X POST "$VSS/v1/ns/$NSID/vm/boxes/standard/1001/wipe" \
-H "Authorization: Bearer $TOKEN"

There is no undo. For single messages use message delete; to take the whole box out of service, remove it from config instead.

Repair is the consistency fixer. It:

  1. Recounts unread / read / urgent from the actual message rows and rewrites the box counters;
  2. Sweeps storage: deletes any audio object under the box’s prefix that no message row or greeting slot references (left behind if a delete was interrupted between storage and database);
  3. Refreshes message-waiting state on the subscriber’s devices.

Run it when a message lamp is stuck, listed counts disagree with the messages actually present, or after any operation that failed midway. It is safe to run on a healthy box — a no-op repair reports identical before/after numbers and zero objects deleted.

Terminal window
curl -s -X POST "$VSS/v1/ns/$NSID/vm/boxes/standard/1001/repair" \
-H "Authorization: Bearer $TOKEN"
# → {"success":true,"context":"standard","box":"1001",
# "unread_before":3,"read_before":10,"urgent_before":1,
# "unread_after":2,"read_after":10,"urgent_after":1,
# "objects_deleted":1}

A drifted before → corrected after pair tells you the counters were wrong; a non-zero objects_deleted tells you stranded audio was reclaimed.

When a box is removed from a document-mode namespace’s config, what happens to its contents is decided by the namespace-level configuration: key cleanup-mailboxes:

  • "true" (the default) — the apply that removes the box also deletes its messages, greetings, and storage. Gone is gone.
  • "false" — the box’s contents are retained as an orphan: absent from config (unreachable by callers and the dial-in menus, invisible to the active-box endpoints) but fully present in storage, waiting for a deliberate decision — inspect it, recover messages from it, move it into an active box, or purge it.

Orphans also cover the rename case: config identifies a box by (context, box), so renaming a box or moving it to another context is, mechanically, “remove one box, add another” — the subscriber’s messages stay with the old name as an orphan until you rehome them into the new one.

An orphan is frozen except for disposal: you can list and download its messages and delete them individually, but greeting/PIN/option writes are refused (409) until the contents are rehomed into an active box.

Terminal window
# All orphan boxes in the namespace
curl -s "$VSS/v1/ns/$NSID/vm/orphans" -H "Authorization: Bearer $TOKEN"
# → {"success":true,"orphans":[{"context":"standard","box":"1017",
# "unread":4,"read":9,"urgent_unread":0,"provisioned":true}]}
# An orphan's messages — same shape as an active box's listing
curl -s "$VSS/v1/ns/$NSID/vm/orphans/standard/1017/messages" \
-H "Authorization: Bearer $TOKEN"
# Download / delete a single orphan message
curl -s "$VSS/v1/ns/$NSID/vm/orphans/standard/1017/messages/01J1FZK7Q0X5B3M8QW9RS2T4VE" \
-H "Authorization: Bearer $TOKEN" -o saved.wav
curl -s -X DELETE "$VSS/v1/ns/$NSID/vm/orphans/standard/1017/messages/01J1FZK7Q0X5B3M8QW9RS2T4VE" \
-H "Authorization: Bearer $TOKEN"

Recorded greetings ride along inside an orphan but are not individually downloadable through the orphan endpoints — they’re preserved for rehoming, and destroyed with the orphan on purge.

Rehome is the recovery verb: it moves everything an orphan still holds — messages, PIN, email, greetings, preferences — into an active box, then purges the now-empty orphan. It’s the second half of a box rename, and the answer to “we deleted the box but the subscriber wants their messages back” (recreate the box in config, apply, rehome the orphan into it).

Terminal window
# Source orphan in the path; active target in the body
curl -s -X POST "$VSS/v1/ns/$NSID/vm/orphans/standard/1017/rehome" \
-H "Authorization: Bearer $TOKEN" \
-d '{"context":"standard","box":"2017"}'
# → {"success":true,"source_context":"standard","source_box":"1017",
# "target_context":"standard","target_box":"2017","messages_moved":13}

Merge semantics, for when the target box isn’t empty:

  • The imported (orphan) data wins on conflict. A message ID present in both boxes is overwritten by the orphan’s copy; a PIN, email, or greeting the orphan has set replaces the target’s. Where the orphan has nothing (no PIN, empty slot), the target’s existing value stays.
  • Counters are recomputed over the merged message set, and message-waiting state on the target’s line is refreshed.
  • Message audio is copied storage-side (no re-upload), so large boxes rehome quickly.
  • The source must classify as an orphan and the target as active — anything else is refused (409) before any data moves. Rehoming a box onto itself is a 400.

When an orphan’s contents are confirmed unwanted (retention window passed, subscriber departed), purge it — messages, greetings, and every trace of the box:

Terminal window
# One orphan
curl -s -X DELETE "$VSS/v1/ns/$NSID/vm/orphans/standard/1017" \
-H "Authorization: Bearer $TOKEN"
# Every orphan in the namespace — requires echoing the nsid as confirmation
curl -s -X DELETE "$VSS/v1/ns/$NSID/vm/orphans?confirm=$NSID" \
-H "Authorization: Bearer $TOKEN"
# → {"success":true,"purged":7}

A purge-all without the correct confirm parameter is refused with a 400 that includes the expected value — the API’s destructive-action confirmation pattern.

Purging is irreversible. A periodic orphans listing (and purge of anything past your retention window) is a reasonable housekeeping cron — orphans hold real storage.

Every box endpoint checks which state the box is in and refuses the wrong family with a 409 problem document whose family field names the state the box is actually in:

Response Meaning Do
404 vm-box-not-found No such box in config or storage (also: unknown message/greeting) Check the (context, box) spelling — both names, in that order
409 vm-box-conflict, family: "orphan" You used an active-box endpoint on an orphan Switch to the /vm/orphans/… family, or rehome first
409 vm-box-conflict, family: "active" You used an orphan endpoint on an active box Switch to /vm/boxes/…; a box present in running config cannot be purged — remove it from config first
409 rehome target not active Rehome destination is missing or itself an orphan Add the target box to config and apply, then rehome
400 pin errors Non-digit PIN, or shorter than the context’s min-pin-length Fix the PIN value
400 confirmation required Purge-all without ?confirm=<nsid> Echo the namespace UUID (or let vsscli do it)

One subtlety worth knowing: a box that is in config but was never applied doesn’t exist yet — config versions do nothing until applied, so a freshly authored box answers 404 until the apply that provisions it.