---
title: "Set or clear one number's agent lines"
method: PATCH
path: "/voice/bridge/numbers/instructions"
tags: ["voice"]
---

# Set or clear one number's agent lines

`PATCH /voice/bridge/numbers/instructions`

## Request

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

Replace the spoken lines the conversational agent uses for calls placed from one of your DIDs. instructions is REQUIRED in the body: omitting the key is a 400, not a clear, so a mistyped field name can never silently reset a number. Send null to clear every override and return to the shipped templates. 

WHOLE-DOCUMENT REPLACE, NOT A MERGE. What you send is what the number says. To remove one line, re-send the set without it, there is no per-key delete, because a null leaf is refused by the storage constraint. 

EVERY REJECTION IS A 400 THAT NAMES THE RULE THAT FIRED, which character, which cap, which shape, never a 200 that stores less than you sent. If any single key or value is refused the whole request is refused, so a number is never left half-configured. That includes a `templates` or `variables` that is not an object: it is a 400, not a silently skipped half. 

A 200 MEANS STORED, NOT SPOKEN. Read the `warnings` array on the response and the "when an accepted line is still not spoken" section on SpeechOverrides before concluding from a live call that a line was lost. 

Fields this endpoint returns but does not read (using_shipped_templates, connection_status, corridors, normalized, warnings) are IGNORED if you send them back, so a GET-edit-PATCH round trip works. Any other unrecognised field is a 400 that names it. 

TWO CORRIDORS, TWO SETS OF KEYS, AND THE `corridors` ARRAY IS HOW YOU SEE WHICH ONE YOU CONFIGURED. A live-transfer call (briefing_only absent or false) speaks the `opening` template and reads opening_greeting / opening_preamble. A briefing call (briefing_only true on POST /voice/bridge) speaks `briefing_opening` and reads briefing_opening_greeting / briefing_opening_preamble. NEITHER KEY EVER STANDS IN FOR THE OTHER: a number with only opening_greeting set speaks your words on live transfers and the shipped introduction on every briefing call, with a 200 and a matching GET either way. The `corridors` array on GET and on the PATCH response lists EVERY corridor, including the one you set nothing for, and says what each will speak; the PATCH `warnings` array names, in words, the corridor a key you just sent does NOT affect. 

WE DO NOT COPY ONE GREETING INTO THE OTHER FOR YOU, and that is deliberate rather than unfinished: the live-transfer opening is followed by "Are you able to help them right now?" and asks a dealership to take a caller, while the briefing opening is followed by "Have I reached the right person?" and announces a message that will be read out. One sentence cannot be right in both places. Write the second one, or leave the shipped wording there on purpose. 

ACCEPTED VALUES MAY STILL BE NORMALIZED, accents are folded to ASCII, runs of whitespace collapse to one space, and an unrecognised {slot} is removed. What is stored is the normalized text, because that is what will actually be spoken; any key whose stored value differs from what you sent is listed in the response under `normalized`. 

from_number must be a Telnyx DID owned by your organization, else 403. 

A 400 CAN ALSO MEAN THE DATABASE REFUSED A KEY THIS ENDPOINT ACCEPTED. The allow-list is enforced twice, here and by a storage constraint, and they are deployed separately; when they drift the message names the constraint that fired and the keys you sent, and NOTHING IS WRITTEN. Resending without the most recently added keys works until the pending migration is applied. Requires the voice:bridge scope.

## Request body

