> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/tech/en/api-integration/customer-service-system-integration.md).

# Third-Party Customer Service System Integration (Including Human Handoff)

End-to-end spec for connecting a customer service system or chat platform to MaiAgent as the AI engine via API — message in/out, handoff to your human agents when the AI decides it's needed, and retur

{% hint style="warning" %}
**Release status: awaiting production deployment.** This page describes the new four-event handoff contract and nested payload with `id` and `occurred_at`. This contract is not yet released in production. Do not enable a production integration based on it until the MaiAgent team confirms that your environment has been updated. The following content is for integration planning and testing.
{% endhint %}

This page is for integrators who "already have their own customer service system or chat front end (own website, LINE, Messenger, or other channels on your side) and want to use MaiAgent as the **AI engine**": visitor messages are sent from your system into MaiAgent, AI replies are pushed back to your system; when the AI decides a human is needed, **your human agent** takes over, and once the human service ends, the conversation is handed back to the AI.

The integration only uses MaiAgent's existing public API and two sets of webhooks — no dedicated interface needs to be built for a single customer service system.

## Integration Overview <a href="#overview" id="overview"></a>

```mermaid
sequenceDiagram
    participant V as Visitor
    participant S as Your CS System
    participant M as MaiAgent
    participant H as Your Human Agent

    V->>S: Sends message (web / LINE / …)
    S->>M: ① Identity sync (sourceId → contactId)
    S->>M: ② Create conversation (first time)
    S->>M: ③ Send message POST /messages/
    M-->>S: 201 (AI reply async)
    M-)S: ④ Outgoing Webhook: AI reply
    S->>V: Display AI reply

    Note over M: AI decides human is needed
    M-)S: ⑤ handoff.requested
    S->>H: Create case, assign agent
    H->>V: Human continues service (in your system)
    S->>M: ⑥ PATCH /conversations/{id}/return-to-ai/
    M-)S: handoff.returned_to_ai
    Note over M: Subsequent messages resume AI replies
```

### Division of Responsibilities <a href="#responsibilities" id="responsibilities"></a>

| Who             | Responsible for                                                                                                                                                                                                      |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Your system** | Channel integration, visitor-facing UI, cases and agent seats, storing and displaying conversation history; sending visitor messages into MaiAgent, receiving webhooks, calling return-to-AI when human service ends |
| **MaiAgent**    | AI replies, maintaining conversation context, deciding whether to hand off to a human via LLM, pushing handoff and return-to-AI events                                                                               |

## Prerequisite Setup <a href="#setup" id="setup"></a>

All of the following is done in the MaiAgent admin console, once per chat platform.

### 1. Create a Web Chat platform and get credentials <a href="#setup-inbox" id="setup-inbox"></a>

API integration uses a **Web Chat**-type chat platform. You'll need:

* **API key**: see [Quickstart](/tech/en/api-integration/quickstart.md) for how to obtain one.
* **Web Chat ID**: at the bottom of the AI assistant detail page.

### 2. Set up an Outgoing Webhook (receive AI replies) <a href="#setup-outgoing-webhook" id="setup-outgoing-webhook"></a>

<mark style="color:blue;">Settings</mark> → <mark style="color:blue;">Chat Platforms</mark> → the platform → <mark style="color:blue;">Webhooks</mark> → <mark style="color:blue;">Add Webhook</mark>, choose type **Outgoing**, and enter your reply-receiving URL as the endpoint. Choose format **MaiAgent standard format**; if your system requires a fixed JSON structure, choose **Custom template**. See [Webhook](/tech/en/api-integration/webhook.md) for fields and payload.

### 3. Enable human handoff <a href="#setup-handoff" id="setup-handoff"></a>

On the same chat platform → <mark style="color:blue;">Human Handoff Settings</mark> tab:

