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

# Webhooks

# Webhooks

Webhooks allow your Brainbase agents to send real-time notifications to your systems when events occur. When a call ends or other events happen, Brainbase sends an HTTP POST request to your configured webhook endpoint with detailed information about the interaction.

## Webhook Payload Schema

When a webhook is triggered, your endpoint receives a POST request with the following JSON payload:

```typescript theme={null}
{
  extractions: object,
  call_type?: string,
  from_number?: string,
  to_number?: string,
  direction?: string,
  call_id: string,
  agent_id?: string,
  call_status?: string,
  metadata?: object,
  start_timestamp?: number,
  end_timestamp?: number,
  disconnection_reason?: string,
  transcript?: string,
  transcript_object?: array,
  transcript_with_tool_calls?: array,
  recording_url?: string,
  webhook_id: string,
  log_id: string,
  deployment_id: string,
  raw_data: object,
  log: object
}
```

***

## Extraction Results

The `extractions` object contains AI-extracted data based on your deployment's extraction configuration.

```typescript theme={null}
extractions: {
  // Dynamic fields based on your deployment's extraction config
  customer_name: "John Smith",
  appointment_date: "2024-01-15",
  interested: true,
  // ... any fields you configured
}
```

<Note>
  The fields in `extractions` are entirely defined by your extraction configuration. You can extract any structured data from the conversation.
</Note>

***

## Call Data

These fields contain information about the call itself, spread at the top level of the payload.

| Field                            | Type    | Description                                       |
| -------------------------------- | ------- | ------------------------------------------------- |
| `call_type`                      | string  | Type of call (e.g., `"web_call"`, `"phone_call"`) |
| `from_number`                    | string  | Caller's phone number                             |
| `to_number`                      | string  | Called phone number                               |
| `direction`                      | string  | `"inbound"` or `"outbound"`                       |
| `call_id`                        | string  | External provider's call ID                       |
| `agent_id`                       | string  | External agent ID                                 |
| `call_status`                    | string  | External provider status                          |
| `metadata`                       | object  | Custom metadata from the call                     |
| `start_timestamp`                | number  | Unix timestamp in milliseconds                    |
| `end_timestamp`                  | number  | Unix timestamp in milliseconds                    |
| `disconnection_reason`           | string  | Why the call ended                                |
| `recording_url`                  | string  | URL to the call recording                         |
| `opt_out_sensitive_data_storage` | boolean | Whether sensitive data storage is opted out       |

### Transcript Fields

| Field                        | Type   | Description                                 |
| ---------------------------- | ------ | ------------------------------------------- |
| `transcript`                 | string | Plain text transcript of the conversation   |
| `transcript_object`          | array  | Structured transcript with roles and timing |
| `transcript_with_tool_calls` | array  | Transcript including tool/function calls    |

**Transcript Object Structure:**

```typescript theme={null}
transcript_object: [
  {
    role: "agent",           // "agent" or "user"
    content: "Hello, how can I help you today?",
    words: [
      {
        word: "Hello",
        start: 0.0,          // Start time in seconds
        end: 0.5             // End time in seconds
      },
      // ... more words
    ]
  },
  {
    role: "user",
    content: "I'd like to schedule an appointment.",
    words: [...]
  }
  // ... more messages
]
```

***

## Metadata Fields

| Field           | Type   | Description                 |
| --------------- | ------ | --------------------------- |
| `webhook_id`    | string | Your custom webhook's ID    |
| `log_id`        | string | Brainbase deployment log ID |
| `deployment_id` | string | Brainbase deployment ID     |

***

## Raw Data

The `raw_data` object contains the original data from batch/outbound calls. This is your `outbound_data` that was passed when initiating the call.

```typescript theme={null}
raw_data: {
  // Your original data from CSV or API
  id: "row_123",
  phoneNumber: "+15551234567",
  firstName: "John",
  lastName: "Smith",
  email: "john@example.com",
  customField1: "value1"
  // ... any fields from your data source
}
```

<Note>
  For inbound calls, `raw_data` may be empty or contain minimal data. For outbound batch calls, this contains the full row data you provided.
</Note>

***

## Full Log Object

The `log` object contains the complete `VoiceDeploymentLog` from the database with all session details.

