Documentation

LeadKumo is a self-hosted lead distribution platform supporting both web leads and call leads through the ping/post price discovery model. This documentation will help you get started and make the most of the platform.

System Requirements

You'll need a Linux VPS from any provider (DigitalOcean, Vultr, Linode, AWS, etc.). The installer handles all software setup automatically.

Recommended Server Specs

  • 2 CPU cores - handles typical lead volume
  • 4 GB RAM - sufficient for database and caching
  • 40 GB SSD - stores leads, backups, and call recordings

Supported: Ubuntu 20.04+, Debian 11+, CentOS 8+, or any Linux with Docker support

Installation

Docker Installation (Recommended)

The fastest way to get started is using our automated installer. After completing your purchase, you'll receive a personalized installation script via email:

curl -fsSL https://platform.leadkumo.com/install/YOUR_LICENSE_KEY | bash

What the installer does

  • - Detects your operating system and installs Docker if needed
  • - Generates secure passwords for PostgreSQL and Redis automatically
  • - Configures SSL certificates via Caddy for your domain
  • - Creates all necessary configuration files (.env, docker-compose.yml)
  • - Starts all services and runs database migrations

License Key Information

  • - Your license key is sent via email after purchase completion
  • - Each license key is tied to your hosting domain
  • - The installer validates your key with platform.leadkumo.com
  • - One license per domain - contact support for additional installations

Manual Docker Compose

Create a docker-compose.yml:

version: '3.8'
services:
  leadkumo:
    image: ghcr.io/leadkumo/leadkumo:latest
    ports:
      - "80:8080"
    environment:
      - DATABASE_CONNECTION_STRING=Host=db;Database=leadkumo;Username=postgres;Password=secret
      - REDIS_CONNECTION_STRING=redis:6379
    depends_on:
      - db
      - redis

  db:
    image: postgres:16
    environment:
      - POSTGRES_DB=leadkumo
      - POSTGRES_PASSWORD=secret
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine

volumes:
  pgdata:

Run with docker compose up -d

How Licensing Works

LeadKumo uses a simple domain-locked licensing system. Your license key is permanently tied to your hosting domain, ensuring you maintain full control of your installation.

From Purchase to Running

  1. 1
    Purchase - Complete your order through our payment provider. You'll receive an email with your unique license key.
  2. 2
    Download - Your email contains a personalized install link. The script already has your license key embedded.
  3. 3
    Run Installer - The script prompts you for your domain (e.g., leads.yourcompany.com). It verifies DNS is configured correctly.
  4. 4
    Registration - The installer contacts platform.leadkumo.com to register your domain. This creates the permanent link between your license key and your domain.
  5. 5
    You're Live - LeadKumo starts automatically. Your installation sends periodic heartbeats to confirm it's running on the registered domain.

Domain Binding Explained

When the installer registers your installation, it creates a record linking your license key to your specific domain. This binding includes:

  • - Domain name - The exact domain where LeadKumo is installed
  • - Server IP - Your server's public IP address at installation time
  • - Version - Which version of LeadKumo was installed
  • - Installation date - When the installation was registered

This information is stored securely on our licensing server. Your license cannot be used on a different domain without contacting support.

What Gets Validated

During Installation

  • - License key is valid and active
  • - Installation limit not exceeded
  • - DNS points to your server

Ongoing (Heartbeat)

  • - License key matches domain
  • - License is still active
  • - Checks for available updates

Connectivity Requirement

LeadKumo requires periodic connectivity to the licensing server to verify your installation remains valid. The system sends a heartbeat once per day.

7-Day Grace Period

If your server cannot reach the licensing server for 7 consecutive days, LeadKumo will automatically disable itself until connectivity is restored. This protects both you and us from unauthorized usage.

  • - When disabled: The admin UI shows a license error, and lead processing is paused
  • - To restore: Ensure your server can reach platform.leadkumo.com on port 443
  • - Automatic recovery: Once connectivity is restored, the next heartbeat will re-enable the system
  • - No data loss: Your data remains intact; only processing is paused

Common Questions

Can I move my installation to a different domain?

Contact support to transfer your license to a new domain. We'll deactivate the old installation and register the new one.

What if I need to reinstall on the same domain?

No problem. Running the installer again on the same domain will update the existing registration rather than creating a new one.

Can I install on multiple domains?

Each license includes one domain by default. Contact support to add additional domains to your license, or purchase additional licenses.

What happens if my server IP changes?

IP changes are handled automatically. The next heartbeat from your installation will update the recorded IP address.

Lifetime Upgrades Policy

Your license includes free upgrades for life within your major version. Here's exactly what that means:

1 Within Your Major Version

If you purchase a license for version 1.x, you receive all updates to 1.0, 1.1, 1.2, 1.3, and so on - forever. This includes new features, improvements, bug fixes, and security patches.

2 New Major Versions

When we release version 2.0 (a new major version), this is a separate product with significant new architecture or capabilities. You would need to purchase a new license to upgrade to 2.x.

3 Stay on Your Version Forever

You are never required to upgrade to a new major version. Your 1.x installation will continue to work indefinitely. We will continue to provide security patches for your version as long as you need them.

Lifetime Support Commitment

