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

# Error Handling

> Error codes and handling guide

## Overview

The API uses standard HTTP status codes and returns error details in a consistent format. All errors include a `detail` field with a human-readable message.

## Error Response Format

All error responses follow this structure:

```json theme={null}
{
  "detail": "Error message describing what went wrong"
}
```

## HTTP Status Codes

### 400 Bad Request

Returned when the request is malformed or missing required parameters.

**Common scenarios:**

* No utterances detected in media (`NO_UTTERANCES`)
* File too large (`FILE_TOO_LARGE`)
* Missing timeline for segmentation endpoint
* Invalid file format
* Empty chunk data uploaded

**Example:**

```json theme={null}
{
  "detail": "No utterances detected in uploaded media"
}
```

### 401 Unauthorized

Returned when authentication fails.

**Scenarios:**

* Missing `X-API-Key` header (`INVALID_KEY`)
* Invalid API key provided (`INVALID_KEY`)
* API key not in allowlist (`INVALID_KEY`)

**Example:**

```json theme={null}
{
  "detail": "Invalid or missing API key"
}
```

<Info>
  You can also pass the API key as a query parameter: `api_key=<client key>` when custom headers are not available.
</Info>

### 404 Not Found

Returned when a requested resource doesn't exist.

**Scenarios:**

* Unknown live session ID
* Invalid endpoint path

**Example:**

```json theme={null}
{
  "detail": "Unknown live session"
}
```

### 409 Conflict

Returned when there's a conflict with the current state.

**Scenarios:**

* Concurrent SSE attach (only one SSE consumer per live session)
* Wrong chunk sequence number (chunks must be uploaded sequentially)
* Session already finalized
* Attempting to upload to a finalized session

**Example:**

```json theme={null}
{
  "detail": "Only one SSE consumer may be attached to a live session at a time"
}
```

### 500 Internal Server Error

Returned when server-side processing fails.

**Common causes:**

* Downstream agent or ASR failure (`ANALYSIS_FAILURE`)
* External service failures
* Media processing errors
* General pipeline failures

**Example:**

```json theme={null}
{
  "detail": "Analysis failed: Connection timeout"
}
```

## SSE Error Events

SSE streams may emit error events with specific error codes:

### Error Event Format

```
event: error
data: {"code":"ERROR_CODE","message":"Human-readable message"}
```

### Error Codes

<ResponseField name="NO_UTTERANCES" type="string">
  Media contained no speech above the threshold. Analysis cannot proceed.
</ResponseField>

<ResponseField name="FILE_TOO_LARGE" type="string">
  Exceeded `MAX_FILE_SIZE_MB` (default 500 MB). Upload fails before processing.
</ResponseField>

<ResponseField name="INVALID_KEY" type="string">
  Missing or incorrect API key. Verify header or query parameter.
</ResponseField>

<ResponseField name="ANALYSIS_FAILURE" type="string">
  Downstream agent or ASR failure. Details provided in `detail` field.
</ResponseField>

<ResponseField name="LIVE_ASR_FAILURE" type="string">
  Live ASR connection failed. The live streaming session cannot continue.
</ResponseField>

<ResponseField name="STREAM_FAILURE" type="string">
  General streaming failure. The SSE connection may close after this event.
</ResponseField>

**Example SSE error:**

```
event: error
data: {"code":"STREAM_FAILURE","message":"Streaming connection lost"}
```

## Best Practices

### Retry Logic

* **401 errors**: Check API key configuration. Do not retry with the same key.
* **400 errors**: Fix the request payload. Do not retry without changes.
* **404 errors**: Verify resource IDs. Do not retry.
* **409 errors**: Resolve the conflict (e.g., wait for current SSE consumer to disconnect). Retry after resolution.
* **500 errors**: Implement exponential backoff. These may be transient.

### Error Handling in SSE Streams

When consuming SSE streams:

1. **Listen for error events**: Always handle `error` events in your SSE client
2. **Handle connection drops**: Implement reconnection logic for network failures
3. **Validate event data**: Parse JSON carefully and handle malformed events gracefully
4. **Log errors**: Record error codes and messages for debugging

**Example JavaScript SSE error handling:**

```javascript theme={null}
const eventSource = new EventSource('/analyze/live/session123/events');

eventSource.addEventListener('error', (event) => {
  const errorData = JSON.parse(event.data);
  console.error(`SSE Error [${errorData.code}]: ${errorData.message}`);
  
  if (errorData.code === 'STREAM_FAILURE') {
    eventSource.close();
    // Implement retry or fallback logic
  }
});
```

### Chunk Upload Error Handling

When uploading chunks to live sessions:

* **409 on wrong sequence**: Use the `next_chunk_seq` from the previous response
* **404 on unknown session**: Verify session ID and check if session expired
* **409 on finalized session**: Session is complete; do not upload more chunks

**Example retry logic:**

```python theme={null}
def upload_chunk(session_id, chunk_data, chunk_seq):
    try:
        response = requests.post(
            f'/analyze/live/{session_id}/chunk',
            files={'chunk': chunk_data, 'chunk_seq': chunk_seq}
        )
        response.raise_for_status()
        return response.json()['next_chunk_seq']
    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 409:
            # Wrong sequence - get correct sequence from error or previous response
            return get_correct_sequence(session_id)
        raise
```

## Operational Notes

### Session TTL Management

Live sessions expire after a default TTL (900 seconds). To prevent expiration:

* Call `POST /analyze/live/{session_id}/control` with `{"action": "keepalive"}` during long pauses
* Monitor `expires_at` timestamp from session start response
* Upload chunks regularly to keep session active

### File Size Limits

Files exceeding `MAX_FILE_SIZE_MB` (default 500 MB) will be rejected with a 400 error before processing begins. Check file size client-side before upload.

### Prosody Fallbacks

If audio processing fails post-stream, the service still returns textual insights. Prosody fields may be empty in the response. This is not an error condition.

## Error Handling & Troubleshooting

| Layer          | Symptom                                           | Resolution                                                                                    |
| -------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Authentication | `401 {"detail":"Invalid or missing API key"}`     | Verify header, rotate key if unsure.                                                          |
| Replay stream  | SSE disconnects immediately                       | Ensure `Accept: text/event-stream` and HTTP client supports streaming (no proxies buffering). |
| Live capture   | `409 Session already has an active SSE stream`    | Only one event consumer per session; close existing connection before re-attaching.           |
| Chunk upload   | `409 Expected chunk_seq=<n>`                      | Re-send the missing chunk; chunks must be sequential.                                         |
| Summary        | `summary_update` missing or fallback text appears | Indicates schema validation failure; check server logs for warnings.                          |

**Logs** are available server-side. Look for `[conversation_id]` prefixes for correlated traces.

## Debugging Tips

1. **Check logs**: Server-side logs are available for debugging
2. **Verify artifacts**: Check `artifact_dir` paths in responses for debugging
3. **Monitor metrics**: Use `/metrics` endpoint to watch SSE throughput and latency
4. **Validate OpenAPI**: Ensure your requests match the OpenAPI specification
5. **Correlate traces**: Look for `[conversation_id]` prefixes in logs for debugging specific conversations
