# Create channel

Create a channel. Channel schema is selected by `config.kind`.

Endpoint: POST /channels
Version: 1.4.1
Security: Auth

## Security:

  - `Auth` (unknown)
    apiKey in header X-Api-Key scopes: api:channel:write

## Request fields (application/json):

  - `name` (string, required)
    Display name for the notification channel.
    Example: Production Alerts Webhook

  - `config` (object, required)
    Channel-specific configuration for channel creation. The Telegram
`bot_token` is required in plaintext; after that it's only ever returned
masked.

  - `config.kind` (string, required)
    Configuration type discriminator.
    Enum: "telegram", "webhook"

  - `config.bot_token` (string, required)
    Telegram Bot API token from @BotFather. Format: `{bot_id}:{auth_token}`.
Accepted on write (create, or update to rotate the token). On read the
value is masked (see `TelegramBotTokenMasked`).

  - `config.chat_id` (integer, required)
    Telegram chat ID where notifications are sent.
Positive for private chats, negative for groups, `-100...` prefix for channels.
Use the Telegram Bot API `getUpdates` method to find your chat ID.

  - `config.language` (string, required)
    Language code for localization.
    Enum: "ru", "en"

  - `config.thread_id` (integer, required)
    Unique identifier for the target message thread (topic) of a forum.

Used for forum supergroups and private chats of bots with forum topic mode enabled only.
Default value is 0 (no specific thread).
    Example: 0

  - `config.url` (string, required)
    HTTP/HTTPS endpoint that accepts POST requests with JSON payloads.
Use headers (not query params) for authentication.

  - `config.headers` (object)
    Optional HTTP headers to include with webhook requests, including
receiver authentication headers such as `X-Webhook-Secret`.
Anyone authorized to read the channel can read these values; they are
not masked. The webhook signing secret is managed separately and
produces the `X-Webhook-Signature` header. Custom headers cannot override
signing or event headers. Other names starting with `X-Webhook-` are
reserved; header names are case-insensitive.
On update, omit `headers` to keep the stored set, send an object to
replace it, or `{}` to clear them.
    Example: {"X-Tenant-Id":"acme"}

## Request examples:

  - `Telegram channel` (unknown)

  - `Webhook channel` (unknown)

## Response 200:

  - `200` (unknown)
    Channel created, or matched by `pid` (idempotent).

