For the complete documentation index, see llms.txt. This page is also available as Markdown.

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

Connect a customer service system or chat platform to MaiAgent as an AI engine via API: end-to-end specifications for message exchange, handoff to your human agents when AI determines it is needed, an

This page is for integrators who already have their own customer service system or chat frontend (with channels such as their own website, LINE, or Messenger connected on their side) and want to use MaiAgent as an AI engine: your system sends visitor messages to MaiAgent and receives AI replies; when AI determines that human assistance is needed, your human agents take over, then return the conversation to AI when service ends.

The integration uses only MaiAgent's existing public APIs and two sets of Webhooks. No dedicated interface needs to be developed for an individual customer service system.

Two Integration Scenarios

Scenario
Where visitors chat
Where human agents work
How to integrate

Scenario A: MaiAgent as an AI engine

Your system (with your website, LINE, and other channels connected on your side)

Your system

Complete Setup, then follow Step 1 through Step 6

Scenario B: Only human agents work in your system

MaiAgent's conversation platform (Web Chat, LINE Official Account, etc. connected to MaiAgent)

Your system

Complete Setup, then follow Scenario B

Both scenarios share the same human handoff events, event list, and state queries. The integration overview and Steps 1–6 below describe Scenario A.

Integration Overview

Responsibilities

Party
Responsibilities

Your system

Channel integration, visitor interface, tickets and agent seats, storing and displaying conversation history; sending visitor messages to MaiAgent, receiving Webhooks, and calling the return-to-AI API when human service ends

MaiAgent

AI replies, maintaining conversation context, using an LLM to determine whether human handoff is needed, and sending human handoff and return-to-AI events

Setup

Complete all of the following in the MaiAgent admin console, once per conversation platform.

1. Create a Web Chat Conversation Platform and Obtain Credentials

API integration uses a Web Chat conversation platform. You need:

  • API key: See Quickstart for how to obtain one.

  • Web Chat ID: Customer Service Conversations → Conversation Platforms → edit the API platform → Integration and Login → the API Information card at the bottom of Webhook Settings. The value is read-only and can be copied; see Basic Conversation Platform Settings in the user manual.

2. Configure an Outgoing Webhook (Receive AI Replies)

Customer Service Conversations → Conversation Platforms → edit the platform → Webhook Settings → Add Webhook. Select Outgoing as the type and enter your reply receiver URL as the endpoint. Select MaiAgent Standard Format; if your system requires a fixed JSON structure, select Custom Template. See Webhook for fields and payloads.

3. Enable Human Agent Handoff

On the same conversation platform → Human Handoff Settings. See Human Handoff Settings in the user manual for each field's meaning and the settings screen. When human agents work in your system, use these recommended settings:

Setting
Recommendation when human agents work in your system

Enable Human Agent Handoff

Enable

Evaluation rules (Role Instructions) under Human Handoff Conditions

Start with the default rules: the visitor explicitly requests a human, the issue exceeds AI capabilities, the visitor is upset, or account operations require manual verification. Then adapt them to your business, for example by adding keywords or handing off when confidence is low

Dispatch Settings → Dispatch Mode

Select Handover. MaiAgent will not assign the conversation to admin console members. It stays queued for your system to take over

Dispatch Settings → Queue Timeout

Check No Timeout (available only in Handover mode). The conversation stays queued until you call return-to-AI; MaiAgent will not return it to AI on its own

Dispatch Settings → Queue Limit

Set according to your support capacity (1–500). When the queue is full, new human handoff requests are not triggered: the message receives no AI reply, and no handoff.requested event is sent

Service Hours

Enable as needed. With Display Offline Message, no human handoff occurs outside service hours: the message receives no AI reply and no handoff.requested event is sent (the offline message is sent only to the Web Chat frontend; your system must handle the notice outside service hours). With Accept Messages, the conversation still enters the queue and sends handoff.requested, without starting the queue timeout

When configuring the conversation platform via API, Handover mode with no timeout corresponds to dispatchMode: "handover" and assignmentQueueTimeout: 0.

4. Enable the Human Handoff Webhook

