scrapercity 1.0.20 → 1.0.22

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/AGENT_DOCS.txt CHANGED
@@ -268,6 +268,15 @@ POST /api/v1/database/plan { "query": "dentists in Austin", "database": "local"
268
268
  apiParams, link }] }. Filters use values the database really has; count leaves out
269
269
  records this account already has. Send apiParams as they are to /api/v1/<apiEndpoint>.
270
270
 
271
+ POST /api/v1/autoleads/lookalike { "domains": ["acme.com", "mike@globex.com", "initech.com"] }
272
+ GET /api/v1/autoleads/lookalike?id=<job id>
273
+ $149/mo plan and up. Your customers' websites or work emails -> lookalike groups. POST starts a
274
+ background job (202 { job }); GET it until job.status is done (or failed). When done, job.groups:
275
+ [{ name, description, sites, database, filters, count, tool, addOn, reason }]. Send a group's
276
+ filters to that database's endpoint to pull the records. $0.01 per site read, from credits when the
277
+ job finishes; sites that can't be read are free. 402 = balance under $0.01 x every site (required,
278
+ available). 409 = a job is already running (job_id). At least 3 company sites; personal emails skipped.
279
+
271
280
  ────────────────────────────────────────
272
281
  ERROR CODES
273
282
  ────────────────────────────────────────
package/SKILL.md CHANGED
@@ -82,6 +82,7 @@ Apollo scrapes take **up to 4 days** to deliver. Do NOT poll in a loop.
82
82
  | GET | `/api/v1/database/local-businesses?category=Dentist&country=US&hasContact=true&limit=100` | Local biz DB ($149/mo plan and up, 100k new businesses/day). Search like Google Maps: `keyword` (repeat; names and categories, any keyword) and `location` (repeat; cities, states, countries, postal codes), with `searched_as` in the response and `lead_database` when nothing is found but the Lead Database has 100+ people. Filters: `category`, `country`, `state`, `city`, `postalCode`, `query`, `minRating`/`maxRating`, `minReviews`/`maxReviews`, `hasEmail`, `hasPhone`, `hasWebsite`, `hasContact` (only businesses with a named contact person), `title` (business name), `box=minLat,minLng,maxLat,maxLng` (a map area). Exclusions: `notCategory`. `url=<Google Maps search URL>` searches with that URL's keyword and place. POST with a JSON body takes the same parameters (use it for a long `url`). Same optional `excludeDelivered` / `after` |
83
83
  | GET | `/api/v1/database/ecommerce?...` | Ecommerce DB ($149/mo plan and up). Same optional `excludeDelivered` / `after`. Technologies: `technologies` (any of), `technologiesAll` (all of), `notTechnologies` (none of) |
84
84
  | POST | `/api/v1/database/plan` | $149/mo plan and up (GET with `?query=` also works). `{ "query": "dentists in Austin", "database"?: "leads" or "local" or "ecommerce" }` -> ready-to-run searches: `{ targeting, searches: [{ database, name, filters, count, apiEndpoint, apiParams, link }] }`. Send `apiParams` as they are to `/api/v1/<apiEndpoint>` |
85
+ | POST | `/api/v1/autoleads/lookalike` | $149/mo plan and up, $0.01 per site read. `{ "domains": ["acme.com", "mike@globex.com", ...] }` (websites or work emails, at least 3 company sites) -> 202 `{ job }`. Then GET `/api/v1/autoleads/lookalike?id=<job id>` until `job.status` is `done`: `job.groups` = `[{ name, description, sites, database, filters, count, tool }]`. Send a group's `filters` to that database's endpoint. 402 = balance under $0.01 x every site; 409 = a job is already running |
85
86
 
86
87
  ## Status Values
87
88
  `RUNNING` → `SUCCEEDED` or `FAILED` or `CANCELLED`
package/bin/cli.mjs CHANGED
@@ -460,6 +460,38 @@ async function main() {
460
460
  break
461
461
  }
462
462
 
