Onsidian Help
Lead System

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

  • type must 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, and type

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

  • source is set to 'onsidian' (not 'manual')
  • status defaults to 'open', stage defaults to 'new'
  • agency_id and agent_id come from the request body
  • external_id is stored for deduplication by the vendor
  • The lead_metrics row 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 opens
  • presentation_resumed — logged when returning to an in-progress presentation
  • presentation_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.

On this page