What you get
RemixCRM fires HTTP POSTs to a URL you configure when important things happen in your org — new leads, new payments, lead conversions. Pipe these into Zapier, n8n, Make.com, or any custom endpoint to trigger workflows: Slack notifications, accounting entries, sending a thank-you postcard, anything.
Setup
- Settings → Integrations → Workflow Automation
- Two URL fields:
- n8n Webhook URL — your n8n trigger node URL
- Zapier Webhook URL — from a Zapier "Webhooks by Zapier" Catch Hook trigger
- Save
Both fields are independent — if both are set, RemixCRM fires to both URLs for every event. You can wire one to Zapier and the other to a self-hosted endpoint.
Events fired
Every webhook POST has this envelope:
{
"event": "lead.created",
"org_id": "uuid",
"timestamp": "2026-05-25T20:30:00Z",
"data": { ... }
}
lead.created
A new lead was created (UI, Calendly webhook, or Lead API).
{
"event": "lead.created",
"data": {
"id": "uuid",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"status": "new"
}
}
lead.status_changed
A lead's status changed (e.g. new → qualified → converted → lost).
{
"event": "lead.status_changed",
"data": { "lead_id": "uuid", "status": "qualified" }
}
lead.converted
A lead was converted directly to an event via convertLeadToEvent. Includes
the new event ID and the client ID (existing or freshly created).
{
"event": "lead.converted",
"data": { "lead_id": "uuid", "event_id": "uuid", "client_id": "uuid" }
}
payment.recorded
A payment was recorded — from the public pay page (card, Venmo, Zelle), admin-entered, or pending-confirmed.
{
"event": "payment.recorded",
"data": {
"amount": 500.00,
"payment_type": "stripe",
"client_name": "Jane Doe",
"client_email": "jane@example.com",
"event_date": "2026-08-15",
"event_id": "uuid-or-null",
"stripe_session_id": "cs_...",
"stripe_payment_intent_id": "pi_...",
"receipt_url": "https://pay.stripe.com/receipts/...",
"status": "completed"
}
}
Square payments include square_payment_id instead of the Stripe fields.
Venmo/Zelle have neither — just payment_type: "venmo" or "zelle" and
status: "pending".
Behavior
- Fire-and-forget. RemixCRM doesn't wait for the webhook response — it POSTs and moves on. If your endpoint is slow, RemixCRM is not slow.
- No retries. If your endpoint returns 5xx or times out, the webhook is not retried. For at-least-once delivery, use Zapier or n8n's built-in retry logic, or wire a queue in front of your endpoint.
- No signatures. Currently webhooks are unauthenticated. The URL is the shared secret — don't share it publicly. (HMAC signing is on the roadmap.)
- Both URLs fire. If you have both n8n and Zapier URLs set, every event goes to both.
Pattern: Slack notification on new lead
- Create a Zapier zap with Webhooks by Zapier → Catch Hook as the trigger
- Copy the catch URL
- Paste into RemixCRM Settings → Integrations → Zapier Webhook URL
- In Zapier, add a Slack → Send Channel Message action:
New lead: {{first_name}} {{last_name}} ({{email}}) — {{event_date}} - Add a Filter step before Slack:
event = lead.created(so payment events don't trigger Slack notifications) - Turn it on
Pattern: QuickBooks invoice on payment
- n8n flow with HTTP trigger
- Filter:
event = payment.recorded AND status = completed - QuickBooks → Create Invoice with
amountandclient_email - Connect to your RemixCRM Settings → Integrations → n8n Webhook URL
Programmatic
lib/webhooks.ts exposes fireWebhooks({ orgId, event, data }). Internal
code already calls it on the events listed above — but if you fork or add
custom server actions, calling it manually is one line.