Webhooks

Receive signed events when posts, comments, votes, post statuses, or Linear issue links change.

Connect Boarbs to your own backend with an outbound webhook. Starter and Pro organizations can configure one HTTPS endpoint from Settings → API.

An organization admin creates the endpoint and receives its signing secret once. Store the secret securely before closing the dialog. You can update the endpoint URL, rotate the secret, or remove the webhook later.

Events

Boarbs sends these event types:

EventWhen it is sent
post.createdA post is created
comment.createdA public or internal comment is created
post.status_changedA post moves to another status
vote.createdA vote is added to a post
vote.deletedA vote is undone
linear.linkedA Linear issue is created from a post, or an existing issue is linked
linear.unlinkedA Linear issue is unlinked from a post, including a Linear-side remove
linear.status_changedThe Linear status changes on a linked issue

Every request is an HTTPS POST with a JSON envelope:

{
  "id": "event-id",
  "type": "post.created",
  "createdAt": "2026-08-29T10:24:00.000Z",
  "data": {
    "post": {}
  }
}

The data object depends on the event:

  • post.created includes post
  • comment.created includes comment and its post
  • post.status_changed includes post, previousStatus, and status
  • vote.created includes vote and its post
  • vote.deleted includes vote and its post
  • linear.linked includes post and issue
  • linear.unlinked includes post and issue
  • linear.status_changed includes post and issue

Vote objects include id, postId, userEmail, userId (nullable), and createdAt.

Linear issue objects include id, identifier, url, and status (id, name). linear.status_changed is the Linear issue status on the link. post.status_changed may still fire when that status maps to a Boarbs status.

Verify Signatures

Each delivery includes these headers:

  • Webhook-Id — the event ID
  • Webhook-Timestamp — the Unix timestamp in seconds when the request was signed
  • Webhook-Signature — the HMAC-SHA256 signature as v1=<hex>

Verify the signature against the raw request body before parsing JSON. The signed content is:

<Webhook-Id>.<Webhook-Timestamp>.<raw request body>

This Node.js example compares signatures without leaking timing information:

import { createHmac, timingSafeEqual } from "node:crypto";

const webhookId = request.headers.get("webhook-id") ?? "";
const webhookTimestamp =
  request.headers.get("webhook-timestamp") ?? "";
const signedContent = `${webhookId}.${webhookTimestamp}.${rawBody}`;
const expected = createHmac(
  "sha256",
  process.env.BOARBS_WEBHOOK_SECRET,
)
  .update(signedContent)
  .digest();

const signature = request.headers.get("webhook-signature") ?? "";
const provided = /^v1=[0-9a-f]{64}$/.test(signature)
  ? Buffer.from(signature.slice(3), "hex")
  : null;

const valid =
  provided?.length === expected.length &&
  timingSafeEqual(provided, expected);

Reject invalid signatures and timestamps outside your replay window. Keep the signing secret on the server and never expose it in browser code.

Acknowledge Deliveries

Return any 2xx response within 10 seconds to acknowledge a delivery. If the endpoint times out or returns a non-2xx response, Boarbs retries three times with increasing delays.

Handlers should be idempotent because retries can deliver the same event more than once. Use Webhook-Id as the event identifier when recording processed deliveries.

Rotate or Remove the Webhook

Use Settings → API to rotate the signing secret if it is exposed. Save the replacement secret when it is shown and update your receiver before accepting new deliveries.

Removing the webhook deletes its pending deliveries and stops future events.

Next Steps

Boarbs© 2026 Boarbs