- BridgeNumberInstructionsUpdate: Any field other than these two is a 400, including voice_id, which belongs to PATCH /voice/bridge/numbers.
  - `from_number` string, required: E.164 DID owned by your organization. 403 if it is not.
  - `instructions` SpeechOverrides, required: The spoken lines one DID overrides. Absent or null means the agent speaks every shipped template. templates keys are the lines themselves; variables are values interpolated into them and into the shipped templates. Both objects are optional but the document must set at least one entry, an empty document is a 400, and null (not {}) is how you clear a number. Total serialized size must be at most 8192 bytes. SLOTS. Any line may interpolate {businessName}, {consumerFirstName}, {dealership}, {department}, {prepLine}, {reasonForCall}. {prepLine} is the prep_line you sent when starting the bridge, its first 180 characters, unmodified. It is NOT unbounded: prep_line itself may be up to 500 characters and the closing line of a briefing call carries more of it than a {prepLine} slot does, so a long note is spoken in full at the close and shortened inside a line. Write lines that read correctly when the note is cut. {reasonForCall} is what the agent says the call is about; on a briefing-only call it is deliberately a neutral stand-in so your message is not delivered twice, which is why it is NOT the same value as {prepLine}. {dealership} and {department} come from `variables` below, falling back to the call's business name and to "sales". An unrecognised {slot} is removed from the line rather than read aloud. CHARACTERS. Lines are plain single-line text. Accents are folded to ASCII and whitespace collapses; a line containing a character outside the accepted set is REJECTED rather than stripped, so you are never given back mangled English you did not write. THE ACCEPTED SET IS EXACTLY: letters A-Z a-z, digits, space, apostrophe, comma, full stop, hyphen, exclamation mark, ampersand, percent, dollar, hash, at, slash, colon, semicolon, parentheses, question mark, and the braces of a {slot}. Everything else is refused, and the two that surprise people most are the DOUBLE QUOTE (so a quoted customer line must be written without quotation marks) and any emoji or non-Latin character that survives accent folding. SHAPES THAT ARE REFUSED, on every line AND on every variable. (a) A word followed by a colon in SPEAKER-LABEL POSITION, at the start of the line, or straight after a ".", "!" or "?", because that reads as a new speaker turn in the transcript the model reads. A colon LATER in a sentence is fine, so "Gunn Honda's sales & service: no-hassle pricing" is accepted and "Dana: yes I can help" is not. Note the rule is about POSITION, not about names: "Dana here, thanks so much." is accepted. (b) The reserved words "intent", "confidence" and "affirmative", which name the fields of the model output that decides whether a call is transferred. (c) An instruction aimed at the model ("ignore/disregard/forget/override/follow/obey" near "instructions/rules/previous/prior/above/earlier"). (d) An assertion that the person has already agreed ("has said yes", "already agreed", "has consented"), that is the exact fact the handoff question exists to establish. (e) Backticks and line breaks. These are NARROW, EXACT rules and not a general "no instructions to the model" filter: they close the phrasings that are known to move the transfer decision, and a sufficiently indirect sentence will still be accepted. What contains the risk is that the handoff question itself is code-owned and byte-identical on every call. ⛔ WHEN AN ACCEPTED LINE IS STILL NOT SPOKEN. A 200 means STORED. Three rules are re-checked at SPEAK time, once your {slots} are filled with that call's real values, and any of them returns the shipped wording FOR THAT CALL, never a truncation, never silence. (1) LENGTH AFTER FILLING: a preamble over 200 characters, or any other line over 500, is dropped whole. One filled slot contributes at most 180 characters. (2) A QUESTION ARRIVING THROUGH A SLOT: on the lines that are spoken while the agent is waiting for an answer to the handoff question (briefing_opening_greeting, briefing_opening_preamble, identify_self, opening_greeting, opening_preamble, reprompt_short, state_purpose), if the filled {prepLine} or {reasonForCall} contains a "?" or asks for a yes, the line is dropped for that call. A customer's note is usually a question, so a line like "…a note from a customer. {prepLine}" will speak your wording on some calls and the shipped wording on others. To have the prep line spoken EVERY time, put it in a free-text line (acknowledge_hold, apology_no_answer, clarify_once, consumer_ringing, consumer_ringing_with_reason, consumer_still_ringing, goodbye_confused, goodbye_polite, goodbye_unavailable) instead. (3) A slot value that would introduce one of the refused shapes above. PATCH tells you at write time which of your lines are exposed to (1) and (2): see the `warnings` array on the response. ⛔ STORED IS NOT THE SAME AS IN EFFECT. This API writes the configuration; the conversational voice service reads it, and it does so only when the operator has enabled the per-number-instructions feature on that service. While it is disabled, which is the default and the rollback, every PATCH still returns 200, every GET still shows your lines, and every call still speaks the shipped templates. There is no field on this API that can tell you which state the voice service is in, because the flag does not live here. Confirm activation with your Corebee contact before concluding from a call that your configuration is wrong. ⛔ HOW THE OPENING IS ASSEMBLED, AND WHAT IS STILL HELD BACK. (1) TWO KEYS, TWO DIFFERENT THINGS, ON EACH CALL TYPE. briefing_opening_preamble and opening_preamble PREPEND: your words, then the shipped introduction, then the question, so a preamble that also introduces the agent produces TWO self-introductions in a row, and you should write one that greets or frames instead. briefing_opening_greeting and opening_greeting REPLACE the shipped introduction outright: your words, then the question, and nothing in between. That is the key to use if you want the agent to introduce herself in your own words. Set BOTH on one call type and neither is used, the shipped opening is spoken, because "prepend to the introduction" and "replace the introduction" cannot both be honoured and guessing which you meant is not something this API does silently. (2) A GREETING MUST NAME THE CUSTOMER. It has to interpolate {consumerFirstName}, and a greeting that does not is a 400. The reason is grammatical: the question that follows a live-transfer greeting is "Are you able to help them right now?", and "them" has exactly one referent in the sentence, the customer, whom the shipped introduction names and your greeting replaced. A call that arrives with no customer name falls back to the shipped opening for that call. (2a) A GREETING MAY NOT CLAIM THE CALLER IS A PERSON. This is an artificial voice, so a greeting that asserts the caller is a PERSON is a 400: "a real person", "a live agent", "I'm a human", "not a bot", "this is not a recording" and the like. Introducing the agent by name is fine and is the point of the key, "Hey, it's Sam from Gunn Honda, here about {consumerFirstName}." is accepted. When a greeting is in use, the call opens with your greeting, then the handoff question. (3) There is no way to reword the handoff question, not even as a named variant, and no key, preamble or greeting, can reach it. It is the one sentence held back: it is the switch that dials the consumer and starts billing, and prompt.ts quotes it verbatim to the classifier that decides whether it was answered yes. It is taken as a substring of the shipped line at speak time, so it is byte-identical on every call and is always the last thing said. (4) The briefing script is three parts and you can write the first. briefing_opening_greeting replaces part one, or briefing_opening_preamble goes in front of it; the briefing handoff question is held back for the reason in (3); and briefing_close, the sentence that reads your message back to the dealership, is code-owned, because it is the pure carrier for the prep line you already send and overriding it would delete your own message.
    - `templates` object: Line id -> the words to speak. Any key outside the enum is a 400 that says whether the id is unknown or code-owned. FREE TEXT, QUESTIONS ALLOWED (acknowledge_hold, apology_no_answer, clarify_once, consumer_ringing, consumer_ringing_with_reason, consumer_still_ringing, goodbye_confused, goodbye_polite, goodbye_unavailable): spoken only when nothing is waiting on a yes/no answer. Up to 300 characters. DECLARATIVE ONLY (briefing_opening_greeting, briefing_opening_preamble, identify_self, opening_greeting, opening_preamble, reprompt_short, state_purpose): these are spoken while the agent is waiting for an answer to the handoff question, so they may not contain "?", may not end in a tag question ("..., right?"), and may not ask for a "yes" in any form ("just say yes and I'll connect you"). A line that does is a 400. Up to 300 characters, except the preambles which are capped at 120 to keep the opening inside one breath. identify_self REPLACES ONLY THE SENTENCE IN FRONT OF A QUESTION YOU CANNOT REMOVE. When the agent answers "who is calling?" while it is waiting for the handoff answer, your line is followed by the shipped handoff question: "Are you able to help them right now?" if your line names the customer with {consumerFirstName}, otherwise "Are you able to help this customer right now?", and on a briefing call "Can I read you the message now?". The published example is spoken as "I'm the assistant for Gunn Honda new car sales. Are you able to help this customer right now?". When a question was put in the last few seconds, or the agent is not waiting for that answer, your line is spoken alone. NEVER OVERRIDABLE (ask_for_sales, ask_handoff, ask_handoff_new_person, briefing_ask_handoff, briefing_ask_handoff_new_person, briefing_close, briefing_opening, opening): sending any of these is a 400.
      - `briefing_opening_preamble` string: Prepended to the shipped opening. Capped at 120 characters, shorter than the other lines, so the opening stays inside one breath.
      - `opening_preamble` string: Prepended to the shipped opening. Capped at 120 characters, shorter than the other lines, so the opening stays inside one breath.
      - `briefing_opening_greeting` string: REPLACES the shipped introduction on this call type, it does not prepend. A greeting that asserts the caller is a person ("a real person", "not a bot") is a 400. The code-owned handoff question that ends the shipped opening is kept and spoken immediately after your words, byte-identical, and nothing is ever said after it. MUST interpolate {consumerFirstName}: it replaces the only place the customer is named, and the question that follows refers back to that person. Capped at 120 characters, like the preambles, so the opening stays inside one breath. Setting this AND the matching *_preamble on the same call type is refused at speak time and the shipped opening is used, because the two mean different things.
      - `opening_greeting` string: REPLACES the shipped introduction on this call type, it does not prepend. A greeting that asserts the caller is a person ("a real person", "not a bot") is a 400. The code-owned handoff question that ends the shipped opening is kept and spoken immediately after your words, byte-identical, and nothing is ever said after it. MUST interpolate {consumerFirstName}: it replaces the only place the customer is named, and the question that follows refers back to that person. Capped at 120 characters, like the preambles, so the opening stays inside one breath. Setting this AND the matching *_preamble on the same call type is refused at speak time and the shipped opening is used, because the two mean different things.
    - `variables` object: Per-NUMBER values interpolated into both your lines and the shipped ones. One DID serves one dealership, so these are properties of the number, not of the call. At most 60 characters each, no question mark, and no slots of their own. A variable is interpolated into lines that are spoken while the agent is waiting for an answer to the handoff question, so it INHERITS THE STRICTEST RULES: the same character set and the same refused shapes as a line, including the speaker-label rule. "Gunn Honda: Service & Parts" is refused for that reason (the colon lands in label position after a short opening run); "Gunn Honda Service & Parts" is accepted.

