API Routes
REST endpoints for lead import and presentation logging
Two API routes exist for operations that can't go through the standard Supabase client.
POST /api/leads/import
Bulk lead import endpoint. Used by lead vendors (currently Kynguard) to push leads into the system.
Authentication
x-api-key header, validated against a server-side secret.
Request body
{
"agent_id": "uuid",
"agency_id": "uuid",
"distribution_id": "uuid (optional)",
"leads": [
{
"external_id": "uuid (required)",
"first_name": "string (required)",
"phone": "string (required)",
"state": "string (required)",
"type": "string (required)",
"last_name": "string (optional)",
"email": "string (optional)",
"address": "string (optional)",
"city": "string (optional)",
"zip": "string (optional)",
"language": "string (optional)"
}
]
}Validation
typemust be one of the valid lead types (fwk,csk,br,union,ncr,pos,dcard,fe,globe)- Each lead requires
external_id,first_name,phone,state, andtype
Response
{
"success": true,
"imported": 10,
"failed": 0,
"errors": [],
"lead_ids": ["uuid", "uuid", "..."]
}Each lead is inserted individually. Failures don't block other leads from being imported — the response includes both success and error counts.
How imported leads enter the system
sourceis set to'onsidian'(not'manual')statusdefaults to'open',stagedefaults to'new'agency_idandagent_idcome from the request bodyexternal_idis stored for deduplication by the vendor- The
lead_metricsrow is created by the database trigger
POST /api/leads/log-presentation-activity
Called by the presentation pop-out window to log activity that can't use the main Supabase client (the pop-out runs in a separate browser context).
Request body
{
"lead_id": "uuid (required)",
"agent_id": "uuid (required)",
"type": "string (required)"
}Valid activity types
presentation_started— logged when the presentation first openspresentation_resumed— logged when returning to an in-progress presentationpresentation_paused— logged when the presentation window is minimized/closed without submitting
Response
{
"success": true
}Why this exists
The presentation runs in a pop-out window that opens via window.open(). This window doesn't share the same Supabase auth session as the main app. Rather than trying to pass auth tokens between windows, the presentation window calls this API route, which uses a server-side Supabase client with the service role key.
The heavy lifting (demographics, sale details, referrals) still goes through submit_lead_presentation RPC, which is called from the presentation window's Supabase client with the user's auth context. Only the activity logging uses this API route.