AutoReport.to

Webhooks

Ship report payloads to any HTTPS endpoint. Useful for archiving to S3, piping into your own workflow, or triggering downstream automations.

Webhook delivery is a Pro feature.

Set up a webhook destination

  1. Go to your report → Delivery → Add destination.
  2. Pick Webhook and paste your HTTPS URL.
  3. Copy the generated signing secret and store it in your app's environment (we only show it once).
  4. Send a test payload from the dashboard to verify.

Payload

We POST a JSON body with Content-Type: application/json.

{
  "id": "run_7f9a...",
  "report_id": "rep_abcd1234",
  "title": "Weekly engineering digest",
  "generated_at": "2026-04-25T16:00:00Z",
  "schedule_cron": "0 16 * * 5",
  "sources": ["github", "linear"],
  "destinations": ["webhook"],
  "summary": "Team shipped 12 PRs this week...",
  "content": {
    "markdown": "...",
    "html": "..."
  },
  "metrics": {
    "prs_merged": 12,
    "issues_closed": 7,
    "incidents": 2
  }
}

Headers

X-AutoReport-EventAlways report.delivered.
X-AutoReport-SignatureHMAC-SHA256 of {timestamp}.{body}.
X-AutoReport-TimestampUnix timestamp (seconds) when the request was signed.

Verify signatures

Always verify the signature before trusting the payload. Example in Node.js:

import crypto from "crypto";

const signature = req.headers["x-autoreport-signature"];
const timestamp = req.headers["x-autoreport-timestamp"];
const body = await readRawBody(req);

const signedPayload = `${timestamp}.${body}`;
const expected = crypto
  .createHmac("sha256", process.env.AUTOREPORT_WEBHOOK_SECRET)
  .update(signedPayload)
  .digest("hex");

if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
  return res.status(401).end("Invalid signature");
}

Retries & idempotency

Respond with a 2xx within 10 seconds to acknowledge. Any non-2xx response (or a timeout) triggers our retry policy (up to 5 attempts over ~1 hour). Each attempt carries the same id so you can dedupe safely.