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

# Webhooks

> Configure webhook actions to integrate your Telzino agent with external systems

Webhook actions allow your Telzino AI phone agents to interact with external systems during calls. You can fetch data, create support tickets, log calls to your CRM, and more.

## Webhook Conditions

Webhooks can be triggered at different points in the call lifecycle:

| Condition     | When it Triggers         | Use Cases                                                    |
| ------------- | ------------------------ | ------------------------------------------------------------ |
| `before_call` | Before the agent answers | Pre-fetch caller info, check CRM records, inject context     |
| `during_call` | While the call is active | Create support tickets, real-time lookups, live integrations |
| `after_call`  | After the call ends      | Log to CRM, send summaries, create follow-up tasks           |

<Note>
  **Limits:** You can configure one `before_call` webhook, up to four `during_call` webhooks, and one `after_call` webhook per agent.
</Note>

## Adding a Webhook via Dashboard

<Steps>
  <Step title="Navigate to Agent Settings">
    Log into your account and go to **Agent Settings** > **Functions**.
  </Step>

  <Step title="Add Webhook Action">
    Click the **(+)** button and select **Webhooks**.
  </Step>

  <Step title="Configure the Webhook">
    Fill in the webhook configuration form with the required fields.
  </Step>
</Steps>

## Webhook Configuration

Each webhook requires the following configuration:

### Required Fields

| Field             | Description                                                       |
| ----------------- | ----------------------------------------------------------------- |
| **Name**          | Unique identifier for the webhook (e.g., `Create_Zendesk_Ticket`) |
| **Friendly Name** | Human-readable display name                                       |
| **Description**   | What this webhook does - helps the AI understand when to use it   |
| **Condition**     | When to trigger: `before_call`, `during_call`, or `after_call`    |
| **HTTP Method**   | `GET`, `POST`, `PUT`, `PATCH`, or `DELETE`                        |
| **URL**           | The endpoint to send the request to                               |

### Optional Fields

| Field          | Description                                                                 |
| -------------- | --------------------------------------------------------------------------- |
| **Headers**    | HTTP headers for authentication (e.g., API keys, Bearer tokens)             |
| **Parameters** | Data to send in the request body - AI extracts values from the conversation |

## How Parameters Work

Parameters are the key to making webhooks intelligent. When you define parameters:

1. **You specify the key name** - What the external API expects (e.g., `email`, `subject`, `priority`)
2. **You provide a default/example value** - Used as a fallback or guide for the AI
3. **The AI extracts actual values** - During the call, the AI analyzes the conversation and fills in real values

<Info>
  If you leave a parameter value empty, the AI will attempt to generate an appropriate value based on the conversation context.  This is not reliable however, so avoid this whenever possible.
</Info>

### Example Parameter Configuration

```json theme={null}
{
  "parameters": [
    { "key": "customer_name", "value": "" },
    { "key": "email", "value": "unknown@example.com" },
    { "key": "issue_summary", "value": "" },
    { "key": "priority", "value": "normal" }
  ]
}
```

In this example:

* `customer_name` and `issue_summary` will be extracted from the conversation
* `email` defaults to `unknown@example.com` if the caller doesn't provide one
* `priority` defaults to `normal` unless the AI determines otherwise

## Real-World Examples

### Zendesk Ticket Creation

Create a support ticket in Zendesk during or after a call:

```json theme={null}
{
  "name": "Zendesk_Ticket",
  "friendlyName": "Create Support Ticket",
  "description": "Creates a support ticket in Zendesk with call details and transcript",
  "condition": "during_call",
  "method": "POST",
  "url": "https://yourcompany.zendesk.com/api/v2/tickets.json",
  "headers": [
    {
      "key": "Authorization",
      "value": "Basic YOUR_BASE64_ENCODED_CREDENTIALS"
    },
    {
      "key": "Content-Type",
      "value": "application/json"
    }
  ],
  "parameters": [
    {
      "key": "ticket",
      "value": "{\"ticket\":{\"subject\":\"AI Call - Customer Inquiry\",\"comment\":{\"body\":\"Call summary and transcript\"},\"priority\":\"normal\"}}"
    }
  ]
}
```

<Accordion title="Zendesk Authentication">
  For Zendesk, use Basic authentication with your email and API token:

  ```
  Authorization: Basic base64(email/token:api_token)
  ```

  In JavaScript:

  ```javascript theme={null}
  const credentials = btoa(`${email}/token:${apiToken}`);
  const header = `Basic ${credentials}`;
  ```
</Accordion>

### Freshdesk Ticket Creation

