# Notification channels

Notification channels are the delivery mechanism for blockchain [event](/guides/events) alerts. When Vilna detects activity on your monitored addresses, it sends a notification through your configured channels.

Two channel types are available: **Webhook** and **Telegram**.

## Channel types at a glance

|  | Webhook | Telegram |
|  --- | --- | --- |
| **Delivery** | HTTP POST to your endpoint | Bot message to a chat |
| **Format** | JSON (TransactionAlertPayload) | Formatted text message |
| **Best for** | Automated systems, backends | Human monitoring, alerts |
| **Auth** | Custom headers (HMAC signatures planned) | Bot token from @BotFather |


## Blockchain webhook notifications

Webhook channels send an HTTP POST request with a JSON payload to your endpoint each time a tracked transaction is detected.

### Creating a webhook channel

curl

```bash
curl -X POST "https://api.vilna.io/v1/channels" \
  -H "X-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Webhook",
    "config": {
      "kind": "webhook",
      "url": "https://api.example.com/webhooks/vilna",
      "headers": {
        "Authorization": "Bearer your-secret-token"
      }
    }
  }'
```

TypeScript

```typescript
import { createVilnaClient } from "@vilna/sdk";

const client = createVilnaClient({
  apiKey: "your-api-key",
});

const { data, error } = await client.POST("/channels", {
  body: {
    name: "Production Webhook",
    config: {
      kind: "webhook",
      url: "https://api.example.com/webhooks/vilna",
      headers: {
        Authorization: "Bearer your-secret-token",
      },
    },
  },
});
```

### Webhook payload structure

Every webhook delivery sends a `TransactionAlertPayload` with three top-level fields:


```json
{
  "item": { /* Transaction object */ },
  "references": {
    "tokens": { /* token GID -> token details */ },
    "blockchains": { /* chain GID -> blockchain details */ },
    "addresses": { /* address -> label */ }
  },
  "is_test_message": false
}
```

- **item** - the full transaction object including events (transfers, fees) and activity records with per-address deltas.
- **references** - lookup maps for tokens, blockchains, and addresses referenced in the transaction, so you do not need additional API calls to resolve names and symbols.
- **is_test_message** - `true` when the payload was triggered by the test action, `false` for real blockchain events.


### Webhook security headers

Planned feature
Webhook signature verification is not yet available. The API currently delivers webhooks without cryptographic signatures. This feature is planned for an upcoming release.

Every webhook request includes four headers for verification:

| Header | Description |
|  --- | --- |
| `X-Webhook-Signature` | HMAC-SHA256 digest of the raw request body |
| `X-Webhook-Timestamp` | Unix timestamp of when the event was sent |
| `X-Webhook-Idempotency-Key` | Unique delivery ID for deduplication |
| `X-Webhook-Event` | Event type (`transaction_alert` or `test`) |


### Verifying the signature

To verify webhook authenticity, see [Webhook signature verification](/guides/authentication#webhook-signature-verification).

## Telegram channels

Telegram channels send formatted messages to a Telegram chat via the Bot API.

### Setup

1. Create a bot with [@BotFather](https://t.me/BotFather) and save the bot token.
2. Add the bot to your target chat (group, channel, or direct message).
3. Get the chat ID (use [@userinfobot](https://t.me/userinfobot) or the Telegram `getUpdates` API).


### Creating a Telegram channel

curl

```bash
curl -X POST "https://api.vilna.io/v1/channels" \
  -H "X-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Ops Alerts",
    "config": {
      "kind": "telegram",
      "bot_token": "123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789",
      "chat_id": -1001234567890,
      "language": "en",
      "thread_id": 0
    }
  }'
```

TypeScript

```typescript
const { data, error } = await client.POST("/channels", {
  body: {
    name: "Ops Alerts",
    config: {
      kind: "telegram",
      bot_token: "123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789",
      chat_id: -1001234567890,
      language: "en",
      thread_id: 0,
    },
  },
});
```

**Config fields:**

| Field | Type | Description |
|  --- | --- | --- |
| `bot_token` | string | Token from @BotFather (`{bot_id}:{auth_token}`) |
| `chat_id` | integer | Target chat ID (positive for DMs, negative for groups/channels) |
| `language` | string | Message language (`"en"`, `"ru"`, etc.) |
| `thread_id` | integer | Forum topic thread ID (0 for no specific thread) |


## Delivery logs

Delivery logs record the outcome of every notification attempt for a channel - both webhook HTTP calls and Telegram bot messages. Use them to verify that notifications are reaching their destination and to debug failed deliveries.

Fetch logs with [`GET /channels/{channel_id}/logs`](/apis/platform/api/channel/list-channel-logs). The response is a paginated list sorted by most recent delivery first.

**Query parameters:**

| Parameter | Type | Description |
|  --- | --- | --- |
| `is_success` | boolean | Filter by outcome. `true` for successful deliveries (HTTP 2xx), `false` for failures. Omit to return all. |
| `event_type` | string | Filter by event type: `transaction_alert` (real events) or `test` (test message deliveries). |
| `page` | integer | Page number for pagination. |
| `limit` | integer | Number of items per page. |



```bash
# List failed deliveries for a channel
curl "https://api.vilna.io/v1/channels/{channel_id}/logs?is_success=false" \
  -H "X-Api-Key: your-api-key"
```

**When to use delivery logs:**

- After creating and testing a channel, confirm the test delivery was logged as successful.
- When notifications stop arriving, query with `is_success=false` to find the HTTP status codes and error details returned by your endpoint.
- Filter by `event_type=test` to separate test traffic from production deliveries.


## Channel lifecycle

Channels follow a fixed lifecycle: **create**, **test**, **use**, **update**, **delete**.

| Action | Endpoint | Description |
|  --- | --- | --- |
| Create | `POST /channels` | Create a new channel |
| Test | `POST /channels/{channel_id}/actions/test` | Send a test payload to verify delivery |
| Update | `PATCH /channels/{channel_id}` | Update channel name or config |
| Delete | `DELETE /channels/{channel_id}` | Permanently remove the channel |


### Testing a channel

Always test a channel after creation to verify delivery works:

curl

```bash
curl -X POST "https://api.vilna.io/v1/channels/{channel_id}/actions/test" \
  -H "X-Api-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{ "message_type": "transaction_alert" }'
```

TypeScript

```typescript
const { data, error } = await client.POST(
  "/channels/{channel_id}/actions/test",
  {
    params: { path: { channel_id: channelId } },
    body: { message_type: "transaction_alert" },
  }
);
```

The test sends a sample `TransactionAlertPayload` with `is_test_message: true`.

## Best practices

- **Test before relying on a channel.** Send a test payload immediately after creation.
- **Verify webhook signatures (when available).** Always validate `X-Webhook-Signature` to ensure payloads are authentic.
- **Handle duplicates.** Use `X-Webhook-Idempotency-Key` to skip duplicate deliveries.
- **Respond quickly.** Webhook endpoints must return HTTP 2xx within 10 seconds. Process the payload asynchronously.
- **Use separate channels** for different environments (development, staging, production) and different purposes (critical alerts vs routine notifications).


## Further reading

Events
Understand event types and delivery guarantees

Authentication
Webhook signature verification code examples

Integration Patterns
Common architectures for deposit detection and payments

Platform API
Complete endpoint documentation for notification channels