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

# Create a group chat

> POST /api/v1/comms/groups — start an iMessage group chat from your line and send its first message.

Create an iMessage group chat with two or more phone numbers and send its opening message in the same call. The group is created by sending that message, so `body` is required. The response returns the new group (a conversation) and the message.

Group chats are iMessage-only. They are created from a dedicated line that you own, and only from a line whose bridge advertises the `groups` capability (see [List available lines](/messages-api/list-available-lines)). An older device without native group support answers `409 group_chats_unsupported` before any group or message is written. A shared platform line answers `409 group_requires_dedicated_line`. All participants must be reachable over iMessage; the service does not silently substitute separate messages or SMS.

**Scope:** `comms_send`

## Request

```bash theme={null}
curl -X POST "https://osis.co/api/v1/comms/groups" \
  -H "Authorization: Bearer $COMMS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: launch-crew-2026-09" \
  -d '{
    "line_e164": "+16282646448",
    "participants": ["+12125550147", "+12125550148", "+12125550149"],
    "name": "Launch crew",
    "body": "Welcome aboard. This is the launch group for Tuesday."
  }'
```

### Headers

| Header            | Required    | Description                                                                                                                           |
| ----------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `Authorization`   | Yes         | `Bearer <COMMS_API_KEY>`                                                                                                              |
| `Content-Type`    | Yes         | `application/json`                                                                                                                    |
| `Idempotency-Key` | Recommended | Stable key for safe retries. A replay returns the original group and message with `duplicate: true` and never creates a second group. |

### Body parameters

<ParamField body="participants" type="string[]" required>
  Two to 31 distinct phone numbers to add to the group. E.164 unless `default_country` is set. Duplicates are dropped. The line itself is never a participant.
</ParamField>

<ParamField body="body" type="string" required>
  Opening message, up to 10,000 characters. A group chat cannot exist without it.
</ParamField>

<ParamField body="line_e164" type="string">
  Your dedicated line that creates the group. Required unless `line_id` is set or the API key is bound to a line. `from` is accepted as an alias. A line-bound key can only create groups from its own line; naming another line answers `409 line_mismatch`.
</ParamField>

<ParamField body="line_id" type="string">
  Provider line id (for example `line_se_xxhtvk`). Alternative to `line_e164`.
</ParamField>

<ParamField body="name" type="string">
  Optional display name for the group. Up to 100 characters.
</ParamField>

<ParamField body="default_country" type="string">
  ISO country code used only when participants are given in national format.
</ParamField>

<ParamField body="idempotency_key" type="string">
  Same as the `Idempotency-Key` header.
</ParamField>

## Response

### 201 Created

The line created the group and accepted the opening message. `message.status` is `submitted` until the line observes the send, then follows the same lifecycle as [Send a message](/messages-api/send-message) and fires the same `comms.message.*` webhook events.

```json theme={null}
{
  "group": {
    "id": "conversation_01HZX…",
    "name": "Launch crew",
    "state": "created",
    "channel": "imessage",
    "participants": [
      { "phone": "+12125550147", "contact_id": "ctc_01HZX…" },
      { "phone": "+12125550148", "contact_id": "ctc_01HZY…" },
      { "phone": "+12125550149", "contact_id": "ctc_01HZZ…" }
    ],
    "line_id": "line_se_xxhtvk",
    "line_e164": "+16282646448",
    "provider_group_id": "grp_…",
    "created_at": "2026-09-06T18:04:11.000Z"
  },
  "message": {
    "id": "msg_01HZX…",
    "conversation_id": "conversation_01HZX…",
    "contact_id": "",
    "direction": "outbound",
    "channel": "imessage",
    "body": "Welcome aboard. This is the launch group for Tuesday.",
    "status": "submitted",
    "line_id": "line_se_xxhtvk",
    "line_e164": "+16282646448",
    "created_at": "2026-09-06T18:04:11.000Z"
  }
}
```

`group.state` is `creating`, `created`, `unknown`, or `failed`; an unknown outcome is not confirmation that the group exists.

`group.id` is a conversation id. Pass it as `conversation_id` to [List messages](/messages-api/list-messages) to read the thread.

### 202 Accepted (outcome unknown)

The request may have reached the line but the outcome is not yet known. The body carries `delivery_unknown: true` and `message.status` is `unknown`. Do not retry with a new key; poll the message instead.

### 200 OK (duplicate)

The same `Idempotency-Key` was already used for this exact request. A successful creation returns the original group and message with `duplicate: true`. An uncertain creation remains HTTP 202 on replay, and a failed creation retains its error status. Reusing the key with a different participant set, opening message, name, or line returns HTTP 409.

### Errors

| Status  | `error` / `code`                                                         | Meaning                                                                                                                                       |
| ------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 400     | `participants_required`, `too_few_participants`, `too_many_participants` | `participants` is missing, has fewer than two distinct numbers, or more than 31                                                               |
| 400     | `e164_required`, `invalid_phone_number`                                  | A participant is not a valid phone number (`participant` names it)                                                                            |
| 400     | `participant_is_line`                                                    | The creating line was listed as a participant                                                                                                 |
| 400     | `body_required`, `body_too_long`                                         | The opening message is missing or over 10,000 characters                                                                                      |
| 400     | `line_required`                                                          | No `line_e164`, `line_id`, or bound line                                                                                                      |
| 402     | `channel_entitlement_denied`                                             | The workspace has no remaining sending entitlement                                                                                            |
| 403     | `line_not_owned`                                                         | The line is not assigned to this workspace                                                                                                    |
| 409     | `group_chats_unsupported`                                                | The line's bridge does not advertise the `groups` capability. Nothing was created.                                                            |
| 409     | `group_requires_dedicated_line`                                          | The line is the shared platform line                                                                                                          |
| 409     | `line_mismatch`                                                          | A line-bound key named a different line                                                                                                       |
| 409     | `contact_opted_out`                                                      | A participant has opted out (`participant` names it)                                                                                          |
| 409     | `idempotency_key_reused`                                                 | The key was used with a different request                                                                                                     |
| 4xx/502 | `provider_delivery_failed`                                               | The line refused to create the group. `group_id` and `message_id` identify the failed attempt; `provider.code` and `provider.reason` say why. |

## See also

* [Send a message](/messages-api/send-message)
* [List messages](/messages-api/list-messages)
* [List available lines](/messages-api/list-available-lines)
