# Conversation behaviour

Everything about how the agent behaves while it is *not* talking: when it lets itself be interrupted, when it decides you have finished a sentence, how long it tolerates silence, what it does when a machine answers, and what the line sounds like underneath. All of it lives in the `conversation` block, and every `0` means "the default".

`PATCH /v1/agents/{id}`

**Shell**

```bash
curl -s -X PATCH https://voice.sphoro.com/v1/agents/$AGENT_ID \
  -H "Authorization: Bearer $SPHORO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation": {
      "interrupt_words": 2,
      "interrupt_phrases": ["stop", "hold on", "ek minute"],
      "silence_prompt_seconds": 8,
      "silence_hangup_seconds": 20,
      "max_call_seconds": 600,
      "voicemail": "message",
      "voicemail_message": "This is Acme Clinic about your appointment. Please call us back on 020 4000 1234."
    }
  }'
```

> **The block replaces whole.** Sending `{"conversation": {"max_call_seconds": 600}}` resets every other value in it to its default. Read the agent, change the field, send the block back.

## Barge-in: being interrupted

Interruption is decided by **words, not volume**. A caller saying "mm-hm" while the agent talks is listening, not interrupting, and an agent that stops for it sounds broken.

| Field | Type | Description |
| --- | --- | --- |
| `interrupt_words` optional | integer, 1–10 | `0` means the default of **2**. How many words the caller has to say over the agent before it stops. Below the threshold it keeps talking. |
| `interrupt_phrases` optional | string[] | Your own stop phrases, which interrupt on their own regardless of the word count. A short list of built-in stop words — "wait", "no", "ruko" — already does this; add the ones your callers actually use. |

| Symptom | Change |
| --- | --- |
| The agent stops every time the caller says "yeah" | Raise `interrupt_words` to 3. |
| The agent talks over a caller trying to stop it | Lower it to 1, or add the phrase they actually use to `interrupt_phrases`. |
| The agent stops when there is background noise | Not barge-in — noise is not words. Look at transcription; the recognizer is hearing speech in the noise. |

