> ## Documentation Index
> Fetch the complete documentation index at: https://docs.interactly.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Hang Event

> Notifications when assistant fails to respond within timeout

The `hang` event is triggered when the assistant fails to respond for 5+ seconds during a conversation. This indicates potential issues with LLM processing, connectivity, or system overload.

<Warning>
  Hang events signal critical performance problems that can lead to poor user experience and call abandonment. Immediate investigation is recommended.
</Warning>

## When It's Triggered

This event is sent when:

* The assistant takes longer than 5 seconds to generate a response
* LLM API calls experience high latency or timeouts
* System processing queues become backlogged
* Network connectivity issues affect response generation

## Event Structure

```json theme={null}
{
    "message": {
        "timestamp": 1772702490000,
        "type": "hang",
        "call": { /* Call Object */ },
        "assistant": { /* Assistant Object */ },
        "messages": [ /* Conversation up to hang */ ],
        "phone": { /* Phone Object */ },
        "customer": { /* Customer Object */ },
        "analysis": { /* Empty during hang */ }
    }
}
```

## Key Fields

| Field               | Type   | Description                                  |
| ------------------- | ------ | -------------------------------------------- |
| `message.type`      | string | Always "hang" for this event                 |
| `message.timestamp` | number | Unix timestamp when hang was detected        |
| `call.status`       | string | Typically "ongoing" when hang occurs         |
| `messages`          | array  | Conversation history up to the point of hang |

## Call Object

The `call` object contains comprehensive information about the call session.

| Field                   | Type            | Description                                                              |
| ----------------------- | --------------- | ------------------------------------------------------------------------ |
| `id`                    | string          | Unique call identifier (e.g., "WC-82015760-c3bd-427d-a23b-ba9b07e4ab85") |
| `teamId`                | string          | Organization/team identifier                                             |
| `assistantId`           | string          | ID of the assistant handling this call                                   |
| `callType`              | string          | Type of call: "web", "phone", etc.                                       |
| `direction`             | string          | Call direction: "inbound" or "outbound"                                  |
| `startAt`               | string          | ISO timestamp when call started                                          |
| `endAt`                 | string          | ISO timestamp when call ended (only in end-of-call-report)               |
| `userNumber`            | string          | User's phone number or identifier                                        |
| `assistantNumber`       | string          | Assistant's number or identifier                                         |
| `status`                | string          | Current call status: "queued", "ongoing", "finished", "forwarded"        |
| `phoneCallStatus`       | string          | Detailed phone status: "in-progress", "completed", etc.                  |
| `phoneCallStatusReason` | string          | Human-readable status reason                                             |
| `callEndTriggerBy`      | string          | What triggered call end: "bot", "user", "system"                         |
| `assistantCallDuration` | number          | Duration of call in milliseconds                                         |
| `analysis`              | analysis-object | Call analysis results                                                    |
| `recording`             | object          | Recording information with S3 bucket and path                            |
| `assistantOverrides`    | object          | Dynamic variables and validation overrides                               |
| `metadata`              | object          | Custom metadata associated with the call                                 |
| `cost`                  | object          | Cost breakdown (only in end-of-call-report)                              |
| `metrics`               | object          | Detailed call metrics (only in end-of-call-report)                       |

## Assistant Object

The `assistant` object contains the configuration and settings of the assistant handling the call.

<Note>
  In some webhook events, the assistant object may be truncated for brevity. The full assistant configuration is typically included in `status-update` events.
</Note>

| Field                                | Type    | Description                                             |
| ------------------------------------ | ------- | ------------------------------------------------------- |
| `_id`                                | string  | Unique assistant identifier                             |
| `name`                               | string  | Display name of the assistant                           |
| `welcomeMessage`                     | string  | Message played when call starts                         |
| `welcomeMessageMode`                 | string  | How welcome message is triggered: "automatic", "manual" |
| `welcomeMessageInterruptionsEnabled` | boolean | Whether users can interrupt welcome message             |
| `endCallMessage`                     | string  | Message played when call ends                           |
| `endCallPhrases`                     | array   | Phrases that trigger call termination                   |
| `bargeInEnabled`                     | boolean | Whether users can interrupt assistant responses         |
| `assistantProvider`                  | string  | LLM provider: "openai", "anthropic", "gemini", etc.     |
| `assistantModel`                     | string  | Specific model being used                               |
| `assistantSystemPrompt`              | string  | System prompt defining assistant behavior               |
| `assistantTemperature`               | number  | LLM creativity setting (0.0 to 1.0)                     |
| `assistantMaxTokens`                 | number  | Maximum tokens per response                             |
| `assistantAnalysis`                  | object  | Configuration for call analysis features                |
| `assistantServer`                    | object  | Webhook configuration for this assistant                |
| `config`                             | object  | Speech-to-text and text-to-speech configurations        |

