API Documentation

Integrate qualified revenue opportunities directly into your stack.

Data Pipeline Overview

All uploaded leads pass through our 5-phase validation pipeline:

01 Ingest

Parse CSV/API

02 Normalize

Standardize

03 Validate

Email + Phone

04 Enrich

Apollo/Clearbit

05 Dedup

Fuzzy Match

06 Score

Smart Scoring

Only leads marked QUALIFIED are returned in the final output.

Authentication

All API requests require a JWT token obtained from /api/auth/login. Pass it as a Bearer token in the Authorization header.

Get Token
curl -s -X POST https://leedrush.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "you@company.com", "password": "yourpassword"}' \
  | jq -r '.access_token'

Store the token and use -H "Authorization: Bearer $TOKEN" in all subsequent requests.

Base URL

https://leedrush.com/api

All endpoints are relative to this base URL. Use https://leedrush.com/api/upload, /api/process, etc.

Endpoints

POST /api/upload

Upload a file (CSV or JSON) for processing.

curl
TOKEN="your_jwt_token_here"

curl -s -X POST https://leedrush.com/api/upload \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@leads.csv" \
  | jq .
Response
{
  "filename": "leads.csv",
  "size": 24576,
  "file_path": "/uploads/leads_2026-03-19_abc123.csv",
  "rows_detected": 500
}
POST /api/process

Start a background processing job for an uploaded file.

curl
TOKEN="your_jwt_token_here"

curl -s -X POST https://leedrush.com/api/process \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"filename": "leads.csv"}' \
  | jq .
Response
{
  "batch_id": "batch_a1b2c3d4",
  "status": "queued",
  "filename": "leads.csv",
  "rows_total": 500,
  "created_at": "2026-03-19T11:00:00Z"
}
GET /api/batches

Retrieve a list of all batch jobs and their status.

curl
TOKEN="your_jwt_token_here"

curl -s https://leedrush.com/api/batches \
  -H "Authorization: Bearer $TOKEN" \
  | jq .
Response
[
  {
    "batch_id": "batch_a1b2c3d4",
    "status": "completed",
    "filename": "leads.csv",
    "rows_total": 500,
    "rows_qualified": 382,
    "rows_failed": 23,
    "quality_yield": 76.4,
    "created_at": "2026-03-19T11:00:00Z",
    "completed_at": "2026-03-19T11:04:37Z"
  }
]
Polling for Batch Status
Poll until completed
TOKEN="your_jwt_token_here"
BATCH_ID="batch_a1b2c3d4"

while true; do
  STATUS=$(curl -s https://leedrush.com/api/batches \
    -H "Authorization: Bearer $TOKEN" \
    | jq -r --arg id "$BATCH_ID" '.[] | select(.batch_id==$id) | .status')
  echo "Status: $STATUS"
  [ "$STATUS" = "completed" ] && break
  sleep 10
done
echo "Batch ready — download or push to CRM"
GET /api/download/{job_id}

Download the result CSV for a completed job.

Qualified Lead Schema (JSON)
{
  "status": "QUALIFIED",
  "score": 98.5,
  "account": {
    "name": "TechFlow Systems",
    "domain": "techflow.com",
    "signals": ["Series B", "Hiring"],
    "technologies": ["AWS", "Salesforce"]
  },
  "contact": {
    "full_name": "Sarah Miller",
    "title_normalized": "VP of Sales",
    "email": "sarah@techflow.com",
    "email_status": "verified_deliverable",
    "phone": "+1-555-0199",
    "phone_status": "mobile_active"
  },
  "dedup_confidence": 0.99
}

Billing & Subscription API

POST /api/billing/create-checkout

Create a Stripe checkout session for subscription purchase.

Request Body
{ "plan_id": "professional" }
Response
{ "checkout_url": "https://checkout.stripe.com/...", "session_id": "..." }
GET /api/billing/subscription

Get current subscription details and credit balance.

