# Register replies from other channels

Send BeeL. the replies your customers write on WhatsApp, Slack, email or your own product, so they are stored next to their invoice with the same shape and webhook.

BeeL. only receives, by itself, what a [connection](/guides/connections) brings in. For a message
your customer sent you somewhere else (WhatsApp, Telegram, Slack, SMS, your own inbox or the chat of
your product), register it with [`POST /v1/companies/{company_id}/invoice-replies`](/invoice-replies/createCompanyInvoiceReply).
No connection is needed.

The reply is stored with `authenticated_by: API_KEY` and `connection_id: null`. You choose the
invoice, and BeeL. does not verify the sender. It then behaves like any other reply: it is listed,
`invoice.reply.received` is delivered, and it can be deleted
(see [Read customer replies](/guides/customer-replies)).

It works with test and live keys. A reply registered with a `beel_sk_test_` key has `livemode: false`.
The key needs `invoice-replies:write`, a privileged scope (see [Permissions](/guides/reply-permissions)).

## Register a message

```bash
curl -X POST "https://app.beel.es/api/v1/companies/$COMPANY_ID/invoice-replies" \
  -H "Authorization: Bearer $BEEL_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "invoice_id": "b71d5e2a-9c3f-4a7b-8e10-2f6d4c8a9b13",
    "channel": "WHATSAPP",
    "external_id": "wamid.EXAMPLE0001",
    "sender": { "address": "+34600123456", "name": "Laura Gómez" },
    "text": "Hola, ¿podéis mandarme la factura a nombre de Distribuciones Ejemplo S.L.?"
  }'
```

| Field | Notes |
|---|---|
| `invoice_id` | An invoice of the company, in the environment of the key. A draft or a scheduled invoice answers `409` [`INVOICE_REPLY_INVOICE_NOT_ISSUED`](/errors/INVOICE_REPLY_INVOICE_NOT_ISSUED), and an unknown one `404` [`INVOICE_NOT_FOUND`](/errors/INVOICE_NOT_FOUND). |
| `channel` | Where the customer wrote: `EMAIL`, `WHATSAPP`, `TELEGRAM`, `SLACK`, `SMS` or `OTHER`. It is the medium, not a provider. |
| `external_id` | The identifier of the message on its channel: the `Message-ID` for `EMAIL`, the identifier the provider gives for messaging channels, your own for `OTHER`. |
| `sender.address` | An email address for `EMAIL`, a phone number in E.164 format (`+34600000000`) for `WHATSAPP` and `SMS`, the user identifier of the channel otherwise. Otherwise `422` [`VALUE_OUT_OF_RANGE`](/errors/VALUE_OUT_OF_RANGE). |
| `sender.name` | Optional. Omit it when there is none. |
| `received_at` | Optional, the moment you received it; defaults to now. More than 5 minutes ahead answers `422` [`VALUE_OUT_OF_RANGE`](/errors/VALUE_OUT_OF_RANGE). |
| `subject` | Optional, up to 998 characters. |
| `text` | Optional, up to 20,000 characters, without the messages it quotes. |
| `attachments` | Up to 10, each with `content_type` and optionally `filename` and `size_bytes`. Only the description is stored, never the file. |

Send either `text` or `attachments`; with neither the call answers
`422` [`MISSING_REQUIRED_FIELD`](/errors/MISSING_REQUIRED_FIELD).

## One message, one reply

A message is stored once per `channel` and `external_id` in each company and environment. Registering
it again answers `409` [`INVOICE_REPLY_DUPLICATE`](/errors/INVOICE_REPLY_DUPLICATE) with the id of the existing reply in
`error.details.reply_id`. That makes a retry of your own safe, and a message BeeL. already captured
by email is recognized when you send its `Message-ID` as `external_id`.

Once a reply is [deleted](/guides/reply-data-protection), the same `channel` and `external_id` can no
longer be registered: the `409` comes back without `reply_id`.

An `Idempotency-Key` on the call replays the first response instead of answering `409`, as in any
other [write](/guides/idempotency).

## Related

<Related>

- [Read customer replies](/guides/customer-replies): the shape of a reply and what is masked
- [Idempotency](/guides/idempotency): safe retries of a write
- [Register a reply](/invoice-replies/createCompanyInvoiceReply): the endpoint reference

</Related>

---

Full OpenAPI spec: https://docs.beel.es/api/openapi