### Key Subobjects

* **`assistantAnalysis`**: Contains settings for summary generation, success evaluation, and structured data extraction
* **`assistantServer`**: The webhook configuration that triggered this event
* **`config.speech`**: STT/TTS vendor settings, voice configuration, and language options

## Messages Object

The `messages` array contains the conversation history between the user and assistant.

<Info>
  Each `conversation-update` event includes **all messages** from the start of the call up to that point, not just the latest message. This ensures that if any individual event is missed, you still have the complete conversation context.
</Info>

### Message Structure

| Field                      | Type   | Description                                               |
| -------------------------- | ------ | --------------------------------------------------------- |
| `messageId`                | string | Unique message identifier                                 |
| `role`                     | string | Message sender: "user" or "assistant"                     |
| `text`                     | string | Transcribed or generated message content                  |
| `timestamp`                | number | Unix timestamp in milliseconds                            |
| `metrics`                  | object | Performance metrics for this message                      |
| `skippedAssistantMessages` | array  | Assistant messages that were skipped due to interruptions |

### Message Metrics

Each message includes detailed performance metrics:

#### Timeline Metrics

* `totalElapsedTimeMs`: Total time since call start
* `offsetFromPreviousTurnMs`: Time gap from previous message

#### Audio Metrics

* `totalAudioReceivedMs`: Total audio duration received
* `audioDelayPerTurnMs`: Audio processing delay for this turn
* `delayedPacketsPerTurnCount`: Count of delayed network packets

#### Speech-to-Text (STT) Metrics

* `timestampMs`: When transcription was completed
* `startOffsetMs`/`endOffsetMs`: Audio segment boundaries
* `confidence`: Transcription confidence score (0.0 to 1.0)
* `vadMs`: Voice activity detection duration

#### Text-to-Speech (TTS) Metrics

* `audioDurationMs`: Duration of generated audio
* `generationTimeMs`: Time to generate audio
* `queueLatencyMs`: Processing queue delay
* `isCachePlaying`: Whether audio was served from cache

#### LLM Metrics

* `responseLatencyMs`: Time for LLM to generate response
* `queueLatencyMs`: Processing queue delay

### Message Types

* **Welcome Messages**: Have `messageId` starting with "welcome-"
* **User Messages**: Have `messageId` starting with "user-"
* **Assistant Messages**: Have complex `messageId` with user reference and timestamp

## Hang Detection Logic

```mermaid theme={null}
graph TD
    A[User Stops Speaking] --> B[Start Response Timer]
    B --> C{Response Generated?}
    C -->|Yes, < 5s| D[Normal Flow]
    C -->|No, >= 5s| E[Trigger Hang Event]
    E --> F[Continue Waiting for Response]
    F --> G{Response Eventually Generated?}
    G -->|Yes| H[Send Delayed Response]
    G -->|No| I[May Trigger Error Event]
```

## Example Payload

<CodeGroup>
  ```json Hang Event theme={null}
  {
    "message": {
      "timestamp": 1772702490000,
      "type": "hang",
      "call": {
        "id": "WC-82015760-c3bd-427d-a23b-ba9b07e4ab85",
        "teamId": "67c0231ae6880fe48ef929ee",
        "assistantId": "697769ef5e6d94d5ad83e01e",
        "status": "ongoing",
        "assistantCallDuration": 15000
      },
      "assistant": {
        "_id": "697769ef5e6d94d5ad83e01e",
        "name": "Mary Dental - main",
        "assistantProvider": "gemini",
        "assistantModel": "gemini-3-flash-preview"
      },
      "messages": [
        {
          "messageId": "welcome-1",
          "role": "assistant",
          "text": "Welcome to Apollo clinic!!",
          "timestamp": 1772702480279
        },
        {
          "messageId": "user-1",
          "role": "user",
          "text": "I need to book an appointment for a complex procedure",
          "timestamp": 1772702485138
        }
      ],
      "customer": {
        "number": "web-Ramesh Naik"
      }
    }
  }
  ```
</CodeGroup>

## Common Causes

### LLM Provider Issues

* API rate limiting or throttling
* Provider service outages or degraded performance
* Model capacity limitations during peak hours
* Authentication or billing issues

### System Resource Constraints

* High CPU or memory usage on Interactly servers
* Processing queue backlog
* Database connection limitations
* Network bandwidth constraints