| Setting                                                                                                                                                       | Recommendation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <mark style="color:blue;">Enable human handoff</mark>                                                                                                         | On                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| <mark style="color:blue;">Decision model</mark>, <mark style="color:blue;">Role instructions</mark>, <mark style="color:blue;">Reference message count</mark> | The LLM and rules used to decide whether to hand off to a human. Default rules: visitor explicitly requests a human, the question is beyond what the AI can handle, the visitor is upset, or it involves an account operation that needs manual verification. Adjust in role instructions to fit your business (e.g. add keywords, hand off when confidence is low)                                                                                                                                |
| <mark style="color:blue;">Wait timeout</mark>                                                                                                                 | **Critical setting.** After handoff, the conversation enters a queue; if no MaiAgent member picks it up within this many seconds, MaiAgent automatically returns the conversation to the AI. When your human agents work in your own system, MaiAgent has no visibility into the takeover action, so set this to **0 (no timeout — you call return-to-AI yourself)**, or to a duration long enough to cover the entire human service session                                                       |
| <mark style="color:blue;">Queue limit</mark>                                                                                                                  | Maximum number of conversations that can be in handoff state at once (1–500). When full, new handoff requests won't trigger: that message won't get an AI reply, and `handoff.requested` won't be sent either. Set according to your support capacity                                                                                                                                                                                                                                              |
| <mark style="color:blue;">Service hours</mark>                                                                                                                | When enabled, the AI won't hand off outside service hours: with <mark style="color:blue;">Show offline message</mark>, that message won't get an AI reply and `handoff.requested` won't be sent (the offline message is also only pushed to the Web Chat front end — off-hours prompts to visitors must be handled by your own system); with <mark style="color:blue;">Accept messages</mark>, it still enters the queue and sends `handoff.requested` (this path does not start the wait timeout) |

{% hint style="warning" %}
"Visitor-facing" prompt text such as <mark style="color:blue;">Handoff notification message</mark> and <mark style="color:blue;">Queue waiting message</mark> is pushed to MaiAgent's own Web Chat front end and **is not delivered to your system via webhook**. When you receive `handoff.requested`, your system should display a prompt like "Connecting you to a human agent" to the visitor itself.
{% endhint %}

### 4. Turn on the handoff webhook <a href="#setup-handoff-webhook" id="setup-handoff-webhook"></a>

On the same tab → sub-tab <mark style="color:blue;">Notifications</mark> → enable <mark style="color:blue;">Webhook notifications (system integration)</mark>, and fill in:

