# Remove contacts from a group

`POST /v1/groups/{id}/contacts/remove`

Requires an API key with the `groups:write` scope. [About keys and scopes](/docs/api/authentication)

Removes up to 500 contacts from a group in one batch, named by exactly one of `contactIds`, `externalIds` or `emails`: a POST, since some clients and proxies drop the body of a DELETE. Contacts that were not members are ignored; the response reports how many were actually removed, and lists in `notFound` the identifiers that name no contact in this workspace. Agent keys are refused with 403.

## Path parameters

- `id` (string, required, uuid)

## Request body

- One of: **By contact ids**
  - `contactIds` (string[], required, at least 1 item, at most 500 items) — Kirora's ids for the contacts.
- One of: **By external ids**
  - `externalIds` (string[], required, at least 1 item, at most 500 items) — Your own ids for the contacts, as set with identify.
- One of: **By emails**
  - `emails` (string[], required, at least 1 item, at most 500 items) — Email addresses, matched trimmed and without case.

## Returns

Returns `200 OK` with a `RemovedGroupMembers` in `data`. Otherwise returns an error; [Errors](/docs/api/errors) lists every code and which to retry.

- `removed` (integer, required, min 0, max 9007199254740991) — Contacts removed from the group.
- `notFound` (string[], required) — Identifiers as sent (emails normalised) that name no contact in the workspace.

## Example

```bash
curl -X POST https://api.kirora.io/v1/groups/018f2a4e-6b1c-7d3e-9f40-37386ae05a6b/contacts/remove \
  -H "Authorization: Bearer $KIRORA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contactIds": [
      "018f2a4e-6b1c-7d3e-9f40-149f1e875a6b"
    ]
  }'
```

Response `200`:

```json
{
  "data": {
    "removed": 0,
    "notFound": [
      "notFound_example"
    ]
  }
}
```
