Documentation menu

Core concepts

Webhooks

View .md

Subscribe to publish events instead of polling, and verify each delivery with the signature.

What you can subscribe to

Rather than polling the publish history, register an endpoint and Dravo will POST events to it. Available events:

EventFires when
post.publishedA job delivered to at least one account.
post.failedA job failed for every account.
post.queuedA job entered the queue (optional notification).
connection.revokedA connected account was revoked or needs reconnect.

Register endpoints in the dashboard or with POST /v1/webhooks. The signing secret is returned once at creation.

The payload

Dravo sends a JSON body describing the event:

{
  "event_type": "post.published",
  "timestamp": "2026-06-23T10:15:30Z",
  "data": {
    "job_id": "job_2a7f93",
    "account_id": "acc_8f2c1d",
    "provider": "x",
    "platform_post_id": "1890123456789",
    "status": "published"
  }
}

Verifying the signature

Every delivery carries a Dravo-Signature header so you can confirm it came from Dravo and was not tampered with. The header has the form t=timestamp,v1=signature, where the signature is an HMAC-SHA256 of timestamp + "." + raw_body using your endpoint signing secret.

import crypto from "node:crypto";

function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(
    header.split(",").map((kv) => kv.split("="))
  );
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(parts.v1)
  );
}

Compute the HMAC over the raw request body, before any JSON parsing, or the bytes will not match.

Testing

Send a sample event to any endpoint with POST /v1/webhooks/{webhook_id}/test. The response includes the HTTP status your endpoint returned and the attempt count, so you can confirm your receiver works before relying on it.