Regardless of which version you're running, we commit to supporting you for life:

  • - Security patches - Critical security fixes for your major version
  • - Technical support - Email support for installation and configuration issues
  • - Documentation - Maintained documentation for your version
  • - License transfers - Move your installation to a new domain when needed

Example: You purchase LeadKumo 1.4 today. Over the next 5 years, we release versions 1.5, 1.6, 1.7, 1.8, 1.9, and eventually 2.0. You automatically receive 1.5 through 1.9 at no cost. When 2.0 launches, you can choose to stay on 1.9 (with continued security support) or purchase a 2.x license to access the new major version features.

Configuration

LeadKumo is designed for non-technical users. No environment variables or config files are required - everything is configured through the web interface.

Zero-Config Deployment

Our installer handles everything automatically. After running the install script, just open your browser and complete the setup wizard.

1
Run Installer

One command sets up everything

2
Open Browser

Navigate to your domain

3
Complete Setup

Click through the wizard

First-Run Security Setup

When you first access LeadKumo, you'll be guided through a simple setup wizard. No technical knowledge required - just click through the steps.

1. Automatic Redirect

LeadKumo automatically detects first-time setup and redirects you to the setup wizard.

2. Generate Encryption Key

Click the "Generate" button to create a secure encryption key. This protects all personal data (names, emails, phone numbers) stored in the system.

3. Configure CORS Origins (Optional)

If you'll embed forms on other domains, add those domains here. Most users can skip this step.

4. Save and Lock

Click "Save and Lock Settings" to activate encryption and start using LeadKumo.

Save Your Encryption Key

The encryption key displayed during setup cannot be changed once saved. Copy it to a secure password manager before clicking "Save and Lock" - losing this key means losing access to encrypted data.

Ping/Post Model

LeadKumo uses the industry-standard ping/post model for lead distribution. This enables real-time price discovery through competitive bidding.

How It Works

  1. 1
    Ping Phase: Lead arrives via API. PII is stripped (name, email, phone). Non-PII attributes are sent to all matching buyer integrations.
  2. 2
    Price Discovery: Buyers respond with bid prices. Bids are ranked by price and priority settings.
  3. 3
    Post Phase: Full lead data (with PII) is sent to the highest bidder. If rejected, the next bidder is tried.
  4. 4
    Sale Recording: On success, a permanent sale record is created with all payloads preserved.

Data Flow Diagram

Lead Submission → Ping Phase → Price Discovery → Post Phase → Delivery
     ↓                ↓              ↓              ↓            ↓
  [API/Form]    [No PII]      [Stack Rank]    [Full Data]  [Success/Retry]

Call Leads (Phone Distribution)

LeadKumo supports inbound call distribution via Telnyx integration. Calls follow a similar auction model to web leads, but use phone conferencing instead of HTTP posts.

Call Lead Flow

  1. 1
    Inbound Call: Caller dials your provisioned DID (from ads). System answers and plays hold message.
  2. 2
    Availability Ping: System pings matching buyers' availability endpoints with caller info (no PII).
  3. 3
    Conference Transfer: Winner is selected by price. Caller is bridged to buyer via 3-way conference.
  4. 4
    Billable Duration: If call exceeds duration threshold (30/60/90/120s), a sale is created.

Telnyx Integration (BYOK)

Configure your own Telnyx account for call handling. LeadKumo uses Telnyx for:

  • - DID provisioning and management
  • - Call control (answer, transfer, hangup)
  • - Conference bridging (3-way calls)
  • - Call recording with S3 storage
  • - Real-time webhooks for call events

Telnyx Account Required

To use call lead distribution, you'll need your own Telnyx account. This is a "Bring Your Own Key" (BYOK) integration.

What You Need

  • - Telnyx account (telnyx.com)
  • - API Key (v2) from Mission Control
  • - Messaging Profile ID
  • - TeXML Application for webhooks

Telnyx Pricing

  • - Voice: ~$0.002/min (inbound + outbound)
  • - DIDs: ~$1/month per number
  • - Recording storage: included with Telnyx S3
  • - Pay-as-you-go, no minimums

Telnyx rates may vary by region. Check telnyx.com/pricing for current rates.

Duration-Based Billing

Unlike web leads (accepted/rejected), call leads are billed based on connected duration:

Buyer Threshold

Each buyer sets their minimum duration (30s/60s/90s/120s). Calls shorter than threshold are not billed.

Recording Storage

Recordings are stored in S3-compatible storage. Telnyx S3 is the default, or configure your own.

CID Lookup (Caller ID Enrichment)

NEW

Enrich incoming call leads with caller identification data before profile matching. Connect any third-party CID lookup service to automatically append caller details (name, address, carrier info) to the lead record.

How It Works

  1. 1
    Call arrives: An inbound call is received on a provisioned DID.
  2. 2
    CID lookup: The caller's phone number is sent to your configured CID service via HTTP (GET or POST).
  3. 3
    Enrichment: Returned data is merged into the lead's attributes with a cid_ prefix (e.g., cid_name, cid_city).
  4. 4
    Profile matching: Enriched data is available for targeting rules. Then pings are sent to matching buyers with the full enriched dataset.

Configuration

Configure CID Lookup under Settings → System → CID Lookup:

Service Settings

  • - Service URL (HTTP endpoint)
  • - API Key (Bearer token auth)
  • - HTTP Method (GET or POST)
  • - Request body template (POST)
  • - Phone parameter name
  • - Timeout (1-30 seconds)

