Skip to content

Commit 31e941f

Browse files
dhruva-vapiclaude
andcommitted
docs: format call-duration tables and fix bold marker
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e4653bb commit 31e941f

1 file changed

Lines changed: 26 additions & 20 deletions

File tree

docs/learnings/call-duration.md

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ How to enforce call time limits while ending calls gracefully instead of abruptl
88

99
Vapi provides three layers for managing call duration:
1010

11-
| Mechanism | What it does | Type |
12-
|-----------|-------------|------|
13-
| `maxDurationSeconds` | Hard wall-clock cutoff — call ends immediately when reached | Assistant setting |
14-
| `call.timeElapsed` hook | Fires once at a specific second mark from call start | Hook (deterministic) |
15-
| `endCall` tool | LLM decides to end the call | Tool (probabilistic) |
11+
12+
| Mechanism | What it does | Type |
13+
| ----------------------- | ----------------------------------------------------------- | -------------------- |
14+
| `maxDurationSeconds` | Hard wall-clock cutoff — call ends immediately when reached | Assistant setting |
15+
| `call.timeElapsed` hook | Fires once at a specific second mark from call start | Hook (deterministic) |
16+
| `endCall` tool | LLM decides to end the call | Tool (probabilistic) |
17+
1618

1719
**Key distinction:** Hooks are deterministic (guaranteed to fire). Tools are probabilistic (the LLM chooses when to invoke them). For call discipline, use hooks as the enforcement layer and tools as the courtesy layer.
1820

@@ -138,14 +140,16 @@ hooks:
138140

139141
## Hooks vs Tools vs System Prompt — When to Use Which
140142

141-
| Approach | Reliability | Use when |
142-
|----------|-------------|----------|
143-
| `call.timeElapsed` hook with `say` | Guaranteed | You need a deterministic spoken warning at a fixed time |
144-
| `call.timeElapsed` hook with `message.add` | Guaranteed delivery, LLM interprets | You want the LLM to organically wrap up the conversation |
145-
| `call.timeElapsed` hook with `endCall` tool | Guaranteed | You need a hard graceful end (with goodbye) at a fixed time |
146-
| `maxDurationSeconds` | Guaranteed | Last-resort hard cutoff — no goodbye, call just drops |
147-
| `endCall` tool (LLM-invoked) | Probabilistic | You want the LLM to decide when to end based on conversation context |
148-
| System prompt instruction ("end after 10 min") | Unreliable | Don't rely on this alone — the LLM may not track time accurately |
143+
144+
| Approach | Reliability | Use when |
145+
| ---------------------------------------------- | ----------------------------------- | -------------------------------------------------------------------- |
146+
| `call.timeElapsed` hook with `say` | Guaranteed | You need a deterministic spoken warning at a fixed time |
147+
| `call.timeElapsed` hook with `message.add` | Guaranteed delivery, LLM interprets | You want the LLM to organically wrap up the conversation |
148+
| `call.timeElapsed` hook with `endCall` tool | Guaranteed | You need a hard graceful end (with goodbye) at a fixed time |
149+
| `maxDurationSeconds` | Guaranteed | Last-resort hard cutoff — no goodbye, call just drops |
150+
| `endCall` tool (LLM-invoked) | Probabilistic | You want the LLM to decide when to end based on conversation context |
151+
| System prompt instruction ("end after 10 min") | Unreliable | Don't rely on this alone — the LLM may not track time accurately |
152+
149153

150154
**Best practice:** Layer them. Use hooks for deterministic enforcement and the endCall tool + system prompt for conversational flexibility.
151155

@@ -155,12 +159,14 @@ hooks:
155159

156160
These are **not** the same as call duration limits, but they interact:
157161

158-
| Mechanism | What it does | Default |
159-
|-----------|-------------|---------|
160-
| `silenceTimeoutSeconds` | Ends call after sustained silence | 30s |
161-
| `customer.speech.timeout` hook | Fires action when customer is silent for N seconds | 7.5s, up to 3 times |
162-
| `messagePlan.idleTimeoutSeconds` | Speaks an idle message when conversation stalls | 10s |
163-
| `customerJoinTimeoutSeconds` | Ends call if customer never sends audio | 15s |
162+
163+
| Mechanism | What it does | Default |
164+
| -------------------------------- | -------------------------------------------------- | ------------------- |
165+
| `silenceTimeoutSeconds` | Ends call after sustained silence | 30s |
166+
| `customer.speech.timeout` hook | Fires action when customer is silent for N seconds | 7.5s, up to 3 times |
167+
| `messagePlan.idleTimeoutSeconds` | Speaks an idle message when conversation stalls | 10s |
168+
| `customerJoinTimeoutSeconds` | Ends call if customer never sends audio | 15s |
169+
164170

165171
**`silenceTimeoutSeconds` vs `customer.speech.timeout`:** The timeout **ends the call**. The hook **performs an action** (say, tool, message.add). They are independent — configure them separately. See [assistants.md](assistants.md) for the hook events list.
166172

@@ -184,4 +190,4 @@ The `maxDurationSeconds` timer starts when the first audio chunk is processed. `
184190

185191
### Lambda workers reject long calls
186192

187-
If `maxDurationSeconds >= 15 minutes` (900s), the call is rejected when routed to a Lambda-based worker (reason: `lambda-longcalls-not-accepted`). Long calls require non-Lambda workers.
193+
If `maxDurationSeconds >= 15 minutes` (900s), the call is rejected when routed to a Lambda-based worker (reason: `lambda-longcalls-not-accepted`). Long calls require non-Lambda workers.

0 commit comments

Comments
 (0)