Webhooks
Have purser POST signed events to your own system when conversations start, are handed to a person, end or are rated, when a refund or compensation finishes, and when feedback arrives.
Webhooks tell your own system what happened in purser. For example, you can open a ticket in your CRM when a conversation is handed to a person, or record a rating in your data warehouse. purser sends an HTTPS POST to a URL you choose, signed the same way as the refund endpoint.
Adding an endpoint
Open Setup (接入) → Webhooks. This is for owners and admins only.
- Enter your URL. It must be a public
https://address. - Tick the events it should receive.
- Click Add (添加). The signing secret is shown once. Copy it into your server's environment, for example
PURSER_WEBHOOK_SECRET. - Click Send a test (发送测试). purser sends a signed
pingand shows the status code your server returned.
A workspace can have up to 10 endpoints. Each endpoint has:
- Enabled (启用): turn it off to pause deliveries.
- Rotate secret (更换密钥): the new secret is shown once, and the old one stops working immediately.
- Delivery log (投递记录): the last 30 deliveries, each with its status and response code.
Events
| Event | When | data |
|---|---|---|
conversation.created | A conversation starts, on any channel | conversationId, channel, status, customerId, email, language, assignedUserId |
conversation.handoff | The conversation starts waiting for a person: in the live queue (queued) or as a ticket (awaiting_human) | same as above |
conversation.closed | The conversation ends | same as above |
conversation.rated | The customer rates the conversation | conversationId, score (1–5), comment, handledBy (ai or the agent's user ID) |
action.completed | A refund or compensation is carried out, or fails | actionId, kind (refund, coupon, points, replacement, exchange, address_change, order_cancel), status (succeeded or failed), orderId, customerId, amount, currency, conversationId |
feedback.created | New product feedback arrives | feedbackId, number, body, categoryId, source, email, customerId |
customerId is your own customer ID, and only for customers who were identified. Anonymous visitors give null.
Some things are never sent:
- conversations in Try it (试聊);
- emails set aside as not from a customer (newsletters, platform notifications, auto-replies).
Request format
POST <your URL>
content-type: application/json
user-agent: purser-webhooks/1
purser-signature: t=<unix seconds>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>
purser-event: conversation.handoff
purser-delivery: <delivery ID>{
"id": "<delivery ID>",
"event": "conversation.handoff",
"createdAt": 1790000000000,
"workspaceId": "<workspace ID>",
"data": {
"conversationId": "01K…",
"channel": "web",
"status": "queued",
"customerId": "cus_mia",
"email": null,
"language": "en",
"assignedUserId": null
}
}Check the signature the same way as for the refund endpoint (see Checking the signature):
- compute it over the raw body;
- refuse it if
tis more than 5 minutes from your clock; - compare in constant time.
Answering, retries and order
- Any
2xxresponse counts as delivered. Anything else, a timeout (10 seconds) or a network error is retried. - Retries back off after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 12 hours and 24 hours. After 8 tries the delivery is marked failed.
- The endpoint's card shows how many deliveries in a row have failed. Turning the endpoint back on resets that count.
- Deliveries can arrive more than once and out of order. Use
idto drop duplicates, and trustdata.statusandcreatedAtover the order of arrival. - Answer quickly, and do any slow work after you have answered.
- Delivery records are kept for 14 days.
Refund endpoint (Actions API)
A signed HTTPS endpoint your custom store implements so purser can ask for a refund amount and start a refund: request format, signature check, idempotency, retries and reporting the outcome.
Connect your own AI assistant over MCP
Let Claude, Cursor or any MCP-capable assistant read conversations and customers, tag, add knowledge and, if you allow it, approve refunds, acting as you.