Skip to main content

Lead Scoring Flow

Overview

The lead scoring system processes Typeform webhook events to score leads and fire Facebook CAPI events. It runs on the FastAPI backend (www/web_app/backend).

Endpoint: POST /api/v1/leadscoring/webhook

Entry point: services/leadscoring.py → leadscoring_webhook()


Flow Diagram

Typeform Webhook

├─ event_type != "form_response" (partial)
│ │
│ ├─ 1. fire_capi_lead()
│ │ → Fire Facebook CAPI with event_name = "Lead"
│ │ → Logged to logs.facebook_capi_event_log (PostgreSQL)
│ │
│ ├─ 2. upsert_capi_lead_result()
│ │ → If email+client_id exists → update capi_lead=1, updated_at
│ │ → If not exists → insert new row (source="LEAD-SCORING", capi_lead=1)
│ │
│ └─ return OK

└─ event_type == "form_response" (full)

├─ Check scoring_method from client config
│ └─ If not "AI" → log warning, return OK (ML not supported yet)

└─ Run lead scoring in background (run_leadscoring_webhook)

├─ 1. Parse payload
│ → typeform_payload_to_dataframe() for Typeform clients
│ → parse_blush_payload_to_df() for Blush (client_id=30)

├─ 2. Extract fields
│ → email, phone, first_name, last_name (by role)
│ → question/answer pairs for AI prompt

├─ 3. Call Form AI
│ → call_form_ai_api_with_prompt()
│ → Primary: Gemini 2.0 Flash (temperature=0)
│ → Fallback: OpenAI GPT-4o (temperature=0)
│ → Returns: ai_fin, ai_show, ai_sql scores (0-1)
│ → Plus signals: scheduling_commitment, emotional_urgency,
│ personal_responsibility, financial_stability, investment_readiness

├─ 4. Calculate Rotator (config-driven)
│ → If p_fin >= a_rotator_fin AND p_show >= a_rotator_show → "A"
│ → Elif p_fin >= b_rotator_fin AND p_show >= b_rotator_show → "B"
│ → Else → "C"

├─ 5. Determine CAPI SubmitApplication (config-driven)
│ → Fire if p_fin >= fb_capi_fin AND p_show >= fb_capi_show
│ → event_name = "SubmitApplication" (hardcoded)
│ → Logged to logs.facebook_capi_event_log (PostgreSQL)

├─ 6. Save results
│ → Upsert to leadscoring.results (source="LEAD-SCORING")
│ → Stores: p_fin_model, p_show_model, p_sql_model, rotator,
│ capi_data, signals, capi_submitapp (1/0), updated_at

└─ Done


Manual CAPI Fire

Endpoint: POST /api/v1/leadscoring/fire-capi-event/{client_id}/{email}

Entry point: services/leadscoring.py → fire_lead_scoring_capi_event()

1. Look up existing LEAD-SCORING result for email+client_id
2. Read thresholds from settings (not capi_data):
- fb_capi_fin, fb_capi_show, capi_token, pixel_id
- event_name, event_source_url, action_source, test_event_code
3. Fire condition: p_fin >= fb_capi_fin AND p_show >= fb_capi_show
4. If fire → fire_facebook_capi_event() with event_name from settings
5. Update DB: capi_submitapp=1, capi_fired_to_fb=1, updated_at
6. Logged to logs.facebook_capi_event_log (PostgreSQL)

Configuration (Client Settings)

Stored in app.clients.lead_scoring_config (JSONB column).

Managed via UI: Lead Scoring Settings page.

Scoring Settings

FieldDescriptionDefault
scoring_methodAI or ML (only AI supported)AI
fb_capi_finFB CAPI Financial Threshold (decimal 0-1)0.8
fb_capi_showFB CAPI Show Threshold (decimal 0-1)0.6
a_rotator_finA Rotator Financial Threshold0.8
a_rotator_showA Rotator Show Threshold0.8
b_rotator_finB Rotator Financial Threshold0.6
b_rotator_showB Rotator Show Threshold0.3
c_rotator_finC Rotator Financial Threshold0
c_rotator_showC Rotator Show Threshold0

Facebook CAPI Settings

FieldDescription
capi_tokenFacebook CAPI access token
pixel_idFacebook pixel ID
event_nameCAPI event name (e.g., SubmitApplication)
event_source_urlEvent source URL
action_sourceAction source (website, email, app, etc.)
test_event_codeTest event code (optional)
capi_trigger_logicAlways "threshold"

API Endpoints

MethodPathDescription
POST/api/v1/leadscoring/webhookTypeform webhook (partial → Lead CAPI, full → scoring)
GET/api/v1/leadscoring?client_id=X&email=YGet scoring result
POST/api/v1/leadscoring/fire-capi-event/{client_id}/{email}Manually fire CAPI
GET/api/v1/leadscoring/config/{client_id}Get client config
PUT/api/v1/leadscoring/config/{client_id}Update client config
POST/api/v1/leadscoring/predictions/{client_id}Generate predictions