# Connecting an API channel

The API channel allows you to transfer messages from your own service to ChatRex. ChatRex immediately confirms the receipt of the request, processes the message asynchronously and sends a ready response to the specified HTTPS webhook with an HMAC signature.

## Before connecting n

Prepare:

- the public HTTPS address of the callback processor without query parameters;
- a secret to verify an HMAC signature at least 32 characters long
- How to create a unique `request_id` for each message
- stable `client_id`, whereby messages from one client are combined into a dialogue;
- Server storage for access token and callback secret.

If you plan to transfer media files, your service should also be able to send `multipart/form-data` requests and save the received `media_id` before sending a message.

The API channel is designed for server integration. Do not call it directly from the browser or mobile application: the access token will become available to the user of the application.

## Creation of a channel

1. In ChatRex, open **Integrations**.
2. Press **Connect integration**.
3. On the **Channels** tab, select **API** and click **Connect**.
4. Open the tab **Connection installation**.
5. Copy **URL for incoming messages**.
6. Copy **Access Token** and immediately save it in a secure storage of your service.

!!!warning
The token is displayed only before the window closes. If the token is lost, click **Reissue token**. The current token will stop working immediately, but the channel URL will not change.
!!!

After creation, the API channel receives the status **Connected** and is turned on automatically.

## Designation of a botoo channel

1. Open **My Bots** and press **Change** opposite the desired bot.
2. Go to **Channels and Launch**.
3. In **Conditions on channels** click **Add channel**.
4. Select the created **API channel**.
5. Set the launch conditions and save the changes.

Without channel assignment, the bot will not handle incoming API requests.

## Downloading a media file

Media files are transmitted in two stages: first upload the file to ChatRex, then specify the received `media_id` in the message.

The download URL is located next to the URL of incoming messages: replace the end `/messages` with `/uploads`. Use the same Bearer token API channel.

```http
POST https://api.example.com/api/channel/{CHANNEL_ID}/uploads
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: multipart/form-data
```

Pass two form fields:

| Field | Destination |
| --- | --- |
| `upload_id` | Unique external download identifier: up to 100 characters from `A-Z`, `a-z`, `0-9`, `.`, `_`, `:` and `-`. |
| `file` | Binary content of the file. |

Example from `curl`:

```bash
curl --request POST \
  --url "https://api.example.com/api/channel/{CHANNEL_ID}/uploads" \
  --header "Authorization: Bearer {ACCESS_TOKEN}" \
  --form "upload_id=order-42-photo" \
  --form "file=@./photo.png"
```

A successful download returns HTTP `201`:

```json
{
  "status": "uploaded",
  "upload_id": "order-42-photo",
  "media_id": "11111111-1111-4111-8111-111111111111",
  "type": "image",
  "name": "photo.png",
  "mime_type": "image/png",
  "size": 184203,
  "expires_at": "2026-08-12T15:00:00+00:00"
}
```

Supported formats:

Type | Formats |
| --- | --- |
| Images | JPEG, PNG, WEBP, GIF |
Audio | MP3, OGG, WAV, M4A, WEBM |
| Documents | PDF, DOC, DOCX, XLS, XLSX, TXT, CSV |

The API channel does not accept video and archives. ChatRex defines the actual MIME file type and correlates it with the file extension. By default, the maximum size of one file is 25 MiB.

Unattached download is stored for 24 hours. Before the expiration date, reloading the same file with the same `upload_id` will return the previous `media_id`. If the content is different, ChatRex will return HTTP `409` with `upload_id_conflict` - use the new `upload_id`.

## Sending a message

Send the `POST` request to the copied **URL for incoming messages**. Pass the token in the `Authorization` header using the Bearer and JSON scheme in the query body.

```http
POST {CHANNEL_URL}
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
```

```json
{
  "request_id": "req-20260808-0001",
  "client_id": "customer-12345",
  "message": "What is the delivery price?",
  "attachments": [
    {
      "media_id": "11111111-1111-4111-8111-111111111111"
    }
  ],
  "additional_info": "Order 00042, priority customer",
  "callback_url": "https://example.com/webhooks/chatrex",
  "callback_secret": "replace-with-a-random-secret-at-least-32-characters"
}
```

The `attachments` and `additional_info` fields are optional. The `message` field cannot be transmitted unless there is at least one attachment. The remaining fields are mandatory:

| Field | Destination |
| --- | --- |
| `request_id` | Unique request identifier. Do not use the same value for different messages. |
| `client_id` | Customer ID in an external service. Transmit the same value to continue the dialogue with that client. |
| `message` | The text of the message is up to 10,000 characters long. It may be absent if `attachments` is filled. |
| `attachments` | An ordered array of objects with previously obtained `media_id`. |
| `additional_info` | Additional context for processing a current message: a string of up to 10,000 characters or `null`. |
| `callback_url` | A public HTTPS webhook without query parameters to which ChatRex will send the result. |
| `callback_secret` | A secret at least 32 characters long for checking HMAC callback signature. |

A successful response to an incoming request confirms only the reception of the message. The bot will receive a separate request for `callback_url`.

## Media file processing

