theleadrouter-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/admin-guide/SKILL.md +351 -0
- package/.claude/skills/buyer-guide/SKILL.md +405 -0
- package/.claude/skills/partner-guide/SKILL.md +352 -0
- package/.claude/skills/welcome/SKILL.md +351 -0
- package/CLAUDE.md +238 -0
- package/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/api-client.d.ts +10 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +64 -0
- package/dist/api-client.js.map +1 -0
- package/dist/auth-adapter.d.ts +33 -0
- package/dist/auth-adapter.d.ts.map +1 -0
- package/dist/auth-adapter.js +87 -0
- package/dist/auth-adapter.js.map +1 -0
- package/dist/bin/iscale-mcp.d.ts +3 -0
- package/dist/bin/iscale-mcp.d.ts.map +1 -0
- package/dist/bin/iscale-mcp.js +7 -0
- package/dist/bin/iscale-mcp.js.map +1 -0
- package/dist/build-registry.d.ts +3 -0
- package/dist/build-registry.d.ts.map +1 -0
- package/dist/build-registry.js +15 -0
- package/dist/build-registry.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/register.d.ts +4 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +23 -0
- package/dist/register.js.map +1 -0
- package/dist/registry.d.ts +50 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +78 -0
- package/dist/registry.js.map +1 -0
- package/dist/tools/buyers.d.ts +4 -0
- package/dist/tools/buyers.d.ts.map +1 -0
- package/dist/tools/buyers.js +61 -0
- package/dist/tools/buyers.js.map +1 -0
- package/dist/tools/campaigns.d.ts +4 -0
- package/dist/tools/campaigns.d.ts.map +1 -0
- package/dist/tools/campaigns.js +45 -0
- package/dist/tools/campaigns.js.map +1 -0
- package/dist/tools/compliance.d.ts +4 -0
- package/dist/tools/compliance.d.ts.map +1 -0
- package/dist/tools/compliance.js +28 -0
- package/dist/tools/compliance.js.map +1 -0
- package/dist/tools/composite.d.ts +3 -0
- package/dist/tools/composite.d.ts.map +1 -0
- package/dist/tools/composite.js +337 -0
- package/dist/tools/composite.js.map +1 -0
- package/dist/tools/contracts.d.ts +4 -0
- package/dist/tools/contracts.d.ts.map +1 -0
- package/dist/tools/contracts.js +48 -0
- package/dist/tools/contracts.js.map +1 -0
- package/dist/tools/generated/api-keys.gen.d.ts +3 -0
- package/dist/tools/generated/api-keys.gen.d.ts.map +1 -0
- package/dist/tools/generated/api-keys.gen.js +49 -0
- package/dist/tools/generated/api-keys.gen.js.map +1 -0
- package/dist/tools/generated/audit-logs.gen.d.ts +3 -0
- package/dist/tools/generated/audit-logs.gen.d.ts.map +1 -0
- package/dist/tools/generated/audit-logs.gen.js +59 -0
- package/dist/tools/generated/audit-logs.gen.js.map +1 -0
- package/dist/tools/generated/auth.gen.d.ts +3 -0
- package/dist/tools/generated/auth.gen.d.ts.map +1 -0
- package/dist/tools/generated/auth.gen.js +195 -0
- package/dist/tools/generated/auth.gen.js.map +1 -0
- package/dist/tools/generated/blocked-lists.gen.d.ts +3 -0
- package/dist/tools/generated/blocked-lists.gen.d.ts.map +1 -0
- package/dist/tools/generated/blocked-lists.gen.js +146 -0
- package/dist/tools/generated/blocked-lists.gen.js.map +1 -0
- package/dist/tools/generated/buyers.gen.d.ts +3 -0
- package/dist/tools/generated/buyers.gen.d.ts.map +1 -0
- package/dist/tools/generated/buyers.gen.js +153 -0
- package/dist/tools/generated/buyers.gen.js.map +1 -0
- package/dist/tools/generated/calls.gen.d.ts +3 -0
- package/dist/tools/generated/calls.gen.d.ts.map +1 -0
- package/dist/tools/generated/calls.gen.js +106 -0
- package/dist/tools/generated/calls.gen.js.map +1 -0
- package/dist/tools/generated/campaigns.gen.d.ts +3 -0
- package/dist/tools/generated/campaigns.gen.d.ts.map +1 -0
- package/dist/tools/generated/campaigns.gen.js +274 -0
- package/dist/tools/generated/campaigns.gen.js.map +1 -0
- package/dist/tools/generated/catalog.json +7096 -0
- package/dist/tools/generated/compliance.gen.d.ts +3 -0
- package/dist/tools/generated/compliance.gen.d.ts.map +1 -0
- package/dist/tools/generated/compliance.gen.js +119 -0
- package/dist/tools/generated/compliance.gen.js.map +1 -0
- package/dist/tools/generated/consent.gen.d.ts +3 -0
- package/dist/tools/generated/consent.gen.d.ts.map +1 -0
- package/dist/tools/generated/consent.gen.js +109 -0
- package/dist/tools/generated/consent.gen.js.map +1 -0
- package/dist/tools/generated/contacts.gen.d.ts +3 -0
- package/dist/tools/generated/contacts.gen.d.ts.map +1 -0
- package/dist/tools/generated/contacts.gen.js +88 -0
- package/dist/tools/generated/contacts.gen.js.map +1 -0
- package/dist/tools/generated/contracts.gen.d.ts +3 -0
- package/dist/tools/generated/contracts.gen.d.ts.map +1 -0
- package/dist/tools/generated/contracts.gen.js +306 -0
- package/dist/tools/generated/contracts.gen.js.map +1 -0
- package/dist/tools/generated/delivery-test.gen.d.ts +3 -0
- package/dist/tools/generated/delivery-test.gen.d.ts.map +1 -0
- package/dist/tools/generated/delivery-test.gen.js +17 -0
- package/dist/tools/generated/delivery-test.gen.js.map +1 -0
- package/dist/tools/generated/discovery.gen.d.ts +3 -0
- package/dist/tools/generated/discovery.gen.d.ts.map +1 -0
- package/dist/tools/generated/discovery.gen.js +17 -0
- package/dist/tools/generated/discovery.gen.js.map +1 -0
- package/dist/tools/generated/disposition-codes.gen.d.ts +3 -0
- package/dist/tools/generated/disposition-codes.gen.d.ts.map +1 -0
- package/dist/tools/generated/disposition-codes.gen.js +30 -0
- package/dist/tools/generated/disposition-codes.gen.js.map +1 -0
- package/dist/tools/generated/email-templates.gen.d.ts +3 -0
- package/dist/tools/generated/email-templates.gen.d.ts.map +1 -0
- package/dist/tools/generated/email-templates.gen.js +108 -0
- package/dist/tools/generated/email-templates.gen.js.map +1 -0
- package/dist/tools/generated/engagements.gen.d.ts +3 -0
- package/dist/tools/generated/engagements.gen.d.ts.map +1 -0
- package/dist/tools/generated/engagements.gen.js +208 -0
- package/dist/tools/generated/engagements.gen.js.map +1 -0
- package/dist/tools/generated/enrollments.gen.d.ts +3 -0
- package/dist/tools/generated/enrollments.gen.d.ts.map +1 -0
- package/dist/tools/generated/enrollments.gen.js +82 -0
- package/dist/tools/generated/enrollments.gen.js.map +1 -0
- package/dist/tools/generated/events.gen.d.ts +3 -0
- package/dist/tools/generated/events.gen.d.ts.map +1 -0
- package/dist/tools/generated/events.gen.js +20 -0
- package/dist/tools/generated/events.gen.js.map +1 -0
- package/dist/tools/generated/index.d.ts +3 -0
- package/dist/tools/generated/index.d.ts.map +1 -0
- package/dist/tools/generated/index.js +86 -0
- package/dist/tools/generated/index.js.map +1 -0
- package/dist/tools/generated/intake-centers.gen.d.ts +3 -0
- package/dist/tools/generated/intake-centers.gen.d.ts.map +1 -0
- package/dist/tools/generated/intake-centers.gen.js +196 -0
- package/dist/tools/generated/intake-centers.gen.js.map +1 -0
- package/dist/tools/generated/integrations.gen.d.ts +3 -0
- package/dist/tools/generated/integrations.gen.d.ts.map +1 -0
- package/dist/tools/generated/integrations.gen.js +290 -0
- package/dist/tools/generated/integrations.gen.js.map +1 -0
- package/dist/tools/generated/ivr.gen.d.ts +3 -0
- package/dist/tools/generated/ivr.gen.d.ts.map +1 -0
- package/dist/tools/generated/ivr.gen.js +97 -0
- package/dist/tools/generated/ivr.gen.js.map +1 -0
- package/dist/tools/generated/leads.gen.d.ts +3 -0
- package/dist/tools/generated/leads.gen.d.ts.map +1 -0
- package/dist/tools/generated/leads.gen.js +592 -0
- package/dist/tools/generated/leads.gen.js.map +1 -0
- package/dist/tools/generated/number-pool.gen.d.ts +3 -0
- package/dist/tools/generated/number-pool.gen.d.ts.map +1 -0
- package/dist/tools/generated/number-pool.gen.js +62 -0
- package/dist/tools/generated/number-pool.gen.js.map +1 -0
- package/dist/tools/generated/offers.gen.d.ts +3 -0
- package/dist/tools/generated/offers.gen.d.ts.map +1 -0
- package/dist/tools/generated/offers.gen.js +407 -0
- package/dist/tools/generated/offers.gen.js.map +1 -0
- package/dist/tools/generated/organizations.gen.d.ts +3 -0
- package/dist/tools/generated/organizations.gen.d.ts.map +1 -0
- package/dist/tools/generated/organizations.gen.js +161 -0
- package/dist/tools/generated/organizations.gen.js.map +1 -0
- package/dist/tools/generated/partners.gen.d.ts +3 -0
- package/dist/tools/generated/partners.gen.d.ts.map +1 -0
- package/dist/tools/generated/partners.gen.js +121 -0
- package/dist/tools/generated/partners.gen.js.map +1 -0
- package/dist/tools/generated/payouts.gen.d.ts +3 -0
- package/dist/tools/generated/payouts.gen.d.ts.map +1 -0
- package/dist/tools/generated/payouts.gen.js +92 -0
- package/dist/tools/generated/payouts.gen.js.map +1 -0
- package/dist/tools/generated/people.gen.d.ts +3 -0
- package/dist/tools/generated/people.gen.d.ts.map +1 -0
- package/dist/tools/generated/people.gen.js +354 -0
- package/dist/tools/generated/people.gen.js.map +1 -0
- package/dist/tools/generated/posting-log.gen.d.ts +3 -0
- package/dist/tools/generated/posting-log.gen.d.ts.map +1 -0
- package/dist/tools/generated/posting-log.gen.js +150 -0
- package/dist/tools/generated/posting-log.gen.js.map +1 -0
- package/dist/tools/generated/refunds.gen.d.ts +3 -0
- package/dist/tools/generated/refunds.gen.d.ts.map +1 -0
- package/dist/tools/generated/refunds.gen.js +91 -0
- package/dist/tools/generated/refunds.gen.js.map +1 -0
- package/dist/tools/generated/reports.gen.d.ts +3 -0
- package/dist/tools/generated/reports.gen.d.ts.map +1 -0
- package/dist/tools/generated/reports.gen.js +38 -0
- package/dist/tools/generated/reports.gen.js.map +1 -0
- package/dist/tools/generated/sessions.gen.d.ts +3 -0
- package/dist/tools/generated/sessions.gen.d.ts.map +1 -0
- package/dist/tools/generated/sessions.gen.js +90 -0
- package/dist/tools/generated/sessions.gen.js.map +1 -0
- package/dist/tools/generated/settings.gen.d.ts +3 -0
- package/dist/tools/generated/settings.gen.d.ts.map +1 -0
- package/dist/tools/generated/settings.gen.js +473 -0
- package/dist/tools/generated/settings.gen.js.map +1 -0
- package/dist/tools/generated/telephony.gen.d.ts +3 -0
- package/dist/tools/generated/telephony.gen.d.ts.map +1 -0
- package/dist/tools/generated/telephony.gen.js +170 -0
- package/dist/tools/generated/telephony.gen.js.map +1 -0
- package/dist/tools/generated/tenants.gen.d.ts +3 -0
- package/dist/tools/generated/tenants.gen.d.ts.map +1 -0
- package/dist/tools/generated/tenants.gen.js +223 -0
- package/dist/tools/generated/tenants.gen.js.map +1 -0
- package/dist/tools/generated/tracking-numbers.gen.d.ts +3 -0
- package/dist/tools/generated/tracking-numbers.gen.d.ts.map +1 -0
- package/dist/tools/generated/tracking-numbers.gen.js +131 -0
- package/dist/tools/generated/tracking-numbers.gen.js.map +1 -0
- package/dist/tools/generated/transactions.gen.d.ts +3 -0
- package/dist/tools/generated/transactions.gen.d.ts.map +1 -0
- package/dist/tools/generated/transactions.gen.js +62 -0
- package/dist/tools/generated/transactions.gen.js.map +1 -0
- package/dist/tools/generated/users.gen.d.ts +3 -0
- package/dist/tools/generated/users.gen.d.ts.map +1 -0
- package/dist/tools/generated/users.gen.js +339 -0
- package/dist/tools/generated/users.gen.js.map +1 -0
- package/dist/tools/generated/vertical-groups.gen.d.ts +3 -0
- package/dist/tools/generated/vertical-groups.gen.d.ts.map +1 -0
- package/dist/tools/generated/vertical-groups.gen.js +243 -0
- package/dist/tools/generated/vertical-groups.gen.js.map +1 -0
- package/dist/tools/generated/verticals.gen.d.ts +3 -0
- package/dist/tools/generated/verticals.gen.d.ts.map +1 -0
- package/dist/tools/generated/verticals.gen.js +164 -0
- package/dist/tools/generated/verticals.gen.js.map +1 -0
- package/dist/tools/leads.d.ts +4 -0
- package/dist/tools/leads.d.ts.map +1 -0
- package/dist/tools/leads.js +69 -0
- package/dist/tools/leads.js.map +1 -0
- package/dist/tools/offers.d.ts +4 -0
- package/dist/tools/offers.d.ts.map +1 -0
- package/dist/tools/offers.js +33 -0
- package/dist/tools/offers.js.map +1 -0
- package/dist/tools/partners.d.ts +4 -0
- package/dist/tools/partners.d.ts.map +1 -0
- package/dist/tools/partners.js +30 -0
- package/dist/tools/partners.js.map +1 -0
- package/dist/tools/people.d.ts +4 -0
- package/dist/tools/people.d.ts.map +1 -0
- package/dist/tools/people.js +42 -0
- package/dist/tools/people.js.map +1 -0
- package/dist/tools/reports.d.ts +4 -0
- package/dist/tools/reports.d.ts.map +1 -0
- package/dist/tools/reports.js +67 -0
- package/dist/tools/reports.js.map +1 -0
- package/dist/tools/ui.d.ts +3 -0
- package/dist/tools/ui.d.ts.map +1 -0
- package/dist/tools/ui.js +108 -0
- package/dist/tools/ui.js.map +1 -0
- package/dist/tools/verticals.d.ts +4 -0
- package/dist/tools/verticals.d.ts.map +1 -0
- package/dist/tools/verticals.js +25 -0
- package/dist/tools/verticals.js.map +1 -0
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: admin-guide
|
|
3
|
+
description: "Admin guide for iSCALE lead routing — full platform setup, entity management, routing configuration, reports, compliance. Use when configuring verticals, partners, buyers, campaigns, offers, contracts, intake centers, or troubleshooting routing."
|
|
4
|
+
user_invocable: true
|
|
5
|
+
allowed_tools:
|
|
6
|
+
- Bash
|
|
7
|
+
- Read
|
|
8
|
+
- Grep
|
|
9
|
+
- Glob
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# iSCALE Admin Guide
|
|
13
|
+
|
|
14
|
+
Complete guide for platform administrators. Covers entity setup, routing configuration, reports, and troubleshooting.
|
|
15
|
+
|
|
16
|
+
## When to use
|
|
17
|
+
- Setting up the platform from scratch
|
|
18
|
+
- Onboarding new partners or buyers
|
|
19
|
+
- Creating verticals, campaigns, offers, or contracts
|
|
20
|
+
- Configuring intake centers and delivery
|
|
21
|
+
- Understanding how routing decisions work
|
|
22
|
+
- Troubleshooting why leads aren't routing
|
|
23
|
+
- Pulling reports or managing compliance
|
|
24
|
+
|
|
25
|
+
## Platform Overview
|
|
26
|
+
|
|
27
|
+
iSCALE is a B2B lead distribution platform. Partners submit leads, the routing engine evaluates which buyers want them, and delivers leads to the winners.
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Partner submits lead → Campaign → Offer → Routing Engine → Contract(s) → Buyer(s)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Entity Hierarchy
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
Tenant (your organization)
|
|
37
|
+
│
|
|
38
|
+
├── Vertical Group (optional — groups related verticals)
|
|
39
|
+
│ └── Vertical (lead category: "Solar", "Medicare", etc.)
|
|
40
|
+
│ ├── Vertical Fields (custom fields for this lead type)
|
|
41
|
+
│ └── Vertical Group Dispositions (outcome codes)
|
|
42
|
+
│
|
|
43
|
+
├── Partner (lead source — affiliate, publisher)
|
|
44
|
+
│ ├── Campaign (program with posting key, pricing, caps)
|
|
45
|
+
│ │ └── Campaign Fields (extra fields beyond vertical)
|
|
46
|
+
│ └── API Keys (partner portal access)
|
|
47
|
+
│
|
|
48
|
+
├── Buyer (lead purchaser — advertiser, client)
|
|
49
|
+
│ ├── Contract (filters, caps, pricing, delivery config)
|
|
50
|
+
│ └── API Keys (buyer portal access)
|
|
51
|
+
│
|
|
52
|
+
├── Offer (distribution hub)
|
|
53
|
+
│ ├── Linked Campaigns (lead sources)
|
|
54
|
+
│ ├── Linked Contracts (eligible buyers)
|
|
55
|
+
│ └── DQ Contracts (fallback buyers)
|
|
56
|
+
│
|
|
57
|
+
└── Intake Center (buyer's CRM/backend)
|
|
58
|
+
├── Disposition Mappings
|
|
59
|
+
└── Program Cascades
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Setup Order (Dependencies)
|
|
63
|
+
|
|
64
|
+
Create entities in this order — each requires the previous:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
1. Vertical Group (optional)
|
|
68
|
+
2. Vertical
|
|
69
|
+
3. Vertical Fields
|
|
70
|
+
4. Partner (standalone)
|
|
71
|
+
5. Buyer (standalone)
|
|
72
|
+
6. Intake Center (standalone)
|
|
73
|
+
7. Campaign (requires: partner + vertical)
|
|
74
|
+
8. Contract (requires: buyer + vertical)
|
|
75
|
+
9. Offer (requires: vertical)
|
|
76
|
+
10. Link Campaign → Offer
|
|
77
|
+
11. Link Contract → Offer
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Entity Configuration Reference
|
|
81
|
+
|
|
82
|
+
### Vertical Groups
|
|
83
|
+
|
|
84
|
+
**Location:** Settings > Verticals > Vertical Groups tab
|
|
85
|
+
|
|
86
|
+
| Field | Purpose | Options |
|
|
87
|
+
|-------|---------|---------|
|
|
88
|
+
| name | Display name | e.g., "Mass Tort", "Insurance" |
|
|
89
|
+
| dedupScope | How far dedup reaches | `offer`, `vertical`, `group` |
|
|
90
|
+
| attributionScope | Attribution tracking scope | `offer`, `vertical`, `group` |
|
|
91
|
+
|
|
92
|
+
**When to use:** Related verticals (e.g., "Auto Insurance" + "Home Insurance") where dedup/attribution should work across them.
|
|
93
|
+
|
|
94
|
+
### Verticals
|
|
95
|
+
|
|
96
|
+
**Location:** Settings > Verticals
|
|
97
|
+
|
|
98
|
+
Every lead belongs to exactly one vertical. Verticals define the field schema.
|
|
99
|
+
|
|
100
|
+
| Field | Purpose |
|
|
101
|
+
|-------|---------|
|
|
102
|
+
| name | Display name ("Solar", "Medicare Supplement") |
|
|
103
|
+
| slug | URL-safe identifier ("solar", "medicare-supplement") |
|
|
104
|
+
| verticalGroupId | Optional parent group |
|
|
105
|
+
| status | `active` / `inactive` |
|
|
106
|
+
|
|
107
|
+
**Three-tier field architecture:**
|
|
108
|
+
1. **Global fields** (always present): firstName, lastName, email, phone, address, city, state, zipCode, dateOfBirth, ipAddress, tcpaConsent, trustedFormCertUrl
|
|
109
|
+
2. **Vertical fields** (per vertical): e.g., Solar → utilityBill, homeOwner, roofType
|
|
110
|
+
3. **Campaign fields** (per campaign): additional fields for one specific campaign
|
|
111
|
+
|
|
112
|
+
### Partners
|
|
113
|
+
|
|
114
|
+
**Location:** Partners (sidebar)
|
|
115
|
+
|
|
116
|
+
| Field | Purpose |
|
|
117
|
+
|-------|---------|
|
|
118
|
+
| name | Company/partner name |
|
|
119
|
+
| email | Primary contact |
|
|
120
|
+
| status | `active`, `paused`, `inactive` |
|
|
121
|
+
| paymentCycle | `weekly`, `bimonthly`, `monthly`, `adhoc` |
|
|
122
|
+
| balance | Running balance owed to partner |
|
|
123
|
+
|
|
124
|
+
**After creating:** Create campaigns, optionally create API keys for portal access.
|
|
125
|
+
|
|
126
|
+
### Campaigns
|
|
127
|
+
|
|
128
|
+
**Location:** Partners > [Partner] > Campaigns tab
|
|
129
|
+
|
|
130
|
+
| Field | Purpose |
|
|
131
|
+
|-------|---------|
|
|
132
|
+
| partnerId | Owner partner (required) |
|
|
133
|
+
| verticalId | Lead type (required) |
|
|
134
|
+
| postingKey | Auto-generated `lr_xxx` — partners use this to submit leads |
|
|
135
|
+
| pricingModel | `fixed` or `revshare` |
|
|
136
|
+
| costPerLead | Amount paid TO the partner per lead |
|
|
137
|
+
| dailyCap / weeklyCap / monthlyCap | Volume limits |
|
|
138
|
+
| status | `active`, `paused`, `inactive` |
|
|
139
|
+
|
|
140
|
+
**Campaign Fields** (campaign detail > Fields tab):
|
|
141
|
+
- Click "Load Fields" to see inherited global + vertical fields
|
|
142
|
+
- Add campaign-specific fields (must be camelCase, no conflicts)
|
|
143
|
+
- Types: text, number, boolean, date, select, email, phone, url
|
|
144
|
+
|
|
145
|
+
**Posting Spec:** `GET /api/v1/campaigns/{id}/posting` — returns required fields, sample body, endpoint URL.
|
|
146
|
+
|
|
147
|
+
### Buyers
|
|
148
|
+
|
|
149
|
+
**Location:** Buyers (sidebar)
|
|
150
|
+
|
|
151
|
+
| Field | Purpose |
|
|
152
|
+
|-------|---------|
|
|
153
|
+
| name | Company name |
|
|
154
|
+
| status | `active`, `paused`, `suspended`, `inactive` |
|
|
155
|
+
| balance | Amount buyer owes (increases with purchases) |
|
|
156
|
+
| creditLimit | Max balance before pausing |
|
|
157
|
+
| dedupEnabled | Check for duplicate leads |
|
|
158
|
+
| dedupFields | Which fields to hash (default: email, phone) |
|
|
159
|
+
| dedupWindowDays | Days to remember leads (default: 30) |
|
|
160
|
+
| brandName | Brand name for TCPA consent language |
|
|
161
|
+
|
|
162
|
+
**After creating:** Create contracts, configure delivery, optionally set up intake center.
|
|
163
|
+
|
|
164
|
+
### Contracts
|
|
165
|
+
|
|
166
|
+
**Location:** Buyers > [Buyer] > Contracts tab
|
|
167
|
+
|
|
168
|
+
The most complex entity — defines what the buyer wants, how many, at what price, and how to deliver.
|
|
169
|
+
|
|
170
|
+
**Pricing:**
|
|
171
|
+
| Field | Purpose |
|
|
172
|
+
|-------|---------|
|
|
173
|
+
| pricingModel | `fixed` or `ping_post` |
|
|
174
|
+
| pricePerLead | Amount buyer pays |
|
|
175
|
+
| exclusiveMultiplier | Price multiplier for exclusive (default: 1.0) |
|
|
176
|
+
| allowMultiSale | Participates in multisell? |
|
|
177
|
+
|
|
178
|
+
**Filters:**
|
|
179
|
+
| Type | Field | Example |
|
|
180
|
+
|------|-------|---------|
|
|
181
|
+
| Geographic | geoFilters | `{ "states": ["CA", "TX"], "zipCodes": ["902*"] }` |
|
|
182
|
+
| Demographic | demographicFilters | `{ "minAge": 25, "maxAge": 65 }` |
|
|
183
|
+
| Custom | customFilters | `{ "homeOwner": true, "utilityBill": { "min": 100 } }` |
|
|
184
|
+
|
|
185
|
+
**Caps:**
|
|
186
|
+
| Type | Fields |
|
|
187
|
+
|------|--------|
|
|
188
|
+
| Lead count | dailyLeadCap, weeklyLeadCap, monthlyLeadCap |
|
|
189
|
+
| Spend | dailySpendCap, weeklySpendCap, monthlySpendCap |
|
|
190
|
+
|
|
191
|
+
**Schedule:**
|
|
192
|
+
- scheduleTimezone (default: America/Los_Angeles)
|
|
193
|
+
- scheduleHours: hours per day of week (empty = 24/7)
|
|
194
|
+
- expiresAt: contract expiration date
|
|
195
|
+
|
|
196
|
+
**Delivery:**
|
|
197
|
+
- deliveryMethodOverride / deliveryUrlOverride
|
|
198
|
+
- deliveryConfig: field mapping, headers
|
|
199
|
+
- intakeCenterId: link to intake center
|
|
200
|
+
|
|
201
|
+
**CPA:**
|
|
202
|
+
- cpaAmount: bonus paid on conversion
|
|
203
|
+
- cpaWindowDays: days to wait for conversion
|
|
204
|
+
|
|
205
|
+
### Offers
|
|
206
|
+
|
|
207
|
+
**Location:** Offers (sidebar)
|
|
208
|
+
|
|
209
|
+
The distribution hub — connects campaigns (sources) to contracts (buyers).
|
|
210
|
+
|
|
211
|
+
**Distribution:**
|
|
212
|
+
| Field | Purpose | Options |
|
|
213
|
+
|-------|---------|---------|
|
|
214
|
+
| distributionType | How many buyers | `exclusive` (1), `multisell` (all), `hybrid` (N) |
|
|
215
|
+
| distributionRule | How to pick winners | `price`, `priority`, `weight`, `round_robin` |
|
|
216
|
+
| maxSales | For hybrid mode | integer |
|
|
217
|
+
|
|
218
|
+
**Default Payout:**
|
|
219
|
+
- defaultPayoutModel: `fixed` or `revshare`
|
|
220
|
+
- defaultPayoutAmount: default amount (contracts can override)
|
|
221
|
+
|
|
222
|
+
**Dedup:**
|
|
223
|
+
- crossPartnerDedup: check dupes across partners (default: true)
|
|
224
|
+
- crossPartnerDedupWindowDays: lookback window (default: 30)
|
|
225
|
+
|
|
226
|
+
**Tabs:**
|
|
227
|
+
1. **Basic Info** — core settings
|
|
228
|
+
2. **Campaigns** — link lead sources
|
|
229
|
+
3. **Contracts** — link buyers, set weight/priority per contract
|
|
230
|
+
4. **DQ Contracts** — fallback buyers for rejected leads
|
|
231
|
+
|
|
232
|
+
### Intake Centers
|
|
233
|
+
|
|
234
|
+
**Location:** Settings > Intake Centers
|
|
235
|
+
|
|
236
|
+
Buyer's CRM or backend system.
|
|
237
|
+
|
|
238
|
+
| Field | Purpose |
|
|
239
|
+
|-------|---------|
|
|
240
|
+
| name | System name ("Salesforce", "Custom CRM") |
|
|
241
|
+
| deliveryMethod | `http_post`, `http_get`, `email` |
|
|
242
|
+
| deliveryUrl | Endpoint URL |
|
|
243
|
+
| authMethod | `header`, `body`, `query` |
|
|
244
|
+
| authKeyName | Name of auth parameter |
|
|
245
|
+
|
|
246
|
+
**Disposition Mappings:** Map buyer's CRM status codes → internal dispositions.
|
|
247
|
+
**Program Cascades:** Map program codes → specific contracts for routing.
|
|
248
|
+
|
|
249
|
+
## Routing Engine — How It Works
|
|
250
|
+
|
|
251
|
+
When a lead arrives:
|
|
252
|
+
|
|
253
|
+
1. **Identify offer** — campaign → offer link
|
|
254
|
+
2. **Collect contracts** — all contracts linked to the offer
|
|
255
|
+
3. **Evaluate each contract (in order):**
|
|
256
|
+
- a. Contract status = active?
|
|
257
|
+
- b. Buyer status = active?
|
|
258
|
+
- c. Buyer balance < credit limit?
|
|
259
|
+
- d. Within schedule hours?
|
|
260
|
+
- e. Geo filters match (state/zip)?
|
|
261
|
+
- f. Demographic filters match?
|
|
262
|
+
- g. Custom filters match?
|
|
263
|
+
- h. Caps not exceeded (daily/weekly/monthly)?
|
|
264
|
+
- i. Dedup check passed?
|
|
265
|
+
4. **Rank eligible contracts** by distribution rule
|
|
266
|
+
5. **Select winners** by distribution type (1 / all / N)
|
|
267
|
+
6. **Create LeadSale records**
|
|
268
|
+
7. **Deliver leads** to buyer endpoints
|
|
269
|
+
8. **If all rejected** → try DQ contracts
|
|
270
|
+
|
|
271
|
+
## Distribution Patterns
|
|
272
|
+
|
|
273
|
+
### Exclusive (One Winner)
|
|
274
|
+
- distributionType: `exclusive`
|
|
275
|
+
- distributionRule: `price` or `priority`
|
|
276
|
+
- Highest bid or top priority contract gets the lead
|
|
277
|
+
|
|
278
|
+
### Multisell (All Eligible)
|
|
279
|
+
- distributionType: `multisell`
|
|
280
|
+
- Every passing contract gets a copy
|
|
281
|
+
- Each buyer pays their contract price
|
|
282
|
+
|
|
283
|
+
### Hybrid (Top N)
|
|
284
|
+
- distributionType: `hybrid`, maxSales: 3
|
|
285
|
+
- Top 3 eligible contracts get the lead
|
|
286
|
+
|
|
287
|
+
### Ping-Post (Real-Time Auction)
|
|
288
|
+
- Contract pricingModel: `ping_post`
|
|
289
|
+
- Routing engine pings buyers with lead attributes (no PII)
|
|
290
|
+
- Buyers bid, highest wins, PII delivered to winner
|
|
291
|
+
|
|
292
|
+
### DQ/Fallback
|
|
293
|
+
- Offer > DQ Contracts tab
|
|
294
|
+
- Rejected leads route to fallback buyers at lower price
|
|
295
|
+
- Separate distribution rule from primary contracts
|
|
296
|
+
|
|
297
|
+
## Troubleshooting Routing
|
|
298
|
+
|
|
299
|
+
**No leads routing at all?**
|
|
300
|
+
- Check offer has BOTH campaigns AND contracts linked
|
|
301
|
+
- Check campaign, contract, buyer, offer all have status = `active`
|
|
302
|
+
- Check buyer balance hasn't exceeded creditLimit
|
|
303
|
+
|
|
304
|
+
**Lead rejected — "Cap Exceeded"?**
|
|
305
|
+
- Check contract's daily/weekly/monthly caps
|
|
306
|
+
- Caps reset at midnight in contract's scheduleTimezone
|
|
307
|
+
|
|
308
|
+
**Lead rejected — "Duplicate Lead"?**
|
|
309
|
+
- Buyer already received this person within dedupWindowDays
|
|
310
|
+
- Check buyer's dedupFields (default: email + phone)
|
|
311
|
+
|
|
312
|
+
**Lead rejected — filter mismatch?**
|
|
313
|
+
- Check contract's geoFilters (state abbreviations, zip wildcards)
|
|
314
|
+
- Check demographicFilters and customFilters
|
|
315
|
+
- Verify lead data matches expected formats
|
|
316
|
+
|
|
317
|
+
**Lead accepted but delivery failed?**
|
|
318
|
+
- Check deliveryUrl on contract or intake center
|
|
319
|
+
- Check auth configuration
|
|
320
|
+
- View delivery response in lead detail > Distributions tab
|
|
321
|
+
|
|
322
|
+
## Key API Endpoints
|
|
323
|
+
|
|
324
|
+
| Endpoint | Purpose |
|
|
325
|
+
|----------|---------|
|
|
326
|
+
| `GET /api/admin/leads` | List leads |
|
|
327
|
+
| `GET /api/admin/leads/{id}` | Lead detail + routing waterfall |
|
|
328
|
+
| `GET /api/admin/buyers` | List buyers |
|
|
329
|
+
| `GET /api/admin/partners` | List partners |
|
|
330
|
+
| `GET /api/admin/offers` | List offers |
|
|
331
|
+
| `GET /api/admin/contracts` | List contracts |
|
|
332
|
+
| `GET /api/admin/verticals` | List verticals |
|
|
333
|
+
| `POST /api/admin/verticals` | Create vertical |
|
|
334
|
+
| `POST /api/admin/partners` | Create partner |
|
|
335
|
+
| `POST /api/admin/buyers` | Create buyer |
|
|
336
|
+
| `POST /api/admin/offers` | Create offer |
|
|
337
|
+
| `GET /api/v1/campaigns/{id}/posting` | Get posting spec |
|
|
338
|
+
| `POST /api/v1/leads/submit` | Submit test lead |
|
|
339
|
+
|
|
340
|
+
## Gotchas
|
|
341
|
+
|
|
342
|
+
1. **Vertical mismatch** — Campaign, contract, and offer must all reference the SAME vertical
|
|
343
|
+
2. **Posting key ≠ API key** — postingKey (lr_xxx on campaign) is for lead submission only
|
|
344
|
+
3. **Balance blocks routing** — buyer balance > creditLimit = all contracts skipped
|
|
345
|
+
4. **Caps reset in contract timezone** — not UTC
|
|
346
|
+
5. **Inactive cascades** — pausing buyer pauses all contracts; pausing offer can cascade to campaigns
|
|
347
|
+
6. **Dedup is per-buyer** — two buyers can both receive the same person
|
|
348
|
+
7. **Offer needs both sides** — campaigns without contracts = leads accepted, nowhere to route
|
|
349
|
+
8. **Empty schedule = 24/7** — if set, leads outside hours are rejected (not queued)
|
|
350
|
+
9. **State abbreviations** — geo filters use "CA" not "California"
|
|
351
|
+
10. **DQ contracts are separate** — linked via DQ Contracts tab, not regular Contracts tab
|