Design Principles

  • - Non-blocking: calls proceed if lookup fails or times out
  • - Universal: works with any JSON-returning CID API
  • - Testable: built-in test panel with live results
  • - Audited: CidLookup and CidEnriched events logged
  • - Secure: API key stored encrypted at rest

Targeting with CID Data

CID-enriched fields are available in targeting rules. For example, if your CID service returns a city field, you can target it as cid_city in a profile's custom rules: {"cid_city": {"in": ["Austin", "Dallas"]}}

Lead Sources

All leads must have a source. Lead sources track where leads originate, enabling detailed attribution reporting. Each source requires an API key for authenticating lead submissions.

API Key Required

Every lead source must have an associated API key. Create API keys in Settings → API Keys, then assign one when creating the source. The API key authenticates all lead submissions from that source.

Source Types

Web

Form submissions, landing pages, affiliate partners

Call

Inbound phone calls from DIDs in advertising

API

Direct API submissions from partners

Source Attribution Flow

Lead Source → Campaign → Buyer/Profile → Sale
     ↓            ↓           ↓           ↓
[Origin]    [Channel]    [Destination]  [Revenue]

This enables comprehensive reporting: "How much revenue did Source X generate through Buyer Y?"

Lead Types (Verticals)

Lead types define the structure of leads for different verticals. Each lead type has its own schema, ping fields, and PII fields.

Auto Insurance

Vehicle info, driver details, coverage preferences

Solar

Homeowner status, electric bill, roof condition, credit score

Mortgage/Refinance

Loan type, property value, credit score, employment

Home Services

Service type, property info, urgency level

You can create custom lead types with your own JSON schema definitions through the admin dashboard.

Buyers & Campaigns

Buyers

Buyers are the companies that purchase leads. Each buyer can have multiple campaigns and integrations.

  • - Contact information and API key
  • - Revenue share percentage
  • - Active/inactive status

Campaigns

Campaigns define the business rules for lead buying:

  • - Caps: Daily lead and ping limits
  • - Operating Hours: When to accept leads (24hr format)
  • - Price Floor/Ceiling: Min/max bid amounts
  • - Priority: Stack rank boost for competitive bidding
  • - Delay: Seconds to wait before accepting

Targeting Profiles

Buyer profiles define targeting criteria to filter which leads are sent to specific buyers. Profiles are evaluated in real-time for both web leads and call leads, with detailed rejection reasons logged for every evaluation.

Geographic Targeting

Filter leads by location using state and ZIP code rules. Supports both allowlists and blocklists, with ZIP prefix matching (e.g., "787" matches all ZIPs starting with 787).

  • - States: Include specific states (e.g., TX, CA, FL)
  • - Excluded States: Block specific states
  • - ZIP Codes: Target specific ZIP codes or prefixes
  • - Excluded ZIPs: Block specific ZIP codes

Custom Targeting Rules

Define JSON-based rules to filter leads by any attribute. The rule engine supports 15+ operators for numeric, string, array, and boolean comparisons:

{
  "credit_score": { "min": 650 },
  "monthly_electric_bill": { "between": [100, 500] },
  "homeowner": true,
  "coverage_type": { "in": ["full", "liability"] },
  "vehicle_year": { "gte": 2015 }
}

Available Operators

min / gte Greater than or equal
max / lte Less than or equal
gt / lt Greater than / less than
eq / ne Equals / not equals
between Range [min, max]
in / not_in Array membership
contains Substring match
starts_with Prefix match
regex Regular expression match
exists Attribute existence check

Direct value matching is also supported: strings (case-insensitive), numbers (exact), booleans, and arrays (value must be in array).

Profile Evaluation

When a lead arrives, the engine evaluates every integration's assigned profile against the lead's geographic data and custom attributes:

  • - Both engines: Web leads (PingPost) and call leads use the same profile evaluation logic
  • - Fail-open design: Integrations without a profile, or with a disabled profile, pass through without filtering
  • - Rejection reasons: Every rejected profile is logged with specific reasons (e.g., "State CA not in targets")
  • - Audit trail: ProfileMatched and ProfileRejected events appear on the lead's Activity Timeline

Integrations

Integrations define how leads are sent to buyers. Each integration has ping and post endpoints with customizable templates.

Configuration Options

  • - HTTP method (GET, POST, PUT)
  • - Content type (JSON, XML, form-urlencoded)
  • - Custom headers and authentication
  • - Handlebars templates for request body
  • - Response parsing (success string, price path, error path)
  • - Timeout settings

Live Testing

Test integrations directly from the dashboard before going live. See actual request/response payloads and debug issues.

Template Syntax (Handlebars)

LeadKumo uses Handlebars templating for ping and post payloads. This allows flexible formatting for any buyer API.

Available Variables

// Lead Contact Info
{{lead.first_name}}
{{lead.last_name}}
{{lead.email}}
{{lead.phone}}
{{lead.address}}
{{lead.city}}
{{lead.state}}
{{lead.zip_code}}
{{lead.ip_address}}

// Vertical Attributes
{{attributes.vehicle_year}}
{{attributes.monthly_electric_bill}}
{{attributes.credit_score}}

// System Variables
{{ping_id}}
{{timestamp}}
{{source_id}}
{{campaign.custom_field_1}}

