Record a purchase
const url = 'https://app.mondochat.io/v1/server/purchases';const options = { method: 'POST', headers: { 'Mondochat-App-Id': '<Mondochat-App-Id>', Authorization: 'Bearer <token>', 'Content-Type': 'application/json' }, body: '{"buyer":"bob","currency":"EUR","external_ref":"order-1042","item":{"kind":"show","title":"Private show"},"price_minor":1500,"seller":"alice"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://app.mondochat.io/v1/server/purchases \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --header 'Mondochat-App-Id: <Mondochat-App-Id>' \ --data '{ "buyer": "bob", "currency": "EUR", "external_ref": "order-1042", "item": { "kind": "show", "title": "Private show" }, "price_minor": 1500, "seller": "alice" }'Records a purchase made outside the chat. Takes the app id and the server secret, and an Idempotency-Key header; a repeat of the external_ref is deduped. A missing buyer or seller is created from buyer_profile or seller_profile; without a profile a missing user answers 404, and a guest answers 422. It opens the conversation of the two when there is none, started by the buyer, and posts one purchase card from the buyer whatever the policy and even when either blocked the other. Users are created in the same transaction as the purchase, so a refused call creates nothing. See https://docs.mondochat.io/guides/commerce/.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”A purchase made outside the chat, recorded from your server.
object
The buyer, as on your site.
A user’s profile, as your server sets it.
object
Display name.
Per-user overrides carried in the perms claim; a null field changes nothing.
object
ISO 4217 currency of the price.
Your reference for the purchase; a repeat with the same one is deduped.
The price in minor units.
The seller, as on your site.
A user’s profile, as your server sets it.
object
Display name.
Per-user overrides carried in the perms claim; a null field changes nothing.
object
Responses
Section titled “Responses”Successful Response
A purchase of an item by a buyer from a seller.
object
The buyer’s id.
When the purchase was created.
ISO 4217 currency of the price.
The purchase’s id.
How it is paid: the app’s commerce.payment_mode, or external for a purchase recorded from your server.
The price in minor units.
The seller’s id.
pending until paid; insufficient when the balance was short.
Example
{ "buyer_id": "0199d6a0-1000-7000-8000-000000000002", "conversation_id": "0199d6a0-2000-7000-8000-000000000001", "created_at": "2026-11-01T09:30:00Z", "currency": "EUR", "external_ref": "order-1042", "id": "0199d6a0-7000-7000-8000-000000000001", "item": { "id": "private-show", "kind": "show", "title": "Private show" }, "mode": "server_charge", "price_minor": 1500, "seller_id": "0199d6a0-1000-7000-8000-000000000001", "status": "paid"}Problem
An RFC 9457 problem: the body of every error answer.
object
The stable error code to branch on, such as policy_denied.
What went wrong this time, when there is more to say.
For validation, one entry per invalid field.
One invalid field.
object
The path to the field.
What is wrong with it.
The path of the request.
For policy_denied and limit_reached, the rule or limit that refused the request; for forbidden, a short cause such as you_blocked; for banned, temporary when the ban expires.
The HTTP status code.
A short summary of the problem.
A URL that names the problem, https://app.mondochat.io/problems/<code>.
Example
{ "code": "policy_denied", "detail": null, "instance": "/v1/conversations/0199d6a0-2000-7000-8000-000000000001", "reason": "pins", "status": 403, "title": "Policy denied", "type": "https://app.mondochat.io/problems/policy_denied"}