Incoming channel webhooks
Deliver external system events as webhook-authored messages in a channel. Operate the secret URL lifecycle, retries, and error recovery as one contract.
Lifecycle
- CREATE
Create
In Incoming webhooks for the destination channel, enter a source-specific name. Organization owners and admins, plus the channel owner, can manage webhooks. Archived channels cannot create them.
- STORE
Store
The complete secret URL is shown once after creation or rotation. Store it in a secret manager and disclose it only to the sending system.
- ROTATE
Rotate
Rotate after exposure or a sender ownership change. The old URL returns 404 immediately, so update the sender with the new URL and send a test request right away.
- REVOKE
Revoke
Revoke a webhook when it is no longer used. Revocation is immediate and irreversible; create a new webhook if the integration is needed again.
Endpoint
Use the exact URL shown after creation. You do not need to assemble webhook_id and secret yourself or add an Authorization header.
POST https://briar-api.wbai.workers.dev/hooks/channels/{webhook_id}/{secret}JSON schema
The body must be application/json and include at least one of text or blocks. No properties beyond those below are accepted.
| Field | Type | Required | Constraints |
|---|---|---|---|
text | string | Conditional | 1–10,000 characters after trimming. Required without blocks; used as the accessibility and notification fallback when both are sent |
blocks | array | Conditional | 1–50 blocks. Supports header, section, markdown, divider, context, and rich_text. Must contain visible text when text is omitted |
eventId | string | No | 1–200 characters after trimming; must exactly match Idempotency-Key when both are sent |
Optional header
Idempotency-Key is also 1–200 characters after trimming. Use it instead of eventId, or send both with exactly the same value.
Runnable curl example
Replace the entire example URL on the first line with the one-time secret URL from Briar, then run the command.
export BRIAR_WEBHOOK_URL='https://briar-api.wbai.workers.dev/hooks/channels/{webhook_id}/{secret}'
curl --fail-with-body \
--request POST \
--url "$BRIAR_WEBHOOK_URL" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: deploy-2026-08-12-001' \
--data '{
"text": "Production deployment completed.",
"blocks": [
{"type":"header","text":{"type":"plain_text","text":"Deployment complete"}},
{"type":"section","text":{"type":"mrkdwn","text":"`v42` is live in *production*."}},
{"type":"divider"},
{"type":"markdown","text":"- [x] Health checks\n- [ ] Monitor metrics"}
]
}'New message response · 201 Created
{
"message": {
"id": "…",
"body": "Production deployment completed.",
"blocks": [
{ "type": "header", "text": { "type": "plain_text", "text": "Deployment complete" } },
{ "type": "section", "text": { "type": "mrkdwn", "text": "`v42` is live in *production*." } },
{ "type": "divider" },
{ "type": "markdown", "text": "- [x] Health checks\n- [ ] Monitor metrics" }
],
"author": {
"type": "webhook",
"id": "…",
"name": "Deploy alerts"
}
},
"duplicate": false
}Idempotency and safe retries
- Use a value that remains stable in the sending system, such as a deployment ID or monitoring event ID.
- Repeating the same key on the same webhook does not create another message. Briar returns the original message with 200 OK and duplicate: true.
- If duplicate requests contain different text or blocks, the first message stays unchanged. Send the same content and key for every attempt of one logical event.
- Without a key, every request creates a message. Use a key for integrations that can retry after a network failure.
Limits
- Request method
- POST only
- Body format
- application/json
- Body size
- 65,536 bytes (64KiB) maximum
- Message content
- text: 1–10,000 characters; blocks: 1–50; markdown blocks: 12,000 characters total
- Idempotency key
- eventId or Idempotency-Key: 1–200 characters
- Request rate
- Up to 60 requests per webhook per 60 seconds
After the secret URL and Content-Type checks pass, a request counts toward the rate limit even when its JSON or fields are invalid.
Errors and recovery
| Status | Meaning | Recovery |
|---|---|---|
400 | Invalid JSON, fields, or mismatched idempotency values | Send valid JSON and check allowed fields, lengths, and equality of the two keys |
404 | Invalid URL, or the webhook was rotated or revoked | Check the stored URL or create a new webhook in the channel |
409 | The destination channel is archived | Unarchive the channel or create a webhook in an active channel |
413 | The body exceeds 65,536 bytes | Summarize the event and retry with a smaller message |
415 | Content-Type is not application/json | Set the Content-Type: application/json header |
429 | The webhook exceeded 60 requests in 60 seconds | Reduce the rate and retry later with the same Idempotency-Key |
500 | Briar could not store the message | Retry with exponential backoff and the same Idempotency-Key |
Operations checklist
- The one-time secret URL is stored in a secure secret manager.
- The same logical event ID remains stable across retries.
- 201 and duplicate 200 are success; 4xx and 5xx use distinct recovery policies.
- There is an owner and procedure for rotating exposed URLs and revoking retired integrations.