---
title: "List your originating numbers and each one's (disabled) voicemail configuration"
method: GET
path: "/voice/bridge/voicemail"
tags: ["voice"]
---

# List your originating numbers and each one's (disabled) voicemail configuration

`GET /voice/bridge/voicemail`

## Request

- Base URL: `https://corebee.ai/api/v1`
- URL: `https://corebee.ai/api/v1/voice/bridge/voicemail`
- Auth: HTTP bearer

Every Telnyx DID your organization owns, with the per-number consumer-voicemail setting and the script it would speak, plus the ids of the scripts you may choose from. Requires the voice:bridge scope.

THIS FEATURE IS GATED OFF AND SETTING THE FLAG DOES NOT TURN IT ON. Four independent conditions must all hold before any voicemail is left, and they are AND-ed: (1) the source constant OWNER_DECISION_CONSUMER_MAY_HEAR_SYNTHETIC_AUDIO in lib/voice/voicemail/gate.ts, which is false today and is a code change to alter; (2) the runtime flag ASKOTTO_CONSUMER_VOICEMAIL, which ships unset; (3) a per-DID opt-in, which is the consumer_voicemail_enabled column this endpoint reads and writes and which is false or NULL on every row; (4) an admissible answering-machine-detection configuration, which the account does not currently have, the premium AMD config the bridge dials with sets greeting_duration_millis equal to total_analysis_time_millis, so the "a greeting this long is a machine" rule cannot fire before analysis stops. Condition 4 is a property of the dialing configuration, not of anything you can send here. DO NOT READ THIS ENDPOINT AS "voicemail happens once the flag is set": with the flag set and a number opted in, the first and fourth conditions still hold it closed, and no voicemail is left.

The standing owner decision recorded in source is that the consumer never hears synthetic audio, so PATCH with "enabled": true answers 409 for EVERY organization, EVERY number and EVERY key. Nothing you can send makes it a 200; reversing it is a code change, not configuration. This read reports that refusal up front, `enabling_blocked` is true and `enabling_blocked_reason` says why, precisely so you learn it from a GET rather than by tripping the error in your integration. 

WORDING IS NOT FREE TEXT ANYWHERE ON THIS PATH. `available_script_ids` is the complete set of message bodies the system will speak; PATCH selects one by id and REFUSES a string. See the PATCH description for the reason and for the exact field names that are refused. 

THIS OPERATION DOES NOT 409 WHEN THE MIGRATION IS PENDING, and that is deliberate rather than an omission: if the columns behind the feature are not in the database yet, the read succeeds with 200, every number comes back voicemail_enabled:false, and `schema_pending` is true with `schema_pending_reason` naming the migration. False is also the value once the migration lands, so nothing is lost. PATCH answers 409 in the same situation, because a write cannot be honestly reported as done.

## Response `200`

OK

- object
  - `data` object, required
    - `numbers` VoicemailNumber[], required: Up to 200 of your Telnyx DIDs. There is no cursor on this feed; an organization with more than 200 numbers sees the first 200 and is not told so.
      - `from_number` string: The originating DID owned by your organization.
      - `voicemail_enabled` boolean: The per-DID opt-in, which is the THIRD of four conditions and not the feature switch. False on every number today. NOT tri-state: a NULL column and a false column are both reported as false, deliberately, so nothing invites you to read NULL as "not yet decided".
      - `script_id` 'consumer_no_answer_v1' | 'null', nullable: The version-pinned script this number would speak, or null when none has been chosen. Choosing one is allowed today and is the only part of this feature a PATCH can actually change.
      - `connection_status` string, nullable: Provisioning state of the number, informational only.
    - `available_script_ids` string[], required: Every script id PATCH will accept. The bodies are code-owned and version-pinned; this list is what you choose from, and an id outside it is a 400.
    - `enabling_blocked` boolean, required: True whenever a PATCH carrying "enabled": true would be refused. True today for every organization.
    - `enabling_blocked_reason` string, required: One paragraph naming both blockers in words: the standing owner decision, and the separately-unusable answering-machine detection. Shown here rather than only on the 409 so an integrator never has to trip the error to learn it.
    - `runtime_flag` string, required: Name of the runtime flag that is the SECOND of the four conditions. Reported so a support thread can name it exactly. Setting it does not enable the feature.
    - `schema_pending` boolean, required: True when the columns behind this feature are not in the database yet, so the values above are the defaults rather than stored state. False once the operator applies the migration.
    - `schema_pending_reason` string: Present ONLY when schema_pending is true. Names the migration and states that nothing is lost and nothing is enabled.

## Other responses

- `401`: Invalid or missing credential
- `403`: Forbidden (missing scope, or resource not owned by the credential org)
- `429`: Rate limit exceeded (code rate_limit_exceeded). The ceiling is 100 requests per minute per API key. The response carries Retry-After (seconds) plus X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset, and repeats the seconds in the body as retry_after.
- `500`: Error

---

[API](https://skmtc.dev/corebee/apis/corebee-api.md) · [All operations](https://skmtc.dev/corebee/apis/corebee-api/llms.txt) · [OpenAPI document](https://skmtc.dev/corebee/apis/corebee-api/revisions/a48ea543b4dc?raw)