On the same tab → the Notifications subtab → enable Webhook Notifications (System Integration) and enter:

  • Webhook URL: HTTPS only.

  • Signing Secret (Optional) (recommended): When set, each delivery includes an HMAC-SHA256 signature. See Delivery and Signatures for verification.

Email Notifications and Notification Center Announcements are sent only when a conversation is assigned to a MaiAgent member. They are unrelated to this integration and can be disabled.

The conversation platform administrator enables these three notification switches in the admin console; no separate application is required. See Human Handoff Notifications in the user manual for the settings screen.

Step 1: Map Visitor Identities

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

Repeated calls with the same sourceId return the same contactId (idempotent). Store the sourceId ↔ contactId mapping in your user data. Use an unguessable value for sourceId. See Contact Identity Sync and Token Updates for details.

Step 2: Create a Conversation

Create one conversation for each visitor and reuse it over time. MaiAgent maintains context per conversation:

Record id (conversation ID) and inbox.id (conversation platform ID, used when configuring Webhooks) from the response. See Creating Conversations and Messages for response fields.

If you want each visit to start a fresh conversation (for example, after a ticket is closed), create a new conversation. The old conversation history remains available.

Step 3: Send Visitor Messages

A 201 response only means the message was created. The AI reply is delivered within a few seconds via the Outgoing Webhook (Step 4); the HTTP response itself does not contain the reply. For attachments, upload them first to obtain attachment objects, then include them in attachments. See Presigned File Upload Mode.

Step 4: Receive AI Replies

After creating an AI reply, MaiAgent sends a request to your configured Outgoing Webhook. For example, in the standard format your endpoint receives:

Your system uses contact.id to find the user and conversation.id to find the conversation, then converts content and attachments to your channel's format and sends them to the visitor. Respond with 2xx. See Webhook for all fields, custom templates, and delivery behavior.

If you need your own user ID or downloadable attachment URLs directly in the payload, use a Custom Template to output contact.source_id and attachment.file.url. See Webhook › Custom Templates for examples.

Step 5: AI Determines a Human Handoff Is Needed

For each incoming visitor message, MaiAgent first uses an evaluation model to determine whether human assistance is needed. If it determines that assistance is needed:

  1. The conversation status changes to queued and auto_reply_enabled becomes false. This message receives no AI reply, and AI stops replying to subsequent messages as well.

  2. MaiAgent sends a handoff.requested event to your human handoff Webhook URL.

Event Payload

See “Event Format” in the API documentation for Human Handoff Webhook Events for the field table and JSON examples. Key points for this integration:

  • All four event types have exactly the same fields. Route them by event (see the event list below).

  • conversation.id and contact.id correspond to the conversation and visitor recorded in Steps 1 and 2.

  • Deduplicate by event id and order by occurred_at; the payload contains identifiers only, with no conversation content.

  • assignee is the MaiAgent member assigned at the time of the event; it is always null for handoff.requested and when your agents take over.

  • Field names and nesting match the message Webhook in Step 4, so the same receiver can handle both sets of deliveries.

Delivery and Signatures

POST, Content-Type: application/json, with a 10-second timeout. Non-2xx responses or connection failures are retried every 60 seconds, up to 3 retries. When a signing secret is configured, requests include X-MaiAgent-Signature-256: sha256=<hex>, whose value is the HMAC-SHA256 of the raw request body computed with the secret. See “Signature Verification” and the Minimal Receiver Example in the API documentation for Human Handoff Webhook Events for verification code and a receiver you can run directly.

After Your System Receives handoff.requested

  • Create a ticket in your system, assign a human agent, and display a handoff prompt to the visitor.

  • Your agents then handle visitor messages in your system. You can stop sending them to MaiAgent. If you still want MaiAgent to retain the full history, keep calling POST /messages/: messages are stored in the conversation and trigger the Incoming Webhook, but no AI replies are generated until the conversation returns to AI.

  • Your system sends human agent replies directly to the visitor; they do not need to pass through MaiAgent.

Step 6: Return to AI When Human Service Ends

When the ticket is resolved, call return-to-AI:

