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

# Agent assignment webhook

> When you use the API destination of the Transfer Methods block, Treble calls your endpoint so your own system can decide which agent should receive the conversation. Learn the request and response contract here.

## How does it work?

When a conversation reaches a **Transfer Methods** block configured with the **API** destination, Treble sends a `POST` request to the endpoint you configured, with the contact's and the conversation's information. Your service decides which agent should attend to it and returns that agent in the response. Treble assigns the conversation to that agent.

If your service doesn't respond in time, or the agent you return can't receive the conversation, Treble applies your company's **fallback method** so the conversation is never left unassigned.

```mermaid theme={null}
sequenceDiagram
    participant C as Customer
    participant T as Treble
    participant S as Your server

    C->>T: The conversation reaches the transfer block
    T->>S: POST with the contact's context
    S->>S: Decides which agent should attend the chat
    alt Agent resolved
        S->>T: 200 with agent_email or agent_id
        T->>T: Assigns the conversation to that agent
    else No agent, error, or timeout
        S->>T: Status code other than 200, timeout, or invalid agent
        T->>T: Applies the fallback method
    end
```

<Info>
  This webhook is **not configured in the webhook center**, but inside the block itself in the conversation editor. That way, each block can call a different endpoint.
</Info>

<Card title="Configure the block" horizontal icon="gear" href="/en/docs/build-with-treble/blocks/transfer-methods/api">
  Learn how to configure the URL and the authentication from the conversation editor.
</Card>

## Authentication

In the block you can choose between two options:

* **No authentication** — Treble calls your endpoint without credentials.
* **Token / API Key** — Treble sends the token you configured in the `Authorization` header:

```
Authorization: Bearer YOUR_TOKEN
```

<Tip>
  Always use `https://` and configure a token. That way your endpoint can verify the call actually comes from Treble.
</Tip>

## The request Treble sends

Treble makes a `POST` with a JSON body containing the contact's and the conversation's context.

```json theme={null}
{
  "company_id": 1234,
  "survey_user_id": 567890,
  "contact": {
    "treble_id": "5215512345678",
    "name": "Andrea Soto",
    "country_code": "52",
    "cellphone": "5512345678",
    "business_scope_id": "1029384756",
    "username": null
  },
  "crm_type": "salesforce",
  "crm_objects": [
    { "entity": "Contact", "id": "0035f00000ABCDEqAO" },
    { "entity": "Account", "id": "0015f00000FGHIJqAO" }
  ],
  "channel": {
    "phone_number_id": "1234567890"
  },
  "metadata": {
    "poll_id": 4321,
    "node_id": "a1b2c3",
    "tag": "Comercial",
    "language": "es"
  }
}
```

| Field                     | Description                                                                                                            |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `company_id`              | Your company's identifier in Treble.                                                                                   |
| `survey_user_id`          | Identifier of the contact's session in the conversation.                                                               |
| `contact`                 | Information about the contact in the conversation.                                                                     |
| `crm_type`                | The CRM your account is integrated with, for example `salesforce` or `hubspot`. It's `null` if there's no integration. |
| `crm_objects`             | The CRM records associated with the contact.                                                                           |
| `channel.phone_number_id` | Identifier of the WhatsApp line that received the conversation.                                                        |
| `metadata`                | Context of the flow and the block that originated the call: `poll_id`, `node_id`, `tag`, and `language`.               |

<Info>
  `cellphone` and `country_code` can arrive as `null` for contacts that only exist as a Meta username. In that case, use `business_scope_id` or `username` to identify the user.
</Info>

### CRM identifiers

When your account has a CRM integration, the request includes the contact's identifiers in your CRM so you can decide based on the record; for example, look up the record's owner and return that agent.

* **`crm_type`** — the CRM your account is integrated with. It's `null` if the account has no integration.
* **`crm_objects`** — the CRM records associated with the contact. Each one carries its **`entity`** (the object type in the CRM, for example `Contact`, `Account`, or `Lead`) and its **`id`** (the record's identifier in your CRM). A contact associated with several Salesforce objects carries one entry per object; in other CRMs there's a single entry. An empty array means the contact isn't associated with any record yet.

## The response you must return

Respond with `200` and a JSON body that identifies the agent. You can do it by **email** (recommended) or by **id**:

<CodeGroup>
  ```json By email (recommended) theme={null}
  {
    "agent_email": "andrea.soto@yourcompany.com"
  }
  ```

  ```json By id theme={null}
  {
    "agent_id": 4567
  }
  ```
</CodeGroup>

* **`agent_email`** — the agent's email as registered in Treble. It's the recommended option because it doesn't depend on Treble's internal identifiers.
* **`agent_id`** — the agent's identifier in Treble.

The agent you return must be **active**. To find out which agents are available in your account —and the exact `email` and `id` values you must return— use the [get your company's agents](/en/api-reference/endpoints/get-agents) endpoint.

<Warning>
  Your endpoint must respond in **less than 10 seconds**. If it exceeds that, returns a status code other than `200`, or returns an agent that can't receive the conversation, Treble applies the fallback method configured in the main platform.
</Warning>

## Implementation example

A minimal Node.js endpoint that returns an agent based on the contact:

```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());

app.post('/webhooks/on-agent-assignation', (req, res) => {
  // Verify the call comes from Treble
  if (req.header('Authorization') !== `Bearer ${process.env.TREBLE_TOKEN}`) {
    return res.sendStatus(401);
  }

  const { contact, crm_type, crm_objects, metadata } = req.body;

  // Your logic to choose the agent: round robin, language,
  // owner in the CRM, segment, etc.
  const agentEmail = chooseAgent(contact, crm_objects, metadata);

  // Return the agent by email (recommended) or by id
  res.json({ agent_email: agentEmail });
});

app.listen(3000, () => {
  console.log('Server listening on port 3000');
});
```

## Next steps

<CardGroup cols={2}>
  <Card title="Endpoint reference" icon="code" href="/en/api-reference/webhooks/api-assignation/reference">
    Explore the full schema of the request and the response.
  </Card>

  <Card title="Get the agents" icon="users" href="/en/api-reference/endpoints/get-agents">
    Look up the agents in your account to know which email or id to return.
  </Card>
</CardGroup>
