Accessary Embedding
Embed the customer service widget into your website with just one line of code.
Get the Embed Code
Log in to the merchant dashboard → Channel Settings → Embed Code, and copy your exclusive embed code:
<script>
window.$aicrs = window.$aicrs || { q: [] };
</script>
<script async src="https://your-support-domain.com/widget/loader.js" data-wk="YOUR_WIDGET_KEY"></script>
Paste this code before the </body> tag on every page of your website. The widget will display a chat bubble in the bottom-right corner of the page; visitors can click it to start a consultation.
Domain Whitelist
To prevent misuse of the widget, it will only work on domains you have registered. In the merchant dashboard → Channel Settings → Domain Whitelist, add your website domain(s) (multiple domains are supported). Domains not registered will silently fail to load the widget, without affecting your page.
Reset widget_key
If you suspect the key has been compromised, you can reset it in the channel settings. Once reset, the old key becomes immediately invalid, and you must update the embed code on your website accordingly.
FAQ
- The widget is not showing? Check if the current domain is in the whitelist, if the widget_key matches the one in the dashboard, and if the account is within the service period.
- Does it affect website speed? The loader is under 1KB and loads asynchronously, without blocking your page rendering.
identify Member Integration
After a visitor logs in on your website, calling identify with member information will associate the browser session with this member in the customer service system — agents can directly see the member's identity, and visits from multiple devices will be merged into the same visitor.
Calling method
Call it on your page after determining the user is logged in:
$aicrs.identify({
externalId: 'U10086', // Required, the unique identifier of the user in your system
name: 'Jane Doe', // Optional, display name
phone: '138****0000', // Optional
email: 'user@example.com', // Optional
hash: 'HMAC signature computed server-side', // Required, anti-forgery
custom: { vip: 'gold' } // Optional, additional fields, visible on the agent side
})
Signature algorithm
hash must be calculated on your server-side (widget_secret should not appear in front-end code):
hash = hexadecimal lowercase of HMAC-SHA256(widget_secret, externalId)
widget_secret can be viewed in Merchant Backend → Channel Settings → Embed Code, and it is reset together with widget_key.
Node.js example:
const crypto = require('crypto')
const hash = crypto.createHmac('sha256', WIDGET_SECRET).update(externalId).digest('hex')
Verification result
Visitors with a successfully verified signature will display a "Verified" label on the agent side; if the signature verification fails, the identify call will be ignored and the visitor will remain anonymous, without errors interrupting your page.
Webhook Event Push
When key business events occur, the system pushes JSON messages to your configured callback address to help you synchronize customer service data to your own system.
Configuration
Merchant Panel → Data & System → Webhook: Fill in the callback URL (must be HTTPS) and the signature key secret, and select the event types to subscribe to. After saving, you can click "Send Test Event" for immediate integration testing.
Request Format
Each push is a POST request:
POST your callback URL
Content-Type: application/json
X-AICRS-Event: event type
X-AICRS-Signature: HMAC-SHA256(secret, request body) in lowercase hexadecimal
Request body structure:
{
"event": "message.created",
"tenant_id": 129,
"timestamp": 1784500000,
"data": { "object snapshot": "..." }
}
Event Types
| Event | Trigger Condition |
|---|---|
| message.created | New message (visitor/agent/AI) |
| conversation.updated | Conversation status/assignment/tag change |
| ticket.created | New ticket |
| ticket.updated | Ticket status transition |
| leave_message.created | New offline message |
Signature Verification and Retry
After receiving the push, calculate HMAC-SHA256 with the secret against the original request body and compare it with X-AICRS-Signature. If they do not match, discard the request.
A return of 2xx from your interface is considered successful. In case of failure, the system will retry with intervals of 1 minute / 5 minutes / 15 minutes for a total of 3 times. If still unsuccessful, it will be marked as failed. You can view the failure reason in the delivery records in the backend and manually troubleshoot.
Open API
The Open API is used to read customer service data from your system, create tickets, and isolate by merchant.
Authentication
Merchant backend → Data and System to generate API Key (starts with ak_, the plain text is only displayed once when generated, please keep it safe; old Keys become immediately invalid after resetting).
Include the request header for all requests:
Authorization: Bearer ak_YourKey
Rate Limiting
Each Key allows a maximum of 120 requests per 60 seconds. Exceeding this will return 429.
API List
| Method | Path | Description |
|---|---|---|
| GET | /api/open/v1/conversations | Conversation list (paginated) |
| GET | /api/open/v1/conversations/{id} | Conversation details (including messages) |
| GET | /api/open/v1/visitors | Visitor list |
| GET | /api/open/v1/visitors/{id} | Visitor details |
| GET | /api/open/v1/tickets | Ticket list |
| POST | /api/open/v1/tickets | Create a ticket |
| GET | /api/open/v1/tickets/{id} | Ticket details |
| POST | /api/open/v1/tickets/{id}/comments | Add ticket comments |
| GET | /api/open/v1/leave-messages | Leave message list |
Example:
curl -H "Authorization: Bearer ak_xxx" \
"https://YourCustomerServiceDomain/api/open/v1/conversations?page=1"
Notes
- All responses are in JSON format. List interfaces support the
pagepagination parameter. - The current version does not support sending messages to visitors via the API.
- The API will also be suspended if the merchant account is disabled or the service expires.
Error Code Reference
All API error responses follow a unified JSON structure:
{ "code": "error_code", "message": "Chinese message" }
Mapping between HTTP status codes and code:
| HTTP Status | code | Meaning | Common Causes |
|---|---|---|---|
| 400 | bad_request | Request parameter error | Missing fields, invalid format |
| 401 | unauthorized | Not authenticated or authentication expired | Missing, expired, or reset Key/Token |
| 403 | forbidden | No access permission | Cross-merchant access, account suspended, service expired |
| 404 | not_found | Resource not found | Incorrect or deleted id |
| 409 | conflict | Status conflict | Duplicate creation, resource occupied |
| 413 | body_too_large | Request body too large | Exceeding upload/body size limits |
| 429 | rate_limited | Rate limit triggered | Exceeding 120 requests per Key per 60 seconds |
| 50: | internal | Internal service error | Retry later; if persistent, contact technical support |
Handling suggestions:
- 401/403: Check if the Key is valid and the account's service status.
- 429: Retry after
Retry-Afteror using a backoff strategy. - 5xx: Safe to retry for idempotent operations; for non-idempotent actions, check the status first before retrying.
CRM Open Interface
Customer and lead data read and write via Open API (/api/open/v1, Bearer ak_ key, generated in the merchant backend under "Data and System → API").
Customer
| Method | Path | Description |
|---|---|---|
| GET | /api/open/v1/customers | Customer list, supports page, kw (name/phone/email), and stage_id filters |
| POST | /api/open/v1/customers | Create customer: name is required, phone/email/company/external_id/custom fields are optional |
| GET | /api/open/v1/customers/{id} | Customer details (including contact info, stage, owner, and custom fields) |
| PUT | /api/open/v1/customers/{id} | Update customer profile and stage |
| GET | /api/open/v1/customers/{id}/follows | Follow-up record list |
| POST | /api/open/v1/customers/{id}/follows | Write follow-up: content is required, next_at for scheduling the next follow-up is optional |
Deduplication rules are consistent with the backend: external_id > phone number > email. If a match is found, it will be merged into the existing customer instead of creating a duplicate record.
Rate limiting: Each Key allows 120 requests per 60 seconds. Exceeding this will return 429.
Customer Event Push
Customer lifecycle events use the existing Webhook channel (subscribe via the merchant backend "Data & System → Webhooks"), with the signature and retry mechanism consistent with message events (X-AICRS-Signature HMAC-SHA256, exponential backoff retry).
| Event | Trigger Timing |
|---|---|
customer.created | Account creation (manual, API, first-time merge via visitor identification) |
customer.stage_changed | Customer stage change (including Kanban drag-and-drop and API update) |
deal.won | Deal marked as won |
customer.imported | Bulk import completed (payload includes success/failure counts) |
Payload format: {"event":"customer.created","data":{...customer object...},"ts":1690000000}. A 2xx response confirms receipt; non-2xx responses or timeouts will trigger retries according to the backoff strategy.