A keypress always interrupts, whatever these are set to. It is unambiguous, and it is the reason the greeting is interruptible at all — see [keypad and IVR](https://voice.sphoro.com/docs/keypad).

## Silence: when to ask, when to give up

Both clocks run from the same moment — the last thing the caller said — so `silence_hangup_seconds` is total, not "and then this much more".

| Field | Type | Description |
| --- | --- | --- |
| `silence_prompt_seconds` optional | integer, 3–60 | `0` means **8**; `-1` never prompts. How long a quiet line waits before "are you still there?". The wording is the language entry's `silence_prompt`. |
| `silence_hangup_seconds` optional | integer, 5–300 | `0` means **20**; `-1` never hangs up. How long before goodbye and hangup. The call ends with `end_reason: no_input`. |

> **Set `silence_hangup_seconds: -1` on a call you expect to go quiet.** Somebody put on hold while a human is fetched is silent for a minute and has not abandoned the call. The default is tuned for a caller who has walked away.

## Duration

| Field | Type | Description |
| --- | --- | --- |
| `max_call_seconds` optional | integer, 30–7200 | `0` means the carrier's own limit. The agent says a short goodbye before hanging up, so the call ends rather than being cut mid-word. The call records `end_reason: max_duration`. |

Worth setting on anything that dials out. A conversation that will not end is a conversation you are paying for by the minute, and the goodbye means the caller is not left listening to nothing.

## Voicemail

Machine detection runs **alongside** the call, not in front of it — waiting for a verdict before connecting audio adds seconds of silence to the opening of every call, including the ones a person answered. So the agent begins its greeting and the verdict arrives during it.

| Field | Type | Description |
| --- | --- | --- |
| `voicemail` optional | "continue" \| "hangup" \| "message" | What an outbound call does when an answering machine picks up. `continue` is the default and holds the conversation anyway. |
| `voicemail_message` optional | string | What to leave under `message`. Variables are filled in as anywhere else. |
| `voicemail_detection_seconds` optional | integer | A ceiling on how long detection may listen before the call is simply treated as answered by a person. `0` is the default. This is a bound, not a preference: detection allowed to run unbounded holds the caller in silence while it makes up its mind, and somebody who says "hello?" twice into nothing hangs up. |

| Choose | When |
| --- | --- |
| `hangup` | The conversation is worthless without a person — a survey, a qualification call. Ends with `end_reason: voicemail`, which is the value to retry on. |
| `message` | A reminder or a notice. Say who is calling, why, and a number to call back — and keep it under fifteen seconds. |
| `continue` | You would rather have the transcript than the certainty, or detection is unreliable on your carrier and you have decided false positives cost more than voicemails. |

> **Detection is a guess, and it is occasionally wrong in both directions.** A person who answers with a long scripted greeting can read as a machine. If a campaign reports more voicemails than seems plausible, listen to three of the [recordings](https://voice.sphoro.com/docs/recordings) before changing anything else.

## Turn taking: when the caller has finished

The single most consequential setting on a phone agent, and the one people reach for last. Too eager and it interrupts somebody drawing breath mid-sentence; too patient and every exchange gains a beat of dead air.

It is expressed as a preset, because the two numbers underneath are not independent and almost nobody wants to think about either. What you actually know is whether your callers finish their sentences briskly or ramble.

| Field | Type | Description |
| --- | --- | --- |
| `response_rate` optional | "fast" \| "normal" \| "patient" \| "custom" | Defaults to `normal`. `fast` for callers answering closed questions — confirmations, digits, yes/no. `patient` for people describing a problem in their own words. `custom` uses the two numbers below directly. |
| `endpointing_ms` optional | integer, 100–3000 | `0` uses the rate's own value. How long a pause has to last before the caller is taken to have finished. |
| `linear_delay_ms` optional | integer, 0–3000 | `0` uses the rate's own value. Extra wait added on top of endpointing once the caller has been speaking for a while, so a long answer is not cut off at its first comma. |

> **Try the preset before the numbers.** "The agent keeps cutting me off" is `patient`; "there is a pause after everything I say" is `fast`. Reach for `custom` only when neither is right, and change one number at a time.

## The opening

Two settings for carriers and callers that misbehave at the very start of a call. Both default to off, and both are worth knowing about before you conclude a carrier is broken.

| Field | Type | Description |
| --- | --- | --- |
| `greeting_delay_ms` optional | integer, 0–5000 | `0` speaks as soon as the line is up, which is right for most lines. It is wrong on a carrier that connects the media path before the far end has stopped ringing: the greeting then plays into a handset nobody has lifted, and the caller's first word is "sorry, what?". |
| `ignore_speech_before_greeting` optional | boolean | Drops anything the caller says while the greeting is still playing, instead of treating it as their turn. Off by default — somebody who talks over a greeting usually means it. Turn it on for an outbound line whose first second is the callee saying "hello", which is not an answer to a question nobody has asked yet and otherwise derails the opening. |

## Letting the model end the call

| Field | Type | Description |
| --- | --- | --- |
| `hangup_prompt` optional | string | Describes in words when to hang up — "hang up once the caller confirms the appointment and has no further questions". Empty never ends a call this way, and that is the default. |

> **This costs a model call per turn.** The condition is checked after every agent turn on any agent that sets it, which is why it is off rather than on with an empty string meaning "never". If the `end_call` tool already ends your calls cleanly, you do not need this.

## How the line sounds

Two of these are about the caller's ears and one is about the recognizer's.

| Field | Type | Description |
| --- | --- | --- |
| `ambient_noise` optional | string | A looped background bed under the agent, by name — `"office"`, `"call-center"`, `"cafe"`. Empty is silence, which is the default. Not decoration: a line with no room tone reads as a recording, and people talk over a recording differently from how they talk to a person. |
| `ambient_noise_volume` optional | integer, 0–100 | `0` uses the default, which is quiet enough to sit under speech rather than beside it. |
| `noise_cancellation` optional | integer, 0–100 | Attenuates steady background noise on the *caller's* audio. `0` is off, the default. Aimed at the recognizer rather than at anybody's ears — a caller on a street transcribes badly, and the words the model never sees are the ones it answers wrongly. A dial rather than a switch: too much of it eats consonants and makes transcription worse. |

## Calling back an unanswered call

| Field | Type | Description |
| --- | --- | --- |
| `auto_reschedule_seconds` optional | integer | Call back after this long when a call is not answered. `0` never calls back, which is the default. |
| `auto_reschedule_attempts` optional | integer | How many callbacks to make. `0` means one. |

This is deliberately the only retry an agent can express on its own, because "try them again in an hour" should not require building a graph. Anything with branches, a wait window or a fallback channel — a message when the third call goes unanswered — is a [journey](https://voice.sphoro.com/docs/journeys).

## Keypad-only settings

A `keypad` agent listens for digits rather than speech, so the silence and turn settings above do not apply to it. Its equivalents are top-level fields on the agent: `no_input`, `max_no_input`, `keypad_timeout_seconds` and `no_match`. See [keypad and IVR](https://voice.sphoro.com/docs/keypad).

## What good defaults look like

| Kind of call | Settings worth starting from |
| --- | --- |
| Inbound support | Defaults throughout, except `max_call_seconds: 900`. |
| Outbound reminder | `voicemail: "message"`, `max_call_seconds: 180`, `silence_hangup_seconds: 15`. |
| Qualification or survey | `voicemail: "hangup"`, `interrupt_words: 1` — people cut these off and should be able to. |
| Anything that transfers to a person | `silence_hangup_seconds: -1`, so a hold is not read as an abandoned call. |
