Bill-on-match billing
411data enrichment routes use fixed (exact) pricing charged up front by the balance waterfall, with automatic refund when no usable match is found.
Routes (live)
| Route | Refund when |
|---|---|
/api/v1/enrich/phone |
matched: false |
/api/v1/enrich/person |
matched: false |
/api/v1/enrich/websearch |
matched: false |
/api/v1/enrich/lead-session |
no usable enrichment fields |
Catalog routes (offline by default) also bill-on-match when enabled:
/api/v1/enrich/email, /enrich/company (matched: false), and
/api/v1/leads/search (zero rows).
Response signals
{
"matched": false,
"billed": false,
"cache_hit": false
}
After refund, billed should read false on no-match responses.
Billing order (unchanged)
- Virtual USD balance debited first.
- 402 + x402 only when balance cannot cover the price.
Audit
Every call is stored in request_response_store with input hash for cache
lookups — repeated identical inputs may return cache_hit: true without
re-hitting vendors.
Lead-session vendor hops also honor cache_hit.
Agent-scoped warm-seed (AGENT_LEAD_CACHE_TTL_HOURS, default 168h) reuses the
latest lead_enrichment_backfill (or a prior matched batch-row debug graph when
AGENT_LEAD_BATCH_CACHE_ENABLED=1) for the same agent when a new chat or batch row
matches by chat_title, exact input JSON, batch input JSON, CRM contact_id
(int or external string), phone, or company + address (normalized geo key).
Response field agent_cache.cache_scope: "agent"; cache_match includes
chat_title, input_exact, batch_input_exact, company, phone, person, or contact_id.
Cross-agent warm-seed uses unrolled phone/company/person indexes
(GLOBAL_LEAD_CACHE_TTL_HOURS, default 168h) — agent_cache.cache_scope: "global".
CRM contact_id is never shared across agents.
Related
- prepay_deposits — refill balance
- prepay_deposits — top up virtual balance with USDC on Base