Skip to content
Documentation menu

Webhooks

Signed event deliveries with retries and replay.

Preview documentation. Details may change before the API is released.

A webhook sends an HTTPS POST to your endpoint when an event occurs. Manage endpoints in the fund portal under Developers.

Events

EventSent when
investor.createdAn investor entity is created
investor.updatedAn investor entity is updated
subscription.status_changedA subscription moves to a new status
commitment.acceptedA commitment is accepted
capital_call.issuedA capital call is issued
capital_call.item_paidAn investor's call item is paid
capital_call.closedA capital call is closed
distribution.approvedA distribution is approved
distribution.paidA distribution is paid
payment.status_changedA payment changes status
document.publishedA document is published
document.viewedA document is viewed
statement.publishedA statement is published
envelope.completedAll signers complete an envelope
envelope.declinedA signer declines an envelope
period.closedAn accounting period is closed
nav.publishedA NAV is published
tax_document.deliveredA tax document is delivered
bank_account.changedA bank account is added, changed or removed

Verifying a delivery

Each delivery carries two headers:

  • X-CommonRidge-Timestamp: the Unix time in seconds when the delivery was signed.
  • X-CommonRidge-Signature: the hex HMAC-SHA256 of timestamp + "." + raw request body, using your endpoint's signing secret.

To verify:

  1. Read the raw body before any JSON parsing.
  2. Recompute the HMAC-SHA256 with your signing secret over the timestamp, a period and the body.
  3. Compare it to the signature with a constant-time comparison.
  4. Reject the delivery if the timestamp is more than five minutes old, to block replays.
import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(rawBody, timestamp, signature, secret) {
  const expected = createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(signature);
  return a.length === b.length && timingSafeEqual(a, b);
}

Retries

A delivery that does not receive a 2xx response within the timeout is retried with exponential backoff for 24 hours. Every attempt, with its payload and response, is visible in the fund portal and can be replayed. Return 2xx quickly and process the event afterward. Deliveries can arrive more than once and out of order, so make your handler idempotent.

Book demoStart trial