---
title: "Send a customer message and get the reply"
method: POST
path: "/conversations/{id}/messages"
tags: ["Chat"]
---

# Send a customer message and get the reply

`POST /conversations/{id}/messages`

## Request

- Base URL: `https://api.hypamoon.com/api/v1`
- URL: `https://api.hypamoon.com/api/v1/conversations/{id}/messages`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://app.hypamoon.com/oauth/authorize`, token URL `https://api.hypamoon.com/oauth/token`, scopes: `chat:write`)

Sends what the customer typed and returns the assistant's reply in the same response. With `Accept: text/event-stream` the reply streams as Server-Sent Events: `delta` events with pieces of text, then one `done` event with the same body as the JSON response (or an `error` event with a problem+json). The text in `done.reply` is the reply as stored; display that text. The customer's text is never treated as an instruction to the assistant, and the assistant never shares its instructions or keys. In a chat the assistant cannot book, transfer or send anything: it takes a message, which ends up in the summary. At most 2000 characters per message, 30 turns per conversation (then it closes) and 12 messages per minute per conversation. In live mode, every assistant reply is billed per use, usually about one cent a reply: first from the AI credit in your plan, then from your prepaid balance (the greeting is free; a reply that fails costs nothing). The summary of a conversation is charged the same way when it closes. In test mode the first replies of the day are free, after that they are deducted from the balance of your live project. Send an Idempotency-Key (one per customer message) so a retry returns the same reply instead of a second turn.

## Path parameters

- `id` string, uuid, required

## Headers

- `Idempotency-Key` string
- `Accept` 'application/json' | 'text/event-stream'

## Request body

- ChatMessageInput: One message from the customer.
  - `text` string, required: What the customer typed, at most 2000 characters. Send it as is; it is never treated as an instruction to the assistant.

## Response `200`

The customer's message and the assistant's reply.

- ChatTurn: One turn: the customer's message and the assistant's reply.
  - `message` object, required: The customer's message as stored.
    - `id` string, uuid, required: The id of the message.
    - `role` 'customer' | 'assistant', required: Who wrote it: the customer, or the assistant (also the fixed greeting).
    - `text` string, required: The text.
    - `created_at` string, date-time, required: When the message was stored.
  - `reply` object, required: The assistant's reply. Show this text to the customer.
    - `id` string, uuid, required: The id of the message.
    - `role` 'customer' | 'assistant', required: Who wrote it: the customer, or the assistant (also the fixed greeting).
    - `text` string, required: The text.
    - `created_at` string, date-time, required: When the message was stored.
  - `conversation` object, required: The conversation after this turn. status closed means the turn limit was reached.
    - `id` string, uuid, required: The id of the conversation.
    - `channel` 'chat' | 'widget', required: The channel: chat when your app started it with an API key, widget when a visitor started it in the chat widget on a website (public chat token).
    - `status` 'open' | 'closed', required: open: takes messages. closed: takes no more messages; the summary follows.
    - `reference` string, nullable, required: Your own id for this conversation, as you sent it.
    - `metadata` object, required: Your metadata, as you sent it. The assistant never sees it.
    - `customer` object, required: What your app told us about the customer when the conversation started.
      - `name` string, nullable, required
      - `phone` string, nullable, required
      - `email` string, nullable, required
    - `language` string, required: The language the assistant opened in (nl, en, de, fr or es). It replies in the customer's language when that is one of its languages.
    - `turns` integer, required: Customer messages answered so far.
    - `max_turns` integer, required: After this many turns the conversation closes (close_reason turn_limit).
    - `created_at` string, date-time, required: When the conversation started.
    - `last_message_at` string, date-time, nullable, required: When the last message was sent.
    - `closed_at` string, date-time, nullable, required: When the conversation closed.
    - `close_reason` 'closed' | 'inactive' | 'turn_limit' | 'null', nullable, required: closed: POST /conversations/{id}/close. inactive: no message for 30 minutes. turn_limit: max_turns reached.
    - `has_summary` boolean, required: Whether the summary is ready. Fetch it with GET /conversations/{id}.
    - `summary_ready_at` string, date-time, nullable, required: When the summary was ready.
    - `test` boolean, required: true for a conversation in test mode (hm_test_): real replies, free, with a low daily limit.

## Other responses

- `400`: Bad Request: idempotency_key_invalid, invalid_json.
- `401`: Unauthorized: unauthorized, missing_api_key, invalid_api_key, api_key_revoked, project_deleted.
- `402`: Payment Required: payment_mandate_missing, billing_blocked, insufficient_balance, test_free_replies_used.
- `403`: Forbidden: project_not_enabled, key_mode_mismatch, missing_scope, verification_required.
- `404`: Not Found: not_found.
- `409`: Conflict: conversation_closed, conversation_turn_limit_reached, conversation_busy, idempotency_key_reused, idempotency_request_in_progress.
- `422`: Unprocessable Content: validation_failed, company_details_missing, spend_cap_missing.
- `429`: Too Many Requests: rate_limited.
- `500`: Internal Server Error: internal_error.
- `502`: Bad Gateway: upstream_error.
- `503`: Service Unavailable: service_unavailable.

---

[API](https://skmtc.dev/hypamoon/apis/hypamoon-api.md) · [All operations](https://skmtc.dev/hypamoon/apis/hypamoon-api/llms.txt) · [OpenAPI document](https://skmtc.dev/hypamoon/apis/hypamoon-api/revisions/9f0b90004c06?raw)
