---
title: "Send a chat message"
method: POST
path: "/chat/threads/{chatId}/messages"
tags: ["Chat"]
---

# Send a chat message

`POST /chat/threads/{chatId}/messages`

## Request

- Base URL: `https://viral.app/api/v1`
- URL: `https://viral.app/api/v1/chat/threads/{chatId}/messages`
- Auth: API key in header `x-api-key`

Persists a message and broadcasts it to connected participants. Idempotent via clientMessageId. Messages sent with an API key are signed as the brand unless `senderIdentity` is "member". A direct thread whose creator has not been invited to viral.app yet is refused with 409 CREATOR_NOT_INVITED: invite them first (POST /creators/{id}/invite).

## Path parameters

- `chatId` string, required

## Request body

- object
  - `content` string, required
  - `clientMessageId` string, required
  - `replyToMessageId` string
  - `attachmentIds` string[]
  - `senderIdentity` 'member' | 'org': API-key calls only: how the creator sees the sender. "org" (the default) sends as the brand alone; "member" puts the key owner's first name in front of the brand ("Dennis from Acme"). Ignored for every other caller, whose messages follow their own chat settings.

## Response `200`

OK

- object
  - `message` object, required
    - `id` string, required
    - `chatId` string, required
    - `senderType` 'org' | 'creator' | 'system', required
    - `senderUserId` string, nullable, required
    - `senderDisplayName` string, nullable, required
    - `senderMember` object, nullable
      - `firstName` string, required
      - `image` string, nullable, required
    - `kind` string, required
    - `content` string, required
    - `metadata` object, nullable, required
    - `clientMessageId` string, required
    - `replyTo` object, nullable, required
      - `messageId` string, required
      - `senderType` 'org' | 'creator' | 'system', required
      - `senderUserId` string, nullable
      - `senderDisplayName` string, nullable, required
      - `senderMember` object, nullable
        - `firstName` string, required
        - `image` string, nullable, required
      - `contentPreview` string, required
      - `deleted` boolean, required
    - `reactions` object[], required
      - `emoji` string, required
      - `userId` string, required
      - `side` 'org' | 'creator', required
    - `attachments` object[], required
      - `id` string, required
      - `fileName` string, required
      - `mimeType` string, required
      - `sizeBytes` integer, required
      - `url` string, nullable, required
    - `createdAt` string, date-time, required
    - `editedAt` string, date-time, nullable, required
    - `deletedAt` string, date-time, nullable, required
    - `pinnedAt` string, date-time, nullable
    - `seenAt` string, date-time, nullable
    - `source` 'ui' | 'api' | 'copilot' | 'system', nullable
    - `language` string, nullable

## Other responses

- `400`: 400
- `401`: 401
- `402`: 402
- `404`: 404
- `408`: 408
- `409`: 409
- `429`: 429
- `500`: 500

---

[API](https://skmtc.dev/viral/apis/viral-app-api.md) · [All operations](https://skmtc.dev/viral/apis/viral-app-api/llms.txt) · [OpenAPI document](https://skmtc.dev/viral/apis/viral-app-api/revisions/31e97fa79ef1?raw)