JSON Template Example

{
  "request_id": "{{ping_id}}",
  "state": "{{lead.state}}",
  "zip": "{{lead.zip_code}}",
  "vehicle": {
    "year": "{{attributes.vehicle_year}}",
    "make": "{{attributes.vehicle_make}}"
  }
}

XML Template Example

<?xml version="1.0"?>
<LeadRequest>
  <PingID>{{ping_id}}</PingID>
  <Consumer>
    <FirstName>{{lead.first_name}}</FirstName>
    <LastName>{{lead.last_name}}</LastName>
    <Email>{{lead.email}}</Email>
  </Consumer>
</LeadRequest>

AI-Powered Setup

NEW

LeadKumo includes AI-assisted configuration to dramatically reduce setup time. Using a Bring Your Own Key (BYOK) model, you provide your own API key for Claude, GPT-4, or Gemini.

Integration Template Generation

When creating a new buyer integration, instead of manually writing Handlebars templates, you can:

  1. 1 Paste the buyer's API documentation URL or text
  2. 2 Click "AI Generate" button
  3. 3 AI analyzes the documentation and generates both ping and post templates
  4. 4 Templates auto-populate in the form - review and save

The AI understands buyer field naming conventions and maps them to LeadKumo's standard variables automatically.

Lead Type Schema Generation

When creating a new lead type (vertical), AI can infer the complete schema from just a name and description:

  • • JSON Schema - Field definitions with types, validation rules, and constraints
  • • Ping Fields - Non-PII fields suitable for the bidding phase
  • • PII Fields - Personal data fields for post-sale delivery

Example: Enter "Auto Insurance" with description "Vehicle insurance leads with coverage preferences"

AI generates: vehicle_year, vehicle_make, vehicle_model, coverage_type, currently_insured, driver_age, violations_count, etc.

Configuring AI (Settings → System → AI)

1. Choose Provider

Select Anthropic (Claude), OpenAI (GPT-4), or Google (Gemini)

2. Enter API Key

Paste your API key from the provider's dashboard

3. Select Model

Choose the model to use (e.g., claude-3-5-sonnet)

Note: API usage is billed directly by your chosen provider. LeadKumo adds no markup - you pay only for what you use.

Dashboard

The dashboard provides a real-time overview of your lead distribution operations.

Real-Time Statistics

Today's leads, revenue, sell rate, and average price at a glance.

Activity Feed

Live feed of recent lead sales, buyer activity, and system events.

Performance Charts

Visual trends for lead volume, revenue, and conversion rates over time.

Buyer Leaderboard

Top performing buyers ranked by volume, spend, and acceptance rate.

DIDs (Phone Numbers)

DIDs (Direct Inward Dialing numbers) are phone numbers you provision for receiving call leads. Each DID is linked to a campaign and can be assigned to specific buyers.

Provisioning DIDs

  • - Search available numbers by area code or state
  • - Provision instantly via Telnyx API
  • - Assign to campaigns for automatic routing
  • - Copy DID to clipboard for use in ads
  • - Track monthly lead volume per DID

DID Configuration

Campaign Assignment

Link DID to a campaign. All calls to this DID use the campaign's settings.

Direct Buyer Routing

Optionally assign a DID directly to a buyer and profile for direct transfer.

Using DIDs in Advertising

After provisioning, copy the DID from the dashboard and use it in your advertising campaigns (Google Ads call extensions, Facebook call-to-action, print ads, etc.). When callers dial the number, LeadKumo handles the routing automatically.

Form Builder

Create embeddable lead capture forms without writing code. Forms automatically submit to the ping/post engine.

Features

  • - Visual form configuration tied to lead types
  • - Reusable DataSets for dropdown options with cascading select support
  • - Industry-specific schema presets (Solar, Roofing, Auto Insurance, and more)
  • - Custom header and footer HTML
  • - TCPA consent text and partner list
  • - CSS overrides for custom styling
  • - Configurable redirect URL after submission
  • - Live preview mode
  • - Full FormSchema API for programmatic control over fields, types, validation, and layout

Embedding

Each form gets a unique embed code for your landing pages. Just add the script tag where you want the form to appear:

<script src="https://your-domain.com/forms/your-form-slug/embed.js"></script>

You can also add a data-sub-id attribute for source attribution:

<script src="https://your-domain.com/forms/your-form-slug/embed.js" data-sub-id="landing-page-1"></script>

Forms can also be accessed directly at their URL for previewing or linking:

https://your-domain.com/forms/your-form-slug

Live Demo Sites

See forms in action on our showcase sites, each running LeadKumo-powered lead capture:

  • - GetQuoted - Home improvement leads (roofing, solar, windows, and more)
  • - MostQuotes - Insurance quote comparison (auto, home, health, Medicare)
  • - Affloat - Business lending and financing
  • - SelectAccountants - Accounting and bookkeeping services

Form DataSets

Manage reusable dropdown option lists that power your lead capture forms. Define option sets once, reference them across multiple forms, and support cascading selects where one dropdown filters another - all without touching code or JSON schemas.

