Duvet DOCS
GitHub

Webhooks

Endpoints for managing and executing webhooks. Management endpoints require the ManageSpaceWebhooks permission. Execution endpoints use the webhook token for authentication and do not require a user session.

Notes

  • Webhooks can only be created on text rooms (room type 0).
  • The webhook token is shown only once on creation (and again when reset). Store it securely.
  • The webhook URL format is: https://{domain}/api/webhooks/{webhookId}/{token}
  • Messages sent by webhooks have author_id set to null and webhook_id set to the webhook’s ID.
  • The webhook’s username and avatar at the time of sending are stored in the message’s webhook_author JSONB field (see WebhookAuthor).

Management Endpoints

All management endpoints require the ManageSpaceWebhooks permission.

List Room Webhooks

GET /api/spaces/{spaceId}/rooms/{roomId}/webhooks

List all webhooks for a room.

Returns: Array of Webhook objects.

Create Webhook

POST /api/spaces/{spaceId}/rooms/{roomId}/webhooks

Create a new webhook for a room. Supports multipart/form-data for avatar upload.

Multipart Body

FieldTypeDescription
username stringDisplay name for the webhook (max 64 characters)
avatar ?fileAvatar image file

Returns: Object containing a Webhook object and the webhook token (string). The token is only shown on creation.

Errors: 400 when the avatar isn't an image; 413 when it's over 10 MB or the space bucket's limits; 422 when the space has no storage bucket. In all of them the webhook isn't created.

{
  "webhook": { "id": "...", "room_id": "...", "username": "...", "avatar": null },
  "token": "abc123..."
}

Get Webhook

GET /api/spaces/{spaceId}/rooms/{roomId}/webhooks/{webhookId}

Get a specific webhook.

Returns: Webhook object.

Update Webhook

PATCH /api/spaces/{spaceId}/rooms/{roomId}/webhooks/{webhookId}

Update a webhook. Supports both JSON and multipart/form-data for avatar upload.

JSON Body

FieldTypeDescription
username ?stringNew display name (max 64 characters)
avatar ?string?An empty string removes the avatar; null or its current ID keeps it. A new one is uploaded (multipart body): any other value is a 400

Multipart Body

Supports file upload for avatar:

FieldTypeDescription
username ?stringNew display name (max 64 characters)
avatar ?fileAvatar image file
remove_avatar ?stringSet to "true" to remove the avatar

A replaced or removed avatar isn't deleted: the messages the webhook sent with it still show it (webhook_author). It stays in the space's attachments, where it can be deleted.

Returns: Webhook object.

Errors: 400 when the avatar isn't an image, or a JSON avatar sets one; 413 when it's over 10 MB or the space bucket's limits.

Delete Webhook

DELETE /api/spaces/{spaceId}/rooms/{roomId}/webhooks/{webhookId}

Delete a webhook.

Returns: 204 No Content

Reset Webhook Token

POST /api/spaces/{spaceId}/rooms/{roomId}/webhooks/{webhookId}/reset-token

Reset the webhook's token. The old token is immediately invalidated.

Returns: Object containing the new token (string).

{ "token": "xyz789..." }

Execution Endpoints

Execution endpoints do not require user authentication. The webhook token in the URL serves as the credential.

Execute Webhook

POST /api/webhooks/{webhookId}/{token}

Send a message as this webhook. At least one of content or embeds must be provided.

JSON Body

FieldTypeDescription
content ?string?Message text content (max 5000 characters)
embeds ?Embed[]Array of embed objects
username ?stringOverride the webhook's display name for this message
avatar ?stringOverride the webhook's avatar for this message

Returns: 204 No Content

Execute Webhook (GitHub)

POST /api/webhooks/{webhookId}/{token}/github

Receive GitHub webhook events and convert them to rich embed messages. Configure this URL as the Payload URL in your GitHub repository's webhook settings with Content type: application/json.

No request body needed — GitHub sends the payload automatically. The event type is read from the X-GitHub-Event header. Messages are sent with username: "GitHub".

Supported Events

push, pull_request, pull_request_review, pull_request_review_comment, pull_request_review_thread, issues, issue_comment, commit_comment, create, delete, release, star, fork, deployment, deployment_status, workflow_run, workflow_job, check_run, check_suite, discussion, discussion_comment, label, milestone, member, repository, repository_ruleset, branch_protection_rule, branch_protection_configuration, code_scanning_alert, secret_scanning_alert, dependabot_alert, repository_vulnerability_alert, security_advisory, security_and_analysis, deploy_key, package, registry_package, page_build, gollum (wiki), status, team_add, merge_group, meta, ping.

Unrecognized events produce a generic notification. The watch event is silently ignored (duplicates star).

Returns: 204 No Content