Using Webhooks
Status: Complete
Webhooks let external services send messages into Chatalot channels over HTTP. This page covers creating, using, managing, and securing webhooks.
Security & Privacy: Webhook Messages Are Not End-to-End Encrypted
Important: unlike regular user messages -- which are encrypted client-side before being sent, and unreadable by the server -- webhook messages are stored in plaintext on the server. This is intentional: an external service sending to a webhook URL has no way to obtain a per-user encryption key, so end-to-end encryption isn't possible for that flow.
The practical implications:
- Anyone with database access to the Chatalot server can read webhook messages. That includes the server operator, backup readers, and anyone who compromises the database.
- In the UI, webhook messages display a yellow "Webhook · not E2EE" badge next to the sender name to distinguish them from end-to-end-encrypted user messages.
- Don't send sensitive data through webhooks. Build alerts, deploy notifications, commit messages, and monitoring pings are fine. Passwords, API keys, personal information, and anything private should go through a different channel.
If your integration needs to send sensitive content, have it authenticate as a regular user instead of using a webhook.
What Are Webhooks?
A webhook is a unique URL that, when called with an HTTP POST request, sends a message to a specific channel. This allows tools like CI/CD systems, monitoring alerts, bots, and custom scripts to post updates directly into your Chatalot conversations without needing a full user account.
Webhook messages appear in the channel with a special "Webhook" message type, displaying the webhook's name (or an overridden username) as the sender, and a "Webhook · not E2EE" badge to indicate the message is plaintext on the server.
Who Can Create Webhooks?
Permission required: You must be an Owner or Admin of the channel's community to create, view, edit, or delete webhooks.
Regular members cannot see or manage webhooks.
Creating a Webhook
- In the channel sidebar, right-click (or click the settings icon on) the channel you want to add a webhook to.
- In the Channel Settings card that appears, scroll down to the Webhooks section and click it to expand.
- Type a name for the webhook (1-64 characters) in the input field.
- Click Add.
- The webhook appears in the list. Immediately click "Click to copy URL" to copy the full webhook URL to your clipboard.
Important: The webhook token is only visible when the webhook is first created. If you navigate away without copying the URL, you will not be able to retrieve the token again. You would need to delete the webhook and create a new one.
Webhook URL Format
The webhook URL follows this pattern:
The {token} is a 64-character random string that serves as both the identifier and the authentication secret.
Sending a Message via Webhook
To send a message, make an HTTP POST request to the webhook URL with a JSON body.
Payload Format
{
"content": "Hello from a webhook!",
"username": "CI Bot",
"avatar_url": "https://example.com/bot-avatar.png"
}
| Field | Type | Required | Description |
|---|---|---|---|
content |
string | Yes | The message text (1-4000 characters). Supports Markdown. |
username |
string | No | Override the display name (max 64 characters). Defaults to the webhook's name. |
avatar_url |
string | No | Override the avatar URL for this message. Defaults to the webhook's avatar. |
Example: curl
curl -X POST \
https://your-instance.com/api/webhooks/execute/YOUR_TOKEN_HERE \
-H "Content-Type: application/json" \
-d '{
"content": "Build #142 passed successfully.",
"username": "CI Pipeline"
}'
Example: Python
import requests
webhook_url = "https://your-instance.com/api/webhooks/execute/YOUR_TOKEN_HERE"
requests.post(webhook_url, json={
"content": "Deployment complete. Version 2.1.0 is live.",
"username": "Deploy Bot"
})
Example: JavaScript (Node.js)
const response = await fetch(
"https://your-instance.com/api/webhooks/execute/YOUR_TOKEN_HERE",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
content: "New issue opened: Fix login timeout",
username: "Issue Tracker"
})
}
);
Response
- 201 Created -- message was posted. The JSON body confirms delivery so an automation caller can verify it landed:
{
"message_id": "019e92d7-b585-7e02-b5f5-fed2a60c86aa",
"channel_id": "019e6632-06f7-7c62-9955-b0ce707b36b5",
"created_at": "2026-06-04T13:34:30.789723+00:00",
"status": "ok"
}
(Prior to v0.25.23 this was an empty 200 OK.)
- 404 Not Found -- the webhook token is invalid or the webhook has been deactivated.
- 422 Validation Error -- the payload is invalid (e.g., content is empty or exceeds 4000 characters).
Managing Webhooks
Viewing Webhooks
- Open the channel settings card for the channel.
- Expand the Webhooks section.
- All webhooks for that channel are listed with their name and active status.
Enabling / Disabling a Webhook
Each webhook has an ON/OFF toggle. Click it to enable or disable the webhook. A disabled webhook will return a 404 error when called, effectively pausing it without deleting it.
Editing a Webhook
Webhooks can be updated via the API:
Updatable fields:
| Field | Type | Description |
|---|---|---|
name |
string | New webhook name (1-64 characters) |
avatar_url |
string or null | New default avatar URL, or null to remove |
active |
boolean | Enable or disable the webhook |
This endpoint requires authentication (a logged-in admin/owner session).
Deleting a Webhook
In the webhooks list in the channel settings card, click the X button next to the webhook you want to delete. A confirmation dialog will appear. Deleting a webhook is permanent and immediately invalidates its URL.
Mentions
A webhook post can @mention channel members, and they will be notified -- a
live in-app alert if they are online, a push notification if they are offline
and have push enabled. This works because webhook content is plaintext (webhook
messages are not end-to-end encrypted), so the server can read it and resolve
mentions; normal end-to-end-encrypted messages cannot be parsed server-side and
do not generate mention notifications.
Rules:
- Use
@usernamewith the member's exact username (case-sensitive). Only alphanumeric and underscore characters are matched, matching the in-app mention behaviour -- usernames containing hyphens or dots are not currently mention-addressable. - Only members of the webhook's channel are notified. Mentioning a user who is not in the channel does nothing.
- Audience mentions (
@everyone,@here,@channel) are not acted on for webhook posts -- they are ignored. - Mentions are de-duplicated, and at most 50 distinct users are notified per post.
Example:
Security Considerations
Treat your webhook URL like a password. Anyone who has the URL can post messages to your channel.
Best practices:
- Never commit webhook URLs to public repositories. Use environment variables or secret management tools.
- Rotate webhooks periodically. Delete the old webhook and create a new one if you suspect the URL has been exposed.
- Disable unused webhooks rather than leaving them active. This prevents abuse if an old URL is discovered.
- Monitor webhook usage. If unexpected messages appear in a channel, check the webhooks list and revoke any compromised ones.
- Use HTTPS. Always ensure your Chatalot instance is served over HTTPS so webhook tokens are encrypted in transit.
Limitations
- Webhook messages support plain text and Markdown but cannot include file attachments.
- The
contentfield is limited to 4000 characters per message. - The
usernameoverride is limited to 64 characters. - Webhook execution does not require authentication -- the token in the URL is the only credential.
- The webhook token is only shown once at creation time.
- Only
@usernamementions (alphanumeric + underscore) are notified; audience mentions (@everyone/@here/@channel) are ignored, and at most 50 distinct users are notified per post.