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.
Files changed (253) hide show
  1. package/.claude/skills/admin-guide/SKILL.md +351 -0
  2. package/.claude/skills/buyer-guide/SKILL.md +405 -0
  3. package/.claude/skills/partner-guide/SKILL.md +352 -0
  4. package/.claude/skills/welcome/SKILL.md +351 -0
  5. package/CLAUDE.md +238 -0
  6. package/LICENSE +21 -0
  7. package/README.md +166 -0
  8. package/dist/api-client.d.ts +10 -0
  9. package/dist/api-client.d.ts.map +1 -0
  10. package/dist/api-client.js +64 -0
  11. package/dist/api-client.js.map +1 -0
  12. package/dist/auth-adapter.d.ts +33 -0
  13. package/dist/auth-adapter.d.ts.map +1 -0
  14. package/dist/auth-adapter.js +87 -0
  15. package/dist/auth-adapter.js.map +1 -0
  16. package/dist/bin/iscale-mcp.d.ts +3 -0
  17. package/dist/bin/iscale-mcp.d.ts.map +1 -0
  18. package/dist/bin/iscale-mcp.js +7 -0
  19. package/dist/bin/iscale-mcp.js.map +1 -0
  20. package/dist/build-registry.d.ts +3 -0
  21. package/dist/build-registry.d.ts.map +1 -0
  22. package/dist/build-registry.js +15 -0
  23. package/dist/build-registry.js.map +1 -0
  24. package/dist/index.d.ts +12 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +34 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/register.d.ts +4 -0
  29. package/dist/register.d.ts.map +1 -0
  30. package/dist/register.js +23 -0
  31. package/dist/register.js.map +1 -0
  32. package/dist/registry.d.ts +50 -0
  33. package/dist/registry.d.ts.map +1 -0
  34. package/dist/registry.js +78 -0
  35. package/dist/registry.js.map +1 -0
  36. package/dist/tools/buyers.d.ts +4 -0
  37. package/dist/tools/buyers.d.ts.map +1 -0
  38. package/dist/tools/buyers.js +61 -0
  39. package/dist/tools/buyers.js.map +1 -0
  40. package/dist/tools/campaigns.d.ts +4 -0
  41. package/dist/tools/campaigns.d.ts.map +1 -0
  42. package/dist/tools/campaigns.js +45 -0
  43. package/dist/tools/campaigns.js.map +1 -0
  44. package/dist/tools/compliance.d.ts +4 -0
  45. package/dist/tools/compliance.d.ts.map +1 -0
  46. package/dist/tools/compliance.js +28 -0
  47. package/dist/tools/compliance.js.map +1 -0
  48. package/dist/tools/composite.d.ts +3 -0
  49. package/dist/tools/composite.d.ts.map +1 -0
  50. package/dist/tools/composite.js +337 -0
  51. package/dist/tools/composite.js.map +1 -0
  52. package/dist/tools/contracts.d.ts +4 -0
  53. package/dist/tools/contracts.d.ts.map +1 -0
  54. package/dist/tools/contracts.js +48 -0
  55. package/dist/tools/contracts.js.map +1 -0
  56. package/dist/tools/generated/api-keys.gen.d.ts +3 -0
  57. package/dist/tools/generated/api-keys.gen.d.ts.map +1 -0
  58. package/dist/tools/generated/api-keys.gen.js +49 -0
  59. package/dist/tools/generated/api-keys.gen.js.map +1 -0
  60. package/dist/tools/generated/audit-logs.gen.d.ts +3 -0
  61. package/dist/tools/generated/audit-logs.gen.d.ts.map +1 -0
  62. package/dist/tools/generated/audit-logs.gen.js +59 -0
  63. package/dist/tools/generated/audit-logs.gen.js.map +1 -0
  64. package/dist/tools/generated/auth.gen.d.ts +3 -0
  65. package/dist/tools/generated/auth.gen.d.ts.map +1 -0
  66. package/dist/tools/generated/auth.gen.js +195 -0
  67. package/dist/tools/generated/auth.gen.js.map +1 -0
  68. package/dist/tools/generated/blocked-lists.gen.d.ts +3 -0
  69. package/dist/tools/generated/blocked-lists.gen.d.ts.map +1 -0
  70. package/dist/tools/generated/blocked-lists.gen.js +146 -0
  71. package/dist/tools/generated/blocked-lists.gen.js.map +1 -0
  72. package/dist/tools/generated/buyers.gen.d.ts +3 -0
  73. package/dist/tools/generated/buyers.gen.d.ts.map +1 -0
  74. package/dist/tools/generated/buyers.gen.js +153 -0
  75. package/dist/tools/generated/buyers.gen.js.map +1 -0
  76. package/dist/tools/generated/calls.gen.d.ts +3 -0
  77. package/dist/tools/generated/calls.gen.d.ts.map +1 -0
  78. package/dist/tools/generated/calls.gen.js +106 -0
  79. package/dist/tools/generated/calls.gen.js.map +1 -0
  80. package/dist/tools/generated/campaigns.gen.d.ts +3 -0
  81. package/dist/tools/generated/campaigns.gen.d.ts.map +1 -0
  82. package/dist/tools/generated/campaigns.gen.js +274 -0
  83. package/dist/tools/generated/campaigns.gen.js.map +1 -0
  84. package/dist/tools/generated/catalog.json +7096 -0
  85. package/dist/tools/generated/compliance.gen.d.ts +3 -0
  86. package/dist/tools/generated/compliance.gen.d.ts.map +1 -0
  87. package/dist/tools/generated/compliance.gen.js +119 -0
  88. package/dist/tools/generated/compliance.gen.js.map +1 -0
  89. package/dist/tools/generated/consent.gen.d.ts +3 -0
  90. package/dist/tools/generated/consent.gen.d.ts.map +1 -0
  91. package/dist/tools/generated/consent.gen.js +109 -0
  92. package/dist/tools/generated/consent.gen.js.map +1 -0
  93. package/dist/tools/generated/contacts.gen.d.ts +3 -0
  94. package/dist/tools/generated/contacts.gen.d.ts.map +1 -0
  95. package/dist/tools/generated/contacts.gen.js +88 -0
  96. package/dist/tools/generated/contacts.gen.js.map +1 -0
  97. package/dist/tools/generated/contracts.gen.d.ts +3 -0
  98. package/dist/tools/generated/contracts.gen.d.ts.map +1 -0
  99. package/dist/tools/generated/contracts.gen.js +306 -0
  100. package/dist/tools/generated/contracts.gen.js.map +1 -0
  101. package/dist/tools/generated/delivery-test.gen.d.ts +3 -0
  102. package/dist/tools/generated/delivery-test.gen.d.ts.map +1 -0
  103. package/dist/tools/generated/delivery-test.gen.js +17 -0
  104. package/dist/tools/generated/delivery-test.gen.js.map +1 -0
  105. package/dist/tools/generated/discovery.gen.d.ts +3 -0
  106. package/dist/tools/generated/discovery.gen.d.ts.map +1 -0
  107. package/dist/tools/generated/discovery.gen.js +17 -0
  108. package/dist/tools/generated/discovery.gen.js.map +1 -0
  109. package/dist/tools/generated/disposition-codes.gen.d.ts +3 -0
  110. package/dist/tools/generated/disposition-codes.gen.d.ts.map +1 -0
  111. package/dist/tools/generated/disposition-codes.gen.js +30 -0
  112. package/dist/tools/generated/disposition-codes.gen.js.map +1 -0
  113. package/dist/tools/generated/email-templates.gen.d.ts +3 -0
  114. package/dist/tools/generated/email-templates.gen.d.ts.map +1 -0
  115. package/dist/tools/generated/email-templates.gen.js +108 -0
  116. package/dist/tools/generated/email-templates.gen.js.map +1 -0
  117. package/dist/tools/generated/engagements.gen.d.ts +3 -0
  118. package/dist/tools/generated/engagements.gen.d.ts.map +1 -0
  119. package/dist/tools/generated/engagements.gen.js +208 -0
  120. package/dist/tools/generated/engagements.gen.js.map +1 -0
  121. package/dist/tools/generated/enrollments.gen.d.ts +3 -0
  122. package/dist/tools/generated/enrollments.gen.d.ts.map +1 -0
  123. package/dist/tools/generated/enrollments.gen.js +82 -0
  124. package/dist/tools/generated/enrollments.gen.js.map +1 -0
  125. package/dist/tools/generated/events.gen.d.ts +3 -0
  126. package/dist/tools/generated/events.gen.d.ts.map +1 -0
  127. package/dist/tools/generated/events.gen.js +20 -0
  128. package/dist/tools/generated/events.gen.js.map +1 -0
  129. package/dist/tools/generated/index.d.ts +3 -0
  130. package/dist/tools/generated/index.d.ts.map +1 -0
  131. package/dist/tools/generated/index.js +86 -0
  132. package/dist/tools/generated/index.js.map +1 -0
  133. package/dist/tools/generated/intake-centers.gen.d.ts +3 -0
  134. package/dist/tools/generated/intake-centers.gen.d.ts.map +1 -0
  135. package/dist/tools/generated/intake-centers.gen.js +196 -0
  136. package/dist/tools/generated/intake-centers.gen.js.map +1 -0
  137. package/dist/tools/generated/integrations.gen.d.ts +3 -0
  138. package/dist/tools/generated/integrations.gen.d.ts.map +1 -0
  139. package/dist/tools/generated/integrations.gen.js +290 -0
  140. package/dist/tools/generated/integrations.gen.js.map +1 -0
  141. package/dist/tools/generated/ivr.gen.d.ts +3 -0
  142. package/dist/tools/generated/ivr.gen.d.ts.map +1 -0
  143. package/dist/tools/generated/ivr.gen.js +97 -0
  144. package/dist/tools/generated/ivr.gen.js.map +1 -0
  145. package/dist/tools/generated/leads.gen.d.ts +3 -0
  146. package/dist/tools/generated/leads.gen.d.ts.map +1 -0
  147. package/dist/tools/generated/leads.gen.js +592 -0
  148. package/dist/tools/generated/leads.gen.js.map +1 -0
  149. package/dist/tools/generated/number-pool.gen.d.ts +3 -0
  150. package/dist/tools/generated/number-pool.gen.d.ts.map +1 -0
  151. package/dist/tools/generated/number-pool.gen.js +62 -0
  152. package/dist/tools/generated/number-pool.gen.js.map +1 -0
  153. package/dist/tools/generated/offers.gen.d.ts +3 -0
  154. package/dist/tools/generated/offers.gen.d.ts.map +1 -0
  155. package/dist/tools/generated/offers.gen.js +407 -0
  156. package/dist/tools/generated/offers.gen.js.map +1 -0
  157. package/dist/tools/generated/organizations.gen.d.ts +3 -0
  158. package/dist/tools/generated/organizations.gen.d.ts.map +1 -0
  159. package/dist/tools/generated/organizations.gen.js +161 -0
  160. package/dist/tools/generated/organizations.gen.js.map +1 -0
  161. package/dist/tools/generated/partners.gen.d.ts +3 -0
  162. package/dist/tools/generated/partners.gen.d.ts.map +1 -0
  163. package/dist/tools/generated/partners.gen.js +121 -0
  164. package/dist/tools/generated/partners.gen.js.map +1 -0
  165. package/dist/tools/generated/payouts.gen.d.ts +3 -0
  166. package/dist/tools/generated/payouts.gen.d.ts.map +1 -0
  167. package/dist/tools/generated/payouts.gen.js +92 -0
  168. package/dist/tools/generated/payouts.gen.js.map +1 -0
  169. package/dist/tools/generated/people.gen.d.ts +3 -0
  170. package/dist/tools/generated/people.gen.d.ts.map +1 -0
  171. package/dist/tools/generated/people.gen.js +354 -0
  172. package/dist/tools/generated/people.gen.js.map +1 -0
  173. package/dist/tools/generated/posting-log.gen.d.ts +3 -0
  174. package/dist/tools/generated/posting-log.gen.d.ts.map +1 -0
  175. package/dist/tools/generated/posting-log.gen.js +150 -0
  176. package/dist/tools/generated/posting-log.gen.js.map +1 -0
  177. package/dist/tools/generated/refunds.gen.d.ts +3 -0
  178. package/dist/tools/generated/refunds.gen.d.ts.map +1 -0
  179. package/dist/tools/generated/refunds.gen.js +91 -0
  180. package/dist/tools/generated/refunds.gen.js.map +1 -0
  181. package/dist/tools/generated/reports.gen.d.ts +3 -0
  182. package/dist/tools/generated/reports.gen.d.ts.map +1 -0
  183. package/dist/tools/generated/reports.gen.js +38 -0
  184. package/dist/tools/generated/reports.gen.js.map +1 -0
  185. package/dist/tools/generated/sessions.gen.d.ts +3 -0
  186. package/dist/tools/generated/sessions.gen.d.ts.map +1 -0
  187. package/dist/tools/generated/sessions.gen.js +90 -0
  188. package/dist/tools/generated/sessions.gen.js.map +1 -0
  189. package/dist/tools/generated/settings.gen.d.ts +3 -0
  190. package/dist/tools/generated/settings.gen.d.ts.map +1 -0
  191. package/dist/tools/generated/settings.gen.js +473 -0
  192. package/dist/tools/generated/settings.gen.js.map +1 -0
  193. package/dist/tools/generated/telephony.gen.d.ts +3 -0
  194. package/dist/tools/generated/telephony.gen.d.ts.map +1 -0
  195. package/dist/tools/generated/telephony.gen.js +170 -0
  196. package/dist/tools/generated/telephony.gen.js.map +1 -0
  197. package/dist/tools/generated/tenants.gen.d.ts +3 -0
  198. package/dist/tools/generated/tenants.gen.d.ts.map +1 -0
  199. package/dist/tools/generated/tenants.gen.js +223 -0
  200. package/dist/tools/generated/tenants.gen.js.map +1 -0
  201. package/dist/tools/generated/tracking-numbers.gen.d.ts +3 -0
  202. package/dist/tools/generated/tracking-numbers.gen.d.ts.map +1 -0
  203. package/dist/tools/generated/tracking-numbers.gen.js +131 -0
  204. package/dist/tools/generated/tracking-numbers.gen.js.map +1 -0
  205. package/dist/tools/generated/transactions.gen.d.ts +3 -0
  206. package/dist/tools/generated/transactions.gen.d.ts.map +1 -0
  207. package/dist/tools/generated/transactions.gen.js +62 -0
  208. package/dist/tools/generated/transactions.gen.js.map +1 -0
  209. package/dist/tools/generated/users.gen.d.ts +3 -0
  210. package/dist/tools/generated/users.gen.d.ts.map +1 -0
  211. package/dist/tools/generated/users.gen.js +339 -0
  212. package/dist/tools/generated/users.gen.js.map +1 -0
  213. package/dist/tools/generated/vertical-groups.gen.d.ts +3 -0
  214. package/dist/tools/generated/vertical-groups.gen.d.ts.map +1 -0
  215. package/dist/tools/generated/vertical-groups.gen.js +243 -0
  216. package/dist/tools/generated/vertical-groups.gen.js.map +1 -0
  217. package/dist/tools/generated/verticals.gen.d.ts +3 -0
  218. package/dist/tools/generated/verticals.gen.d.ts.map +1 -0
  219. package/dist/tools/generated/verticals.gen.js +164 -0
  220. package/dist/tools/generated/verticals.gen.js.map +1 -0
  221. package/dist/tools/leads.d.ts +4 -0
  222. package/dist/tools/leads.d.ts.map +1 -0
  223. package/dist/tools/leads.js +69 -0
  224. package/dist/tools/leads.js.map +1 -0
  225. package/dist/tools/offers.d.ts +4 -0
  226. package/dist/tools/offers.d.ts.map +1 -0
  227. package/dist/tools/offers.js +33 -0
  228. package/dist/tools/offers.js.map +1 -0
  229. package/dist/tools/partners.d.ts +4 -0
  230. package/dist/tools/partners.d.ts.map +1 -0
  231. package/dist/tools/partners.js +30 -0
  232. package/dist/tools/partners.js.map +1 -0
  233. package/dist/tools/people.d.ts +4 -0
  234. package/dist/tools/people.d.ts.map +1 -0
  235. package/dist/tools/people.js +42 -0
  236. package/dist/tools/people.js.map +1 -0
  237. package/dist/tools/reports.d.ts +4 -0
  238. package/dist/tools/reports.d.ts.map +1 -0
  239. package/dist/tools/reports.js +67 -0
  240. package/dist/tools/reports.js.map +1 -0
  241. package/dist/tools/ui.d.ts +3 -0
  242. package/dist/tools/ui.d.ts.map +1 -0
  243. package/dist/tools/ui.js +108 -0
  244. package/dist/tools/ui.js.map +1 -0
  245. package/dist/tools/verticals.d.ts +4 -0
  246. package/dist/tools/verticals.d.ts.map +1 -0
  247. package/dist/tools/verticals.js +25 -0
  248. package/dist/tools/verticals.js.map +1 -0
  249. package/dist/types.d.ts +19 -0
  250. package/dist/types.d.ts.map +1 -0
  251. package/dist/types.js +2 -0
  252. package/dist/types.js.map +1 -0
  253. 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