```json theme={null}
{
  "name": "Freshdesk_Ticket",
  "friendlyName": "Create Freshdesk Ticket",
  "description": "Creates a ticket in Freshdesk after the call",
  "condition": "after_call",
  "method": "POST",
  "url": "https://yourcompany.freshdesk.com/api/v2/tickets",
  "headers": [
    {
      "key": "Authorization",
      "value": "Basic YOUR_API_KEY_BASE64"
    }
  ],
  "parameters": [
    { "key": "subject", "value": "AI Voice Agent Call" },
    { "key": "description", "value": "" },
    { "key": "email", "value": "caller@example.com" },
    { "key": "priority", "value": "1" },
    { "key": "status", "value": "2" }
  ]
}
```

### CRM Integration (Before Call)

Fetch caller information before the agent answers:

```json theme={null}
{
  "name": "CRM_Lookup",
  "friendlyName": "Lookup Caller in CRM",
  "description": "Fetches caller history and preferences from CRM before the call",
  "condition": "before_call",
  "method": "GET",
  "url": "https://api.yourcrm.com/v1/contacts/lookup",
  "headers": [
    {
      "key": "Authorization",
      "value": "Bearer YOUR_API_TOKEN"
    }
  ],
  "parameters": [
    { "key": "phone", "value": "" }
  ]
}
```

### Post-Call Logging

Log call details to your system after the call ends:

```json theme={null}
{
  "name": "Call_Logger",
  "friendlyName": "Log Call to System",
  "description": "Sends call summary and transcript to internal logging system",
  "condition": "after_call",
  "method": "POST",
  "url": "https://api.yourcompany.com/calls/log",
  "headers": [
    {
      "key": "Authorization",
      "value": "Bearer YOUR_API_TOKEN"
    }
  ],
  "parameters": [
    { "key": "caller_phone", "value": "" },
    { "key": "call_summary", "value": "" },
    { "key": "transcript", "value": "" },
    { "key": "duration", "value": "" },
    { "key": "sentiment", "value": "" }
  ]
}
```

## API Configuration

You can also configure webhooks via the API when creating or updating an agent. Webhooks are stored in the `extensions.tools` array.

[Model Context Protocol (MCP)](/integrations/mcp) connections use the sibling `extensions.mcp_servers` array. **GET** responses document the stored shape [here](/api-reference/agents/get#stored-mcp-connection-shape); **POST/PUT** use the validated request shape [here](/api-reference/agents/create#mcp-servers-request-body) (they differ today).

Example request body with webhooks only:

```bash theme={null}
curl -X POST https://dashboard.telzino.com/v1/agents \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support Agent",
    "organizationId": "your-org-id",
    "greetingMessage": "Hello! How can I help you today?",
    "systemPrompt": "You are a helpful support agent...",
    "extensions": {
      "tools": [
        {
          "type": "webhook",
          "name": "Create_Ticket",
          "friendlyName": "Create Support Ticket",
          "description": "Creates a support ticket when the customer has an issue",
          "condition": "during_call",
          "method": "POST",
          "url": "https://api.helpdesk.com/tickets",
          "headers": [
            { "key": "Authorization", "value": "Bearer API_TOKEN" }
          ],
          "parameters": [
            { "key": "subject", "value": "" },
            { "key": "description", "value": "" },
            { "key": "customer_email", "value": "" }
          ]
        }
      ]
    }
  }'
```

## Best Practices

<AccordionGroup>
  <Accordion title="Write Clear Descriptions">
    The description helps the AI understand when to trigger the webhook. Be specific:

    **Good:** "Creates a support ticket when the customer reports a problem or needs help with their order"

    **Bad:** "Creates a ticket"
  </Accordion>

  <Accordion title="Use Meaningful Parameter Names">
    Use descriptive key names that match what your external API expects. The AI uses these names to understand what data to extract.
  </Accordion>

  <Accordion title="Provide Default Values">
    For optional parameters, provide sensible defaults. For required parameters where you want AI extraction, leave the value empty.
  </Accordion>

  <Accordion title="Secure Your Credentials">
    Never expose API keys in client-side code. Use environment variables or secure credential storage when possible.
  </Accordion>

  <Accordion title="Test Your Webhooks">
    Test your webhook endpoints independently before configuring them in your agent. Use tools like Postman or curl to verify they work correctly.
  </Accordion>
</AccordionGroup>

## Troubleshooting

| Issue                   | Cause                     | Solution                                              |
| ----------------------- | ------------------------- | ----------------------------------------------------- |
| Webhook not triggering  | Wrong condition           | Verify the condition matches when you want it to fire |
| Authentication errors   | Invalid credentials       | Check your API key/token and header format            |
| Missing data in request | Parameters not configured | Ensure all required parameters are defined            |
| Timeout errors          | Slow external API         | Consider using `after_call` for slow endpoints        |