The conversation returns to open, auto_reply_enabled returns to true, and MaiAgent sends handoff.returned_to_ai. AI resumes replying to subsequent visitor messages. The response is the updated conversation object.

Scenario B: Visitors on MaiAgent's Conversation Platform, Human Agents in Your System

Visitors chat with the Agent through MaiAgent's conversation platform, while human agents reply from your customer service system only after handoff. Visitor messages already enter MaiAgent, so your system does not need Steps 1–3. Instead, use message Webhooks to bring messages into your system during human handoff, then use the API to write agent replies back to the conversation for bidirectional sync.

Complete setup on the conversation platform used by visitors: Enable Human Agent Handoff (Handover mode + No Timeout) and Enable the Human Handoff Webhook are the same as Scenario A. For Message Webhooks, add both Incoming (visitor messages) and Outgoing (Agent or human agent replies). Writing human agent replies back and returning to AI require an API key; see Quickstart to obtain one.

Integration Flow

  1. Detect the start of human handoff: When you receive handoff.requested, open a ticket or create a session in your system using conversation.id, and record contact.id. The event contains no conversation text. To retrieve the conversation before handoff, use conversation.id to call List Messages in the API documentation. If you later receive handoff.assigned, the conversation has been assigned to a member in the MaiAgent admin console, identified by assignee.id.

  2. Receive visitor messages and human agent replies: Each message Webhook payload includes the current conversation state. Process only messages where conversation.auto_reply_enabled is false to skip traffic while the Agent is replying automatically. Use sender.type to distinguish visitors (contact), human agents (user), and the Agent (chatbot). See Webhook › Field Definitions.

  3. Write human agent replies back to the conversation: Call POST /api/v1/messages/outgoing/ with your API key, passing conversation and content. MaiAgent sends the message to the visitor's conversation platform. The sender is the member who owns the API key, and that member must have conversation access permissions for the platform. See Send Proactive Messages in the API documentation for fields.

  4. End human handoff: After service is complete, call return-to-ai (as in Step 6) to let the Agent take over again. Whether you call the API or a member clicks “Return to AI Agent” in the admin console, you receive handoff.returned_to_ai. Use it to close the session in your system.

Call Examples

(1) Message Webhook received during human handoff (MaiAgent standard format, excerpt): auto_reply_enabled set to false means a human is handling the conversation; sender.type set to contact means it is a visitor message.

(2) Write a human agent reply back to the conversation: Pass only conversation and content. The message is sent to the visitor's conversation platform as the member who owns the API key.

(3) Combine all three steps (Python, requests):

Notes

  • Human agent replies written via API are also sent once through the Outgoing message Webhook (sender.type is user). Deduplicate by message id to avoid displaying them twice in your system.

  • handoff.assigned is sent again when the conversation is transferred to another member, with assignee.id identifying the new owner. Update the existing session using conversation.id instead of opening another ticket.

  • Message Webhooks and human handoff Webhooks use different verification methods. See Pre-integration FAQ › Authentication.

Event List

event

Trigger

Meaning for your system

handoff.requested

AI determines human assistance is needed; the conversation enters the queue and AI stops replying

Your human agents take over

handoff.assigned

The conversation is assigned to a human agent member in the MaiAgent admin console (a member takes over, transfers it, or is assigned automatically; a transfer sends another event)

You will not receive this event if all human agents work in your system

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 ticket

handoff.queue_timeout

The queue timeout expires and MaiAgent automatically returns the conversation to AI

AI has resumed replying; if your agents are still handling it, this is an anomaly that requires an alert

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

Events are sent by separate background tasks. Arrival order is not guaranteed, and retries may produce duplicates. Deduplicate by event id, order by occurred_at, and treat handoff.assigned as implicitly indicating that handoff has already been triggered.

Query the Current State via API

In addition to Webhooks, you can query who is currently handling a conversation at any time:

status (open / queued / resolved), autoReplyEnabled, and progressStatus (ai_processing / waiting_for_human / human_serving) are sufficient to reconstruct the state. GET /api/v1/conversations/{conversationId}/events/ lists human handoff event records (transfer_triggered, queued, human_assigned, returned_to_ai, queue_timeout, etc.) for reconciliation or recovery.

