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

# Connect your own channel to the AI agent

> Pass customer messages to Clarity's AI agent from your own system on an existing web-chat ticket, and read the conversation back.

The AI service endpoints let a system you run take part in a web-chat conversation between a customer and Clarity's AI agent. Your system forwards customer messages into the ticket, reads the ticket back to get the replies, and can ask a voice agent to call the customer.

All paths are under `/api/integration/ai_service/` on `https://back.leap.onclarity.com`, and every request sends `Authorization: Bearer $CLARITY_API_KEY` (see [Authentication](/authentication.md)).

## How it works

**1. Start from a web-chat ticket**

The conversation starts in your [chat widget or mobile SDK](/sdks/overview.md), which opens the ticket. Get its `ticket_id` and the customer's id (`customer.id`) from the [`ticket_created` webhook](/support/webhooks#ticket-lifecycle) for a ticket whose `channel` is `web`, `android_sdk` or `ios_sdk`, or list a known customer's tickets with `GET /api/integration/ai_service/customer/{customer_id}/tickets`.

**2. Forward each customer message**

`POST /api/integration/ai_service/customer/send` adds a message to the ticket as if the customer had typed it in the chat widget. The AI agent then processes it the same way it processes widget messages.

**3. Read the replies**

Subscribe to the `message` [webhook](/support/webhooks.md), or read the ticket's events with `GET /api/integration/ai_service/ticket/{ticket_id}/details`, and relay the agent's replies to the customer on your channel.

> [!NOTE]
>
> Opening a brand-new ticket from your own system, without the widget, needs an integration credential bound to an AI agent, which an organization API key is not. Contact Clarity support if your integration needs it.

## Send a customer message

```bash Request theme={null}
curl -X POST https://back.leap.onclarity.com/api/integration/ai_service/customer/send \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": 67890,
    "ticket_id": 12345,
    "text": "Hi, my order has not arrived yet.",
    "files": []
  }'
```

```json Response theme={null}
{
  "created_at": "2026-10-22T15:30:45.123000Z",
  "internal_id": "0199f3a2-6c1e-7d4b-9a10-2f5c8e1b7a44",
  "files": []
}
```

**customer\_id** `integer` *required*

The customer the ticket belongs to.

**ticket\_id** `integer` *required*

The ticket to add the message to.

**text** `string` *required*

The message text. Required, but may be an empty string when you only send files.

**files** `integer[]` (default: \[])