## Response 200 fields (application/json):

  - `item` (object, required)
    Notification delivery channel.
    Example: {"id":"550e8400-e29b-41d4-a716-446655440001","kind":"telegram","name":"Production Alerts","config":{"kind":"telegram","bot_token":"123456789:••••6789","chat_id":-1001234567890,"language":"en","thread_…

  - `item.id` (string, required)
    Unique identifier (UUID).
    Example: 550e8400-e29b-41d4-a716-446655440000

  - `item.kind` (string, required)
    Type of notification delivery channel.
    Enum: "telegram", "webhook"

  - `item.name` (string, required)
    Display name for the notification channel.
    Example: Production Alerts Webhook

  - `item.config` (object, required)
    Channel-specific configuration as returned in responses. Schema depends
on `kind`: `telegram` (bot_token + chat_id) or `webhook` (url + headers).
The Telegram `bot_token` is masked; webhook headers are returned verbatim.

  - `item.config.kind` (string, required)
    Configuration type discriminator.
    Enum: "telegram", "webhook"

  - `item.config.bot_token` (string, required)
    Masked Telegram bot token returned in responses. The `bot_id` prefix is
preserved for identification; the secret `auth_token` portion is hidden,
showing only its last 4 characters: `{bot_id}:••••<last4>`.
To keep the stored token on update, omit `bot_token` from the request.
To rotate it, send a new plaintext token (see `TelegramBotToken`).

  - `item.config.chat_id` (integer, required)
    Telegram chat ID where notifications are sent.
Positive for private chats, negative for groups, `-100...` prefix for channels.
Use the Telegram Bot API `getUpdates` method to find your chat ID.

  - `item.config.language` (string, required)
    Language code for localization.
    Enum: "ru", "en"

  - `item.config.thread_id` (integer, required)
    Unique identifier for the target message thread (topic) of a forum.

Used for forum supergroups and private chats of bots with forum topic mode enabled only.
Default value is 0 (no specific thread).
    Example: 0

  - `item.config.url` (string, required)
    HTTP/HTTPS endpoint that accepts POST requests with JSON payloads.
Use headers (not query params) for authentication.

  - `item.config.headers` (object)
    Optional HTTP headers to include with webhook requests, including
receiver authentication headers such as `X-Webhook-Secret`.
Anyone authorized to read the channel can read these values; they are
not masked. The webhook signing secret is managed separately and
produces the `X-Webhook-Signature` header. Custom headers cannot override
signing or event headers. Other names starting with `X-Webhook-` are
reserved; header names are case-insensitive.
On update, omit `headers` to keep the stored set, send an object to
replace it, or `{}` to clear them.
    Example: {"X-Tenant-Id":"acme"}

  - `item.created_at` (string, required)
    Timestamp when the resource was created.
    Example: 2024-01-15T10:30:00Z

  - `item.updated_at` (string, required)
    Timestamp when the resource was last updated.
    Example: 2024-01-15T10:30:00Z

  - `webhook_secret` (string)
    The full webhook signing secret, 55 characters: `vilna_whsec_{body}`
where `{body}` is 43 ASCII base62 characters. Used as the HMAC-SHA256 key
for the `X-Webhook-Signature` header on outgoing webhook deliveries.
**Returned only at channel creation and on rotation; store it
securely.** Lost secrets must be rotated.
    Example: vilna_whsec_a3K9pQ2mB5N8rT1xY7cZ4dH6eJ0fLm0123456789ABC

## Response 201:

  - `201` (unknown)
    Channel created, or matched by `pid` (idempotent).

## Response 201 fields (application/json):

  - `item` (object, required)
    Notification delivery channel.
    Example: {"id":"550e8400-e29b-41d4-a716-446655440001","kind":"telegram","name":"Production Alerts","config":{"kind":"telegram","bot_token":"123456789:••••6789","chat_id":-1001234567890,"language":"en","thread_…

  - `item.id` (string, required)
    Unique identifier (UUID).
    Example: 550e8400-e29b-41d4-a716-446655440000

  - `item.kind` (string, required)
    Type of notification delivery channel.
    Enum: "telegram", "webhook"

  - `item.name` (string, required)
    Display name for the notification channel.
    Example: Production Alerts Webhook

  - `item.config` (object, required)
    Channel-specific configuration as returned in responses. Schema depends
on `kind`: `telegram` (bot_token + chat_id) or `webhook` (url + headers).
The Telegram `bot_token` is masked; webhook headers are returned verbatim.

  - `item.config.kind` (string, required)
    Configuration type discriminator.
    Enum: "telegram", "webhook"

  - `item.config.bot_token` (string, required)
    Masked Telegram bot token returned in responses. The `bot_id` prefix is
preserved for identification; the secret `auth_token` portion is hidden,
showing only its last 4 characters: `{bot_id}:••••<last4>`.
To keep the stored token on update, omit `bot_token` from the request.
To rotate it, send a new plaintext token (see `TelegramBotToken`).

  - `item.config.chat_id` (integer, required)
    Telegram chat ID where notifications are sent.
Positive for private chats, negative for groups, `-100...` prefix for channels.
Use the Telegram Bot API `getUpdates` method to find your chat ID.

  - `item.config.language` (string, required)
    Language code for localization.
    Enum: "ru", "en"

  - `item.config.thread_id` (integer, required)
    Unique identifier for the target message thread (topic) of a forum.

Used for forum supergroups and private chats of bots with forum topic mode enabled only.
Default value is 0 (no specific thread).
    Example: 0

  - `item.config.url` (string, required)
    HTTP/HTTPS endpoint that accepts POST requests with JSON payloads.
Use headers (not query params) for authentication.

  - `item.config.headers` (object)
    Optional HTTP headers to include with webhook requests, including
receiver authentication headers such as `X-Webhook-Secret`.
Anyone authorized to read the channel can read these values; they are
not masked. The webhook signing secret is managed separately and
produces the `X-Webhook-Signature` header. Custom headers cannot override
signing or event headers. Other names starting with `X-Webhook-` are
reserved; header names are case-insensitive.
On update, omit `headers` to keep the stored set, send an object to
replace it, or `{}` to clear them.
    Example: {"X-Tenant-Id":"acme"}

  - `item.created_at` (string, required)
    Timestamp when the resource was created.
    Example: 2024-01-15T10:30:00Z

  - `item.updated_at` (string, required)
    Timestamp when the resource was last updated.
    Example: 2024-01-15T10:30:00Z

  - `webhook_secret` (string)
    The full webhook signing secret, 55 characters: `vilna_whsec_{body}`
where `{body}` is 43 ASCII base62 characters. Used as the HMAC-SHA256 key
for the `X-Webhook-Signature` header on outgoing webhook deliveries.
**Returned only at channel creation and on rotation; store it
securely.** Lost secrets must be rotated.
    Example: vilna_whsec_a3K9pQ2mB5N8rT1xY7cZ4dH6eJ0fLm0123456789ABC

## Response 400:

  - `400` (unknown)
    Bad request (e.g., missing or invalid fields). Invalid text may be reported as address.label_invalid, address.meta_invalid, public_key.label_invalid, invoice.comment_invalid, invoice.metadata_invalid.

## Response 400 fields (application/problem+json):

  - `type` (string, required)
    A URI that identifies the error type.
    Example: https://docs.vilna.io/apis/errors#internal-error

  - `title` (string, required)
    A short summary of the error type.
Use `detail` for information specific to this occurrence.
    Example: Bad Request

  - `status` (integer, required)
    The HTTP status code for this error.
Matches the status code of the HTTP response.
    Example: 400

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.
    Example: The address is already assigned to another invoice

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.
    Example: /traces/0123456789abcdef0123456789abcdef

  - `code` (string, required)
    Stable machine-readable error code for programmatic error handling. Unlike the HTTP `status` or free-form `detail`, this code is guaranteed not to change between versions for a given error condition, so it is safe to branch on in client code. Defaults to `unspecified` when the server has not assigned a specific code.
    Example: blockchain.not_found

  - `fields` (array)
    List of invalid fields in the request.

  - `fields.name` (string, required)
    The name of the invalid field.
    Example: max_len

  - `fields.reason` (string, required)
    Why this field is invalid.
    Example: 32

## Response 401:

  - `401` (unknown)
    Missing or invalid authentication credentials.

## Response 401 fields (application/problem+json):

  - `type` (string, required)
    A URI that identifies the error type.
    Example: https://docs.vilna.io/apis/errors#internal-error

  - `title` (string, required)
    A short summary of the error type.
Use `detail` for information specific to this occurrence.
    Example: Bad Request

  - `status` (integer, required)
    The HTTP status code for this error.
Matches the status code of the HTTP response.
    Example: 400

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.
    Example: The address is already assigned to another invoice

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.
    Example: /traces/0123456789abcdef0123456789abcdef

  - `code` (string, required)
    Stable machine-readable error code for programmatic error handling. Unlike the HTTP `status` or free-form `detail`, this code is guaranteed not to change between versions for a given error condition, so it is safe to branch on in client code. Defaults to `unspecified` when the server has not assigned a specific code.
    Example: blockchain.not_found

## Response 403:

  - `403` (unknown)
    Insufficient permissions.

## Response 403 fields (application/problem+json):

  - `type` (string, required)
    A URI that identifies the error type.
    Example: https://docs.vilna.io/apis/errors#internal-error

  - `title` (string, required)
    A short summary of the error type.
Use `detail` for information specific to this occurrence.
    Example: Bad Request

  - `status` (integer, required)
    The HTTP status code for this error.
Matches the status code of the HTTP response.
    Example: 400

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.
    Example: The address is already assigned to another invoice

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.
    Example: /traces/0123456789abcdef0123456789abcdef

  - `code` (string, required)
    Stable machine-readable error code for programmatic error handling. Unlike the HTTP `status` or free-form `detail`, this code is guaranteed not to change between versions for a given error condition, so it is safe to branch on in client code. Defaults to `unspecified` when the server has not assigned a specific code.
    Example: blockchain.not_found

## Response default:

  - `default` (unknown)
    Unexpected error.

## Response default fields (application/problem+json):

  - `type` (string, required)
    A URI that identifies the error type.
    Example: https://docs.vilna.io/apis/errors#internal-error

  - `title` (string, required)
    A short summary of the error type.
Use `detail` for information specific to this occurrence.
    Example: Bad Request

  - `status` (integer, required)
    The HTTP status code for this error.
Matches the status code of the HTTP response.
    Example: 400

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.
    Example: The address is already assigned to another invoice

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.
    Example: /traces/0123456789abcdef0123456789abcdef

  - `code` (string, required)
    Stable machine-readable error code for programmatic error handling. Unlike the HTTP `status` or free-form `detail`, this code is guaranteed not to change between versions for a given error condition, so it is safe to branch on in client code. Defaults to `unspecified` when the server has not assigned a specific code.
    Example: blockchain.not_found

## Response 400 examples:

  - `The create-invoice request body contains malformed JSON` (unknown)

## Response 401 examples:

  - `The API service refused authentication` (unknown)

## Response 403 examples:

  - `The API key lacks the required permission` (unknown)