Pre-integration FAQ

Customer service system vendors usually ask the following questions at kick-off. The answers are collected here and can be used directly as an appendix to the integration document shared by both parties.

Environments and Paths

Environment
Base URL

Test

https://api-dev.maiagent.ai/api/v1/

Production

https://api.maiagent.ai/api/v1/

The paths used by this integration are fixed: POST /web-chats/{webChatId}/setup-contact-credentials/, POST /conversations/, POST /messages/, and PATCH /conversations/{id}/return-to-ai/; use GET /conversations/{id}/ and GET /conversations/{id}/events/ for reconciliation. Your integration contact will create and provide the organization, API key, and Web Chat in the test environment.

Authentication

  • Your calls to MaiAgent: Use the header Authorization: Api-Key <KEY>. The identity sync API requires no key; it identifies the platform by webChatId.

  • MaiAgent deliveries to you: Message Webhooks include your configured static X-Webhook-Secret header; human handoff Webhooks include the HMAC-SHA256 signature X-MaiAgent-Signature-256: sha256=<hex>, computed over the raw request body.

Timeouts, Retries, and Rate Limits

Direction
Timeout
Retries

You call POST /messages/

Returns 201 synchronously; a 10-second client timeout is recommended

Correct the request for 4xx errors; a 5xx error or timeout means the outcome is uncertain. Reconcile first rather than immediately resending

Message Webhook (MaiAgent → you)

30 seconds

No retries; persist the message before returning 2xx, and deduplicate by message id

Human handoff Webhook (MaiAgent → you)

10 seconds

On failure, retries every 60 seconds, up to 3 times; deduplicate by event id

POST /messages/ does not guarantee idempotency: the server may have created the message even if the response was lost in transit. Check conversation records and your own submission logs to confirm the outcome first. If you cannot confirm it, resending directly may create duplicate messages and trigger another AI reply.

Each API key can have a requests-per-minute (RPM) limit; by default, there is no limit. Before going live, provide your estimated traffic to your integration contact to configure the limit.

Source IP allowlist

MaiAgent uses fixed outbound IP addresses for Webhook delivery. If your receiver requires an allowlist, ask your integration contact for the latest production and test environment lists. MaiAgent places no outbound restrictions on your receiver's domain.

Conversation session mapping

The key is the contact's sourceId (use {platform}:{your user ID} to avoid collisions across channels). Repeated calls to the identity synchronization API with the same sourceId return the same contactId. Once created, a conversation has no expiration limit. You can reuse the same conversation ID long term to maintain context, or create a new conversation for the same contact after closing a case to start afresh.

Human handoff decision logic

The decision model evaluates the most recent N messages in the conversation. Default rules cover visitors explicitly requesting a human, questions beyond the AI's capabilities, upset visitors, and account-related operations requiring manual verification. Adjust these rules in natural language in Role Instructions, adding conditions such as keywords or handoff when confidence is low. You can also configure Service Hours to determine whether handoff occurs outside service hours. The decision produces a handoff.requested event.

Multipart replies and message formats

Each AI reply is delivered as one message Webhook (one message per request), without batching; a reply can contain multiple attachments. If your system requires an array, use a custom template to output a single-element array. Standard support covers text (Markdown) and attachments (images/videos/audio/files). Channel-specific formats such as buttons, cards, and quick replies are outside the standard scope; raise these requirements at kick-off for a separate assessment.

Attachment URLs and lifetime

Use a custom template to output attachment.file.url for AI reply attachments. These are signed URLs valid for 1 hour; download and save the files as soon as you receive them. For visitor-uploaded attachments, your system must first obtain a downloadable URL and include it in attachments[] when sending the message.

Error and usage queries

View each message Webhook delivery's request, response, and status code in the Webhook tab on the Agent page in the MaiAgent console. Use the conversation API and event records API to query and reconcile conversation status and human handoff events. AI usage is available under Usage Statistics in the console. Failed human handoff Webhook deliveries trigger MaiAgent monitoring alerts.

Integration checklist

Last updated

Was this helpful?