Skip to main content

Overview

The Channel Webhooks API allows you to create incoming webhooks that can post messages to channels programmatically. Webhooks are useful for integrations with external services like CI/CD pipelines, monitoring tools, and third-party applications. Each webhook creates a bot user that posts messages on behalf of the webhook. Only organization admins can manage webhooks.

Security

  • Webhook tokens are only shown once during creation or regeneration
  • Tokens are stored as SHA-256 hashes in the database
  • Tokens can be regenerated at any time, immediately invalidating the old token
  • Webhooks can be enabled/disabled without regenerating tokens

Methods

channelWebhook.create

Creates a new webhook for a channel. A new bot user is created for this webhook. Returns the webhook data including the plain token (only shown once).
channelId
string
required
Channel ID where the webhook will post messages
name
string
required
Webhook name (1-100 characters)
description
string
Webhook description (max 500 characters)
avatarUrl
string
Avatar URL for the webhook bot user
integrationProvider
'openstatus' | 'railway'
When set, uses a global integration bot user instead of creating a unique webhook bot
data
ChannelWebhook
token
string
Plain webhook token (only returned once)
webhookUrl
string
Full webhook URL for posting messages
transactionId
string
Transaction ID for optimistic updates
const result = await client.channelWebhook.create({
  channelId: "ch-abc123",
  name: "CI/CD Notifications",
  description: "Notifications from GitHub Actions",
  avatarUrl: "https://example.com/avatar.png"
});

// Save the token and webhookUrl - they won't be shown again!
console.log(result.token);
console.log(result.webhookUrl);
Important: Store the token and webhookUrl securely. The token cannot be retrieved again after creation. Errors:
  • ChannelNotFoundError - Channel doesn’t exist
  • UnauthorizedError - User is not org admin
  • InternalServerError - Unexpected server error

channelWebhook.list

Lists all webhooks for a channel.
channelId
string
required
Channel ID
data
ChannelWebhook[]
Array of webhook objects (without token hashes)
const result = await client.channelWebhook.list({
  channelId: "ch-abc123"
});
Errors:
  • ChannelNotFoundError - Channel doesn’t exist
  • UnauthorizedError - User is not org admin
  • InternalServerError - Unexpected server error

channelWebhook.listByOrganization

Lists all webhooks for the user’s organization. Used by the integration settings page to show all configured webhooks.
data
ChannelWebhook[]
Array of webhooks across all channels in the organization
const result = await client.channelWebhook.listByOrganization({});
Errors:
  • UnauthorizedError - User is not authenticated
  • InternalServerError - Unexpected server error

channelWebhook.update

Updates webhook configuration (name, description, avatar, enabled).
id
string
required
Webhook ID to update
name
string
New webhook name (1-100 characters)
description
string | null
New description (max 500 characters) or null to remove
avatarUrl
string | null
New avatar URL or null to remove
isEnabled
boolean
Enable or disable the webhook
data
ChannelWebhook
Updated webhook object
transactionId
string
Transaction ID for optimistic updates
const result = await client.channelWebhook.update({
  id: "wh-xyz789",
  name: "GitHub CI/CD"
});
Note: Updating name or avatar also updates the associated bot user. Errors:
  • ChannelWebhookNotFoundError - Webhook doesn’t exist
  • UnauthorizedError - User is not org admin
  • InternalServerError - Unexpected server error

channelWebhook.regenerateToken

Generates a new token for a webhook. The old token is invalidated immediately.
id
string
required
Webhook ID
data
ChannelWebhook
Webhook object with updated tokenSuffix
token
string
New plain webhook token (only returned once)
webhookUrl
string
Updated webhook URL with new token
transactionId
string
Transaction ID for optimistic updates
const result = await client.channelWebhook.regenerateToken({
  id: "wh-xyz789"
});

// Save the new token and URL - the old token is now invalid!
console.log(result.token);
console.log(result.webhookUrl);
Important: The old token is immediately invalidated. Update all systems using the webhook. Errors:
  • ChannelWebhookNotFoundError - Webhook doesn’t exist
  • UnauthorizedError - User is not org admin
  • InternalServerError - Unexpected server error

channelWebhook.delete

Deletes a webhook (soft delete).
id
string
required
Webhook ID to delete
transactionId
string
Transaction ID for optimistic updates
const result = await client.channelWebhook.delete({
  id: "wh-xyz789"
});
Note: The webhook is soft-deleted. The bot user is not automatically deleted and may be cleaned up separately. Errors:
  • ChannelWebhookNotFoundError - Webhook doesn’t exist
  • UnauthorizedError - User is not org admin
  • InternalServerError - Unexpected server error

Using Webhooks

Once created, send POST requests to the webhook URL:
curl -X POST "https://api.hazel.chat/webhooks/incoming/wh-xyz789/your-token" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Build completed successfully!",
    "embeds": [
      {
        "title": "Deployment Status",
        "description": "Production deployment succeeded",
        "color": "#00ff00"
      }
    ]
  }'

Complete Example

// 1. Create webhook
const webhook = await client.channelWebhook.create({
  channelId: "ch-abc123",
  name: "GitHub Actions",
  description: "CI/CD notifications from GitHub"
});

// 2. Store credentials securely
const WEBHOOK_URL = webhook.webhookUrl;
const WEBHOOK_TOKEN = webhook.token;

// 3. Use webhook in external service
await fetch(WEBHOOK_URL, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    content: 'Deployment completed'
  })
});

// 4. Later: Disable temporarily
await client.channelWebhook.update({
  id: webhook.data.id,
  isEnabled: false
});

// 5. If compromised: Regenerate token
const newCreds = await client.channelWebhook.regenerateToken({
  id: webhook.data.id
});

// 6. When done: Delete webhook
await client.channelWebhook.delete({
  id: webhook.data.id
});

Build docs developers (and LLMs) love