Response
{
  "plan_id": "professional",
  "plan_name": "Professional",
  "credits_total": 5000,
  "credits_remaining": 3250,
  "billing_cycle_start": "2026-02-01",
  "billing_cycle_end": "2026-03-01",
  "status": "active"
}
POST /api/billing/subscription/upgrade

Upgrade subscription plan (immediate, resets credits).

Request Body
{ "plan_id": "enterprise" }
POST /api/billing/subscription/downgrade

Schedule downgrade at end of billing cycle.

Request Body
{ "plan_id": "starter" }
GET /api/billing/usage?days=30

Get usage statistics for the specified period.

Response
{
  "total_consumed": 1750,
  "daily_usage": [
    {"date": "2026-02-01", "credits": 50},
    {"date": "2026-02-02", "credits": 75}
  ]
}
POST /api/billing/refund

Request a refund for a specific order.

Request Body
{ 
  "order_id": "ord_abc123",
  "amount": 49900,
  "reason": "Customer request"
}
GET /api/billing/invoices

List all invoices for the current user.

Response
[
  {
    "invoice_number": "INV-2026-001",
    "amount": 499.00,
    "status": "paid",
    "created_at": "2026-02-01T10:00:00Z"
  }
]
GET /api/billing/invoices/{invoice_number}/pdf

Download invoice PDF.

Phase 3 API Endpoints

Access advanced caching, predictive enrichment, and multi-source validation features.

GET /v1/cache/stats

Cache Performance Metrics

Get real-time cache performance statistics including hit rates, latency, and cost savings.

Response
{
  "l1_cache": {
    "hit_rate": 0.94,
    "avg_latency_ms": 0.8,
    "total_hits": 15420,
    "total_misses": 980
  },
  "l2_cache": {
    "hit_rate": 0.89,
    "avg_latency_ms": 12.5,
    "total_hits": 8730,
    "total_misses": 1080
  },
  "similarity_matches": {
    "total": 3240,
    "threshold": 0.85
  },
  "cost_savings": {
    "api_calls_saved": 24150,
    "estimated_savings_usd": 1207.50
  }
}
GET /v1/enrichment/predictive

Predictive Enrichment Status

Check the status of predictive enrichment including detected patterns and pre-enriched leads.

Response
{
  "patterns_detected": {
    "company_batches": 12,
    "sequential_patterns": 8,
    "domain_patterns": 15
  },
  "predictions": {
    "total_generated": 450,
    "pre_enriched": 360,
    "success_rate": 0.80
  },
  "performance": {
    "avg_prediction_accuracy": 0.82,
    "zero_latency_requests": 0.78,
    "throughput_increase": 2.1
  },
  "background_queue": {
    "pending": 45,
    "processing": 12,
    "completed": 360
  }
}
GET /v1/validation/multi-source

Multi-Source Validation Results

Retrieve cross-validated data with source attribution and confidence scores.

Request
GET /v1/validation/multi-source?email=john.smith@techcorp.com
Response
{
  "lead": {
    "email": "john.smith@techcorp.com",
    "name": "John Smith",
    "title": "VP of Engineering",
    "company": "TechCorp Inc",
    "phone": "+1-555-0123",
    "linkedin": "https://linkedin.com/in/johnsmith"
  },
  "validation": {
    "confidence_score": 0.96,
    "data_quality": 0.99,
    "coverage": 0.98
  },
  "sources": {
    "hunter_io": {
      "agreement": true,
      "confidence": 0.95,
      "fields_provided": ["email", "name", "title", "company"]
    },
    "clearbit": {
      "agreement": true,
      "confidence": 0.98,
      "fields_provided": ["name", "title", "company", "linkedin"]
    },
    "snov_io": {
      "agreement": true,
      "confidence": 0.94,
      "fields_provided": ["email", "phone", "company"]
    }
  },
  "consensus": {
    "email": { "agreement_score": 1.0, "sources": 3 },
    "name": { "agreement_score": 1.0, "sources": 3 },
    "title": { "agreement_score": 0.95, "sources": 2 },
    "company": { "agreement_score": 1.0, "sources": 3 }
  }
}

Phase 3 Metrics

Enhanced batch and lead responses now include Phase 3 performance metrics.

