Agent webhooks
Workspace webhooks let your own Claude Code process, automation, or queue consumer react to mdedit activity without continuously polling. mdedit can deliver:
review.mentionedwhen a new comment or reply contains an@handlereview.repliedwhen someone replies to a review threadarticle.updatedwhen document content is committed or checkpointed
Create a webhook
Workspace owners and admins can manage webhooks with a JWT or an API key scoped with
workspaces:write. The destination must use HTTPS and resolve only to public addresses.
curl -X POST "https://apiv2.mdedit.ai/workspaces/$WORKSPACE_ID/webhooks" \
-H "x-api-key: $MDEDIT_API_KEY" \
-H "content-type: application/json" \
-d '{
"url": "https://agents.example.com/mdedit",
"events": ["review.mentioned", "review.replied", "article.updated"]
}'The create response contains a secret beginning with whsec_. It is shown only once;
store it in your secret manager. GET lists configured webhooks without secrets.
PATCH /workspaces/{workspaceId}/webhooks/{webhookId} updates the URL, subscriptions,
or active state; send { "rotateSecret": true } to receive a new one-time secret.
Verify a delivery
Verify the signature against the exact raw request body before parsing JSON. The signed
message is <timestamp>.<raw-body> and the digest uses HMAC-SHA256:
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyMdeditWebhook({ rawBody, timestamp, signature, secret }) {
const expected = `v1=${createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex')}`;
const left = Buffer.from(expected);
const right = Buffer.from(signature ?? '');
return left.length === right.length && timingSafeEqual(left, right);
}Deliveries include x-mdedit-event, x-mdedit-delivery, x-mdedit-timestamp, and
x-mdedit-signature. Reject stale timestamps according to your own replay window and
deduplicate work by x-mdedit-delivery.
Delivery behavior
The JSON body includes id, event, createdAt, workspaceId, and event-specific
data. mdedit treats any non-2xx response or network error as a failed attempt and
retries with exponential backoff. Redirects are not followed. A webhook that is deleted,
disabled, or unsubscribed before a queued attempt runs is skipped.
For a process that already has an article ID and should remain attached to one document,
you can also stream events with mdedit article watch <articleId>.