linkedin-secret-sauce 0.12.1 → 0.12.3

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 (184) hide show
  1. package/README.md +339 -31
  2. package/dist/cosiall-client.d.ts +1 -1
  3. package/dist/cosiall-client.js +1 -1
  4. package/dist/enrichment/index.d.ts +23 -2
  5. package/dist/enrichment/index.js +38 -22
  6. package/dist/enrichment/matching.d.ts +16 -2
  7. package/dist/enrichment/matching.js +387 -65
  8. package/dist/enrichment/providers/bounceban.d.ts +82 -0
  9. package/dist/enrichment/providers/bounceban.js +447 -0
  10. package/dist/enrichment/providers/bouncer.d.ts +1 -1
  11. package/dist/enrichment/providers/bouncer.js +19 -21
  12. package/dist/enrichment/providers/construct.d.ts +1 -1
  13. package/dist/enrichment/providers/construct.js +22 -38
  14. package/dist/enrichment/providers/cosiall.d.ts +1 -1
  15. package/dist/enrichment/providers/cosiall.js +3 -4
  16. package/dist/enrichment/providers/dropcontact.d.ts +15 -9
  17. package/dist/enrichment/providers/dropcontact.js +188 -19
  18. package/dist/enrichment/providers/hunter.d.ts +8 -1
  19. package/dist/enrichment/providers/hunter.js +52 -28
  20. package/dist/enrichment/providers/index.d.ts +2 -0
  21. package/dist/enrichment/providers/index.js +10 -1
  22. package/dist/enrichment/providers/ldd.d.ts +1 -10
  23. package/dist/enrichment/providers/ldd.js +20 -97
  24. package/dist/enrichment/providers/smartprospect.js +28 -48
  25. package/dist/enrichment/providers/snovio.d.ts +1 -1
  26. package/dist/enrichment/providers/snovio.js +29 -31
  27. package/dist/enrichment/providers/trykitt.d.ts +63 -0
  28. package/dist/enrichment/providers/trykitt.js +210 -0
  29. package/dist/enrichment/types.d.ts +220 -7
  30. package/dist/enrichment/types.js +16 -8
  31. package/dist/enrichment/utils/candidate-parser.d.ts +107 -0
  32. package/dist/enrichment/utils/candidate-parser.js +173 -0
  33. package/dist/enrichment/utils/noop-provider.d.ts +39 -0
  34. package/dist/enrichment/utils/noop-provider.js +37 -0
  35. package/dist/enrichment/utils/rate-limiter.d.ts +103 -0
  36. package/dist/enrichment/utils/rate-limiter.js +204 -0
  37. package/dist/enrichment/utils/validation.d.ts +75 -3
  38. package/dist/enrichment/utils/validation.js +164 -11
  39. package/dist/linkedin-api.d.ts +40 -1
  40. package/dist/linkedin-api.js +160 -27
  41. package/dist/types.d.ts +50 -1
  42. package/dist/utils/lru-cache.d.ts +105 -0
  43. package/dist/utils/lru-cache.js +175 -0
  44. package/docs/COSIALL_PROFILE_EMAILS.md +342 -0
  45. package/docs/ENRICHMENT.md +622 -0
  46. package/docs/INTEGRATION.md +405 -0
  47. package/docs/PLAYGROUND.md +558 -0
  48. package/docs/SALES_SEARCH.md +171 -0
  49. package/docs/api/.nojekyll +1 -0
  50. package/docs/api/assets/hierarchy.js +1 -0
  51. package/docs/api/assets/highlight.css +92 -0
  52. package/docs/api/assets/icons.js +18 -0
  53. package/docs/api/assets/icons.svg +1 -0
  54. package/docs/api/assets/main.js +60 -0
  55. package/docs/api/assets/navigation.js +1 -0
  56. package/docs/api/assets/search.js +1 -0
  57. package/docs/api/assets/style.css +1633 -0
  58. package/docs/api/classes/LinkedInClientError.html +37 -0
  59. package/docs/api/functions/_testGetAccountCookies.html +4 -0
  60. package/docs/api/functions/_testGetAccountEntry.html +4 -0
  61. package/docs/api/functions/_testGetAllAccountIds.html +3 -0
  62. package/docs/api/functions/_testGetPoolState.html +3 -0
  63. package/docs/api/functions/adminResetAccount.html +1 -0
  64. package/docs/api/functions/adminSetCooldown.html +1 -0
  65. package/docs/api/functions/buildCookieHeader.html +1 -0
  66. package/docs/api/functions/clearAllSmartLeadTokens.html +2 -0
  67. package/docs/api/functions/clearRequestHistory.html +1 -0
  68. package/docs/api/functions/clearSessionAccount.html +1 -0
  69. package/docs/api/functions/clearSmartLeadToken.html +2 -0
  70. package/docs/api/functions/createEnrichmentClient.html +8 -0
  71. package/docs/api/functions/extractCsrfToken.html +1 -0
  72. package/docs/api/functions/extractLinkedInHandle.html +7 -0
  73. package/docs/api/functions/fetchCookiesFromCosiall.html +14 -0
  74. package/docs/api/functions/fetchProfileEmailsFromCosiall.html +18 -0
  75. package/docs/api/functions/forceRefreshCookies.html +1 -0
  76. package/docs/api/functions/getAccountForSession.html +1 -0
  77. package/docs/api/functions/getAccountsSummary.html +1 -0
  78. package/docs/api/functions/getCompaniesBatch.html +5 -0
  79. package/docs/api/functions/getCompanyById.html +9 -0
  80. package/docs/api/functions/getCompanyByUrl.html +1 -0
  81. package/docs/api/functions/getConfig.html +1 -0
  82. package/docs/api/functions/getCookiePoolHealth.html +1 -0
  83. package/docs/api/functions/getProfileByUrn.html +17 -0
  84. package/docs/api/functions/getProfileByVanity.html +10 -0
  85. package/docs/api/functions/getProfilesBatch.html +1 -0
  86. package/docs/api/functions/getRequestHistory.html +1 -0
  87. package/docs/api/functions/getSalesNavigatorProfileDetails.html +1 -0
  88. package/docs/api/functions/getSalesNavigatorProfileFull.html +16 -0
  89. package/docs/api/functions/getSmartLeadToken.html +1 -0
  90. package/docs/api/functions/getSmartLeadTokenCacheStats.html +2 -0
  91. package/docs/api/functions/getSmartLeadUser.html +2 -0
  92. package/docs/api/functions/getSnapshot.html +1 -0
  93. package/docs/api/functions/getYearsAtCompanyOptions.html +2 -0
  94. package/docs/api/functions/getYearsInPositionOptions.html +2 -0
  95. package/docs/api/functions/getYearsOfExperienceOptions.html +2 -0
  96. package/docs/api/functions/incrementMetric.html +1 -0
  97. package/docs/api/functions/initializeCookiePool.html +1 -0
  98. package/docs/api/functions/initializeLinkedInClient.html +1 -0
  99. package/docs/api/functions/isBusinessEmail.html +4 -0
  100. package/docs/api/functions/isDisposableDomain.html +4 -0
  101. package/docs/api/functions/isDisposableEmail.html +4 -0
  102. package/docs/api/functions/isPersonalDomain.html +4 -0
  103. package/docs/api/functions/isPersonalEmail.html +4 -0
  104. package/docs/api/functions/isRoleAccount.html +4 -0
  105. package/docs/api/functions/isValidEmailSyntax.html +4 -0
  106. package/docs/api/functions/parseFullProfile.html +15 -0
  107. package/docs/api/functions/parseSalesSearchResults.html +1 -0
  108. package/docs/api/functions/reportAccountFailure.html +1 -0
  109. package/docs/api/functions/reportAccountSuccess.html +1 -0
  110. package/docs/api/functions/resolveCompanyUniversalName.html +1 -0
  111. package/docs/api/functions/searchSalesLeads.html +16 -0
  112. package/docs/api/functions/selectAccountForRequest.html +1 -0
  113. package/docs/api/functions/setAccountForSession.html +1 -0
  114. package/docs/api/functions/typeahead.html +1 -0
  115. package/docs/api/functions/verifyEmailMx.html +1 -0
  116. package/docs/api/hierarchy.html +1 -0
  117. package/docs/api/index.html +12 -0
  118. package/docs/api/interfaces/AccountCookies.html +4 -0
  119. package/docs/api/interfaces/BatchEnrichmentOptions.html +14 -0
  120. package/docs/api/interfaces/CacheAdapter.html +6 -0
  121. package/docs/api/interfaces/CanonicalEmail.html +14 -0
  122. package/docs/api/interfaces/Company.html +17 -0
  123. package/docs/api/interfaces/ConstructConfig.html +8 -0
  124. package/docs/api/interfaces/CosiallProfileEmailsResponse.html +11 -0
  125. package/docs/api/interfaces/DropcontactConfig.html +3 -0
  126. package/docs/api/interfaces/EnrichmentCandidate.html +34 -0
  127. package/docs/api/interfaces/EnrichmentClient.html +10 -0
  128. package/docs/api/interfaces/EnrichmentClientConfig.html +12 -0
  129. package/docs/api/interfaces/EnrichmentLogger.html +6 -0
  130. package/docs/api/interfaces/EnrichmentOptions.html +10 -0
  131. package/docs/api/interfaces/HunterConfig.html +3 -0
  132. package/docs/api/interfaces/LddConfig.html +4 -0
  133. package/docs/api/interfaces/LddProfileData.html +6 -0
  134. package/docs/api/interfaces/LinkedInClientConfig.html +20 -0
  135. package/docs/api/interfaces/LinkedInCookie.html +9 -0
  136. package/docs/api/interfaces/LinkedInPosition.html +14 -0
  137. package/docs/api/interfaces/LinkedInProfile.html +21 -0
  138. package/docs/api/interfaces/LinkedInSpotlightBadge.html +5 -0
  139. package/docs/api/interfaces/LinkedInTenure.html +3 -0
  140. package/docs/api/interfaces/Metrics.html +22 -0
  141. package/docs/api/interfaces/MetricsSnapshot.html +23 -0
  142. package/docs/api/interfaces/ProfileEducation.html +8 -0
  143. package/docs/api/interfaces/ProfileEmailsLookupOptions.html +9 -0
  144. package/docs/api/interfaces/ProfilePosition.html +12 -0
  145. package/docs/api/interfaces/ProfileSkill.html +3 -0
  146. package/docs/api/interfaces/ProviderResult.html +11 -0
  147. package/docs/api/interfaces/ProvidersConfig.html +17 -0
  148. package/docs/api/interfaces/RequestHistoryEntry.html +8 -0
  149. package/docs/api/interfaces/SalesLeadSearchResult.html +31 -0
  150. package/docs/api/interfaces/SalesNavigatorContactInfo.html +5 -0
  151. package/docs/api/interfaces/SalesNavigatorPosition.html +11 -0
  152. package/docs/api/interfaces/SalesNavigatorProfile.html +9 -0
  153. package/docs/api/interfaces/SalesNavigatorProfileFull.html +24 -0
  154. package/docs/api/interfaces/SearchSalesResult.html +5 -0
  155. package/docs/api/interfaces/SmartLeadAuthConfig.html +6 -0
  156. package/docs/api/interfaces/SmartLeadCredentials.html +3 -0
  157. package/docs/api/interfaces/SmartLeadLoginResponse.html +3 -0
  158. package/docs/api/interfaces/SmartLeadUser.html +8 -0
  159. package/docs/api/interfaces/SmartProspectConfig.html +19 -0
  160. package/docs/api/interfaces/SmartProspectContact.html +24 -0
  161. package/docs/api/interfaces/SmartProspectSearchFilters.html +42 -0
  162. package/docs/api/interfaces/TypeaheadItem.html +3 -0
  163. package/docs/api/interfaces/TypeaheadResult.html +3 -0
  164. package/docs/api/interfaces/VerificationResult.html +16 -0
  165. package/docs/api/types/CostCallback.html +2 -0
  166. package/docs/api/types/Geo.html +4 -0
  167. package/docs/api/types/LddApiResponse.html +1 -0
  168. package/docs/api/types/ProviderFunc.html +2 -0
  169. package/docs/api/types/ProviderName.html +2 -0
  170. package/docs/api/types/SalesSearchFilters.html +7 -0
  171. package/docs/api/types/TypeaheadType.html +1 -0
  172. package/docs/api/variables/COMPANY_SIZE_OPTIONS.html +1 -0
  173. package/docs/api/variables/DEFAULT_PROVIDER_ORDER.html +20 -0
  174. package/docs/api/variables/DISPOSABLE_DOMAINS.html +2 -0
  175. package/docs/api/variables/FUNCTION_OPTIONS.html +1 -0
  176. package/docs/api/variables/INDUSTRY_OPTIONS.html +1 -0
  177. package/docs/api/variables/LANGUAGE_OPTIONS.html +1 -0
  178. package/docs/api/variables/PERSONAL_DOMAINS.html +2 -0
  179. package/docs/api/variables/PROVIDER_COSTS.html +15 -0
  180. package/docs/api/variables/REGION_OPTIONS.html +1 -0
  181. package/docs/api/variables/SENIORITY_OPTIONS.html +3 -0
  182. package/docs/api/variables/YEARS_OPTIONS.html +1 -0
  183. package/docs/index.html +98 -0
  184. package/package.json +16 -5