Attachment ids from `POST /api/attachment/upload` (see [Attachments](/support/messages.md#attachments)). At most 5 per message.

**created\_at** `string`

When Clarity accepted the message (ISO 8601).

**internal\_id** `string`

The message's id. The same value appears as `internal_id` on the event in the ticket details.

**files** `object[]`

The attached files, each with `id`, `original_url`, `thumbnail_url`, `mime_type`, and `original_filename`.

The message is processed asynchronously: a `200` means Clarity accepted it, and the AI agent's reply arrives later.

The ticket must have an active chat session, which tickets opened through the chat widget and the mobile SDKs have. Other tickets, such as WhatsApp or email ones, cannot receive customer messages this way.

### Errors

| Code | Meaning |
| - | - |
| `ticket_not_found` | No ticket with that id in your organization. |
| `ticket_does_not_belong_to_customer` | The `customer_id` is not the customer of that ticket. |
| `too_many_files_error` | More than 5 files in one message. |

## Read the ticket

`GET /api/integration/ai_service/ticket/{ticket_id}/details` returns the customer, the ticket, its tags and team, and the latest events of the chat.

```bash theme={null}
curl "https://back.leap.onclarity.com/api/integration/ai_service/ticket/12345/details?events_limit=20" \
  -H "Authorization: Bearer $CLARITY_API_KEY"
```

**events\_limit** `integer` (default: 20)

How many events to return. When the ticket continues a closed chat, at least 60 are returned so the earlier tickets are included.

**customer** `object`

The customer: `id`, `first_name`, `last_name`, `avatar_url`, `organization_id`, `attributes` (a list of `{key, value}`), `tags`, and `custom_attributes`.

**ticket** `object`

`id`, `conversation_id`, `status`, `priority`, `category`, `is_archived`, and `custom_attributes`.

**tags** `object[]`

The ticket's tags, each with `id`, `name`, `description`, and `color`.

**team** `object | null`

The team the ticket is assigned to.

**events** `object[]`

Timeline events. Each has `id`, `type` (for example `message`, `private_note`, `status_change`), `created_at`, `ticket_id`, `conversation_id`, `internal_id`, and a `payload` whose shape depends on the type.

**handoff\_brief** `object | null`

When a voice agent handed this customer over to chat, the summary it wrote of the call.

> [!NOTE]
>
> `custom_attributes` on the ticket and the customer include only the attributes whose definition has `ai_context` turned on (**Settings > Custom attributes**). Use [`GET /api/custom-attributes/values`](/support/customers-and-tickets#custom-attributes) to read every attribute.

## Read the customer

| Endpoint | Returns |
| - | - |
| `GET /api/integration/ai_service/customer/{customer_id}/details` | `id`, `first_name`, `last_name`, `avatar_url`, `organization_id`, `attributes`, `tags`, and `custom_attributes` (AI-context attributes only) |
| `GET /api/integration/ai_service/customer/{customer_id}/tickets?limit=10` | `tickets`: the customer's tickets, each with `id`, `conversation_id`, `channel`, `status`, `priority`, `category`, `team`, `created_at`, `is_archived`, and a `summary` of up to 400 characters when one exists |

## Ask a voice agent to call the customer

`POST /api/integration/ai_service/ticket/{ticket_id}/voice_handoff` asks a Clarity voice agent to phone the customer of a chat ticket. It works when the AI agent that answers the ticket has the request-a-call tool configured with a voice agent, and your organization has a voice project.

```bash Request theme={null}
curl -X POST https://back.leap.onclarity.com/api/integration/ai_service/ticket/12345/voice_handoff \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+14155550134",
    "brief": {
      "reason": "Customer wants to change the delivery address",
      "summary": "Order 4471 ships tomorrow. The customer moved last week.",
      "open_question": "Which address should the order go to?"
    }
  }'
```

```json Dialing theme={null}
{
  "status": "dialing",
  "reason": null,
  "message": "Calling you now on +14155550134."
}
```

```json Refused theme={null}
{
  "status": "refused",
  "reason": "call_in_progress",
  "message": "A call to you is already on its way."
}
```

**phone** `string` *required*

The number to call, 1 to 64 characters. It is normalized against your organization's region.

**brief** `object`

What the voice agent should know before it speaks. Optional fields: `reason` (up to 200 characters), `summary` (800), `key_facts` (up to 10 `{label, value}` pairs), `commitments` (up to 5 strings), `open_question` (300), `opening_line` (200), and `language`. Longer values are cut, not refused.

A refusal is a `200` with `status: "refused"` and a `message` you can relay to the customer:

| `reason` | Meaning |
| - | - |
| `no_tool_config` | The AI agent on this ticket has no voice call tool, or no voice agent is chosen in it. |
| `invalid_number` | The phone number is not valid. |
| `voice_unavailable` | Your organization has no voice project, or the voice service did not answer. |
| `agent_not_published` | The chosen voice agent is not published. |
| `no_outbound_caller_id` | The voice project has no number to call from. |
| `handoff_limit` | The customer has reached the limit of channel handoffs in 24 hours (3 unless the tool sets another). |
| `call_in_progress` | A call to this customer is already being placed. |

## Next steps

> **[Webhooks](/support/webhooks.md)**
>
> Receive the AI agent's replies as they are written.

> **[Messages](/support/messages.md)**
>
> Reply as the business, add private notes, and upload attachments.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.