Docs

Webhooks

Webhooks Quickstart

Webhooks are the fastest way to send messages into a Chattr text channel.

Create a webhook

  1. Open the developer portal.
  2. Choose the server and text channel.
  3. Create a Webhook app.
  4. Copy the generated webhook URL.

Send a message

POST /webhooks/:appId/:token
Content-Type: application/json

{
  "content": "Deploy completed successfully."
}

Optional fields:

  • name: override the webhook display name for this message
  • avatarUrl: override the webhook avatar for this message
  • allowedMentions: opt the payload into mention notifications

Controlling mentions

By default, a webhook message does not fire mention notifications even if its content contains @all, a role mention, or @nickname. This is the safe default — a leaked webhook token can't be used to page the server. Opt in explicitly via allowedMentions.parse:

Token Enables
"all" @all group notification (requires the webhook creator to still hold the Mention @all channel permission)
"roles" Notifications for mentioned roles (@role_name / @role_NNN) — mentionable roles fire for everyone; non-mentionable roles still require the creator to hold Mention @all
"users" Direct @nickname user mentions, and resolves @<USERID> ID mentions (see below)

Example — ping the whole channel on a deploy failure:

{
  "content": "@all deploy failed — rolling back",
  "allowedMentions": { "parse": ["all"] }
}

Pass an empty array (or omit the field) to send a silent message that mentions no one regardless of its content:

{
  "content": "@all nothing to see here",
  "allowedMentions": { "parse": [] }
}

Mentioning users by ID

Nicknames change. To reliably ping a specific user, reference them by their numeric user ID using @<USERID>:

{
  "content": "Build failed — @<42> please check the log.",
  "allowedMentions": { "parse": ["users"] }
}
  • @<42> is rewritten server-side to @<current_nickname> before storage, so the message renders as a normal user-mention pill in the UI.
  • Rewriting only happens when allowedMentions.parse includes "users". Without it the literal @<42> is preserved and no notification fires.
  • The target must be a member of the webhook's server; unresolvable IDs are left as literal text.
  • Webhook payloads can contain up to 16 distinct @<USERID> tokens. Additional tokens beyond that cap are not resolved.

Code examples

cURL

curl -X POST "https://chattr.example.com/webhooks/APP_ID/WEBHOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": "Deploy completed successfully."}'

JavaScript (Node.js)

const WEBHOOK_URL = "https://chattr.example.com/webhooks/APP_ID/WEBHOOK_TOKEN";

const res = await fetch(WEBHOOK_URL, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    content: "Deploy completed successfully.",
    name: "CI Bot",            // optional
    avatarUrl: null             // optional
  })
});

const data = await res.json();
console.log("Message ID:", data.message.id);

Python

import requests

WEBHOOK_URL = "https://chattr.example.com/webhooks/APP_ID/WEBHOOK_TOKEN"

res = requests.post(WEBHOOK_URL, json={
    "content": "Deploy completed successfully.",
    "name": "CI Bot",            # optional
    "avatarUrl": None            # optional
})

data = res.json()
print("Message ID:", data["message"]["id"])

Go

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

func main() {
	webhookURL := "https://chattr.example.com/webhooks/APP_ID/WEBHOOK_TOKEN"

	body, _ := json.Marshal(map[string]any{
		"content": "Deploy completed successfully.",
		"name":    "CI Bot",
	})

	resp, err := http.Post(webhookURL, "application/json", bytes.NewReader(body))
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	fmt.Println("Status:", resp.StatusCode)
}

PHP

$webhookUrl = "https://chattr.example.com/webhooks/APP_ID/WEBHOOK_TOKEN";

$ch = curl_init($webhookUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "content"   => "Deploy completed successfully.",
    "name"      => "CI Bot",       // optional
    "avatarUrl" => null            // optional
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
echo "Message ID: " . $data["message"]["id"];

Permissions

Creating and managing webhooks requires the manage_server permission on the target server. Server owners and administrators have this by default.

Notes

  • Webhooks target one text channel at a time.
  • Regenerating the webhook URL invalidates the old one.