Skip to main content
Webhooks push events to your server so you don’t have to poll. They’re the reliable way to learn the outcome of scheduled posts and asynchronous (video) uploads.

Subscribe

curl -X POST https://api.madiad.com/v1/webhooks \
  -H "Authorization: Bearer $MADIAD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "url": "https://example.com/madiad-webhook",
        "events": ["post.published", "post.failed"]
      }'
The response includes a secret — store it. You’ll use it to verify every delivery.

Events

EventFires when
post.publishedA post (immediate or scheduled) goes live on a platform
post.failedA platform rejects the post
Each delivery is a JSON body describing the post, the platform, and the result.

Verify the signature

Every request carries an X-MADIAD-Signature header: an HMAC-SHA256 of the raw request body, keyed with your subscription secret. Recompute it and compare before trusting the payload.
import crypto from "node:crypto";

function verify(rawBody, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected),
  );
}
Verify against the raw, unparsed body. Re-serializing parsed JSON changes the bytes and the signature will not match.

Respond and retries

  • Return a 2xx status quickly (within a few seconds) to acknowledge receipt.
  • Any non-2xx response or a timeout is retried with exponential backoff.
  • Make your handler idempotent — a delivery can arrive more than once. Dedupe on the event or post id.
Do slow work (database writes, downstream calls) after you respond 2xx — for example by enqueueing the event — so you never trip the delivery timeout.