@@ -0,0 +1,622 @@
1
+ # Email Enrichment Guide
2
+
3
+ Complete guide to using the email enrichment module in LinkedIn Secret Sauce.
4
+
5
+ ## Overview
6
+
7
+ The enrichment module finds and verifies business emails using multiple providers in an optimized 3-phase strategy. It automatically balances cost, speed, and accuracy.
8
+
9
+ ## Quick Start
10
+
11
+ ```typescript
12
+ import { createEnrichmentClient } from 'linkedin-secret-sauce';
13
+
14
+ const enrichment = createEnrichmentClient({
15
+ providers: {
16
+ // FREE providers (Phase 1)
17
+ ldd: { apiUrl: process.env.LDD_API_URL, apiToken: process.env.LDD_API_TOKEN },
18
+ smartprospect: { email: process.env.SMARTLEAD_EMAIL, password: process.env.SMARTLEAD_PASSWORD },
19
+ trykitt: { apiKey: process.env.TRYKITT_API_KEY },
20
+ // construct and cosiall are enabled by default (no config needed)
21
+
22
+ // Verification (Phase 2)
23
+ bounceban: { apiKey: process.env.BOUNCEBAN_API_KEY },
24
+
25
+ // Paid finders (Phase 3 - only if needed)
26
+ hunter: { apiKey: process.env.HUNTER_API_KEY },
27
+ snovio: { clientId: process.env.SNOVIO_CLIENT_ID, clientSecret: process.env.SNOVIO_CLIENT_SECRET },
28
+ },
29
+ });
30
+
31
+ const result = await enrichment.enrich({
32
+ firstName: 'John',
33
+ lastName: 'Doe',
34
+ company: 'Acme Corp',
35
+ domain: 'acme.com',
36
+ linkedinUrl: 'https://linkedin.com/in/johndoe',
37
+ });
38
+
39
+ console.log(result.business_email); // john.doe@acme.com
40
+ console.log(result.business_email_source); // 'trykitt'
41
+ console.log(result.business_email_verified); // true
42
+ console.log(result.business_email_confidence); // 95
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 3-Phase Enrichment Strategy
48
+
49
+ The default provider order optimizes for cost and accuracy:
50
+
51
+ ```
52
+ PHASE 1 - Free Lookups (Parallel)
53
+ ┌─────────────────┬─────────────────┬─────────────────┬─────────────────┐
54
+ │ LDD │ SmartProspect │ Cosiall │ TryKitt │
55
+ │ (Database) │ (Database) │ (LinkedIn API) │ (AI Finder) │
56
+ │ FREE │ FREE* │ FREE │ FREE** │
57
+ └─────────────────┴─────────────────┴─────────────────┴─────────────────┘
58
+
59
+ If no verified email found (confidence < 80%)
60
+
61
+ PHASE 2 - Pattern + Verification
62
+ ┌─────────────────────────────┬─────────────────────────────┐
63
+ │ Construct │ BounceBan │
64
+ │ (Pattern Guessing + MX) │ (Catch-all Verification) │
65
+ │ FREE │ FREE single / $0.003 │
66
+ └─────────────────────────────┴─────────────────────────────┘
67
+
68
+ If still no verified email found
69
+
70
+ PHASE 3 - Paid Finders (Only if needed)
71
+ ┌─────────────────────────────┬─────────────────────────────┐
72
+ │ Hunter │ Snov.io │
73
+ │ $0.005/email │ $0.02/email │
74
+ └─────────────────────────────┴─────────────────────────────┘
75
+ ```
76
+
77
+ *FREE with SmartLead subscription
78
+ **FREE for individuals with unlimited searches
79
+
80
+ ---
81
+
82
+ ## Supported Providers (11 Total)
83
+
84
+ ### FREE Providers
85
+
86
+ | Provider | Type | Description | Required Config |
87
+ |----------|------|-------------|-----------------|
88
+ | **Construct** | Pattern | Email pattern guessing + MX verification | None (always enabled) |
89
+ | **Cosiall** | Lookup | Emails from LinkedIn profiles | None (uses global config) |
90
+ | **LDD** | Database | LinkedIn Data Dump (~500M verified emails) | `apiUrl`, `apiToken` |
91
+ | **SmartProspect** | Database | SmartLead's prospect database | `email`, `password` |
92
+ | **TryKitt.ai** | AI Finder | AI-powered email finder with catch-all verification | `apiKey` |
93
+
94
+ ### PAID Providers
95
+
96
+ | Provider | Cost | Description | Required Config |
97
+ |----------|------|-------------|-----------------|
98
+ | **BounceBan** | FREE single / $0.003 bulk | Catch-all specialist (85-95% accuracy) | `apiKey` |
99
+ | **Hunter** | $0.005/email | Domain search + email finder | `apiKey` |
100
+ | **Bouncer** | $0.006/email | SMTP verification (99%+ accuracy) | `apiKey` |
101
+ | **Dropcontact** | $0.01/email | Email finder API | `apiKey` |
102
+ | **Snov.io** | $0.02/email | Email finding + verification | `clientId`, `clientSecret` |
103
+
104
+ ---
105
+
106
+ ## Provider Configuration
107
+
108
+ ### LDD (LinkedIn Data Dump)
109
+
110
+ ```typescript
111
+ ldd: {
112
+ apiUrl: process.env.LDD_API_URL, // Required: API endpoint
113
+ apiToken: process.env.LDD_API_TOKEN, // Required: Bearer token
114
+ }
115
+ ```
116
+
117
+ ### SmartProspect
118
+
119
+ ```typescript
120
+ smartprospect: {
121
+ // Option 1: Email/password (recommended)
122
+ email: process.env.SMARTLEAD_EMAIL,
123
+ password: process.env.SMARTLEAD_PASSWORD,
124
+
125
+ // Option 2: Direct token
126
+ apiToken: process.env.SMARTLEAD_TOKEN,
127
+ }
128
+ ```
129
+
130
+ ### TryKitt.ai
131
+
132
+ AI-powered email finding with enterprise identity server verification. FREE for individuals.
133
+
134
+ ```typescript
135
+ trykitt: {
136
+ apiKey: process.env.TRYKITT_API_KEY, // Required
137
+ apiUrl: 'https://api.trykitt.ai', // Optional override
138
+ timeoutMs: 30000, // Optional (default: 30s)
139
+ }
140
+ ```
141
+
142
+ Get your API key at: https://trykitt.ai
143
+
144
+ ### BounceBan
145
+
146
+ Specializes in catch-all email verification with 85-95% accuracy WITHOUT sending emails.
147
+
148
+ ```typescript
149
+ bounceban: {
150
+ apiKey: process.env.BOUNCEBAN_API_KEY, // Required
151
+ useDeepVerify: true, // +15-25% accuracy for pattern-guessed emails
152
+ useWaterfall: true, // Recommended: includes 30-min free retry window
153
+ apiUrl: 'https://api.bounceban.com', // Optional override
154
+ waterfallApiUrl: 'https://api-waterfall.bounceban.com', // Optional
155
+ }
156
+ ```
157
+
158
+ Get your API key at: https://bounceban.com
159
+
160
+ ### Hunter
161
+
162
+ ```typescript
163
+ hunter: {
164
+ apiKey: process.env.HUNTER_API_KEY, // Required
165
+ }
166
+ ```
167
+
168
+ Get your API key at: https://hunter.io
169
+
170
+ ### Bouncer
171
+
172
+ SMTP verification with 99%+ accuracy.
173
+
174
+ ```typescript
175
+ bouncer: {
176
+ apiKey: process.env.BOUNCER_API_KEY, // Required
177
+ }
178
+ ```
179
+
180
+ Get your API key at: https://bouncer.io
181
+
182
+ ### Snov.io
183
+
184
+ ```typescript
185
+ snovio: {
186
+ clientId: process.env.SNOVIO_CLIENT_ID, // Required
187
+ clientSecret: process.env.SNOVIO_CLIENT_SECRET, // Required
188
+ }
189
+ ```
190
+
191
+ Get your credentials at: https://snov.io
192
+
193
+ ### Dropcontact
194
+
195
+ ```typescript
196
+ dropcontact: {
197
+ apiKey: process.env.DROPCONTACT_API_KEY, // Required
198
+ }
199
+ ```
200
+
201
+ Get your API key at: https://dropcontact.com
202
+
203
+ ### Cosiall
204
+
205
+ Enabled by default using global Cosiall configuration. To disable:
206
+
207
+ ```typescript
208
+ cosiall: {
209
+ enabled: false,
210
+ }
211
+ ```
212
+
213
+ ### Construct
214
+
215
+ Pattern guessing + MX verification. Always enabled, no API key needed.
216
+
217
+ ```typescript
218
+ construct: {
219
+ maxAttempts: 8, // Max patterns to try (default: 8)
220
+ timeoutMs: 5000, // MX verification timeout (default: 5s)
221
+ smtpVerifyDelayMs: 2000, // Delay between SMTP checks (default: 2s)
222
+ }
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Environment Variables
228
+
229
+ Complete reference:
230
+
231
+ ```bash
232
+ # LinkedIn API (required for Cosiall)
233
+ COSIALL_API_URL=https://...
234
+ COSIALL_API_KEY=...
235
+
236
+ # LDD
237
+ LDD_API_URL=https://...
238
+ LDD_API_TOKEN=...
239
+
240
+ # SmartProspect/SmartLead
241
+ SMARTLEAD_EMAIL=...
242
+ SMARTLEAD_PASSWORD=...
243
+ # OR
244
+ SMARTLEAD_TOKEN=...
245
+
246
+ # TryKitt.ai (FREE for individuals)
247
+ TRYKITT_API_KEY=...
248
+
249
+ # BounceBan (FREE single verification)
250
+ BOUNCEBAN_API_KEY=...
251
+
252
+ # Hunter ($0.005/email)
253
+ HUNTER_API_KEY=...
254
+
255
+ # Bouncer ($0.006/email)
256
+ BOUNCER_API_KEY=...
257
+
258
+ # Snov.io ($0.02/email)
259
+ SNOVIO_CLIENT_ID=...
260
+ SNOVIO_CLIENT_SECRET=...
261
+
262
+ # Dropcontact ($0.01/email)
263
+ DROPCONTACT_API_KEY=...
264
+ ```
265
+
266
+ ---
267
+
268
+ ## API Reference
269
+
270
+ ### `createEnrichmentClient(config)`
271
+
272
+ Creates an enrichment client instance.
273
+
274
+ ```typescript
275
+ const enrichment = createEnrichmentClient({
276
+ providers: { /* provider configs */ },
277
+ options: {
278
+ providerOrder: ['ldd', 'trykitt', 'construct', 'hunter'], // Custom order
279
+ maxCostPerEmail: 0.05, // Max USD to spend per email
280
+ confidenceThreshold: 70, // Min confidence to accept (0-100)
281
+ retryMs: 200, // Retry delay on transient errors
282
+ },
283
+ cache: myRedisCache, // Optional cache adapter
284
+ onCost: (provider, cost) => { /* track costs */ },
285
+ logger: myLogger, // Optional logger
286
+ });
287
+ ```
288
+
289
+ ### `enrichment.enrich(candidate)`
290
+
291
+ Find a single business email. Returns first verified match.
292
+
293
+ ```typescript
294
+ const result = await enrichment.enrich({
295
+ firstName: 'John',
296
+ lastName: 'Doe',
297
+ company: 'Acme Corp',
298
+ domain: 'acme.com', // Optional but improves accuracy
299
+ linkedinUrl: 'linkedin.com/in/johndoe', // For LDD/Cosiall lookups
300
+ });
301
+
302
+ // Result
303
+ {
304
+ business_email: 'john.doe@acme.com',
305
+ business_email_source: 'trykitt',
306
+ business_email_verified: true,
307
+ business_email_confidence: 95,
308
+ last_checked_at: '2024-01-15T10:30:00.000Z',
309
+ }
310
+ ```
311
+
312
+ ### `enrichment.enrichAll(candidate)`
313
+
314
+ Get ALL emails from ALL providers (doesn't stop at first match).
315
+
316
+ ```typescript
317
+ const result = await enrichment.enrichAll({
318
+ firstName: 'John',
319
+ lastName: 'Doe',
320
+ domain: 'acme.com',
321
+ });
322
+
323
+ // Result
324
+ {
325
+ emails: [
326
+ { email: 'john.doe@acme.com', source: 'trykitt', confidence: 95, verified: true, type: 'business' },
327
+ { email: 'j.doe@acme.com', source: 'construct', confidence: 70, verified: false, type: 'business' },
328
+ { email: 'johndoe@gmail.com', source: 'cosiall', confidence: 100, verified: true, type: 'personal' },
329
+ ],
330
+ totalCost: 0.005,
331
+ providersQueried: ['ldd', 'smartprospect', 'cosiall', 'trykitt', 'construct', 'hunter'],
332
+ completedAt: '2024-01-15T10:30:00.000Z',
333
+ }
334
+ ```
335
+
336
+ ### `enrichment.enrichBatch(candidates, options)`
337
+
338
+ Process multiple candidates efficiently.
339
+
340
+ ```typescript
341
+ const results = await enrichment.enrichBatch(candidates, {
342
+ batchSize: 50, // Process 50 at a time
343
+ delayMs: 200, // Delay between batches
344
+ });
345
+ ```
346
+
347
+ ### `enrichment.enrichAllBatch(candidates, options)`
348
+
349
+ Batch version of `enrichAll()`.
350
+
351
+ ```typescript
352
+ const results = await enrichment.enrichAllBatch(candidates, {
353
+ batchSize: 50,
354
+ delayMs: 200,
355
+ });
356
+ ```
357
+
358
+ ---
359
+
360
+ ## Standalone Provider Functions
361
+
362
+ For advanced use cases, you can call providers directly:
363
+
364
+ ### TryKitt.ai
365
+
366
+ ```typescript
367
+ import { findEmailWithTryKitt, verifyEmailWithTryKitt } from 'linkedin-secret-sauce';
368
+
369
+ // Find email
370
+ const result = await findEmailWithTryKitt(
371
+ 'John Doe',
372
+ 'acme.com',
373
+ { apiKey: process.env.TRYKITT_API_KEY },
374
+ 'https://linkedin.com/in/johndoe' // Optional LinkedIn URL
375
+ );
376
+
377
+ // Verify email
378
+ const verification = await verifyEmailWithTryKitt(
379
+ 'john@acme.com',
380
+ { apiKey: process.env.TRYKITT_API_KEY }
381
+ );
382
+ ```
383
+
384
+ ### BounceBan
385
+
386
+ ```typescript
387
+ import {
388
+ verifyEmailWithBounceBan,
389
+ verifyEmailsBatchWithBounceBan,
390
+ checkCatchAllWithBounceBan
391
+ } from 'linkedin-secret-sauce';
392
+
393
+ // Verify single email (FREE)
394
+ const result = await verifyEmailWithBounceBan('john@acme.com', {
395
+ apiKey: process.env.BOUNCEBAN_API_KEY,
396
+ useDeepVerify: true,
397
+ useWaterfall: true,
398
+ });
399
+
400
+ // Check catch-all domain
401
+ const isCatchAll = await checkCatchAllWithBounceBan('acme.com', config);
402
+
403
+ // Batch verification
404
+ const results = await verifyEmailsBatchWithBounceBan(emails, config);
405
+ ```
406
+
407
+ ### Bouncer
408
+
409
+ ```typescript
410
+ import { verifyEmailWithBouncer, checkCatchAllDomain, verifyEmailsBatch } from 'linkedin-secret-sauce';
411
+
412
+ const result = await verifyEmailWithBouncer('john@acme.com', {
413
+ apiKey: process.env.BOUNCER_API_KEY,
414
+ });
415
+ ```
416
+
417
+ ### Snov.io
418
+
419
+ ```typescript
420
+ import { findEmailsWithSnovio, verifyEmailWithSnovio } from 'linkedin-secret-sauce';
421
+
422
+ const emails = await findEmailsWithSnovio('John', 'Doe', 'acme.com', {
423
+ clientId: process.env.SNOVIO_CLIENT_ID,
424
+ clientSecret: process.env.SNOVIO_CLIENT_SECRET,
425
+ });
426
+ ```
427
+
428
+ ---
429
+
430
+ ## Email Validation Utilities
431
+
432
+ ```typescript
433
+ import {
434
+ isValidEmailSyntax,
435
+ isPersonalEmail,
436
+ isBusinessEmail,
437
+ isDisposableEmail,
438
+ isRoleAccount,
439
+ verifyEmailMx,
440
+ checkDomainCatchAll,
441
+ PERSONAL_DOMAINS,
442
+ DISPOSABLE_DOMAINS,
443
+ } from 'linkedin-secret-sauce';
444
+
445
+ // Syntax validation
446
+ isValidEmailSyntax('john@example.com'); // true
447
+
448
+ // Domain classification
449
+ isPersonalEmail('john@gmail.com'); // true
450
+ isBusinessEmail('john@acme.com'); // true
451
+ isDisposableEmail('x@mailinator.com'); // true
452
+ isRoleAccount('info@company.com'); // true
453
+
454
+ // MX verification
455
+ const hasMx = await verifyEmailMx('john@acme.com');
456
+
457
+ // Catch-all detection
458
+ const isCatchAll = await checkDomainCatchAll('acme.com');
459
+ ```
460
+
461
+ ---
462
+
463
+ ## Cost Tracking
464
+
465
+ Track costs across providers:
466
+
467
+ ```typescript
468
+ let totalCost = 0;
469
+
470
+ const enrichment = createEnrichmentClient({
471
+ providers: { /* ... */ },
472
+ onCost: (provider, cost) => {
473
+ totalCost += cost;
474
+ console.log(`${provider}: $${cost.toFixed(4)}`);
475
+ },
476
+ });
477
+
478
+ // After enrichment
479
+ console.log(`Total spent: $${totalCost.toFixed(4)}`);
480
+ ```
481
+
482
+ Provider costs are also available as constants:
483
+
484
+ ```typescript
485
+ import { PROVIDER_COSTS } from 'linkedin-secret-sauce';
486
+
487
+ console.log(PROVIDER_COSTS);
488
+ // {
489
+ // construct: 0,
490
+ // ldd: 0,
491
+ // smartprospect: 0,
492
+ // cosiall: 0,
493
+ // trykitt: 0,
494
+ // bounceban: 0.003,
495
+ // hunter: 0.005,
496
+ // dropcontact: 0.01,
497
+ // bouncer: 0.006,
498
+ // snovio: 0.02,
499
+ // }
500
+ ```
501
+
502
+ ---
503
+
504
+ ## Caching
505
+
506
+ Implement a cache adapter to avoid duplicate lookups:
507
+
508
+ ```typescript
509
+ const enrichment = createEnrichmentClient({
510
+ providers: { /* ... */ },
511
+ cache: {
512
+ async get(key: string) {
513
+ return redis.get(key);
514
+ },
515
+ async set(key: string, value: any, ttlMs?: number) {
516
+ await redis.set(key, value, 'PX', ttlMs || 30 * 24 * 60 * 60 * 1000);
517
+ },
518
+ },
519
+ });
520
+ ```
521
+
522
+ Default cache TTL is 30 days.
523
+
524
+ ---
525
+
526
+ ## Custom Provider Order
527
+
528
+ Override the default 3-phase strategy:
529
+
530
+ ```typescript
531
+ const enrichment = createEnrichmentClient({
532
+ providers: { /* ... */ },
533
+ options: {
534
+ providerOrder: [
535
+ 'ldd', // Check database first
536
+ 'trykitt', // Then AI finder
537
+ 'construct', // Pattern guess
538
+ 'bounceban', // Verify patterns
539
+ 'hunter', // Paid finder last
540
+ ],
541
+ },
542
+ });
543
+ ```
544
+
545
+ ---
546
+
547
+ ## Error Handling
548
+
549
+ The enrichment client handles errors gracefully - providers that fail return `null` and the next provider is tried. To get visibility:
550
+
551
+ ```typescript
552
+ const enrichment = createEnrichmentClient({
553
+ providers: { /* ... */ },
554
+ logger: {
555
+ debug: (msg, data) => console.debug(msg, data),
556
+ info: (msg, data) => console.info(msg, data),
557
+ warn: (msg, data) => console.warn(msg, data),
558
+ error: (msg, data) => console.error(msg, data),
559
+ },
560
+ });
561
+ ```
562
+
563
+ ---
564
+
565
+ ## LinkedIn Contact Matching
566
+
567
+ For workflows that start with LinkedIn data:
568
+
569
+ ```typescript
570
+ import {
571
+ getEmailsForLinkedInContact,
572
+ salesLeadToContact,
573
+ searchSalesLeads,
574
+ } from 'linkedin-secret-sauce';
575
+
576
+ // Search LinkedIn
577
+ const results = await searchSalesLeads('cto fintech', { count: 25 });
578
+
579
+ // Enrich each lead
580
+ for (const lead of results.items) {
581
+ const contact = salesLeadToContact(lead);
582
+
583
+ const emailResult = await getEmailsForLinkedInContact(contact, {
584
+ smartprospect: { email: '...', password: '...' },
585
+ trykitt: { apiKey: '...' },
586
+ bounceban: { apiKey: '...' },
587
+ });
588
+
589
+ console.log(emailResult.bestEmail);
590
+ console.log(emailResult.emails);
591
+ }
592
+ ```
593
+
594
+ ---
595
+
596
+ ## Troubleshooting
597
+
598
+ ### No emails found
599
+
600
+ 1. Ensure at least one provider is configured correctly
601
+ 2. Check that the candidate has enough data (name + domain/company)
602
+ 3. Try `enrichAll()` to see what each provider returns
603
+ 4. Check logs for provider errors
604
+
605
+ ### Low confidence scores
606
+
607
+ 1. Provide more candidate data (LinkedIn URL improves accuracy)
608
+ 2. Enable BounceBan verification for pattern-guessed emails
609
+ 3. Consider using TryKitt for AI-powered finding
610
+
611
+ ### High costs
612
+
613
+ 1. Ensure FREE providers are configured first
614
+ 2. Use `maxCostPerEmail` option to set a budget
615
+ 3. Use `confidenceThreshold` to accept lower confidence results from free providers
616
+ 4. Monitor costs with `onCost` callback
617
+
618
+ ### Rate limiting
619
+
620
+ 1. Use `delayMs` in batch operations
621
+ 2. Check provider-specific rate limits in their documentation
622
+ 3. Implement caching to avoid duplicate lookups