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
| Event | Sent when |
|---|---|
investor.created | An investor entity is created |
investor.updated | An investor entity is updated |
subscription.status_changed | A subscription moves to a new status |
commitment.accepted | A commitment is accepted |
capital_call.issued | A capital call is issued |
capital_call.item_paid | An investor's call item is paid |
capital_call.closed | A capital call is closed |
distribution.approved | A distribution is approved |
distribution.paid | A distribution is paid |
payment.status_changed | A payment changes status |
document.published | A document is published |
document.viewed | A document is viewed |
statement.published | A statement is published |
envelope.completed | All signers complete an envelope |
envelope.declined | A signer declines an envelope |
period.closed | An accounting period is closed |
nav.published | A NAV is published |
tax_document.delivered | A tax document is delivered |
bank_account.changed | A 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 oftimestamp + "." + raw request body, using your endpoint's signing secret.
To verify:
- Read the raw body before any JSON parsing.
- Recompute the HMAC-SHA256 with your signing secret over the timestamp, a period and the body.
- Compare it to the signature with a constant-time comparison.
- 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.