Skip to content

Chat Events

Chat events provide real-time messaging between auction participants and staff during a live auction. Both events below are planned in the current server build; the socket chat.send and chat.typing contracts are part of the documented protocol but no route is registered yet.

Reference: rooms.md · errors.md · rate-limits.md


Event list

Event Direction Status
chat.send Client → Server Planned
chat.typing Client → Server Planned

Chat is delivered within a room (auction:<cycleId> by default). The server validates message size and rate, persists (when enabled), and rebroadcasts the message to every other member of the room.


chat.send

Description

Sends a chat message to the auction room. The server records the message and emits it to all other room members. The sender does not receive its own message back (the acknowledgement confirms delivery).

Direction

Client → Server

Roles Allowed

All roles subscribed to the auction (participants and staff).

Permissions Required

chat:send (planned).

Request Schema

Field Type Required Description
type string Yes chat.send
data.cycleId string Yes Auction cycle to which the message belongs.
data.body string Yes Message text, trimmed, max 2000 chars.
data.clientMessageId string Yes Client-generated id for idempotency and echo control.

Response Schema

Field Type Description
messageId string Server-assigned message id.
clientMessageId string Echoes the request's id.
createdAt string ISO-8601 server timestamp.

Success Response

{
  "type": "ack",
  "requestId": "req_01HQ5BXWYP1Y5RX0W5X0W5X0W5X",
  "eventType": "chat.send",
  "data": {
    "messageId": "msg_01HQ5BYN1K7ZRX0W5X0W5X0W5X",
    "clientMessageId": "msg_cl_01HQ5BYN1K7",
    "createdAt": "2026-08-03T10:00:00.000Z"
  }
}

Error Responses

Code Description
FORBIDDEN Caller not in the auction room or lacks chat:send.
NOT_FOUND Auction/cycle not found or not subscribed.
BAD_REQUEST body empty/too long, cycleId missing, clientMessageId missing.
RATE_LIMITED Chat rate limit exceeded (see rate-limits.md).

Validation Rules

Rule Behaviour
cycleId non-empty string Required.
body trimmed, 1–2000 chars Required.
clientMessageId non-empty string Required for idempotency.
Duplicate clientMessageId in window Returns previous ack (idempotent).

Example Request

{
  "type": "chat.send",
  "requestId": "req_01HQ5BXWYP1Y5RX0W5X0W5X0W5X",
  "data": {
    "cycleId": "cyc_01HQ5BWN3F9P5RX0W5X0W5X0W5X",
    "body": "Best of luck, everyone!",
    "clientMessageId": "msg_cl_1HQ5KYP1K7"
  }
}

Example Response

{
  "type": "ack",
  "requestId": "req_01HQ5BXWYP1Y5RX0W5X0W5X0W5X",
  "eventType": "chat.send",
  "data": {
    "messageId": "msg_01HQ5BY2K7K21X210W5X0W5X0W5X",
    "clientMessageId": "msg_cl_1HQ5KYP1K7",
    "createdAt": "2026-08-03T10:00:00.000Z"
  }
}

Broadcast Behaviour

After a successful chat.send, the server pushes the message to every other member of the auction:<cycleId> room (excluding the sender) with type chat.created (planned) and the full message payload. The same clientMessageId is echoed so clients can reconcile order of UI with the ack.

Notes

  • Implementation status: Planned.
  • Messages are tied to the auction room; joining requires auction.subscribe/room.join with the same cycleId.

Best Practices

  • Send clientMessageId to make retries safe.
  • Charge chat.send rate limit per user + per IP (see rate-limits.md).

chat.typing

Description

A lightweight typing indicator pushed to the room. Typing events are transient, short-lived, and rate-limited aggressively. They are not persisted.

Direction

Client → Server

Roles Allowed

All roles subscribed to the auction.

Permissions Required

chat:typing (planned).

Request Schema

Field Type Required Description
type string Yes chat.typing
data.cycleId string Yes Auction cycle.
data.isTyping boolean Yes true to start, false to stop.

Response (ack)

{
  "type": "ack",
  "requestId": "req_01HQ5BXWYP1Y5RX0W5X0W5X0W5X",
  "eventType": "chat.typing",
  "data": {
    "cycleId": "cyc_01HQ5BWN3F5RX0W6X0W5X0W5X",
    "isTyping": true
  }
}

Validation Rules

Rule Behaviour
cycleId non-empty Required.
isTyping boolean Required.

Example Request

{
  "type": "chat.typing",
  "requestId": "req_01HQ5HXWYP1Y5RX0W5X0W5X0W5X",
  "data": { "cycleId": "cyc_01HQ5BWN3F5RX0W5X0W5X0W5X", "isTyping": true }
}

Broadcast Behaviour

Fanned out to the room as chat.typing with the sender identity, throttled server-side to avoid flooding.

  • chat.send

Notes

  • Implementation status: Planned.
  • Never block actual sending on a typing indicator; it is best-effort and can be dropped under load.

Best Practices

  • Coalesce typing events client-side (at most one every few hundred ms).
  • Stop the indicator when the message is sent or a timeout elapses.

Example broadcast for a chat message

Recipients (other room members) receive a server-push message:

{
  "type": "chat.send",
  "data": {
    "messageId": "msg_01HQ5BY2K7K2RY210W5X0W5X0W5X",
    "cycleId": "cyc_01HQ5BWN3F5P5RX0W5X0W5X0W5X",
    "clientMessageId": "msg_cl_1HQ5KYP1K7",
    "author": {
      "userId": "sub_01HQ5BWYP1Y5RX0W5X0W5X0W5X",
      "name": "Annie Mohan"
    },
    "body": "Best of luck, everyone!",
    "createdAt": "2026-08-03T10:00:00.000Z"
  }
}