Key Concepts

  • - DataSet: A named collection of options (e.g., "car_makes") that can be referenced by any form
  • - Cascading Selects: Link a child dataset to a parent so options filter dynamically (e.g., selecting "Toyota" shows only Toyota models)
  • - Redis Caching: Dataset options are cached for 5 minutes, so public forms load instantly without hitting the database on every request
  • - Graceful Degradation: If Redis is not configured, datasets load directly from the database with zero configuration needed

Creating a DataSet

  1. 1
    Navigate to DataSets in the sidebar and click Create DataSet
  2. 2
    Enter a Name (slug used in form schemas, e.g., car_makes) and a Display Name
  3. 3
    Add your options as a JSON array in the Data field
  4. 4
    Optionally link a Parent DataSet for cascading behavior

Option Format

Each dataset stores its options as a JSON array. Every option has a value (submitted with the form) and a label (shown to the user). For cascading selects, include a parent field that matches a value from the parent dataset.

[
  { "value": "toyota", "label": "Toyota" },
  { "value": "honda", "label": "Honda" },
  { "value": "ford", "label": "Ford" }
]

Cascading Example

To create a make/model relationship, create two datasets. The child dataset ("car_models") references the parent dataset ("car_makes") and each option includes a parent value:

Parent: car_makes

[
  { "value": "toyota", "label": "Toyota" },
  { "value": "honda", "label": "Honda" }
]

Child: car_models

[
  { "value": "camry", "label": "Camry",
    "parent": "toyota" },
  { "value": "corolla", "label": "Corolla",
    "parent": "toyota" },
  { "value": "civic", "label": "Civic",
    "parent": "honda" }
]

When a user selects "Toyota" in the makes dropdown, the models dropdown automatically shows only Camry and Corolla.

Caching & Performance

When Redis is configured, dataset options are automatically cached to minimize database load on high-traffic forms:

  • - Options are cached per dataset with a 5-minute TTL
  • - Cache is automatically invalidated when you create, update, or delete a dataset
  • - Bulk form loads check cache individually - only missing datasets hit the database
  • - Without Redis, every request loads directly from the database - no configuration required

Referencing in Form Schemas

Reference a dataset in your form schema by using the dataset name. The form renderer fetches the options at load time and populates the dropdown automatically.

{
  "name": "vehicle_make",
  "type": "select",
  "label": "Vehicle Make",
  "dataset": "car_makes",
  "required": true
}

FormSchema API

Every form's fields, layout, validation, and behavior are controlled through a JSON-based FormSchema. You have full programmatic control over what fields appear, how they're validated, and how they're rendered — no code changes required.

How It Works

The FormSchema is a JSON object stored on each form. It defines the fields array that the renderer uses to build the form UI. You can set it through the admin UI's JSON editor, or generate it automatically from a LeadType's JSON Schema definition using the built-in schema converter.

  • - Schema-driven rendering: The form renderer reads the schema at load time and builds fields dynamically
  • - Instant updates: Change the schema in the admin, and embedded forms update immediately on next load
  • - Fallback behavior: If no schema is defined, forms render standard contact fields (name, email, phone, address)
  • - Auto-conversion: When a LeadType has a JSON Schema, it can be automatically converted to FormSchema format

Schema Structure

The top-level schema object contains a fields array. Each field object defines a single form input:

{
  "fields": [
    {
      "name": "field_name",
      "type": "text",
      "label": "Display Label",
      "required": true,
      "placeholder": "Hint text",
      "pattern": "regex pattern",
      "minlength": 5,
      "maxlength": 100,
      "options": [
        { "value": "val1", "label": "Option 1" },
        { "value": "val2", "label": "Option 2" }
      ],
      "dataset": "dataset_name"
    }
  ]
}

Field Properties

Property Type Required Description
name string Yes Field identifier, used as the form field name on submission
type string Yes Input type (see Field Types below)
label string Yes Display label shown above the field
required boolean No Whether the field must be filled before submission
placeholder string No Placeholder text shown inside the input
pattern string No Regex pattern for client-side validation
minlength number No Minimum character count
maxlength number No Maximum character count
options array Conditional Required for select and radio types. Each option: { value, label }
dataset string No Name of a DataSet to load options from dynamically

Field Types

Text Inputs

  • text - Standard text input
  • email - Email with format validation
  • tel - Phone number input
  • number - Numeric input
  • url - URL with format validation
  • textarea - Multi-line text area

Choice Inputs

  • select - Dropdown menu (requires options or dataset)
  • radio - Radio button group (requires options)
  • checkbox - Boolean checkbox (Yes/No)
  • date - Date picker

Intelligent Layout

The form renderer automatically groups certain fields for a professional layout. You control the field order in the schema, and the renderer handles responsive column placement:

Field Names Layout Behavior
first_name + last_name Side-by-side in a 2-column grid
email + phone Side-by-side in a 2-column grid
address Full-width row
city + state + zip_code 3-column responsive grid (city wider, state and zip narrower)
All other fields Full-width, rendered in schema order

The state field is always rendered as a dropdown with all 50 US states plus DC, regardless of whether you define options in the schema.

Auto-Generated Field Order

When a form schema is automatically generated from a LeadType definition, fields are sorted into a consistent priority order:

  1. 1
    Contact fields first: first_name, last_name, email, phone
  2. 2
    Address fields next: address, city, state, zip_code
  3. 3
    Vertical-specific fields last: All remaining custom fields for the lead type

You can override this by manually editing the schema and reordering the fields array. The renderer always respects the array order.

