linkedin-secret-sauce 0.12.2 → 0.12.4

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