Built for teams who route a lot of leads.
LeadRails started because routing inbound webhooks reliably is harder than it looks. Idempotency, retries, dead-letter queues, multi-tenant scoping — none of that is rocket science individually, but assembling it correctly while also being usable by non-engineers is the gap we set out to close.
Our priorities, in order.
- 1
Reliability over features.
A lead that doesn't land is a lead lost. We over-invest in retries, idempotency, replay, and audit trails — the boring infrastructure that pays off when something breaks at 3am.
- 2
Honest defaults.
No magic configs. No "we'll figure it out for you." Every retry budget, signing secret, and SSRF guard is documented and tunable.
- 3
Multi-tenant from the start.
Agency + client + operator scoping is baked into every endpoint, not bolted on later. Your customers see only their data; their customers see only theirs.
- 4
BYO where it matters.
You bring your own email + SMS credentials. You own your sending reputation, your compliance posture, your customer relationship.
Why this stack.
Cloudflare Workers + D1: Edge compute + low-latency serverless SQL. We picked it because lead events are bursty (form spikes), latency-sensitive (acks must be fast), and globally distributed (customers everywhere). D1's per-tenant database model gave us multi-tenancy without per-customer infrastructure.
TypeScript end-to-end: Schema-first from packages/adapters → admin-api zod-openapi → admin-ui openapi-typescript. One contract, everywhere. No hand-rolled API clients.
HMAC over raw bearer tokens: Forces customers to prove they hold the secret on every request. Trades convenience for unforgeable origin. Replay protection via nonce + timestamp.
In-DB retry counter as SoT: We could trust Cloudflare Queue's retry mechanic, but it's opaque. Tracking attempts in D1 means a retry budget is visible, replayable, and survives queue restarts.