> For the complete documentation index, see [llms.txt](https://docs.suvvy.ai/en/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.suvvy.ai/en/channels/kastomnyi-kanal/otpravka-soobshenii.md).

# Sending messages

To send messages from a custom channel, use the following method:

<table data-header-hidden><thead><tr><th width="114"></th><th></th></tr></thead><tbody><tr><td>Method</td><td><strong>POST</strong></td></tr><tr><td>URL</td><td><a href="https://api.suvvy.ai/api/webhook/custom/message">https://api.suvvy.ai/api/webhook/custom/message</a></td></tr></tbody></table>

## Headers

<table><thead><tr><th width="406">Header</th><th>Value</th></tr></thead><tbody><tr><td><code>Authorization</code></td><td><code>Bearer &#x3C;token></code></td></tr><tr><td><code>Content-Type</code></td><td><code>application/json</code></td></tr></tbody></table>

A token obtained when connecting the channel must be included in the request.

## Request Body

```json
{
  "api_version": 1,
  "message_id": "<message id>",
  "chat_id": "<chat id>",
  "text": "Hello!",
  "attachments": [
    {
      "file_name": "file.png",
      "file_type": "image",
      "data": "aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQ=="
    }
  ],
  "source": "John Doe from Amazon",
  "placeholders": {
     "some_id": "123123"
  },
  "link": {
    "type": "chat",
    "hint": "Dialogue",
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  },
  "message_sender": "customer",
  "client_name": "John Doe",
  "client_phone": "+44312345678"
}
```

<table><thead><tr><th width="191">Field</th><th width="175">Field Required</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>api_version</code></td><td>yes</td><td>integer (only <code>1</code>)</td><td><strong>API Version.</strong> In the future, we will update our API, and to avoid any disruptions, we will support old versions in parallel for a while.</td></tr><tr><td><code>message_id</code></td><td>yes</td><td>string</td><td><strong>Message ID in your system.</strong> Necessary to prevent accidental re-triggers.</td></tr><tr><td><code>chat_id</code></td><td>yes</td><td>string</td><td><strong>Chat ID in your system.</strong> The linking part that determines which dialogue the message will appear in.</td></tr><tr><td><code>text</code></td><td>yes, if <code>attachments</code> field is not specified</td><td>string, at least 1 character</td><td><strong>Message text.</strong></td></tr><tr><td><code>attachments</code></td><td>yes, if <code>text</code> field is not specified</td><td>array of <code>Attachment</code> objects</td><td><strong>Attachments.</strong> Currently, only images and audio are supported.</td></tr><tr><td><code>message_sender</code></td><td>yes</td><td>string (<code>customer</code> or <code>employee</code>)</td><td><strong>Message sender.</strong> Customer or employee from your system.</td></tr><tr><td><code>source</code></td><td>yes</td><td>string</td><td><strong>Source.</strong> The value that appears in the "Source" column in the Suvvy dashboard.<br><br>Typically, the client's name or username, or the deal name.</td></tr><tr><td><code>link</code></td><td>no</td><td><code>Link</code> object</td><td><strong>Link to chat in your system.</strong> Will be displayed as a button in the Suvvy dashboard.</td></tr><tr><td><code>placeholders</code></td><td>no</td><td>object, where key and value are strings</td><td><strong>Variables for instructions.</strong> More details below.</td></tr><tr><td><code>client_name</code></td><td>no</td><td>string</td><td><strong>Client name.</strong></td></tr><tr><td><code>client_phone</code></td><td>no</td><td>string</td><td><strong>Client phone number.</strong></td></tr></tbody></table>

{% content-ref url="/pages/JKeKaf00ZmDZO0fOzr7B" %}
[Variables](/en/main-settings/prompts/prompts-1.md)
{% endcontent-ref %}

### `Attachment` Object

All fields are required.

| Field       | Type                        | Description                                      |
| ----------- | --------------------------- | ------------------------------------------------ |
| `file_name` | string                      | **File name.**                                   |
| `file_type` | string (`image` or `audio`) | **File type.**                                   |
| `data`      | string, base64 of file      | **File.** Permissible types are indicated below. |

Suvvy accepts files of the following types:

* For images: `image/png`, `image/jpeg`, `image/gif`
* For audio: `audio/ogg`, `audio/mpeg`, `audio/wav`, `audio/x-wav`, `audio/webm`, `audio/mp4`, `audio/m4a`, `audio/x-m4a`

Maximum file size - **15 megabytes**

### `Link` Object

| Field  | Type                                              | Description                                                                                                                                                                                                                                                                                                                                                                   |
| ------ | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | string (`user`, `chat`, `phone`, `lead`, `other`) | <p><strong>Link type.</strong> Affects the icon displayed in the dashboard<br><br><code>user</code> - 👤<br><code>chat</code> - 💬<br><code>phone</code> - 📞<br><code>lead</code> - 🤝🏻<br><code>other</code> - 🔗</p>                                                                                                                                                      |
| `hint` | string or `null`                                  | <p><strong>Text for button.</strong> Optional. If not specified (or <code>null</code>), titles are used depending on the type:<br><br><code>user</code> - <strong>Account</strong><br><code>chat</code> - <strong>Chat</strong><br><code>phone</code> - <strong>Phone</strong><br><code>lead</code> - <strong>Lead</strong><br><code>other</code> - <strong>Link</strong></p> |
| `url`  | string                                            | **Link.**                                                                                                                                                                                                                                                                                                                                                                     |

## Response

Upon success, the webhook returns a body of the following form:

```json
{
  "message": "Successful"
}
```

This can be ignored as it doesn't carry useful information.

## Errors

### Invalid Token

Returns a body of the following type and code **401:**

```json
{
  "detail": "Invalid token.",
  "status_code": 401,
  "error_code": "auth_invalid_token"
}
```

### Channel Disabled

Returns when the channel is not connected or disabled in settings.\
Returns a body of the following type and code **424:**

```json
{
  "detail": "Channel is disabled.",
  "status_code": 424,
  "error_code": "instance_channel_is_disabled"
}
```

### Unsupported File Type

Returns when the submitted file is unsupported by Suvvy. Provides supported types.\
Returns a body of the following type and code **415:**

```json
{
  "detail": "File type is not supported or invalid.",
  "status_code": 415,
  "error_code": "file_invalid_type",
  "allowed_mime_types": [
    "image/png",
    "text/csv",
    "audio/ogg"
  ]
}
```

### Negative Balance

Returns when your Suvvy balance is below zero.\
Returns a body of the following type and code **402:**

```json
{
  "detail": "Your balance is below zero, so you can't perform this action.'",
  "status_code": 402,
  "error_code": "user_balance_below_zero"
}
```

### Validation Error

Returns code **422** and a body detailing what was submitted incorrectly.

## Code Examples

{% tabs %}
{% tab title="Python (requests)" %}

```python
import requests

response = requests.post(
    'https://api.suvvy.ai/api/webhook/custom/message',
    headers={
        'Authorization': 'Bearer your_token',
        'Content-Type': 'application/json'
    },
    json={
        'api_version': 1,
        'message_id': 'unique_message_id',
        'chat_id': 'unique_chat_id',
        'text': 'Hello!',
        'attachments': [
            {
                'file_name': 'file.png',
                'file_type': 'image',
                'data': 'base64_file_data'
            }
        ],
        'source': 'John Doe from Amazon',
        'placeholders': {
            'some_id': '123123'
        },
        'link': {
            'type': 'chat',
            'hint': 'Dialogue',
            'url': 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
        },
        'message_sender': 'customer',
        'client_name': 'John Doe',
        'client_phone': '+44312345678'
    }
)
```

{% endtab %}

{% tab title="JavaScript (fetch)" %}

```javascript
fetch('https://api.suvvy.ai/api/webhook/custom/message', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer your_token',
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        api_version: 1,
        message_id: 'unique_message_id',
        chat_id: 'unique_chat_id',
        text: 'Hello!',
        attachments: [
            {
                file_name: 'file.png',
                file_type: 'image',
                data: 'base64_file_data'
            }
        ],
        source: 'John Doe from Amazon',
        placeholders: {
            some_id: '123123'
        },
        link: {
            type: 'chat',
            hint: 'Dialogue',
            url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
        },
        message_sender: 'customer',
        client_name: 'John Doe',
        client_phone: '+44312345678'
    })
});
```

{% endtab %}

{% tab title="PHP (cURL)" %}

```php
$ch = curl_init('https://api.suvvy.ai/api/webhook/custom/message');
$data = [
    'api_version' => 1,
    'message_id' => 'unique_message_id',
    'chat_id' => 'unique_chat_id',
    'text' => 'Hello!',
    'attachments' => [
        [
            'file_name' => 'file.png',
            'file_type' => 'image',
            'data' => 'base64_file_data'
        ]
    ],
    'source' => 'John Doe from Amazon',
    'placeholders' => [
        'some_id' => '123123'
    ],
    'link' => [
        'type' => 'chat',
        'hint' => 'Dialogue',
        'url' => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
    ],
    'message_sender' => 'customer',
    'client_name' => 'John Doe',
    'client_phone' => '+44312345678'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer your_token',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
```

{% endtab %}

{% tab title="Ruby (net/http)" %}

```ruby
require 'net/http'
require 'uri'
require 'json'

uri = URI.parse('https://api.suvvy.ai/api/webhook/custom/message')
header = {
  'Authorization' => 'Bearer your_token',
  'Content-Type' => 'application/json'
}
data = {
  api_version: 1,
  message_id: 'unique_message_id',
  chat_id: 'unique_chat_id',
  text: 'Hello!',
  attachments: [
    {
      file_name: 'file.png',
      file_type: 'image',
      data: 'base64_file_data'
    }
  ],
  source: 'John Doe from Amazon',
  placeholders: {
    some_id: '123123'
  },
  link: {
    type: 'chat',
    hint: 'Dialogue',
    url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
  },
  message_sender: 'customer',
  client_name: 'John Doe',
  client_phone: '+44312345678'
}

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = data.to_json

response = http.request(request)
```

{% endtab %}

{% tab title="Rust (reqwest)" %}

```rust
use reqwest::blocking::Client;
use serde_json::json;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let client = Client::new();
    let res = client.post("https://api.suvvy.ai/api/webhook/custom/message")
        .header("Authorization", "Bearer your_token")
        .header("Content-Type", "application/json")
        .json(&json!({
            "api_version": 1,
            "message_id": "unique_message_id",
            "chat_id": "unique_chat_id",
            "text": "Hello!",
            "attachments": [
                {
                    "file_name": "file.png",
                    "file_type": "image",
                    "data": "base64_file_data"
                }
            ],
            "source": "John Doe from Amazon",
            "placeholders": {
                "some_id": "123123"
            },
            "link": {
                "type": "chat",
                "hint": "Dialogue",
                "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
            },
            "message_sender": "customer",
            "client_name": "John Doe",
            "client_phone": "+44312345678"
        }))
        .send()?;
        
    Ok(())
}
```

{% endtab %}
{% endtabs %}