### Complex Queries

* User requests requiring extensive reasoning
* Long conversation context requiring more processing time
* Queries that trigger multiple LLM function calls
* Malformed or problematic user input

## Response Strategies

### Immediate Alerting

```python theme={null}
def handle_hang_event(event_data):
    call = event_data["message"]["call"]
    assistant = event_data["message"]["assistant"]
    timestamp = event_data["message"]["timestamp"]

    # Immediate alert to operations team
    alert_data = {
        "alert_type": "assistant_hang",
        "call_id": call["id"],
        "assistant_id": assistant["_id"],
        "assistant_name": assistant["name"],
        "provider": assistant["assistantProvider"],
        "model": assistant["assistantModel"],
        "hang_duration": "5+ seconds",
        "timestamp": timestamp,
        "severity": "high"
    }

    send_immediate_alert(alert_data)

    # Log for analysis
    logger.critical(f"Assistant hang detected: {call['id']}")
```

### Performance Monitoring

```python theme={null}
def track_hang_metrics(event_data):
    call = event_data["message"]["call"]
    assistant = event_data["message"]["assistant"]

    # Increment hang counters
    metrics.increment("assistant.hang.count", tags={
        "assistant_id": assistant["_id"],
        "provider": assistant["assistantProvider"],
        "model": assistant["assistantModel"]
    })

    # Track by time of day for pattern analysis
    hour_of_day = datetime.fromtimestamp(
        event_data["message"]["timestamp"] / 1000
    ).hour

    metrics.increment("assistant.hang.by_hour", tags={
        "hour": hour_of_day,
        "provider": assistant["assistantProvider"]
    })
```

### Automated Remediation

```python theme={null}
def auto_remediate_hang(event_data):
    call = event_data["message"]["call"]
    assistant = event_data["message"]["assistant"]

    # Check for patterns indicating system issues
    recent_hangs = get_recent_hangs(assistant["_id"], minutes=10)

    if len(recent_hangs) >= HANG_THRESHOLD:
        # Multiple hangs suggest systematic issue

        # Option 1: Switch to backup provider/model
        if assistant["assistantProvider"] == "openai":
            switch_assistant_provider(call["id"], "anthropic")

        # Option 2: Reduce response complexity
        adjust_assistant_parameters(call["id"], {
            "maxTokens": 100,  # Shorter responses
            "temperature": 0.3  # More deterministic
        })

        # Option 3: Graceful degradation message
        queue_fallback_response(call["id"],
            "I apologize for the delay. Let me help you with that.")
```

### Pattern Analysis

```python theme={null}
def analyze_hang_patterns():
    # Get recent hang events
    recent_hangs = db.hang_events.find({
        "timestamp": {"$gte": datetime.utcnow() - timedelta(hours=24)}
    })

    # Group by various dimensions
    patterns = {
        "by_provider": defaultdict(int),
        "by_model": defaultdict(int),
        "by_assistant": defaultdict(int),
        "by_hour": defaultdict(int),
        "by_conversation_length": defaultdict(int)
    }

    for hang in recent_hangs:
        assistant = hang["message"]["assistant"]
        timestamp = hang["message"]["timestamp"]
        messages = hang["message"]["messages"]

        patterns["by_provider"][assistant["assistantProvider"]] += 1
        patterns["by_model"][assistant["assistantModel"]] += 1
        patterns["by_assistant"][assistant["_id"]] += 1

        hour = datetime.fromtimestamp(timestamp / 1000).hour
        patterns["by_hour"][hour] += 1

        msg_count = len(messages)
        patterns["by_conversation_length"][f"{msg_count//5*5}-{msg_count//5*5+4}"] += 1

    # Generate insights
    generate_hang_insights(patterns)
```

## User Experience Impact

Hang events directly affect user experience:

### User Behavior During Hangs

* Users may repeat their question
* Users might hang up if wait is too long
* Users experience frustration and reduced trust
* Call abandonment rate increases significantly

### Mitigation Strategies

```python theme={null}
def implement_hang_mitigation():
    # Strategy 1: Proactive timeout warnings
    # After 3 seconds of processing, play hold message

    # Strategy 2: Streaming responses
    # Start playing response as it's generated

    # Strategy 3: Fallback responses
    fallback_responses = [
        "Let me think about that for a moment...",
        "I'm processing your request, please hold on...",
        "That's a great question, give me just a second..."
    ]

    # Strategy 4: Context reduction
    # If conversation is very long, summarize for faster processing
```

## Prevention Best Practices

### Assistant Configuration

