Supported sources
| Source | Setup | Latency | Plan |
|---|---|---|---|
| Website form (embed) | Paste snippet from Settings → Integrations | < 1s | All plans |
| Missed-call SMS | Forward business number to LeadRescue relay | ~5s | Rescue Plus, Bundle Pro |
Forward to +leads@ alias | < 5s | All plans | |
| Facebook lead forms | OAuth in Integrations | Webhook (~2s) | All plans |
| Google Business Profile | OAuth in Integrations | Polling (~60s) | All plans |
| Voice AI (after-hours triage) | Forward to the GenAI voice number | Real-time | Bundle Pro only |
| Manual entry | Leads → New | Instant | All plans |
Field mapping
Every lead ends up as a row with this canonical shape, regardless of source:
{
customer_name: string?,
phone: string?,
email: string?,
source: "website" | "landing_page" | "sms" | "email" |
"facebook" | "google_business" | "missed_call" | "manual",
service_type: string?,
message: string, // required — verbatim text we received
property_address: string?,
zip_code: string?,
created_at: ISO-8601 string
}If a source sends a field we don't recognize (e.g. a Facebook custom question), it lands in message appended below a --- separator so nothing is silently dropped.
Deduplication
We dedupe on a rolling 24-hour window using phone OR email within the same business_id. A duplicate doesn't create a new lead — it appends to the existing lead's message thread and triggers a follow-up rule ("customer reached out again"). This is intentional: customers who text and then fill the web form are the same person and you don't want two AI replies.
Routing rules
After parse, each lead is checked against your rules in order. The first matching rule wins:
- Out of service area — zip not in your list → polite decline + suggest a referral partner if you've set one.
- Blocked service type — e.g. "commercial only" or "residential only" → polite decline.
- Quiet hours — outside your hours → confirm receipt + schedule follow-up for your next open window.
- VIP customer — phone matches an existing customer → routed directly to you, AI does not reply.
- Default — qualify + reply.
Testing a source
Every source has a Send test lead button in Integrations. The test lead is tagged source = manual so it doesn't pollute your analytics. You can also pipe to a sandbox AI configuration (Settings → AI Rules → "Test mode for new sources") to verify the reply before going live.