LeadType Schema Conversion

When you create a form and select a LeadType that has a JSON Schema definition, the platform automatically converts it to FormSchema format. Here's how property types map:

LeadType Schema FormSchema Type
string (default) text
string + format: "email" email
string + phone pattern tel
string + format: "date" date
string + format: "uri" url
string + enum array select (options from enum values)
integer / number number
boolean select (Yes/No options auto-generated)

Form Configuration Properties

Beyond the schema itself, each form has additional configuration properties that control behavior and appearance:

Property Description
HeaderHtml Custom HTML rendered above the form fields (logos, headings, intro text)
FooterHtml Custom HTML rendered below the form fields (disclaimers, additional content)
TcpaText TCPA consent text shown with a checkbox the user must accept
PartnerList Comma-separated partner names displayed in the consent disclosure
CssOverrides Custom CSS injected into the form page for styling overrides
RedirectUrl URL to redirect the user to after successful form submission
AllowedDomains Comma-separated list of domains permitted to embed this form
HeadlessEnabled Enables API-only form submission without rendering UI

Complete Example

Here's a full FormSchema for an auto insurance lead form with contact fields, address, and vertical-specific questions:

{
  "fields": [
    {
      "name": "first_name",
      "type": "text",
      "label": "First Name",
      "required": true,
      "placeholder": "John"
    },
    {
      "name": "last_name",
      "type": "text",
      "label": "Last Name",
      "required": true,
      "placeholder": "Doe"
    },
    {
      "name": "email",
      "type": "email",
      "label": "Email Address",
      "required": true,
      "placeholder": "john@example.com"
    },
    {
      "name": "phone",
      "type": "tel",
      "label": "Phone Number",
      "required": true,
      "placeholder": "(555) 123-4567"
    },
    {
      "name": "address",
      "type": "text",
      "label": "Street Address",
      "required": false
    },
    {
      "name": "city",
      "type": "text",
      "label": "City",
      "required": true
    },
    {
      "name": "state",
      "type": "select",
      "label": "State",
      "required": true
    },
    {
      "name": "zip_code",
      "type": "text",
      "label": "ZIP Code",
      "required": true,
      "pattern": "^\\d{5}(-\\d{4})?$",
      "maxlength": 10
    },
    {
      "name": "vehicle_year",
      "type": "number",
      "label": "Vehicle Year",
      "required": true,
      "placeholder": "2024"
    },
    {
      "name": "vehicle_make",
      "type": "select",
      "label": "Vehicle Make",
      "required": true,
      "dataset": "car_makes"
    },
    {
      "name": "vehicle_model",
      "type": "select",
      "label": "Vehicle Model",
      "required": true,
      "dataset": "car_models"
    },
    {
      "name": "current_insurance",
      "type": "select",
      "label": "Currently Insured?",
      "required": true,
      "options": [
        { "value": "yes", "label": "Yes" },
        { "value": "no", "label": "No" }
      ]
    },
    {
      "name": "accidents_3yr",
      "type": "select",
      "label": "Accidents in Past 3 Years",
      "required": true,
      "options": [
        { "value": "0", "label": "None" },
        { "value": "1", "label": "One" },
        { "value": "2+", "label": "Two or more" }
      ]
    }
  ]
}

This schema produces a fully responsive form with paired name/email/phone fields, an address row, city/state/zip grouping, and vertical-specific dropdowns powered by DataSets.

Return Management

Handle buyer returns efficiently with individual and bulk processing. Track return rates, net revenue, and maintain complete audit trails for dispute resolution.

Key Concepts

  • - Sales are permanent: Unlike leads, sale records are never archived or deleted
  • - Return tracking: Each return captures reason, code, date, and who processed it
  • - Net revenue: Reports automatically calculate gross revenue minus returns
  • - Audit trail: Complete history preserved for dispute resolution

Individual Returns

Process single returns directly from the Sales page or Sale Details page:

  1. 1
    Navigate to Sales and find the transaction
  2. 2
    Click the return action button or open Sale Details
  3. 3
    Enter return reason and optional return code
  4. 4
    Confirm - the sale status updates to "Returned"

Bulk Returns (CSV Upload)

Process multiple returns at once using buyer-provided return files:

Required Fields

  • - Buyer: Select the buyer who provided the file
  • - Month: Returns can only be processed once per buyer per month
  • - CSV File: Transaction IDs in first column

CSV Format

  • - Column 1: Transaction ID (GUID) - required
  • - Column 2: Return Reason - optional
  • - Column 3: Return Code - optional
  • - Column 4: Return Date - optional
# Example CSV format
transaction_id,reason,code,date
a1b2c3d4-e5f6-7890-abcd-ef1234567890,Bad contact info,INVALID_CONTACT,2024-01-15
b2c3d4e5-f6a7-8901-bcde-f12345678901,Duplicate lead,DUPLICATE,
c3d4e5f6-a7b8-9012-cdef-123456789012,Customer canceled,,

Validation & Results

The system validates each return and provides detailed feedback:

Success Cases

  • - Sale found and marked as returned
  • - Return reason and code recorded
  • - Audit log entry created

Error Cases

  • - Not Found: Transaction ID doesn't exist
  • - Already Returned: Sale was previously returned
  • - Wrong Buyer: Sale belongs to a different buyer
  • - Invalid GUID: Transaction ID format is invalid