```json theme={null}
{
    "assistantModel": "gpt-4o-mini",  // Faster models for time-sensitive uses
    "assistantMaxTokens": 150,        // Limit response length
    "assistantTemperature": 0.3,      // More deterministic = faster
    "assistantSystemPrompt": "Keep responses concise and direct. Aim for 1-2 sentences maximum."
}
```

### Monitoring Thresholds

```python theme={null}
# Set up monitoring for early warning signs
MONITORING_RULES = {
    "response_time_p95": {
        "threshold": 3000,  # 3 seconds
        "alert": "warning"
    },
    "hang_rate": {
        "threshold": 0.05,  # 5% of calls
        "window": "1h",
        "alert": "critical"
    },
    "provider_error_rate": {
        "threshold": 0.02,  # 2% error rate
        "alert": "warning"
    }
}
```

### Load Balancing

```python theme={null}
def implement_provider_fallback():
    # Primary: Fast, reliable provider
    # Secondary: Backup with different characteristics

    provider_config = {
        "primary": {
            "provider": "openai",
            "model": "gpt-4o-mini",
            "max_tokens": 150
        },
        "fallback": {
            "provider": "anthropic",
            "model": "claude-3-haiku",
            "max_tokens": 100
        }
    }
```

## Recovery Actions

When hang events occur:

1. **Monitor**: Track if response eventually comes through
2. **Alert**: Notify engineering team for investigation
3. **Document**: Record context for post-incident analysis
4. **Optimize**: Adjust assistant settings to prevent recurrence
5. **Communicate**: Update users about potential temporary delays

<Card title="Related Events" icon="link">
  Hang events often precede [error events](/webhooks/events/error) if the underlying issue persists
</Card>

## Hang Event Example

This is a complete example of a hang webhook event payload.

```json theme={null}
{
    "message": {
        "timestamp": 1772702490000,
        "type": "hang",
        "call": {
            "id": "WC-82015760-c3bd-427d-a23b-ba9b07e4ab85",
            "teamId": "67c0231ae6880fe48ef929ee",
            "assistantId": "697769ef5e6d94d5ad83e01e",
            "callType": "web",
            "direction": "inbound",
            "startAt": "2026-03-05T09:21:20.063Z",
            "userNumber": "web-Ramesh Naik",
            "assistantNumber": "697769ef5e6d94d5ad83e01e",
            "status": "ongoing",
            "phoneCallStatus": "in-progress",
            "phoneCallStatusReason": "Call is in progress",
            "callEndTriggerBy": "",
            "assistantCallDuration": 15000,
            "analysis": {
                "summary": "",
                "successEvaluation": ""
            },
            "recording": {
                "s3Bucket": "",
                "path": ""
            },
            "assistantOverrides": {
                "dynamicVariables": {
                    "serial_number": ""
                },
                "variablesValidations": {
                    "serial_number": "none"
                }
            },
            "metadata": {}
        },
        "assistant": {
            "_id": "697769ef5e6d94d5ad83e01e",
            "name": "Mary Dental - main",
            "welcomeMessage": "Welcome to Apollo clinic!!",
            "assistantProvider": "gemini",
            "assistantModel": "gemini-3-flash-preview",
            "assistantSystemPrompt": "You here are a voice assistant for Apollo clinic clinic, located at 123 North Face Place, Anaheim, California. Your name is Rachel...",
            "assistantTemperature": 0,
            "assistantMaxTokens": 256
        },
        "messages": [
            {
                "messageId": "welcome-1",
                "role": "assistant",
                "text": "Welcome to Apollo clinic!!",
                "timestamp": 1772702480279,
                "metrics": {
                    "tts": {
                        "audioDurationMs": 1442,
                        "generationTimeMs": 7,
                        "isCachePlaying": true
                    }
                }
            },
            {
                "messageId": "user-1",
                "role": "user",
                "text": "I need to book an appointment for a complex orthopedic procedure that requires consultation with multiple specialists and coordination between different departments.",
                "timestamp": 1772702485138,
                "metrics": {
                    "stt": {
                        "confidence": 0.7364502,
                        "durationMs": 4200
                    }
                },
                "skippedAssistantMessages": []
            }
        ],
        "phone": {
            "provider": {
                "name": ""
            }
        },
        "customer": {
            "number": "web-Ramesh Naik"
        },
        "analysis": {}
    }
}
```

## Context

This hang event occurred after a user made a complex request that required significant LLM processing time. The assistant failed to respond within the 5-second threshold, triggering the hang event. The system continued processing the request and may eventually deliver a response or trigger an error event if processing ultimately fails.