In one message, you can transfer no more than three attachments: a maximum of one image, one audio and one document. The total size of investments should not exceed 80 MiB.

ChatRex uses attachments in the same processing as message text and `additional_info`:

- the image is transmitted to the image recognition circuit;
- audio is decrypted and transcription is taken into account when generating a response.
- The document is transmitted to the model as file entry.

The message can only consist of an attachment. For example:

```json
{
  "request_id": "req-20260808-0002",
  "client_id": "customer-12345",
  "attachments": [
    {
      "media_id": "11111111-1111-4111-8111-111111111111"
    }
  ],
  "callback_url": "https://example.com/webhooks/chatrex",
  "callback_secret": "replace-with-a-random-secret-at-least-32-characters"
}
```

Each `media_id` can be assigned to only one incoming request. Resending a completely identical request with the same `request_id` is safe and will return the existing receipt. For another message, download the file with the new `upload_id` and use the new `media_id`.

Investments are part of the idempotent request. If you change the composition or order of `attachments` and keep the previous `request_id`, ChatRex returns HTTP `409` with the code `request_id_conflict`.

### Mistakes in working with media

If the error occurs, ChatRex returns the JSON code to the `error.code` field. Basic codes:

| HTTP | Code | What to check |
| --- | --- | --- |
| `422` | `media_upload_required`, `invalid_upload_request` | The correct `upload_id` and `file` are present in the download request. |
| `422` | `file_type_not_allowed`, `file_too_large` | The format is supported, the MIME type corresponds to the extension, the size does not exceed the limit. |
| `422` | `message_or_attachment_required` | The message contains a text or at least one attachment. |
| `422` | `too_many_files`, `duplicate_media_type`, `total_media_size_exceeded` | Restrictions on the number, types and total size of investments are met. |
| `404` | `media_not_found` | `media_id` received in the same API channel and the file still exists. |
| `409` | `upload_id_conflict`, `media_already_claimed` | New `upload_id` and `media_id` are used for other content or message. |
| `410` | `media_expired` | The file is not expired; download it again if necessary. |
| `500` or `503` | `media_storage_failed`, `media_claim_failed` | Repeat the operation later; if the error persists, contact technical support. |

## Additional context `additional_info`

Use `additional_info` if, along with the message, you need to transfer information from your system to the bot, such as order status, customer category or selected tariff.

ChatRex adds a non-empty value to the additional system context of ongoing processing marked **Additional information**. The meaning is:

- not added to the text of the message of the client;
- Does not return to callback;
- is not used to select a bot and verify the launch conditions;
- It is not automatically transferred to the next API request.

If context is needed when processing the next message, retransmit it. Do not place passwords, tokens, payment details and other secrets in `additional_info`: the content of the field is transmitted to the model when generating a response.

`additional_info` is part of the idempotent request. Repeating with the same `request_id` data does not create a new message. If you change `additional_info` or another field, saving the previous `request_id`, ChatRex will return HTTP `409` with the code `request_id_conflict`. For a modified request, create a new `request_id`.

## Callback processing

The callback handler shall:

1. Receive HTTPS requests from ChatRex
2. Check the HMAC signature with `callback_secret` prior to data processing;
3. compare the result with the original query by `request_id`;
4. retain the response or transmit it to the client only after successful verification of the signature;
5. Return successful HTTP status after receiving the result.

Do not record the token, callback secret and the full content of requests to public logs. Limit access to logs and keep secrets separate from source code.

## Verification

1. Assign an API channel to the test bot.
2. Send a request with a new `request_id` and a test `client_id`.
3. Make sure that ChatRex has accepted the request.
4. Check for callback at the specified HTTPS address.
5. Make sure that the HMAC signature is validated and the answer is `request_id`.
6. Check the dialog in **Chats** and **History**ChatRex.
7. Send a second message with the same `client_id` and a new `request_id` to check the dialogue continues.
8. To check the media, download the test file, transfer it `media_id` to `attachments` and make sure the answer takes into account the contents of the file.

## If the request is not processed

Check it out.

- Whether the current token and the `Authorization: Bearer` header are used;
- Whether a request is sent to the URL of the desired API channel;
- Whether all mandatory fields are filled;
- Whether `message` or at least one object is transferred to `attachments`
- Whether `additional_info` is a string not exceeding 10,000 characters in length or a value `null`
- Whether each `media_id` is received via endpoint `/uploads` of that particular API channel
- 24 hours have elapsed since the unfixed file was downloaded;
- Whether `media_id` was previously used in another request
- Are the restrictions exceeded: one file of each type, up to three attachments, up to 25 MiB per file and up to 80 MiB in total;
- Whether the file extension matches its actual MIME type and whether the format is supported
- Is `request_id` unique?
- Does `callback_url` start with `https://` and does not contain query parameters?
- Whether `callback_secret` contains at least 32 characters
- whether a callback is available from the Internet and accepts incoming requests;
- Is the channel assigned to the bot and is the launch conditions suitable?
- Integration and subscription are active.

If the token may have landed in a log, repository, or client application, immediately re-release it and update the secret in your server storage.