* <mark style="color:blue;">Webhook URL</mark>: HTTPS only.
* <mark style="color:blue;">Signing secret</mark> (recommended): once set, every push includes an HMAC-SHA256 signature; see [Step 5](#step-handoff) for verification.

<mark style="color:blue;">Email notifications</mark> and <mark style="color:blue;">Notification center announcements</mark> are only sent when a conversation is assigned to a MaiAgent member, and are unrelated to this integration — you can turn them off.

{% hint style="info" %}
Handoff notifications (including the webhook) must be enabled for your organization by MaiAgent. If this section doesn't appear on the Notifications tab, contact your account representative.
{% endhint %}

## Step 1: Map Visitor Identity <a href="#step-identity" id="step-identity"></a>

Call the identity sync API with the user ID from your system to get that visitor's `contactId` in MaiAgent:

```bash
curl -X POST \
  'https://api.maiagent.ai/api/v1/web-chats/{webChatId}/setup-contact-credentials/' \
  -H 'Content-Type: application/json' \
  -d '{ "sourceId": "your-user-id", "name": "Jane Doe" }'
```

```json
{ "contactId": "c0ffee00-1111-2222-3333-444455556666" }
```

Calling with the same `sourceId` repeatedly returns the same `contactId` (idempotent) — store the `sourceId ↔ contactId` mapping in your user data. Use a non-guessable value for `sourceId`. See [Contact Identity Sync & Token Refresh](/tech/en/authorization-integration/contact-credentials-sync.md) for full details.

## Step 2: Create a Conversation <a href="#step-conversation" id="step-conversation"></a>

Create one conversation per visitor and **reuse it long-term** — MaiAgent maintains context per conversation:

```bash
curl -X POST 'https://api.maiagent.ai/api/v1/conversations/' \
  -H 'Authorization: Api-Key <your API key>' \
  -H 'Content-Type: application/json' \
  -d '{ "webChat": "<Web Chat ID>", "contact": "<contactId>" }'
```

Record `id` (conversation ID) and `inbox.id` (chat platform ID, used when setting up webhooks) from the response. See [Create Conversations and Messages](/tech/en/api-integration/dui-hua-yu-xun-xi.md) for response fields.

If you want each visit to start a fresh conversation (e.g. after a case is closed), just create a new conversation — the old conversation's history is retained.

## Step 3: Send a Visitor Message <a href="#step-send" id="step-send"></a>

```bash
curl -X POST 'https://api.maiagent.ai/api/v1/messages/' \
  -H 'Authorization: Api-Key <your API key>' \
  -H 'Content-Type: application/json' \
  -d '{
    "conversation": "<conversation ID>",
    "content": "I want to check my order status",
    "attachments": []
  }'
```

A `201` response only means the message was created — **the AI reply is pushed via Outgoing Webhook within seconds** (step 4); the HTTP response itself does not carry the reply. Upload attachments first to get an attachment object before including it in `attachments`; see [Presigned File Upload Mode](/tech/en/api-integration/api_knowledge.md).

## Step 4: Receive the AI Reply <a href="#step-receive" id="step-receive"></a>

Once the AI reply is created, MaiAgent sends a request to the Outgoing Webhook you configured. Using the standard format as an example, your endpoint receives:

```json
{
  "id": "2491074a-6d23-4289-af45-caa12531420e",
  "type": "outgoing",
  "content": "Your order #12345 is currently out for delivery and expected to arrive tomorrow.",
  "created_at": "2026-09-09T10:15:30.123456+00:00",
  "conversation": {
    "id": "8e44604a-8278-4c96-96b5-3e5a0548d738",
    "status": "open",
    "progress_status": "ai_processing",
    "auto_reply_enabled": true,
    "assignee": null
  },
  "contact": { "id": "c0ffee00-1111-2222-3333-444455556666", "name": "Jane Doe" },
  "sender": { "id": "…", "name": "AI Assistant", "type": "chatbot" },
  "attachments": []
}
```

Your system looks up the corresponding user by `contact.id` and the conversation by `conversation.id`, then converts `content` and any attachments into your channel's format to send to the visitor. Respond with 2xx; see [Webhook](/tech/en/api-integration/webhook.md) for the full field list, custom templates, and delivery behavior.

{% hint style="info" %}
If you need your own user ID or a downloadable attachment URL directly in the payload, use a **custom template** to output `contact.source_id` and `attachment.file.url` — see [Webhook › Custom Template](/tech/en/api-integration/webhook.md#custom-template) for an example.
{% endhint %}

## Step 5: AI Decides to Hand Off <a href="#step-handoff" id="step-handoff"></a>

Whenever a visitor message arrives, MaiAgent first uses the decision model to determine whether a human is needed. When the decision is "needed":

1. The conversation status changes to `queued`, `auto_reply_enabled` becomes `false`, **this message does not get an AI reply**, and subsequent messages are no longer answered by the AI either.
2. MaiAgent sends a `handoff.requested` event to your handoff webhook URL.

### Event Payload <a href="#handoff-payload" id="handoff-payload"></a>

```json
{
  "event": "handoff.requested",
  "id": "7d1e2f3a-4b5c-4d6e-8f90-1a2b3c4d5e6f",
  "occurred_at": "2026-09-09T10:15:30.123456+00:00",
  "conversation": {
    "id": "8e44604a-8278-4c96-96b5-3e5a0548d738",
    "url": "https://admin.maiagent.ai/conversations/index?conversationId=8e44604a-…"
  },
  "inbox": { "id": "1f9c1c1e-4d1a-4b1e-9d0e-7b2f4a5c6d7e" },
  "organization": { "id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d" },
  "contact": { "id": "c0ffee00-1111-2222-3333-444455556666" },
  "assignee": null
}
```

| Field                            | Description                                                                                                                                                                                  |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event`                          | Event name, see [Event Overview](#events) below                                                                                                                                              |
| `id`                             | Event identifier; retries send identical content, use this to de-duplicate                                                                                                                   |
| `occurred_at`                    | Event timestamp (ISO 8601); delivery order is not guaranteed, use this to sort                                                                                                               |
| `conversation.id` / `contact.id` | Match the conversation and visitor recorded in steps 1 and 2; `conversation.url` links to this conversation in the MaiAgent admin console                                                    |
| `inbox.id` / `organization.id`   | Chat platform and organization ID                                                                                                                                                            |
| `assignee`                       | The MaiAgent member assigned **at the time of the event**, as `{ "id" }` (a snapshot, unaffected by later changes); always `null` for `handoff.requested` and when your own agents take over |

Field naming and nesting are consistent with the message webhook in step 4 (snake\_case, related objects nested as `{ "id" }`), so a single receiving endpoint can handle both pushes. The payload only contains identifying information, not conversation content; all four event types share exactly the same fields — branch on `event`. See [Handoff Webhook Events](https://docs.maiagent.ai/api/preparation/handoff-webhook) in the API docs for the full spec and ready-to-run receiver examples.

### Delivery and Signing <a href="#handoff-delivery" id="handoff-delivery"></a>

* `POST`, `Content-Type: application/json`, 10-second timeout; a non-2xx response or connection failure is **retried every 60 seconds, up to 3 times**.
* When a signing secret is configured, the request includes `X-MaiAgent-Signature-256: sha256=<hex>`, an HMAC-SHA256 computed with the secret over the **raw request body (bytes)**. Verify against the raw body you received — don't parse and re-serialize first:

```python
import hashlib
import hmac


def verify_maiagent_signature(secret: str, raw_body: bytes, header_value: str) -> bool:
    expected = 'sha256=' + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header_value)
```

### After your system receives `handoff.requested` <a href="#after-triggered" id="after-triggered"></a>

* Create a case in your system, assign a human agent, and show the visitor a handoff prompt.
* From then on, visitor messages are handled by your agent within your own system. **You no longer need to send them into MaiAgent**; if you still want MaiAgent to keep a complete record, you can keep calling `POST /messages/` — the message is stored in the conversation and triggers the Incoming Webhook, but no AI reply is generated until the conversation returns to AI.
* Your human agent's replies are sent to the visitor directly by your system — no need to go through MaiAgent.

## Step 6: Human Service Ends, Return to AI <a href="#step-return" id="step-return"></a>

When the case is closed, call return-to-AI:

```bash
curl -X PATCH 'https://api.maiagent.ai/api/v1/conversations/{conversationId}/return-to-ai/' \
  -H 'Authorization: Api-Key <your API key>'
```

The conversation returns to `open`, `auto_reply_enabled` becomes `true` again, MaiAgent sends `handoff.returned_to_ai`, and subsequent visitor messages resume getting AI replies. The response is the updated conversation object.

{% hint style="warning" %}
The member the API key belongs to needs access to conversations on that chat platform. If <mark style="color:blue;">Wait timeout</mark> is not 0, MaiAgent automatically returns to AI and sends `handoff.queue_timeout` when the timeout expires — make sure this fits your workflow, or set it to 0 per the setup steps above. Conversations queued via <mark style="color:blue;">Accept messages</mark> outside service hours **do not start the wait timeout** — your system must always call `return-to-ai` to end them.
{% endhint %}

## Event Overview <a href="#events" id="events"></a>

| `event`                  | Trigger                                                                                                                                                                 | Meaning for your system                                                                             |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `handoff.requested`      | AI decides a human is needed, conversation enters the queue, AI stops replying                                                                                          | Your human agent should take over                                                                   |
| `handoff.assigned`       | Conversation is assigned to an agent in the MaiAgent admin console (a member takes over, transfers, or is auto-assigned in the console; a transfer sends another event) | If your agents are entirely in your own system, you won't receive this event                        |
| `handoff.returned_to_ai` | You call `return-to-ai`, or a member clicks "Return to AI Agent" in the admin console                                                                                   | AI resumes replying, you can close the case                                                         |
| `handoff.queue_timeout`  | Wait timeout expires, MaiAgent automatically returns the conversation to AI                                                                                             | AI has resumed replying; if your agent is still working on it, this is an anomaly worth alerting on |

Each event has a corresponding `event_type` in `GET /api/v1/conversations/{id}/events/` (`transfer_triggered` / `human_assigned` / `returned_to_ai` / `queue_timeout`), which can be used for reconciliation.

{% hint style="info" %}
Each event is sent as a separate background task, **delivery order is not guaranteed**, and retries can cause duplicates. De-duplicate by event `id`, sort by `occurred_at`, and treat `handoff.assigned` as implying handoff already occurred.
{% endhint %}

### Querying Current State via API <a href="#query-state" id="query-state"></a>

Besides webhooks, you can query who's currently handling a conversation at any time:

```bash
GET https://api.maiagent.ai/api/v1/conversations/{conversationId}/
```

`status` (`open` / `queued` / `resolved`), `autoReplyEnabled`, and `progressStatus` (`ai_processing` / `waiting_for_human` / `human_serving`) are enough to reconstruct state; `GET /api/v1/conversations/{conversationId}/events/` lists the handoff-related event history (`transfer_triggered`, `queued`, `human_assigned`, `returned_to_ai`, `queue_timeout`, etc.), useful for reconciliation or compensation.

## Kick-off FAQ <a href="#kickoff-faq" id="kickoff-faq"></a>

Customer service system vendors typically raise the following questions during kick-off; the answers are collected here and can be used directly as an appendix to your integration document.

### Environments and Paths <a href="#faq-environments" id="faq-environments"></a>

| Environment | Base URL                              |
| ----------- | ------------------------------------- |
| Staging     | `https://api-dev.maiagent.ai/api/v1/` |
| Production  | `https://api.maiagent.ai/api/v1/`     |

This integration uses a fixed set of paths: `POST /web-chats/{webChatId}/setup-contact-credentials/`, `POST /conversations/`, `POST /messages/`, `PATCH /conversations/{id}/return-to-ai/`; use `GET /conversations/{id}/` and `GET /conversations/{id}/events/` for reconciliation. Your account representative will provision the staging environment's organization, API key, and Web Chat.

### Authentication <a href="#faq-auth" id="faq-auth"></a>

* **You calling MaiAgent**: header `Authorization: Api-Key <key>`. The identity sync API needs no key — it's identified by `webChatId`.
* **MaiAgent pushing to you**: the message webhook carries the fixed header `X-Webhook-Secret` you configured; the handoff webhook carries an HMAC-SHA256 signature computed over the raw request body, `X-MaiAgent-Signature-256: sha256=<hex>`.

### Timeouts, Retries, and Rate Limits <a href="#faq-limits" id="faq-limits"></a>

| Direction                        | Timeout                                                             | Retry                                                                                                                 |
| -------------------------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| You call `POST /messages/`       | Synchronous 201 response; a 10-second client timeout is recommended | Fix the request first for 4xx; 5xx or a timeout means the result is uncertain — reconcile first, don't resend blindly |
| Message webhook (MaiAgent → you) | 30 seconds                                                          | **No retry**; persist the data before responding 2xx, de-duplicate by message `id`                                    |
| Handoff webhook (MaiAgent → you) | 10 seconds                                                          | Retried every 60 seconds on failure, up to 3 times; de-duplicate by event `id`                                        |

`POST /messages/` is not guaranteed idempotent: the server may have created the message even if the response is lost in transit. Confirm the outcome via conversation history and your own send logs first; if you can't confirm, resending blindly may create a duplicate message and trigger another AI reply.

Each API key can have a requests-per-minute (RPM) limit configured; unlimited by default. Provide your expected traffic before going live so your account representative can configure it.

### Source IP Allowlist <a href="#faq-egress" id="faq-egress"></a>

MaiAgent's outbound webhook IPs are fixed. If your receiving endpoint requires an allowlist, ask your account representative for the latest list for production and staging. MaiAgent has no outbound restrictions on your receiving endpoint's domain.

### Mapping Conversation Sessions <a href="#faq-session" id="faq-session"></a>

The key is the contact's `sourceId` (recommend `{platform}:{your user ID}` to avoid collisions across channels). Calling the identity sync API repeatedly with the same `sourceId` returns the same `contactId`; once created, a conversation has **no expiration** — you can reuse the same conversation ID long-term to maintain context, or create a new conversation for the same contact after a case is closed to start fresh.

### Handoff Decision Logic <a href="#faq-handoff-logic" id="faq-handoff-logic"></a>

The decision model judges based on the most recent N messages in the conversation, with default rules: visitor explicitly requests a human, the question is beyond what the AI can handle, the visitor is upset, or it involves an account operation that needs manual verification. Rules are adjusted in natural language via <mark style="color:blue;">Role instructions</mark> — you can add keywords, hand off when confidence is low, and so on; you can also configure <mark style="color:blue;">Service hours</mark> to decide whether to hand off outside of service hours. The decision result is the `handoff.requested` event.

### Multi-part Replies and Message Format <a href="#faq-message-format" id="faq-message-format"></a>

Each AI reply is pushed as one message webhook (one message per push), not batched; a single reply can contain multiple attachments. If your system requires an array format, use a custom template to output a single-element array. Standard support covers text (Markdown) and attachments (image / video / audio / file); channel-specific formats like buttons, cards, or quick replies are outside the standard scope — raise these requirements at kick-off for separate evaluation.

### Attachment URLs and Expiry <a href="#faq-attachments" id="faq-attachments"></a>

AI reply attachments, output via custom template as `attachment.file.url`, are signed URLs **valid for 1 hour** — fetch and re-store them immediately after receipt. For visitor-uploaded attachments, your system should first obtain a downloadable URL and include it in `attachments[]` when sending the message.

### Errors and Usage Queries <a href="#faq-observability" id="faq-observability"></a>

Requests, responses, and status codes for each message webhook push can be viewed on the <mark style="color:blue;">Webhook</mark> tab of the AI assistant page in the MaiAgent admin console; conversation state and handoff events can be reconciled via the conversation API and event history API; AI usage is under <mark style="color:blue;">Usage Statistics</mark> in the admin console. Failed handoff webhook pushes go to MaiAgent's monitoring alerts.

## Integration Checklist <a href="#checklist" id="checklist"></a>

* [ ] Admin console: Outgoing Webhook is configured and receiving AI replies
* [ ] Admin console: Human handoff is enabled, <mark style="color:blue;">Wait timeout</mark> is set per your workflow (0 recommended for external human agents)
* [ ] Admin console: Handoff webhook is enabled, the HTTPS endpoint is reachable, and signature verification passes
* [ ] Your system: `sourceId ↔ contactId ↔ conversationId` mapping is in place
* [ ] Your system: `handoff.requested` → creates a case and shows a handoff prompt; `handoff.returned_to_ai` → closes the case; `handoff.queue_timeout` → alerts or closes the case
* [ ] Your system: calls `return-to-ai` when human service ends
* [ ] Both webhook endpoints are idempotent: handoff events and message pushes are each de-duplicated by their own `id`
* [ ] If your network requires a source IP allowlist, request MaiAgent's outbound IPs from your account representative

## Related Pages <a href="#related" id="related"></a>

* [Handoff Webhook Events](https://docs.maiagent.ai/api/preparation/handoff-webhook) (API docs): full event spec, signature verification, ready-to-run receiver examples, and the pattern where the visitor stays on the MaiAgent channel while the human agent works in your system
* [Webhook](/tech/en/api-integration/webhook.md): message push format, custom templates, managing webhooks via API
* [Create Conversations and Messages](/tech/en/api-integration/dui-hua-yu-xun-xi.md): full conversation and message API fields
* [Contact Identity Sync & Token Refresh](/tech/en/authorization-integration/contact-credentials-sync.md): full spec for `setup-contact-credentials`
* [Presigned File Upload Mode](/tech/en/api-integration/api_knowledge.md): attachment uploads


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.maiagent.ai/tech/en/api-integration/customer-service-system-integration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