## Response `200`

Updated

- object
  - `data` BridgeNumberInstructionsResult, required
    - `from_number` string
    - `instructions` SpeechOverrides: The spoken lines one DID overrides. Absent or null means the agent speaks every shipped template. templates keys are the lines themselves; variables are values interpolated into them and into the shipped templates. Both objects are optional but the document must set at least one entry, an empty document is a 400, and null (not {}) is how you clear a number. Total serialized size must be at most 8192 bytes. SLOTS. Any line may interpolate {businessName}, {consumerFirstName}, {dealership}, {department}, {prepLine}, {reasonForCall}. {prepLine} is the prep_line you sent when starting the bridge, its first 180 characters, unmodified. It is NOT unbounded: prep_line itself may be up to 500 characters and the closing line of a briefing call carries more of it than a {prepLine} slot does, so a long note is spoken in full at the close and shortened inside a line. Write lines that read correctly when the note is cut. {reasonForCall} is what the agent says the call is about; on a briefing-only call it is deliberately a neutral stand-in so your message is not delivered twice, which is why it is NOT the same value as {prepLine}. {dealership} and {department} come from `variables` below, falling back to the call's business name and to "sales". An unrecognised {slot} is removed from the line rather than read aloud. CHARACTERS. Lines are plain single-line text. Accents are folded to ASCII and whitespace collapses; a line containing a character outside the accepted set is REJECTED rather than stripped, so you are never given back mangled English you did not write. THE ACCEPTED SET IS EXACTLY: letters A-Z a-z, digits, space, apostrophe, comma, full stop, hyphen, exclamation mark, ampersand, percent, dollar, hash, at, slash, colon, semicolon, parentheses, question mark, and the braces of a {slot}. Everything else is refused, and the two that surprise people most are the DOUBLE QUOTE (so a quoted customer line must be written without quotation marks) and any emoji or non-Latin character that survives accent folding. SHAPES THAT ARE REFUSED, on every line AND on every variable. (a) A word followed by a colon in SPEAKER-LABEL POSITION, at the start of the line, or straight after a ".", "!" or "?", because that reads as a new speaker turn in the transcript the model reads. A colon LATER in a sentence is fine, so "Gunn Honda's sales & service: no-hassle pricing" is accepted and "Dana: yes I can help" is not. Note the rule is about POSITION, not about names: "Dana here, thanks so much." is accepted. (b) The reserved words "intent", "confidence" and "affirmative", which name the fields of the model output that decides whether a call is transferred. (c) An instruction aimed at the model ("ignore/disregard/forget/override/follow/obey" near "instructions/rules/previous/prior/above/earlier"). (d) An assertion that the person has already agreed ("has said yes", "already agreed", "has consented"), that is the exact fact the handoff question exists to establish. (e) Backticks and line breaks. These are NARROW, EXACT rules and not a general "no instructions to the model" filter: they close the phrasings that are known to move the transfer decision, and a sufficiently indirect sentence will still be accepted. What contains the risk is that the handoff question itself is code-owned and byte-identical on every call. ⛔ WHEN AN ACCEPTED LINE IS STILL NOT SPOKEN. A 200 means STORED. Three rules are re-checked at SPEAK time, once your {slots} are filled with that call's real values, and any of them returns the shipped wording FOR THAT CALL, never a truncation, never silence. (1) LENGTH AFTER FILLING: a preamble over 200 characters, or any other line over 500, is dropped whole. One filled slot contributes at most 180 characters. (2) A QUESTION ARRIVING THROUGH A SLOT: on the lines that are spoken while the agent is waiting for an answer to the handoff question (briefing_opening_greeting, briefing_opening_preamble, identify_self, opening_greeting, opening_preamble, reprompt_short, state_purpose), if the filled {prepLine} or {reasonForCall} contains a "?" or asks for a yes, the line is dropped for that call. A customer's note is usually a question, so a line like "…a note from a customer. {prepLine}" will speak your wording on some calls and the shipped wording on others. To have the prep line spoken EVERY time, put it in a free-text line (acknowledge_hold, apology_no_answer, clarify_once, consumer_ringing, consumer_ringing_with_reason, consumer_still_ringing, goodbye_confused, goodbye_polite, goodbye_unavailable) instead. (3) A slot value that would introduce one of the refused shapes above. PATCH tells you at write time which of your lines are exposed to (1) and (2): see the `warnings` array on the response. ⛔ STORED IS NOT THE SAME AS IN EFFECT. This API writes the configuration; the conversational voice service reads it, and it does so only when the operator has enabled the per-number-instructions feature on that service. While it is disabled, which is the default and the rollback, every PATCH still returns 200, every GET still shows your lines, and every call still speaks the shipped templates. There is no field on this API that can tell you which state the voice service is in, because the flag does not live here. Confirm activation with your Corebee contact before concluding from a call that your configuration is wrong. ⛔ HOW THE OPENING IS ASSEMBLED, AND WHAT IS STILL HELD BACK. (1) TWO KEYS, TWO DIFFERENT THINGS, ON EACH CALL TYPE. briefing_opening_preamble and opening_preamble PREPEND: your words, then the shipped introduction, then the question, so a preamble that also introduces the agent produces TWO self-introductions in a row, and you should write one that greets or frames instead. briefing_opening_greeting and opening_greeting REPLACE the shipped introduction outright: your words, then the question, and nothing in between. That is the key to use if you want the agent to introduce herself in your own words. Set BOTH on one call type and neither is used, the shipped opening is spoken, because "prepend to the introduction" and "replace the introduction" cannot both be honoured and guessing which you meant is not something this API does silently. (2) A GREETING MUST NAME THE CUSTOMER. It has to interpolate {consumerFirstName}, and a greeting that does not is a 400. The reason is grammatical: the question that follows a live-transfer greeting is "Are you able to help them right now?", and "them" has exactly one referent in the sentence, the customer, whom the shipped introduction names and your greeting replaced. A call that arrives with no customer name falls back to the shipped opening for that call. (2a) A GREETING MAY NOT CLAIM THE CALLER IS A PERSON. This is an artificial voice, so a greeting that asserts the caller is a PERSON is a 400: "a real person", "a live agent", "I'm a human", "not a bot", "this is not a recording" and the like. Introducing the agent by name is fine and is the point of the key, "Hey, it's Sam from Gunn Honda, here about {consumerFirstName}." is accepted. When a greeting is in use, the call opens with your greeting, then the handoff question. (3) There is no way to reword the handoff question, not even as a named variant, and no key, preamble or greeting, can reach it. It is the one sentence held back: it is the switch that dials the consumer and starts billing, and prompt.ts quotes it verbatim to the classifier that decides whether it was answered yes. It is taken as a substring of the shipped line at speak time, so it is byte-identical on every call and is always the last thing said. (4) The briefing script is three parts and you can write the first. briefing_opening_greeting replaces part one, or briefing_opening_preamble goes in front of it; the briefing handoff question is held back for the reason in (3); and briefing_close, the sentence that reads your message back to the dealership, is code-owned, because it is the pure carrier for the prep line you already send and overriding it would delete your own message.
      - `templates` object: Line id -> the words to speak. Any key outside the enum is a 400 that says whether the id is unknown or code-owned. FREE TEXT, QUESTIONS ALLOWED (acknowledge_hold, apology_no_answer, clarify_once, consumer_ringing, consumer_ringing_with_reason, consumer_still_ringing, goodbye_confused, goodbye_polite, goodbye_unavailable): spoken only when nothing is waiting on a yes/no answer. Up to 300 characters. DECLARATIVE ONLY (briefing_opening_greeting, briefing_opening_preamble, identify_self, opening_greeting, opening_preamble, reprompt_short, state_purpose): these are spoken while the agent is waiting for an answer to the handoff question, so they may not contain "?", may not end in a tag question ("..., right?"), and may not ask for a "yes" in any form ("just say yes and I'll connect you"). A line that does is a 400. Up to 300 characters, except the preambles which are capped at 120 to keep the opening inside one breath. identify_self REPLACES ONLY THE SENTENCE IN FRONT OF A QUESTION YOU CANNOT REMOVE. When the agent answers "who is calling?" while it is waiting for the handoff answer, your line is followed by the shipped handoff question: "Are you able to help them right now?" if your line names the customer with {consumerFirstName}, otherwise "Are you able to help this customer right now?", and on a briefing call "Can I read you the message now?". The published example is spoken as "I'm the assistant for Gunn Honda new car sales. Are you able to help this customer right now?". When a question was put in the last few seconds, or the agent is not waiting for that answer, your line is spoken alone. NEVER OVERRIDABLE (ask_for_sales, ask_handoff, ask_handoff_new_person, briefing_ask_handoff, briefing_ask_handoff_new_person, briefing_close, briefing_opening, opening): sending any of these is a 400.
        - `briefing_opening_preamble` string: Prepended to the shipped opening. Capped at 120 characters, shorter than the other lines, so the opening stays inside one breath.
        - `opening_preamble` string: Prepended to the shipped opening. Capped at 120 characters, shorter than the other lines, so the opening stays inside one breath.
        - `briefing_opening_greeting` string: REPLACES the shipped introduction on this call type, it does not prepend. A greeting that asserts the caller is a person ("a real person", "not a bot") is a 400. The code-owned handoff question that ends the shipped opening is kept and spoken immediately after your words, byte-identical, and nothing is ever said after it. MUST interpolate {consumerFirstName}: it replaces the only place the customer is named, and the question that follows refers back to that person. Capped at 120 characters, like the preambles, so the opening stays inside one breath. Setting this AND the matching *_preamble on the same call type is refused at speak time and the shipped opening is used, because the two mean different things.
        - `opening_greeting` string: REPLACES the shipped introduction on this call type, it does not prepend. A greeting that asserts the caller is a person ("a real person", "not a bot") is a 400. The code-owned handoff question that ends the shipped opening is kept and spoken immediately after your words, byte-identical, and nothing is ever said after it. MUST interpolate {consumerFirstName}: it replaces the only place the customer is named, and the question that follows refers back to that person. Capped at 120 characters, like the preambles, so the opening stays inside one breath. Setting this AND the matching *_preamble on the same call type is refused at speak time and the shipped opening is used, because the two mean different things.
      - `variables` object: Per-NUMBER values interpolated into both your lines and the shipped ones. One DID serves one dealership, so these are properties of the number, not of the call. At most 60 characters each, no question mark, and no slots of their own. A variable is interpolated into lines that are spoken while the agent is waiting for an answer to the handoff question, so it INHERITS THE STRICTEST RULES: the same character set and the same refused shapes as a line, including the speaker-label rule. "Gunn Honda: Service & Parts" is refused for that reason (the colon lands in label position after a short opening run); "Gunn Honda Service & Parts" is accepted.
    - `using_shipped_templates` boolean: True when instructions is null, i.e. this number speaks every shipped template.
    - `corridors` BridgeCorridorCoverage[]: What each KIND OF CALL will speak for its opening AFTER this write. Same shape GET returns. Read the entry whose speaks is shipped_wording before concluding the write covered your traffic.
      - `corridor` 'live_transfer' | 'briefing': live_transfer = briefing_only absent or false, the calls that can bridge a consumer and bill. briefing = briefing_only true, message delivered and the call ends.
      - `template` 'opening' | 'briefing_opening': The shipped template this corridor speaks. Published so a support thread can name it.
      - `greeting_key` string: The key that REPLACES the shipped introduction on this corridor.
      - `preamble_key` string, nullable: The key that goes IN FRONT of the shipped introduction on this corridor.
      - `configured_by` string[]: Dotted paths this document sets for THIS corridor, sorted. Empty means this corridor is unconfigured and speaks the shipped wording however much the other corridor is configured.
      - `speaks` 'your_greeting' | 'your_preamble' | 'shipped_wording': What a call on this corridor actually opens with. NOT a synonym for "configured_by is empty": a corridor with BOTH its greeting and its preamble set speaks shipped_wording on every call, because the two mean opposite things and are not composed by guessing.
      - `note` string, nullable: Why shipped_wording, in one sentence. null when your own words are spoken.
    - `normalized` string[]: Dotted paths of the values that were ACCEPTED but stored differently from what you sent (accent folding, whitespace collapse, unknown-slot removal). Empty on the common path. Read these back from `instructions` to see the exact words that will be spoken.
    - `warnings` object[]: Lines that were ACCEPTED and STORED but that will not necessarily be spoken on every call, because a rule is re-checked at speak time once your {slots} carry that call's real values. Empty on the common path. This is the only place the API can tell you about a conditional fallback, because the condition depends on data that does not exist yet at write time. OBJECTS, NOT STRINGS, deliberately: `normalized` above shipped as bare strings and can never carry a reason without breaking a client that parses it.
      - `path` string, required: Dotted path of the line this is about.
      - `code` 'slot_may_overflow' | 'gate_armed_slot_may_drop_line' | 'other_corridor_unconfigured' | 'corridor_never_speaks_these_keys', required: Stable machine token. New codes may be added over time; an existing code never changes meaning. The first two are CONDITIONAL, they depend on what your {slots} carry on a given call, so they say "may". other_corridor_unconfigured and corridor_never_speaks_these_keys are CERTAIN: they are decided by the document you just sent, and the calls they describe speak the shipped wording every single time.
      - `message` string, required: One sentence naming the condition and what to do instead.

## Other responses

- `400`: Validation error
- `401`: Invalid or missing credential
- `403`: Forbidden (missing scope, or resource not owned by the credential org)
- `404`: Not found
- `409`: Conflict (code conflict): the column backing this feature has not been added to the database yet. The message names the migration. Nothing was written and every number reads as unset.
- `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)