Return Statistics

The Sales page displays key return metrics:

Total Sales
All transactions
Returned
Marked as returned
Net Revenue
Gross minus returns
Return Rate
Percentage returned

Buyer Return Reports

Track return rates by buyer to identify quality issues. High return rates may indicate targeting problems or integration issues that need attention. The Reports section includes return rate breakdowns per buyer and campaign.

Ingest Endpoints (Legacy Field Mapping)

Ingest endpoints allow legacy forms and partners to submit leads without changing their field names. Only the endpoint URL changes - field mappings automatically transform legacy field names to LeadKumo standard fields.

Key Benefits

  • - Zero partner changes - Partners only update the URL, keep existing field names
  • - Flexible formats - Accepts JSON, XML, and form-urlencoded data
  • - Field transformations - Automatic phone formatting, state abbreviation, zip normalization
  • - Nested JSON support - Map fields like data.contact.first_name
  • - Per-endpoint auth - Unique tokens or standard API keys

Creating an Ingest Endpoint

Navigate to Management → Ingest Endpoints → New Endpoint. The wizard guides you through three steps:

1. Basic Info

  • - Name and description
  • - URL slug (e.g., legacy-partner)
  • - Lead type
  • - Default source attribution

2. Field Mappings

  • - Source field (legacy name)
  • - Target field (LeadKumo field)
  • - Transformation to apply
  • - Required/optional

3. Settings

  • - Expected content type
  • - Response format
  • - Rate limit
  • - Authentication method

Field Mapping Types

Type Target Fields
Standard FirstName, LastName, Email, Phone, Address, City, State, ZipCode
Consent IpAddress, UserAgent, TrustedFormCertUrl, ConsentText
Custom Custom1 through Custom10
Attribute Any key (stored in the Attributes JSON field)

Available Transformations

Transform Description Example
lowercase Convert to lowercase JOHN@EXAMPLE.COM → john@example.com
uppercase Convert to uppercase john → JOHN
trim Remove whitespace " John " → "John"
phone_digits Extract digits only (555) 123-4567 → 5551234567
state_abbrev Convert state name to abbreviation California → CA
zip_normalize Extract first 5 digits 90210-1234 → 90210
boolean Convert to true/false "yes", "1", "on" → true
number Extract numeric value $1,234.56 → 1234.56

Testing Transformations

Use the Test page to validate your mappings before going live:

  • - Paste sample JSON from your partner
  • - See field-by-field transformation trace
  • - View final output that would be created
  • - Identify missing required fields

Authentication Options

Endpoint Token

Generate a unique token for this endpoint. Partner sends via Authorization: Bearer or X-Ingest-Token header.

API Key

Use standard API key authentication via X-API-Key header. Useful for internal integrations.

Anonymous

Allow unauthenticated access. Use with caution - enable rate limiting and consider IP whitelisting.

Dot Notation for Nested JSON

Source fields support dot notation to extract values from nested JSON structures:

// Partner sends nested data:
{
  "data": {
    "contact": {
      "first_name": "John",
      "last_name": "Doe"
    },
    "email": "john@example.com"
  }
}

// Field mappings:
data.contact.first_name → FirstName
data.contact.last_name  → LastName
data.email              → Email

Email & SMS Delivery

In addition to HTTP post endpoints and call transfers, deliver leads via email or SMS. Configure per-integration delivery methods with Handlebars templating, provider flexibility, and delivery tracking.

Delivery Methods

HTTP Post

Traditional webhook delivery with customizable payloads

Email

SMTP delivery with HTML or plain text templates

SMS

Text message delivery via Telnyx or Twilio

Email Delivery Setup

Configure SMTP settings once in Settings → System → SMTP, then create reusable email templates.

SMTP Configuration

  • - SMTP host and port
  • - Authentication credentials
  • - TLS/SSL encryption
  • - From address and display name
  • - Connection test verification

Email Templates

  • - Subject line with variables
  • - HTML or plain text body
  • - Handlebars variable substitution
  • - Preview before saving
  • - Active/inactive status

SMS Delivery Setup

Configure your SMS provider in Settings → System → SMS. Supports Telnyx (recommended) and Twilio.

Provider Configuration

  • - API key / Auth token
  • - From phone number (E.164)
  • - Messaging profile ID (Telnyx)
  • - Connection test verification

SMS Templates

  • - 160 character segments
  • - Real-time character counter
  • - Handlebars variable substitution
  • - Multi-segment support

Template Variables

Use Handlebars syntax to insert lead data into your templates. All standard lead fields are available:

New lead received!

Name: {{FirstName}} {{LastName}}
Email: {{Email}}
Phone: {{Phone}}
State: {{State}}
Source: {{SourceName}}

