Add a webhook
Under Develop → Webhooks, select Add Webhook and give it a destination URL. Every webhook is scoped by three independent choices: the channel it renders for, the events it fires on, and — optionally — a single flag or environment.
Paste an Incoming Webhook URL from Slack. Events render as a readable block message, no payload wrangling required.
Paste a Teams Workflow URL. See Notifications & Teams for the full setup walkthrough.
Point at any HTTPS endpoint you control. Add a signing secret so you can verify each request came from Maxlona.
Authenticate outgoing requests
Two independent mechanisms protect a webhook, and you can use either or both.
Outbound API key
An API key attached to every request this webhook sends, so your receiving server can authenticate the caller. Available on any channel type, and stored keys are never displayed again after creation — only rotated or removed.
| How it's sent | Where it lands | Example |
|---|---|---|
| Custom HTTP header | A header name you choose | X-API-Key: <key> |
| Authorization: Bearer | The standard bearer scheme | Authorization: Bearer <key> |
| Query string parameter | A parameter name you choose | ?api_key=<key> |
Signing secret (Generic channel)
A Generic webhook can also carry a signing secret. When set, every request includes an X-Webhook-Signature header — an HMAC-SHA256 digest of the raw request body — plus X-Webhook-Event naming the event. Recompute the digest with your stored secret and compare before trusting the payload.
Scope deliveries
Flag and Environment both default to Any, giving you one organization-wide feed. Narrow either dropdown to build a webhook dedicated to a single release or a single environment — useful for routing a noisy flag's changes to its own channel without touching the org-wide feed.
Event types
Select any combination, or every event for a complete operational feed.
| Area | Events | Useful for |
|---|---|---|
| Flags | flag.created, flag.updated, flag.evaluation_changed, flag.deleted, flag.archived, flag.promoted, flag.unpromoted, flag.toggled | Release visibility, including dependency and automation effects |
| Approvals | approval.pending, approval.approved, approval.rejected | Review queues and governance |
| Kill switch | killswitch.activated, killswitch.cleared | Incident response |
| Billing | subscription.activated, subscription.canceled, payment.succeeded, payment.failed | Account health |
Delivery log, retries, and testing
Every dispatch attempt is recorded per webhook, with the request status, HTTP response code, duration, and — for the Generic channel — the exact payload sent. Use Test to send a sample event on demand without waiting for a real change.
| Status | Meaning |
|---|---|
| Delivered | The endpoint accepted the request. |
| Pending | Queued, or waiting on its next retry attempt. |
| Failed | The most recent attempt errored; a retry is scheduled if attempts remain. |
| Dead | Every automatic attempt was exhausted. Replay it manually from the delivery log. |
Failed requests retry automatically with exponential backoff, up to five attempts, before being marked dead. A dead or failed delivery can be replayed manually at any time from the deliveries panel — deleting a webhook stops future events but keeps its delivery history.
Payload shape
Every Generic-channel delivery shares the same envelope, regardless of event type — only data changes shape per event.
{
"eventType": "flag.toggled",
"timestamp": "2026-09-08T14:32:07Z",
"data": {
"flag": "new-payment-screen",
"environment": "prod",
"action": "enabled"
}
}Slack and Microsoft Teams webhooks receive this same data pre-formatted as a chat message or Adaptive Card instead of raw JSON — nothing further to parse on your end.