Handle webhooks

  1. Create an endpoint:
$curl -X POST $API/api/v1/webhook-endpoints \
> -H "Authorization: Bearer $REVENTLOV_API_KEY" \
> -d '{"url":"https://example.com/hooks","events":["directive.issued"]}'
  1. Save the returned secret — you’ll use it to verify signatures.

  2. On your server, verify:

1import { createHmac, timingSafeEqual } from 'node:crypto';
2
3export function verify(req: Request, raw: string, secret: string) {
4 const h = req.headers.get('x-reventlov-signature') ?? '';
5 const [tPart, vPart] = h.split(',');
6 const t = Number(tPart.split('=')[1]);
7 const sig = vPart.split('=')[1];
8 const expected = createHmac('sha256', secret).update(`${t}.${raw}`).digest('hex');
9 return timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
10}

Reject if the timestamp is older than 5 minutes to prevent replay.

Event types

Every state-changing customer action in the dashboard fans out one of these signed events. Subscribe to the ones you care about, or leave events: [] on your endpoint to receive all of them.

Companies

eventwhen it fires
company.createdA company is created via onboarding or /api/v1/companies
company.updatedCompany fields are mutated
company.dissolvedCompany is dissolved
company.formation.step_completedA formation milestone is recorded

Agents

eventwhen it fires
agent.linkedA new agent is created (dashboard, /api/v1/agents, or onboarding)
agent.updatedAn agent’s name, provider, model, phone, or email is changed
agent.paused / agent.resumedThe agent (or its case binding on a company) is paused/resumed
agent.unlinkedAn agent is detached from a company

Filings & compliance

eventwhen it fires
filing.dueA new open filing is created
filing.submittedAn open filing is marked submitted
compliance.resyncedThe compliance matrix is reseeded for a company

API keys

eventwhen it fires
api_key.createdA new API key is minted
api_key.revokedAn API key is revoked
eventwhen it fires
case.comment_postedA customer or staff comment is added to a case
directive.issued / directive.suspended / directive.resolvedDirective lifecycle

Treasury & bank

eventwhen it fires
bank.connected / bank.connection.linkedA Mercury (or other provider) connection is configured
bank.connection.secret_configuredThe connection’s API token is stored
bank.connection.disconnectedA connection is removed
bank.transaction.postedA new transaction is ingested
bank.balance.updatedThe cash balance snapshot is refreshed
bank.approval.requiredA wire crosses an approval threshold
mercury.sync_completedA manual Mercury sync finished
financial.snapshot.updatedA periodic financial snapshot is checkpointed

Agent runtime

eventwhen it fires
agent.action.logged / completed / failed / blockedAction lifecycle from the agent runtime
agent.approval.requested / decidedOperator approval flow
agent.flag.created / resolvedOperator-raised flags
openclaw.runtime.snapshot.updatedOpenClaw runtime checkpoint

Webhook hygiene

eventwhen it fires
webhook_endpoint.failingAn endpoint has had repeated delivery failures

Every event payload includes id, type, created_at, account_id, optional company_id, and a data object with the affected record. The full delivery is signed (x-reventlov-signature) and recorded in Activity at /dashboard/logs and Webhooks → Recent deliveries at /dashboard/settings/webhooks.