```typescript theme={null}
log: {
  // Identifiers
  id: "log_abc123...",
  workerId: string,
  deploymentId: string,
  flowId: string,
  bbEngineSessionId: string,
  externalCallId: string,
  call_sid: string,               // Twilio call SID

  // Timestamps
  createdAt: "2024-01-15T10:30:00Z",
  updatedAt: "2024-01-15T10:35:00Z",
  startTime: "2024-01-15T10:30:00Z",
  endTime: "2024-01-15T10:35:00Z",

  // Call details
  direction: "inbound" | "outbound",
  fromNumber: string,
  toNumber: string,
  status: "queued" | "ongoing" | "completed" | "failed",
  duration: 300,                  // Duration in seconds
  Telephony_source: "twilio",

  // Content
  transcription: string,          // Plain text transcript
  messages: [                     // Structured transcript
    { role: "agent", content: "..." },
    { role: "user", content: "..." }
  ],
  recordingUrl: string,

  // Stored data
  extractionsData: object,        // Stored extraction results
  metadata: object,
  flowSnapshot: string,           // Flow code at time of call
  sessionLogData: object,         // Session data from engine

  // Nested data object
  data: {
    event: "call_ended",
    call_ended: object,           // Full call_ended event payload
    outbound_data: {
      // Same as raw_data
    },
    extraction: {
      status: "processing" | "completed",
      queuedAt: "2024-01-15T10:35:00Z"
    }
  }
}
```

### Log Status Values

| Status      | Description                                   |
| ----------- | --------------------------------------------- |
| `initiated` | Call has been initiated but not yet connected |
| `queued`    | Call is queued but not yet started            |
| `ongoing`   | Call is currently in progress                 |
| `completed` | Call has ended successfully                   |
| `failed`    | Call failed to complete                       |
| `voicemail` | Call went to voicemail                        |

***

## Example Payload

Here's a complete example of a webhook payload:

```json theme={null}
{
  "extractions": {
    "customer_name": "John Smith",
    "appointment_confirmed": true,
    "preferred_date": "2024-01-20",
    "notes": "Prefers morning appointments"
  },

  "call_type": "phone_call",
  "from_number": "+14154650216",
  "to_number": "+14158738252",
  "direction": "inbound",
  "call_id": "call_abc123",
  "call_status": "completed",
  "start_timestamp": 1705312200000,
  "end_timestamp": 1705312500000,
  "disconnection_reason": "customer_ended_call",
  "transcript": "Agent: Hello, how can I help you today?\nUser: I'd like to schedule an appointment...",
  "recording_url": "https://storage.example.com/recordings/call_abc123.mp3",

  "webhook_id": "wh_xyz789",
  "log_id": "log_def456",
  "deployment_id": "deploy_a05e0b20-87ed-440b-9cd4-0427cc812c41",

  "raw_data": {
    "firstName": "John",
    "lastName": "Smith",
    "phoneNumber": "+14154650216",
    "email": "john@example.com"
  },

  "log": {
    "id": "log_def456",
    "createdAt": "2024-01-15T10:30:00Z",
    "status": "completed",
    "duration": 300,
    "direction": "inbound",
    "fromNumber": "+14154650216",
    "toNumber": "+14158738252"
  }
}
```

***

## Handling Webhooks

When processing webhook payloads, we recommend:

1. **Validate the payload** - Check that required fields like `webhook_id` and `deployment_id` are present
2. **Respond quickly** - Return a 200 status code promptly; process data asynchronously if needed
3. **Handle duplicates** - Use `log_id` or `call_id` to deduplicate if your endpoint receives the same event twice
4. **Store raw payloads** - Consider logging the full payload for debugging purposes

```python theme={null}
# Example webhook handler (Python/Flask)
@app.route('/webhook', methods=['POST'])
def handle_webhook():
    payload = request.json
    
    # Extract key fields
    extractions = payload.get('extractions', {})
    log_id = payload.get('log_id')
    direction = payload.get('direction')
    
    # Process the data
    if extractions.get('appointment_confirmed'):
        schedule_appointment(
            customer=extractions.get('customer_name'),
            date=extractions.get('preferred_date')
        )
    
    return {'status': 'ok'}, 200
```