463
+ // ── Lookalike groups from your customers ($149/mo plan and up) ──
464
+ case 'lookalike': {
465
+ const file = flag('--file')
466
+ let domains = [...args]
467
+ if (typeof file === 'string') domains = [...domains, ...fs.readFileSync(file, 'utf-8').split(/[\n,;\t]+/).map(l => l.trim()).filter(Boolean)]
468
+ if (!domains.length) die('Usage: scrapercity lookalike acme.com mike@globex.com ... [--file customers.txt]')
469
+ const start = await sc.lookalikeStart(domains)
470
+ let job = start.job
471
+ console.log(`Job ${job.id}: ${job.sites} sites, up to $${Number(job.max_cost).toFixed(2)}`)
472
+ while (job.status === 'running') {
473
+ await new Promise(r => setTimeout(r, 10000))
474
+ job = (await sc.lookalikeJob(job.id)).job
475
+ process.stdout.write(`\r ${job.stage} ${job.percent}% `)
476
+ }
477
+ console.log('')
478
+ if (job.status !== 'done') die(job.error || 'The job did not finish.')
479
+ console.log(`${job.sites_read} of ${job.sites} sites read, $${Number(job.charged).toFixed(2)} charged, ${job.groups.length} groups`)
480
+ for (const g of job.groups) {
481
+ console.log(`\n${g.name} (${g.database}): ${Number(g.count).toLocaleString()} matches, ${g.sites.length} of your customers`)
482
+ console.log(` ${g.description}`)
483
+ console.log(` Best tool: ${g.tool}${g.addOn ? ' + ' + g.addOn : ''}`)
484
+ console.log(` filters: ${JSON.stringify(g.filters)}`)
485
+ }
486
+ break
487
+ }
488
+
489
+ case 'lookalike-status': {
490
+ if (!args[0]) die('Usage: scrapercity lookalike-status <jobId>')
491
+ console.log(json((await sc.lookalikeJob(args[0])).job))
492
+ break
493
+ }
494
+
463
495
  // ── Poll (convenience) ────────────────────────────────
464
496
  case 'poll': {
465
497
  if (!args[0]) die('Usage: scrapercity poll <runId> [--interval 15]')
@@ -514,6 +546,11 @@ ScraperCity CLI - B2B lead generation from your terminal
514
546
  scrapercity plan "dentists in Austin" Plain English -> ready-to-run database searches
515
547
  --database leads|local|ecommerce Only this database (default: the ones that fit)
516
548
 
549
+ Lookalike groups ($149/mo plan and up, $0.01 per site read):
550
+ scrapercity lookalike acme.com mike@globex.com ... Group your customers into lookalike audiences
551
+ --file customers.txt One website or work email per line
552
+ scrapercity lookalike-status <jobId> Read a lookalike job
553
+
517
554
  Database ($149/mo plan and up):
518
555
  scrapercity db-leads [filters] Query lead database
519
556
  --title --industry --country --state --city --company --domain --seniority --department
package/bin/mcp.mjs CHANGED
@@ -56,6 +56,20 @@ const UTILITY_TOOLS = [
56
56
  database: { type: 'string', enum: ['leads', 'local', 'ecommerce'], description: 'Optional: plan in this database only (leads = people at companies, local = local businesses, ecommerce = online stores). Leave it out to let the planner pick the databases that fit.' }
57
57
  }, required: ['query'] }
58
58
  },