{{#if Custom1}}Notes: {{Custom1}}{{/if}}
Variable Description
{{FirstName}}, {{LastName}} Contact name fields
{{Email}}, {{Phone}} Contact information
{{Address}}, {{City}}, {{State}}, {{ZipCode}} Location fields
{{SourceName}}, {{LeadTypeName}} Attribution data
{{Custom1}} - {{Custom10}} Custom fields from lead type schema
{{SoldPrice}} Winning bid amount

Integration Configuration

When creating or editing an integration, select the delivery method and assign a template:

  1. 1 Navigate to Buyers → Integrations and create or edit an integration
  2. 2 Select Delivery Method: HTTP Post, Email, or SMS
  3. 3 For Email: Enter recipient address and select an email template
  4. 4 For SMS: Enter recipient phone number and select an SMS template

Activity Timeline

NEW

Every lead now has a complete activity timeline showing every step from ingestion through sale. The timeline appears on the lead detail page, providing full visibility into how each lead was processed, which profiles matched or rejected it, and every buyer interaction.

Timeline Events

Each event is color-coded and displayed chronologically with expandable details:

Success Events

  • - Received — Lead entered the system
  • - ProfileMatched — Targeting profile passed
  • - Sold — Lead sold to buyer

Action Events

  • - Pinged — Ping sent to buyer
  • - Posted — Post sent to buyer
  • - CidLookup — CID lookup attempted
  • - CidEnriched — CID data merged

Rejection Events

  • - ProfileRejected — Targeting failed (with reasons)
  • - Returned — Lead returned by buyer

Additional Event Types

Response Events

  • - PingResponse — Buyer's ping response received
  • - PostResponse — Buyer's post response received
  • - Transferred — Call transferred to buyer
  • - Completed — Call completed

Expandable Details

Click any timeline entry to expand its detail panel. View profile match reasons, rejection explanations, bid prices, HTTP response summaries, and more. All personally identifiable information is automatically filtered from the display.

Profile Matching Visibility

The timeline shows exactly which buyer profiles matched and which were rejected, with specific reasons. This makes it easy to debug targeting rules — if a lead didn't reach a particular buyer, the rejection reasons explain why (e.g., "State 'CA' not in target states", "vehicle_year < 2015").

Reports

Comprehensive reporting to understand your lead flow and optimize performance across both web and call channels.

Lead Volume Reports

Track leads by vertical, source, date range, status, and channel (Web/Call). Export to CSV.

Channel Breakdown

Compare Web vs Call performance: volume, revenue, conversion rates by channel.

Source Performance

Revenue attribution by lead source. Track which sources deliver the best ROI.

Buyer Performance

Revenue, acceptance rates, response times, and return rates per buyer.

Call Reports

Total calls, connected, billable, abandoned. Average duration, DID performance, buyer call stats.

Geographic Distribution

Visualize lead volume and revenue by state and region.

Backups & System Administration

Built-in tools to protect your data and manage system operations.

Database Backups

  • - Automated PostgreSQL backups with pg_dump
  • - Gzip compression for storage efficiency
  • - AES-256 encryption for sensitive data
  • - Optional SFTP upload to remote server
  • - Configurable retention period
  • - Backup history and status tracking

Data Cleanup

  • - Configurable lead expiry (default: 365 days)
  • - Ping/post expiry for unsold leads (default: 120 days)
  • - Grace period before permanent deletion
  • - Audit log retention settings
  • - Sales records are never deleted (permanent)

Job Management

  • - View scheduled job execution history
  • - Manually trigger backup or cleanup jobs
  • - Monitor progress of running jobs
  • - View job results and error messages

Redis Cache

  • - Connection configuration and testing
  • - Cache statistics monitoring
  • - Used for campaign caps, ping queuing, and form dataset options
  • - Optional - all features work without Redis, loading directly from the database

Security & Data Protection

KEY FEATURE

LeadKumo provides enterprise-grade security with encryption at rest and in transit. You provide your own PII encryption key during setup - we never have access to it.

Encrypted at Rest

All PII fields (names, emails, phones, addresses) are encrypted with AES-256 before storage. Your encryption key is provided during setup and stored only on your server.

Encrypted in Transit

All API traffic uses TLS 1.3. HTTPS is enforced with HSTS headers. Buyer webhooks are delivered over secure connections with configurable authentication.

What Gets Protected

Data Type Protection Examples
Lead Contact Info AES-256 Encrypted First/last name, email, phone, address, city, IP
User Passwords BCrypt Hashed Admin and user login passwords
API Keys BCrypt Hashed Buyer authentication keys
Lead Attributes Unencrypted State, zip, credit score, vehicle year (for targeting)

Note: Geographic and attribute data remains unencrypted to enable buyer targeting rules. Do not store PII in custom fields.

Encryption Key Management

Key Generation

The setup wizard generates a cryptographically secure 256-bit key. Just click "Generate" - no technical knowledge needed.

Key Storage

Your encryption key is stored securely in the database. Save a backup copy in a password manager before completing setup.

Advanced: Environment Variables

For most users, the automated installer handles all configuration. Advanced users deploying manually may need these environment variables.

Variable Description Required
DATABASE_CONNECTION_STRING PostgreSQL connection string (set by installer) Yes*
APP_URL Public URL of the application (set by installer) Yes*
REDIS_CONNECTION_STRING Redis connection for caching (set by installer) No
PHOENIX_PII_KEY PII encryption key (alternative to setup wizard) No*
GOOGLE_CLIENT_ID Google OAuth client ID No
GOOGLE_CLIENT_SECRET Google OAuth client secret No
FORCE_MIGRATIONS Run migrations in production (true/false) No

* PHOENIX_PII_KEY can be set via environment variable OR via the setup wizard (UI). The setup wizard is recommended for non-technical users.

Next Steps