API & Webhooks
Integrate lead sources and email event tracking with LeadFlow's webhook endpoints.
Overview
LeadFlow accepts incoming data through webhook endpoints — one for new leads from any lead provider (Boberdoo or otherwise), and one for email events from Email Bison. Both endpoints are secured and require authentication.
Lead Intake Webhook
Endpoints
Two interchangeable routes share a single handler. Use /leads for new integrations; /boberdoo is a back-compat alias.
Authentication
Include your API key in the X-Api-Key header. Each client workspace has a unique key that determines which agency the lead is routed to. All agencies use the same URL with different keys.
Field-Name Matching
Field names are matched case- and separator-insensitively: Property Type == property_type == PROPERTY_TYPE all resolve to the same field. Send your payload as-is — we recognize the names below and never drop anything we don't recognize (see the lossless capture note).
Required Fields
Exactly two fields are required. A request missing either returns 422 naming the field.
| Field | Accepted Names | Description |
|---|---|---|
| Email, email | Lead's email address — required | |
| first_name | First Name, first_name | Lead's first name — required, used in personalization |
Core Contact Fields
These optional fields are extracted from the top level of the payload.
| Field | Accepted Names |
|---|---|
| last_name | Last Name, last_name |
| phone | Primary Phone, Cell Phone, Daytime Phone, Secondary Phone, phone |
| address | Address, address |
| city | City, city |
| state | State, state |
| zip | Zip, zip |
| insurance_type | insurance_type (auto / home — inferred from vehicle/property if omitted) |
| lead_id | lead_id (optional external ID — used for deduplication) |
Primary Phone, Cell Phone, Daytime Phone, Secondary Phone, or phone, in that precedence order. Primary Phone is the name most providers send.Property Fields (Home Leads)
Sent at the top level on home leads. If property fields are present and no vehicle is, the lead is auto-classified as insurance_type: "home".
| Field | Accepted Names |
|---|---|
| property_type | Property Type, property_type |
| year_built | Year Built, year_built |
| square_footage | Square Footage, square_footage |
| dwelling_coverage | Home Value, dwelling_coverage |
| roof_type | Roof Type, roof_type |
| construction_type | Construction Type, construction_type |
| stories | Stories, stories |
| bedrooms / bathrooms | Bedrooms, Bathrooms |
| liability / deductible | Liability, Deductible |
| occupancy | Occupancy |
| exterior_walls / foundation | Exterior Walls, Foundation |
| heating_type | Heating Type |
| home_security / smoke_alarm / indoor_sprinklers | Home Security, Smoke Alarm, Indoor Sprinklers |
| central_air_conditioning | Central Air Conditioning |
| currently_insured / current_insurance_company | Currently Insured, Current Insurance Company |
| coverage_type / claims / garage | Coverage Type, Claims, Garage |
| insured_since / policy_expiration | Insured Since, Policy Expiration |
| years_at_current_residence / years_at_previous_residence | Years At Current Residence, Years At Previous Residence |
Applicant Demographics (Home Leads)
Top-level Age, Gender, and DOB on home leads are captured as applicant contact info. (On auto leads these arrive under the Driver N prefixes instead.)
| Field | Accepted Names |
|---|---|
| age | Age |
| gender | Gender |
| dob | DOB |
Vehicle Fields (Vehicle 1 & Vehicle 2)
Prefix each field with Vehicle 1 or Vehicle 2. If any vehicle fields are present and no property is, the lead is auto-classified as insurance_type: "auto".
| Field | Example Key |
|---|---|
| Year | Vehicle 1 Year |
| Make | Vehicle 1 Make |
| Model | Vehicle 1 Model |
| Sub Model | Vehicle 1 Sub Model |
| Vin | Vehicle 1 Vin |
| Ownership | Vehicle 1 Ownership |
| Primary Use | Vehicle 1 Primary Use |
| Average One Way Mileage | Vehicle 1 Average One Way Mileage |
| Annual Mileage | Vehicle 1 Annual Mileage |
| Parking | Vehicle 1 Parking |
| Average Days Per Week Used | Vehicle 1 Average Days Per Week Used |
| Coverage Type | Vehicle 1 Coverage Type |
| Desired Collision Coverage | Vehicle 1 Desired Collision Coverage |
| Desired Comprehensive Coverage | Vehicle 1 Desired Comprehensive Coverage |
| Security System | Vehicle 1 Security System |
Driver Fields (Driver 1 & Driver 2)
Prefix each field with Driver 1 or Driver 2.
| Field | Example Key |
|---|---|
| First Name / Last Name | Driver 1 First Name |
| Address / City / State / Zip | Driver 1 Address |
| Daytime / Evening / Cell Phone | Driver 1 Cell Phone |
| Driver 1 Email | |
| Birthdate | Driver 1 Birthdate |
| Age | Driver 1 Age |
| Gender | Driver 1 Gender |
| Marital Status | Driver 1 Marital Status |
| Credit Rating | Driver 1 Credit Rating |
| License Status | Driver 1 License Status |
| Licensed State | Driver 1 Licensed State |
| Age When First Licensed | Driver 1 Age When First Licensed |
| Education | Driver 1 Education |
| Occupation | Driver 1 Occupation |
| Current Residence | Driver 1 Current Residence |
| Years At Current Residence | Driver 1 Years At Current Residence |
| Insurance Company | Driver 1 Insurance Company |
| Insured Past 30 Days | Driver 1 Insured Past 30 Days |
| Policy Expiration Date | Driver 1 Policy Expiration Date |
| Insured Since | Driver 1 Insured Since |
| Current Insurance Company Years / Months | Driver 1 Current Insurance Company Years |
| Continuously Insured Years / Months | Driver 1 Continuously Insured Years |
| Tickets Accidents Claims Past 3 Years | Driver 1 Tickets Accidents Claims Past 3 Years |
| Suspended Or Revoked In The Past 5 Years | Driver 1 Suspended Or Revoked In The Past 5 Years |
| DUI DWI In The Past 5 Years | Driver 1 DUI DWI In The Past 5 Years |
| Bankruptcy In Past 5 Years | Driver 1 Bankruptcy In Past 5 Years |
| Additional Drivers / Additional Vehicles | Driver 1 Additional Drivers |
| Relationship To Applicant | Driver 1 Relationship To Applicant |
Incident Fields (up to 3 per Driver)
Incidents are suffix-indexed: the index is the last token of the key, e.g. Driver 1 Incident Type 1. Use Driver N where N is 1-2 and the trailing number M is 1-3.
| Field | Example Key |
|---|---|
| Incident Type | Driver 1 Incident Type 1 |
| Approximate Date | Driver 1 Approximate Date 1 |
| Damages | Driver 1 Damages 1 |
| At Fault | Driver 1 At Fault 1 |
| Insurance Paid Amount | Driver 1 Insurance Paid Amount 1 |
Lossless Capture
Every key you send is stored verbatim — keyed by the exact name you sent. Recognized fields are additionally promoted into structured groups (vehicle, driver, property, contact), but nothing is ever discarded. Two keys that differ only in casing/separators (e.g. Property Type and property_type) are both kept.
Example — Home Lead
{
"First Name": "Jordan",
"Last Name": "Sample",
"Email": "jordan@example.com",
"Primary Phone": "4075551234",
"Address": "123 Oak St",
"City": "Oviedo",
"State": "FL",
"Zip": "32765",
"insurance_type": "home",
"Property Type": "Single Family",
"Year Built": 2016,
"Square Footage": 2500,
"Stories": "1",
"Roof Type": "Asphalt Shingle",
"Construction Type": "Wood Frame",
"Home Value": 300000,
"Bedrooms": 4,
"Bathrooms": 4,
"Currently Insured": "Yes",
"Current Insurance Company": "Company Not Listed",
"Age": 65,
"Gender": "Male",
"DOB": "01/01/1960"
}Example — Auto Lead
{
"First Name": "Riley",
"Last Name": "Sample",
"Email": "riley@example.com",
"Primary Phone": "3525551234",
"City": "Eustis",
"State": "FL",
"Zip": "32736",
"insurance_type": "auto",
"Vehicle 1 Year": 2002,
"Vehicle 1 Make": "FORD",
"Vehicle 1 Model": "TAURUS LX",
"Vehicle 1 Ownership": "Owned",
"Vehicle 1 Coverage Type": "Standard",
"Vehicle 1 Annual Mileage": 14108,
"Driver 1 Age": 36,
"Driver 1 Gender": "Female",
"Driver 1 Marital Status": "Single",
"Driver 1 Credit Rating": "Good",
"Driver 1 License Status": "Active",
"Driver 1 Licensed State": "FL",
"Driver 1 Incident Type 1": "Speeding Violation",
"Driver 1 Approximate Date 1": "08/01/2025",
"Driver 1 At Fault 1": "Unknown",
"Driver 1 Insurance Paid Amount 1": "0.00"
}Response
| HTTP Code | Body | Meaning |
|---|---|---|
| 200 | {"status": "received", "client": "greg-blanchard"} | Lead accepted and queued for AI processing |
| 200 | {"status": "duplicate", "client": "greg-blanchard"} | Lead already processed (by lead_id or body hash) |
| 401 | {"detail": "Invalid API key"} | API key not found or client inactive |
| 422 | {"detail": "...required field(s) missing/empty: email"} | email and/or first_name missing or empty |
| 429 | {"detail": "Rate limit exceeded"} | Too many requests — retry after Retry-After header |
Deduplication
A request is deduplicated by lead_id when present. lead_id is optional — when omitted, the system deduplicates on a hash of the request body. A duplicate returns {"status":"duplicate"} and is not reprocessed.
cURL Example
curl -X POST https://api.leadflowss.com/api/v1/webhooks/leads \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY_HERE" \
-d '{
"First Name": "Jordan",
"Last Name": "Sample",
"Email": "jordan@example.com",
"Primary Phone": "4075551234",
"City": "Oviedo",
"State": "FL",
"Zip": "32765",
"insurance_type": "home",
"Property Type": "Single Family",
"Year Built": 2016,
"Home Value": 300000
}'What Happens After
- Lead is validated (
email+first_name), deduplicated, and stored with full field capture - AI drafts a personalized email using the lead's vehicle/driver (auto) or property (home) data
- Email is sent via Email Bison from the agency's sender accounts
- Lead appears in your dashboard under Conversations
- When the lead replies, the AI classifies the intent (interested, question, not interested)
- Interested leads are escalated — agent is CC'd on a handoff email
Email Event Webhook (Bison)
Endpoint
Tracked Events
Email Bison sends event notifications for the following actions:
| Event | Description | Dashboard Effect |
|---|---|---|
| reply | Lead replied to an email | New message in conversation thread + AI classification |
| delivered | Email was delivered successfully | Delivery confirmation in email events |
| bounced | Email bounced (invalid address) | Lead marked, bounce rate updated |
| opened | Lead opened the email | Open event tracked in analytics |
| clicked | Lead clicked a link in the email | Click event tracked in analytics |
| unsubscribed | Lead opted out | Lead suppressed — no further emails sent |
Rate Limits
| Endpoint | Limit | Window |
|---|---|---|
| Lead intake webhook | 120 requests | Per 60 seconds per IP |
| Bison webhook | 120 requests | Per 60 seconds per IP |
If you exceed the rate limit, you'll receive a 429 Too Many Requests response with a Retry-After header indicating when you can retry.