> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trychert.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a group

> POST /api/v1/chats — create an iMessage group chat with 2-31 recipients.

<Note>
  **Auth.** HMAC v1 or bearer token — see [Authentication](/api/authentication).
  **Status.** Live · **Idempotent:** Yes when `message.idempotency_key` is supplied.
</Note>

Creates an iMessage group and returns a Chert `chat.id`. Use that `chat.id` for follow-up messages, history, typing, mark-read, reactions to messages, and group operations.

Group creation uses the same route as direct chat creation: send `POST /api/v1/chats` with 2-31 recipients in `to`.

## Request

`POST /api/v1/chats`

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://console.trychert.com/api/v1/chats \
    -H "Authorization: Bearer $CHERT_SIGNING_SECRET" \
    -H "Content-Type: application/json" \
    -d '{
      "from": "+15555550100",
      "to": ["+14155551234", "+14155559876"],
      "message": {
        "subject": "Launch follow-up",
        "parts": [
          { "type": "text", "value": "Starting this group here." }
        ],
        "idempotency_key": "group-launch-follow-up-001"
      }
    }'
  ```

  ```js Node.js theme={null}
  const res = await fetch("https://console.trychert.com/api/v1/chats", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${CHERT_SIGNING_SECRET}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      from: "+15555550100",
      to: ["+14155551234", "+14155559876"],
      message: {
        subject: "Launch follow-up",
        parts: [{ type: "text", value: "Starting this group here." }],
        idempotency_key: "group-launch-follow-up-001",
      },
    }),
  })
  ```
</RequestExample>

<Warning>
  Use a text-only first message when creating a group. Send media attachments or rich links afterward with `POST /api/v1/chats/{id}/messages`.
</Warning>

## Response

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "chat": {
      "id": "0f2d3c1a-8b4e-4f6a-90d2-1a3b4c5d6e7f",
      "display_name": "Launch follow-up",
      "handles": [
        { "service": "imessage", "address": "+14155551234" },
        { "service": "imessage", "address": "+14155559876" }
      ],
      "is_group": true,
      "service": "imessage",
      "health_score": 87,
      "created_at": "2026-05-01T12:00:00Z"
    },
    "message": {
      "id": "46eb1003c8b54b7ea8f1c2b03e9a7d12",
      "chat_id": "0f2d3c1a-8b4e-4f6a-90d2-1a3b4c5d6e7f",
      "parts": [{ "type": "text", "value": "Starting this group here." }],
      "status": "sent",
      "direction": "outbound",
      "created_at": "2026-05-01T12:00:00Z",
      "delivered_at": null,
      "read_at": null,
      "service": "imessage"
    }
  }
  ```
</ResponseExample>

### Body

<ParamField body="from" type="string" required>
  Sender phone number from [Phone numbers](/api/phone-numbers).
</ParamField>

<ParamField body="to" type="string[]" required>
  2-31 E.164 phone numbers.
</ParamField>

<ParamField body="message.parts" type="object[]" required>
  First group-create message parts. Use one `text` part for the initial group creation.
</ParamField>

<ParamField body="message.subject" type="string">
  Optional group display name.
</ParamField>

<ParamField body="message.idempotency_key" type="string">
  Optional retry key. Reuse the same key and body to safely retry the create call.
</ParamField>

### Response fields

<ResponseField name="chat.id" type="string">
  Chert chat id for this group. Use it with `/api/v1/chats/{id}/messages` and group-management routes.
</ResponseField>

<ResponseField name="chat.handles" type="object[]">
  Known group participant handles. This is useful for display and debugging, but the durable group identity is the Chert `chat.id`.
</ResponseField>

<ResponseField name="message.id" type="string">
  Message id for the first outbound group message. Use this id with message-scoped routes such as reactions.
</ResponseField>

## Externally-created groups

If a Chert-managed number is added to a group outside the API, Chert creates a `chat.id` for that group when the number receives the first group event. The group is identified internally by the upstream group conversation key, then decorated with the participant handles and display name that are available on the event.

This means silent membership changes are not visible until a message, reaction, or other group event reaches the Chert line.

## Errors

| Code   | HTTP | When                                                           |
| ------ | ---- | -------------------------------------------------------------- |
| `1001` | 400  | Missing `from`, `to`, or `message.parts`.                      |
| `1003` | 400  | Invalid phone number.                                          |
| `2006` | 403  | `from` is not assigned to this tenant.                         |
| `4001` | 502  | Downstream delivery failed.                                    |
| `1006` | 422  | More than 31 recipients.                                       |
| `4099` | 501  | Group creation included media/rich links in the first message. |

See the full [error code reference](/api/errors).

## See also

* [Send a follow-up](/api/chats/send-message)
* [Rename a group](/api/group-chats/rename)
* [Add a participant](/api/group-chats/add-participant)