Example: Enhanced Batch Response
{
  "batch_id": "batch_123",
  "status": "completed",
  "leads_processed": 1000,
  "leads_qualified": 847,
  "phase3_metrics": {
    "cache_hit_rate": 0.94,
    "predictive_matches": 780,
    "multi_source_validated": 847,
    "avg_confidence": 0.96
  }
}

Rate Limits

Each plan has request-per-minute and concurrent batch limits. When exceeded, the API returns 429 Too Many Requests with a Retry-After header in seconds.

Plan Requests / min Concurrent batches Max rows / batch
PAYG 30 3 10,000
Starter 60 5 25,000
Scale 120 10 100,000
Enterprise Unlimited Unlimited Unlimited
Handle 429 in bash
RETRY_AFTER=$(curl -s -o /dev/null -w "%{header:retry-after}" \
  https://leedrush.com/api/batches \
  -H "Authorization: Bearer $TOKEN")
echo "Rate limited — retrying in ${RETRY_AFTER}s"
sleep "$RETRY_AFTER"

Pagination

List endpoints support cursor-based pagination via limit and offset query parameters.

Parameter Type Default Max Description
limit integer 20 100 Number of items per page
offset integer 0 Number of items to skip
sort string created_at Sort field: created_at, status, rows_total
order string desc Sort order: asc or desc
curl — paginate batches
TOKEN="your_jwt_token_here"

# Page 1 — 20 newest batches
curl -s "https://leedrush.com/api/batches?limit=20&offset=0&sort=created_at&order=desc" \
  -H "Authorization: Bearer $TOKEN" | jq .

# Page 2
curl -s "https://leedrush.com/api/batches?limit=20&offset=20" \
  -H "Authorization: Bearer $TOKEN" | jq .
Response shape
{
  "items": [ ...batch objects... ],
  "total": 143,
  "limit": 20,
  "offset": 0,
  "has_more": true
}

Webhook Events

Configure your webhook URL in Settings → Integrations → Webhooks. All events include an X-Leedrush-Signature header for verification.

Event Trigger
batch.completed Batch processing finished successfully
batch.failed Batch failed — see error_reason
lead.qualified Individual lead passed all validation stages
credits.low Credit balance below 10% of plan limit
credits.exhausted All credits consumed — processing paused
subscription.upgraded Plan successfully upgraded
topup.completed Credit top-up payment confirmed
batch.completed payload
{
  "event": "batch.completed",
  "batch_id": "batch_a1b2c3d4",
  "timestamp": "2026-03-21T11:00:00Z",
  "data": {
    "filename": "leads.csv",
    "rows_total": 500,
    "rows_qualified": 382,
    "rows_failed": 23,
    "quality_yield": 76.4,
    "processing_time_s": 47
  }
}
Python — receive & verify webhook
import hmac, hashlib
from fastapi import Request, HTTPException

WEBHOOK_SECRET = "your_webhook_secret"

async def handle_webhook(request: Request):
    payload = await request.body()
    sig = request.headers.get("X-Leedrush-Signature", "")
    expected = hmac.new(
        WEBHOOK_SECRET.encode(), payload, hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(expected, sig):
        raise HTTPException(status_code=401, detail="Invalid signature")

    event = await request.json()
    if event["event"] == "batch.completed":
        batch_id = event["batch_id"]
        # your logic here
    return {"ok": True}

Error Reference

All errors return JSON with a detail field. Use the HTTP status code to determine the cause.

Code Meaning Common Cause
200 OK Request succeeded
400 Bad Request Malformed JSON or missing required fields
401 Unauthorized Missing or invalid Bearer token — re-authenticate
403 Forbidden Endpoint requires a higher plan tier
404 Not Found Batch ID or resource does not exist
422 Unprocessable CSV has no recognised email column or encoding issue
429 Rate Limited Exceeded plan request limit — wait 60s and retry
500 Server Error Unexpected server error — contact support@leedrush.com

Webhook Signature Verification

All Stripe webhooks are verified using HMAC-SHA256 signatures:

Python Example
import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)