Webhooks
Barakah Tasks webhooks deliver published CloudEvents to an HTTPS receiver even when no MCP client or model session is connected. MCP remains the authenticated control plane for creating, inspecting, pausing, resuming, rotating, replaying, and deleting subscriptions.
Use events:read plus the underlying read scopes for the selected event types.
Webhook reads require webhooks:read; controls require webhooks:write.
Endpoint verification
Section titled “Endpoint verification”Creating a subscription queues one durable verification attempt. Repeated verification commands coalesce while that attempt is live, so they reuse the same challenge. The challenge expires after ten minutes.
Generation 6 subscriptions use the selected structured or binary representation
and the same v2 signature profile as production. The CloudEvent data object is
closed:
{"version":"2","kind":"barakah.webhook.verification","subscription_id":"<subscription-id>","probe_id":"<probe-id>","challenge":"<challenge>"}Locate that five-key object from the received Content-Type:
- For binary v2
application/json, the entire parsed request body is the five-key object. Echo the entire parsed body exactly; never usebody.data. - For structured v2
application/cloudevents+json, the parsed request body is a CloudEvents envelope. Echo only the five-key object atbody.data, never the envelope.
This rule is vendor-neutral: select the body location from Content-Type, not
from whether the receiver is n8n, Activepieces, Zapier, Make, or custom code.
The platform-specific field name may differ, but it must resolve to the same
five-key object. A host that exposes neither a customizable synchronous response
nor an outbound step for asynchronous confirmation needs a small compatible
HTTP ingress in front of it; it is not a reason for a vendor-specific Barakah
wire format.
Return exactly those five keys as UTF-8 JSON with base media type
application/json and no more than 1024 bytes. Key order and insignificant JSON
whitespace are ignored. Missing or unknown keys, duplicate JSON keys, malformed
UTF-8, wrong values, the wrong media type, and oversized output are rejected.
Compare the challenge through a constant-time digest comparison. The challenge
expires after ten minutes and can activate the subscription once only.
Legacy subscriptions retain their version 1 verification representation. A host that cannot customize its callback response can submit the same version-specific object asynchronously. For v2, post that same five-key object directly, not a CloudEvents envelope, to:
POST https://mcp.barakahtasks.com/webhooks/verification/confirmContent-Type: application/jsonEvery syntactically valid asynchronous submission receives HTTP 202, including unknown, stale, expired, already used, or incorrect challenges. This public route does not reveal whether a subscription or attempt exists. Read the authenticated subscription to see the truthful verification status, expiry, failure code, and recovery action. A valid confirmation activates promptly and both confirmation paths use the same atomic activation operation.
Replacing an active endpoint immediately stops new delivery to the old
receiver. Matching events advance the subscription cursor and form an
endpoint_reverification gap until the replacement proves possession. They do
not flow automatically after activation; use explicit replay if they are still
required.
HTTP Message Signatures v2
Section titled “HTTP Message Signatures v2”Every new endpoint or delivery-mode revision uses
barakah.http-message-signatures.v2: RFC 9421 HTTP Message Signatures with
Ed25519 and an RFC 9530 Content-Digest. Preserve the untouched body bytes.
Pin both the exact subscription ID and the authenticated MCP-returned whpk_
public key for that subscription. Reject an unpinned key, a mismatched
barakah-subscription-id, or a keyid that does not match the pinned public
key. A valid signature delivered to the wrong receiver must fail those checks.
Signature-Input and Signature contain barakah-current first. During an
eligible same-endpoint rotation overlap they contain barakah-previous second.
Parameters are exactly ordered created, expires, keyid, alg, tag, with
alg="ed25519" and tag="barakah.http-message-signatures.v2". keyid is the
unpadded base64url SHA-256 digest of the raw 32-byte public key.
The digest is exactly
sha-256=:<standard-padded-Base64-of-the-raw-body-SHA-256>:. expires must
equal created + 300; webhook-timestamp is the same unsigned decimal as
created. Accept only from 60 seconds before created through 60 seconds after
expires. All profile headers are emitted once with lowercase names. Reject
duplicates, obsolete folding, malformed structured fields, missing components,
and non-canonical decimal values.
Covered components
Section titled “Covered components”Structured production, in order:
@method content-digest content-type webhook-id webhook-timestampbarakah-subscription-id barakah-endpoint-generation barakah-message-kindbarakah-event-id barakah-delivery-id barakah-attempt-idbarakah-replay-generation barakah-key-idStructured verification, in order:
@method content-digest content-type webhook-id webhook-timestampbarakah-subscription-id barakah-endpoint-generation barakah-message-kindbarakah-probe-id barakah-key-idBinary production has exactly two valid covered-component sequences, with or
without ce-barakahresourceat at position 12; the verifier rejects every other
shape:
@method content-digest content-type ce-specversion ce-id ce-source ce-typece-subject ce-time ce-barakahpublishedat ce-barakahsubscriptionsequence[ce-barakahresourceat] webhook-id webhook-timestamp barakah-subscription-idbarakah-endpoint-generation barakah-message-kind barakah-event-idbarakah-delivery-id barakah-attempt-id barakah-replay-generation barakah-key-idBinary verification, in order:
@method content-digest content-type ce-specversion ce-id ce-source ce-typece-subject ce-time webhook-id webhook-timestamp barakah-subscription-idbarakah-endpoint-generation barakah-message-kind barakah-probe-id barakah-key-id@method is POST. Structured content type is exactly
application/cloudevents+json; binary is exactly application/json, without
parameters. Binary CloudEvents use specversion 1.0, source
https://barakahtasks.com/events, the registry type and subject, and the exact
received RFC 3339 ce-time text. Production always signs authoritative
ce-barakahpublishedat and ce-barakahsubscriptionsequence.
ce-barakahresourceat is informational but must be covered when present and
must never drive authorization or routing. Future extensions are
non-authoritative unless a new profile version adds them to an ordered list.
Endpoint or mode changes create a fresh subscription key without overlap. Explicit rotation on the same endpoint revision retains the previous key for 96 hours; both signatures have the same receiver audience. During that overlap, the verifier accepts the matching signed member for either authenticated pinned key, so a receiver can move from the previous pin to the current pin safely.
Copy-paste Node verifier
Section titled “Copy-paste Node verifier”Download the copy-paste Node verifier and the
fixed positive and negative vectors.
The verifier accepts raw body bytes, request headers, the expected subscription
ID, and the pinned whpk_ public key. It validates the profile, clock window,
digest, exact component order, signature, key pin, subscription audience, and
message-kind invariants. The vectors cover structured and binary production,
both binary production shapes, structured and binary verification, dual-key
overlap, body/header tampering, component changes, duplicates, time failures,
wrong keys/subscriptions, and unsigned authoritative extensions.
Legacy Standard Webhooks signature
Section titled “Legacy Standard Webhooks signature”Callbacks use the Standard Webhooks 1.0.0 Ed25519 profile. Preserve the raw request body bytes. Do not parse and reserialize JSON before verification.
The signed bytes are:
webhook-id + "." + webhook-timestamp + "." + raw-bodyRequired headers are:
webhook-id: the immutable CloudEvent ID for event delivery, or the durable verification-attempt ID for verification.webhook-timestamp: Unix seconds for this HTTP request.webhook-signature: one or more space-delimitedv1a,<standard-base64-signature>values.
The authenticated subscription read returns Ed25519 public keys serialized as
whpk_ followed by standard Base64 of the raw 32-byte public key. Trust that
control-plane value or a separately pinned configuration. Never trust a key
that appears only in the callback.
During rotation, callbacks carry current and previous signatures for 96 hours. Verify each member against its corresponding current or previous key. The overlap is longer than the 72-hour automatic retry horizon.
Download the fixed byte-exact vector and the independent Node verifier. The vector contains synthetic keys only.
Identity, retries, and replay
Section titled “Identity, retries, and replay”The CloudEvent id and webhook-id identify the underlying business event.
They remain stable across automatic retry and explicit replay, but they are not
the receiver’s delivery-deduplication key.
- Automatic HTTP retry is the same logical delivery:
barakah-delivery-idandbarakah-replay-generationstay stable whilebarakah-attempt-id,webhook-timestamp, and the signature change. Deduplicate repeated attempts by the stable delivery identity. - Explicit Barakah replay preserves the event ID but creates a new deliberate
barakah-delivery-idand replay generation. It is allowed to execute again. Never deduplicate explicit replay by CloudEvent ID alone. barakah-attempt-id,webhook-timestamp, and the signature change for every HTTP request.- The CloudEvent extension
barakahsubscriptionsequenceis monotonic only within one subscription. It is stable on replay and does not reveal Barakah Tasks’ private global event position.
Delivery is at least once and is not globally ordered. A slow earlier event does not hold later events behind its backoff. Use the subscription sequence to detect ordering or gaps when that matters to the automation.
Network failures, 408, 429, and 5xx responses retry with full-jitter
exponential backoff for at least 72 hours. A bounded Retry-After is honored.
Ordinary terminal failures degrade health, create a visible gap, and allow
later events to progress. HTTP 410 pauses the subscription immediately and
atomically creates a receiver_gone gap.
Automatic retries use the original delivery’s pinned endpoint generation, filter revision, delivery mode, and wire profile. After repairing or replacing a receiver, complete any required verification or resume transition, then explicitly replay the exact preserved gap. Explicit replay uses the endpoint revision active when replay starts, keeps the CloudEvent ID and subscription sequence, and creates a new delivery ID and replay generation.
Task-ref filters bind to the selected occurrence row only. There is no series-wide selector. When a recurring task is selected, the agent must tell the user that only that occurrence matches instead of silently narrowing “this task.”
Operational limits
Section titled “Operational limits”These are operational limits, not a plan feature: the numbers may change as usage patterns become clearer, and a receiver should treat them as capacity boundaries to design around rather than as marketed capabilities.
Subscriptions. An account may hold at most 5 subscriptions on any single connection and 20 subscriptions total across every connection combined. Creating past either bound is rejected with a clear error; delete an unused subscription to free a slot.
Delivery allowance. Each account has a rolling 30-day allowance of logical deliveries. One delivery ID is one logical delivery, so:
- Automatic HTTP retry attempts on the same delivery are free: they never count again against the allowance.
- An explicit replay creates a new delivery ID and does count, even when it replays an event that was already delivered once.
If an account’s rolling usage is exhausted, the affected subscription stops receiving new deliveries and the gap tracking already described above records exactly what was skipped: nothing is silently dropped. The subscription resumes receiving new deliveries once the rolling window has room again; nothing needs to be done manually, and once resumed, the gapped window remains available for explicit replay as usual.
Hidden attempt ceiling. Each account also has a short rolling ceiling on outbound HTTP attempts. This is invisible in ordinary operation: when it is reached, the affected delivery’s next attempt is deferred rather than failed; no attempt is consumed, the 72-hour retry window is not shortened, and the receiver sees no behavior change beyond the delivery arriving a little later than it otherwise would have. At-least-once delivery and the retry contract above are preserved throughout.
n8n and Activepieces
Section titled “n8n and Activepieces”For n8n, choose binary mode after the workflow’s Webhook node can retain the raw
request bytes for signature verification. The parsed request body is already the
event data JSON, while CloudEvents attributes and Barakah delivery identities
are in headers. The intended exact-task flow can route that JSON directly into
Gmail without extracting an uploaded file or filtering task IDs again in n8n;
the subscription filter is authoritative. If the installed trigger cannot make
the raw bytes available before parsing, use structured mode until it can. Do not
re-serialize parsed JSON and treat it as the signed body.
Activepieces should receive the same generic binary or structured HTTP request
through its normal /sync ingress. Diagnose raw-body access, header retention,
and custom verification-response support at that ingress. Record any residual
receiver limitation as receiver-class evidence; do not add an Activepieces-only
wire branch.
A receiver 2xx acknowledges only that one HTTP attempt. It does not prove that a downstream Gmail send or other workflow side effect completed. Make the receiver durably accept its own work before acknowledging, and use the platform’s own execution records for downstream confirmation.
Receiver checklist
Section titled “Receiver checklist”- Read and pin the current and previous public keys from the authenticated subscription.
- Pin the exact subscription ID and reject a callback for another audience.
- Read the raw body and required profile headers without changing the bytes.
- Apply the v2 60-second skew and five-minute expiry checks, then verify the exact covered-component sequence and current Ed25519 signature.
- Deduplicate automatic attempts by delivery ID; allow a new explicit replay generation to execute even when the event ID was seen before.
- Return a 2xx response only after the receiver has durably accepted the callback.
- Monitor subscription health and open gaps through MCP.