59
+ {
60
+ name: 'find_lookalike_groups',
61
+ description: 'Group your customers into lookalike audiences. Send their websites or work emails (mike@acme.com reads acme.com and looks up Mike\'s title). Starts a background job and returns it with its id; then call get_lookalike_groups until status is done. Each group comes with ready-to-run database filters, a match count and the best tool to reach businesses like them. $0.01 per site read, from credits; your balance must cover $0.01 x every site. One job at a time. $149/mo plan and up.',
62
+ inputSchema: { type: 'object', properties: {
63
+ domains: { type: 'array', items: { type: 'string' }, description: 'Your customers\' websites, URLs or work emails. At least 3 company sites.' }
64
+ }, required: ['domains'] }
65
+ },
66
+ {
67
+ name: 'get_lookalike_groups',
68
+ description: 'Read a lookalike job started with find_lookalike_groups: status (running, done, failed), percent, and when done the groups. Each group has name, description, sites (your customers in it), database (leads, local, ecommerce), filters, count and tool. Pass its filters to query_lead_database, query_local_business_database or query_ecommerce_database to pull the records.',
69
+ inputSchema: { type: 'object', properties: {
70
+ id: { type: 'string', description: 'The job id from find_lookalike_groups' }
71
+ }, required: ['id'] }
72
+ },
59
73
  {
60
74
  name: 'query_lead_database',
61
75
  description: 'Query the B2B lead database directly. Returns contacts with names, emails, phones, titles, companies (plus company website, revenue, HQ location and keywords). Up to 100 per request. Included with the $149/mo plan (100,000 new leads a day; leads you already have do not count again). For a daily pull of only new leads set excludeDelivered=true. For big pulls page with after: send after="0" first, then the pagination.next_after from each response until it is null. Have a saved people-search URL? Pass it as url to search with its filters right away (search_translation in the response says what was applied). Target by the technologies a company\'s website runs: technologies (any of), technologiesAll (all of), notTechnologies (none of), e.g. technologiesAll ["Klaviyo", "PayPal", "Shopify"] with notTechnologies ["Facebook Pixel"].',
@@ -180,6 +194,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
180
194
  }
181
195
  case 'cancel_run': result = await sc.cancel(args.runId); break
182
196
  case 'plan_search': result = await sc.planSearch(args.query, args.database); break
197
+ case 'find_lookalike_groups': result = await sc.lookalikeStart(args.domains); break
198
+ case 'get_lookalike_groups': result = await sc.lookalikeJob(args.id); break
183
199
  case 'query_lead_database': {
184
200
  const params = { ...args }
185
201
  if (params.hasEmail) params.hasEmail = 'true'
@@ -1,6 +1,6 @@
1
1
  // AUTO-GENERATED by scripts/generate.mjs — DO NOT EDIT BY HAND.
2
2
  // Source of truth: scraperConfigs.ts (+ src/config/scrapers.ts). Regenerate: npm run generate
3
- // Generated: 2026-10-20T21:18:28.662Z
3
+ // Generated: 2026-10-27T21:55:24.779Z
4
4
  export const TOOLS = [
5
5
  {
6
6
  "name": "scrape_apollo",
@@ -14,7 +14,7 @@ export const TOOLS = [
14
14
  },
15
15
  "count": {
16
16
  "type": "number",
17
- "description": "Number of leads to scrape (500-50,000)"
17
+ "description": "Number of leads to scrape (1,000-50,000)"
18
18
  },
19
19
  "fileName": {
20
20
  "type": "string",
@@ -662,5 +662,6 @@ export const ENDPOINTS = {
662
662
  "database-local-business-enrichment": "/api/v1/enrich/local-businesses",
663
663
  "database-local-businesses": "/api/v1/database/local-businesses",
664
664
  "database-ecommerce": "/api/v1/database/ecommerce",
665
- "database-plan": "/api/v1/database/plan"
665
+ "database-plan": "/api/v1/database/plan",
666
+ "autoleads-lookalike": "/api/v1/autoleads/lookalike"
666
667
  }
package/lib/client.mjs CHANGED
@@ -212,6 +212,10 @@ export const dbEcommerce = (params) => {
212
212
  export const planSearch = (query, database) =>
213
213
  post('/api/v1/database/plan', database ? { query, database } : { query })
214
214
 
215
+ // Lookalike groups from your customers ($149/mo plan and up): start a job with websites or work emails, then read it by id.
216
+ export const lookalikeStart = (domains) => post('/api/v1/autoleads/lookalike', { domains })
217
+ export const lookalikeJob = (id) => get(`/api/v1/autoleads/lookalike?id=${encodeURIComponent(id)}`)
218
+
215
219
  // ── Poll until done ───────────────────────────────────────────
216
220
  export async function pollUntilDone(runId, { interval = 15000, timeout = 3600000, onStatus } = {}) {
217
221
  const start = Date.now()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scrapercity",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "description": "ScraperCity CLI & MCP Server - B2B lead generation for AI agents",
5
5
  "type": "module",
6
6
  "bin": {