Agent skill
scrapercity-lead-database
Plans and runs pulls from the ScraperCity B2B Lead Database: filter specs, count checks, people-search URL translation, cursor paging, daily pulls of only new leads, and the choice between the database and the Apollo Scraper.
Filed under Prospecting and list building.
From scrapercity/gtm-skills · 31 skill entries · 0 · pushed 2026-11-02
What it does when it runs
Plans and runs pulls from the ScraperCity B2B Lead Database: filter specs, count checks, people-search URL translation, cursor paging, daily pulls of only new leads, and the choice between the database and the Apollo Scraper. Produces a lead pull plan with a filter table, counts, allowance share and a sample QA. Use when the user asks for B2B contacts by title, seniority, industry, company size, revenue or location, wants a daily lead feed, pastes a people-search URL, or hits a 400, 409 or 503 from the Lead Database.
Automated analysis of the skill and the 11 files bundled beside it. A skill’s own description is written to be selected by an agent, so it describes the job and not the dependencies.
- Keys and connectors you must supply
- SCRAPERCITY_API_KEY
- Hosts it reaches
- alexberman.com
- app.scrapercity.com
- aws.amazon.com
- blog.google
- datatracker.ietf.org
- docs.apollo.io
- emt.gartnerweb.com
- help.instantly.ai
- helpcenter.smartlead.ai
- leanb2bbook.com
- publicsuffix.org
- scrapercity.com
- senders.yahooinc.com
- support.google.com
- techcommunity.microsoft.com
- www.bls.gov
- www.bmj.com
- www.crexi.com
- www.linkedin.com
- www.rfc-editor.org
- www.twilio.com
- www.zerobounce.net
- Tool permissions it declares
- No
allowed-toolsin the frontmatter. It does act, so it runs under whatever permissions your session already grants. - Actions present in the files
- shellnetwork
Ask about scrapercity-lead-database
Opens your assistant with this page's recorded context. Check the linked sources before relying on it.
Install it
View source on GitHub ↗git clone --depth 1 --filter=blob:none --sparse https://github.com/scrapercity/gtm-skills.git /tmp/gtm-skills git -C /tmp/gtm-skills sparse-checkout set "skills/scrapercity/scrapercity-lead-database" mkdir -p ~/.claude/skills/scrapercity-lead-database cp -R "/tmp/gtm-skills/skills/scrapercity/scrapercity-lead-database/." ~/.claude/skills/scrapercity-lead-database/
Picked up without a restart. A project skill of the same name is shadowed by your personal one. For one repository only, swap ~/.claude/skills for .claude/skills. Claude Code docs ↗
Or take the whole library
This repo ships a .claude-plugin manifest, so Claude Code can install all 31 skills at once. Plugin skills are invoked as /<plugin>:<skill>, so they never collide with your own.
/plugin marketplace add scrapercity/gtm-skills /plugin
The folder is the same in every client that implements the format — 46 of them — so if yours is not above, only the destination changes.
Before you install: this skill will not complete its job on a bare agent. It needs SCRAPERCITY_API_KEY, which you have to obtain separately.
The skill
Source on GitHub ↗Reproduced in full from scrapercity/gtm-skills/blob/46d446143690c8048b17817aecf36990ea6880e5/skills/scrapercity/scrapercity-lead-database/SKILL.md, which is licensed MIT (skill frontmatter). 2,959 words, 26 headings.
ScraperCity Lead Database
Overview
This skill turns "get me B2B leads for X" into a filter spec that returns the right people, a count check before anything is pulled, a paging plan that fits the 100,000 new leads a day allowance, and a short QA of the first 100 rows.
The Lead Database is included with the Growth plan ($149/mo) and up. Every lead returned is saved to the account. Only new leads count toward the daily allowance, and fetching a lead the account already has is free.
The mistakes it prevents:
- Pulling 20,000 rows on a filter that was wrong, because
pagination.totaland a 1-row sample were never checked first. - Using
country(where the person lives) when the user meantcompanyCountry(where the company is headquartered). - Paging with
page=2, 3, 4whileexcludeDelivered=true, which skips records. - Paying for an Apollo Scraper run and waiting 15 to 30 minutes for leads the database already returns in seconds.
When to Use
Use it when the user says:
- "Find VPs of Sales at 50-200 person SaaS companies in the US."
- "Pull every CFO in Texas at companies over $50M revenue."
- "Here is my people-search URL, get me these leads."
- "Set up a daily feed of new leads that match our ICP."
- "The database returned 503" or "409 filters_not_applied_yet" or "400 on my URL."
- "Should I use the Apollo Scraper or the Lead Database?"
- "Is this person still at that company?" (one
socialUrllookup)
Use a different skill for nearby jobs:
| Job | Skill |
|---|---|
| Defining the ICP before any filter exists | icp-list-builder |
| Sizing a market (accounts and people) | tam-builder |
| Finding the 1-3 right people at named accounts | decision-maker-finder |
| Local businesses (dentists, plumbers, restaurants) | scrapercity-local-business-database |
| Validating the emails after the pull | email-list-cleaner |
| Building the final send-ready file for a sequencer | cold-email-list |
| Re-checking a whole list of champions every month for job changes | scrapercity-integrations (job-change recipe) |
| MCP install and tool behavior in general | scrapercity-mcp |
Prerequisites
- A ScraperCity account on Growth ($149/mo) or Scale ($649/mo). Starter does not include database access. Run
check_walletand readplan.name. - An API key in
SCRAPERCITY_API_KEY(MCP and CLI) or a Bearer header (REST). - The ICP in words: titles, seniority, departments, industries, company size, revenue band, person or company geography, exclusions.
- The volume target and cadence: one-off (how many) or daily (how many new per day).
Authoritative Foundations
| Source | What it contributes here |
|---|---|
ScraperCity Lead Database API (npm scrapercity 1.0.17: bin/mcp.mjs, bin/cli.mjs, AGENT_DOCS.txt) | Every filter name, matching rule, paging rule, error code and the allowance. The only source for behavior. |
references/scrapercity-catalog.md | Prices for the paid tools around the database (scrape_apollo $0.0039 per lead, validate_emails $0.00169 per email, find_emails $0.05 per email found, find_mobiles $0.25 per number found). |
references/scrapercity-platform.md | Plans, the 100 records per request cap, excludeDelivered, after, and the 503 rule shared by all databases. |
| Apollo.io People API docs | The seniority vocabulary people-search URLs carry, and that title search there includes similar titles. Useful when translating a URL. |
| US Bureau of Labor Statistics, Employee Tenure | Median tenure of 4.1 years (January 2026): spread evenly, about 1.4% of a list changes employer each month, so every pull is dated and named people are re-checked by socialUrl before an important send. |
| Alex Berman | Narrow lists with one offer each beat one broad list with a generic pitch. Split pulls by segment, never one mega-query. |
Details and routing: references/framework-notes.md.
Workflow
1. Confirm access and the job type
Call check_wallet. If the plan is Starter, stop and explain that the Lead Database needs Growth or Scale, and offer scrape_apollo as the pay-per-lead route. Classify the job:
| Job type | Paging | excludeDelivered |
|---|---|---|
| One-off list under 5,000 | after cursor | optional |
| One-off list 5,000-100,000 | after cursor, may span days | true if re-running |
| Daily feed of new leads | after=0 each day | true always |
| Re-export of leads already owned | page or after | false (re-fetch is free) |
2. Translate the ICP into filters
Map every ICP sentence to one filter. The full semantics are in references/filter-semantics.md. The rules that cause the most errors:
- Person vs company location.
country,state,cityare where the person is.companyCountry,companyState,companyCityare the company HQ. "US companies" meanscompanyCountry. "People based in Texas" meansstate. - Titles are partial match, comma separated.
title: "VP Sales, Head of Sales"returns either."CEO"also matches longer titles that contain it. UsenotTitleto remove unwanted titles ("Assistant, Intern, Executive Assistant"). - Keywords are whole-word, any match.
keywords: ["saas", "fintech"]returns companies tagged with either word. UsenotKeywordsto drop adjacent categories. - Arrays are OR inside a filter, filters are AND across.
seniority: ["vp","director"]plusindustry: ["computer software"]means (VP or Director) and software. - Countries take full names. "United States", "Germany". US, USA, UK and UAE also work.
If the user gave a people-search URL, pass it as url and read search_translation (step 4).
An ICP attribute with no filter (funding stage, technology, hiring, recent news) gets two routes, each written out as a call in the plan: the user's company list for that attribute, passed as companyDomain in comma-separated batches of about 200 domains, and a limit: 1 call with url set to a people-search URL that carries the attribute, whose search_translation shows whether it was applied. Tell the user how to build the URL. Never stand in a proxy (size band, keywords) for the attribute without labeling the list as the proxy. Add a column naming where the attribute came from (stage_source, tech_source).
3. Run a count check before pulling
Call with limit: 1. Read pagination.total and look at data[0]. Report the total to the user with the filter table. Decision rule:
| Total | Action |
|---|---|
| 0 | Loosen: drop hasPhone, widen the size band, remove one exclusion, check country spelling. |
| Under the number the user asked for | Widen titles or geography, or switch to decision-maker-finder at named accounts. Say how far short the count is. |
| From the user's number to 100,000 | Pull. Show the user the count and the day count (total / 100,000). |
| Over 100,000 | Split into segments (by state, size band or seniority) so each segment fits a day and a message. |
A 503 here means the search ran too long: add a location or size band, or cut the title list, then retry.
4. Handle a people-search URL
Pass the URL as url. Any other filter you pass overrides the matching one from the URL. The response adds search_translation with three lists:
applied: used as is.approximated: mapped to the closest database filter. Read each one and confirm with the user.not_supported: ignored. If a dropped filter defines the ICP (for example a technology filter), tell the user the count is broader than their URL.
A URL with nothing the database can use returns 400. Rebuild the search with explicit filters. A long URL or a long title list belongs in a POST body: the query string is refused past about 16KB, and the CLI switches to POST on its own past 6,000 characters.
5. Pull with the cursor
Send after: "0", limit: 100, then each response's pagination.next_after until it is null or the target count is reached. Use after for anything over a few pages. Use page only for small one-off reads without excludeDelivered.
6. Design the daily pull (feeds)
Each day: excludeDelivered: true, after: "0", limit: 100, loop next_after, stop at the daily target or when next_after is null. Starting from after=0 daily catches every lead the account does not own yet. Keep each day under 100,000 new leads (the allowance resets at midnight UTC per scrapercity.com/api-docs). Per the same page, the API takes 100 requests a minute per key, so 1,000 calls of 100 take at least 10 minutes. Write the run log: date, segment, new leads, last cursor.
7. QA the first page
Before the full pull, agree a sample size and pass mark with the user, open that many rows and check: title matches intent, company size inside the band, company HQ where expected, email present when hasEmail was set, no excluded titles leaking. Below the pass mark, fix the filter and re-run the count. The checklist is in references/troubleshooting.md.
8. Cut to the requested number and hand off
When the pull holds more rows than the user asked for, cut it the way references/scrapercity-agent-patterns.md section 6 sets out: dedupe on lowercased email, rank by the user's title order, cap per company domain (the user's cap, or one per role named), validate the top N, and top up from the ranked remainder for exactly the shortfall. Write each step as a script the user can run. Leave excludeDelivered off for a one-off list (re-fetching owned leads is free) and on for repeat pulls.
Send emails to validate_emails before any campaign, and route the file to cold-email-list. Never load an unvalidated pull into a sequencer.
ScraperCity Implementation
MCP (query_lead_database)
{
"title": "VP Sales, Vice President of Sales, Head of Sales",
"notTitle": "Assistant, Intern, Operations",
"companyCountry": ["United States"],
"minEmployees": 50,
"maxEmployees": 200,
"keywords": ["saas"],
"hasEmail": true,
"limit": 1
}
Then the same body with "limit": 100, "after": "0", looping on pagination.next_after.
CLI (db-leads)
npx scrapercity db-leads --title "VP Sales, Head of Sales" --not-title "Assistant, Intern" \
--company-country "United States" --min-employees 50 --max-employees 200 \
--keywords saas --has-email --limit 1
The CLI prints the total, the next cursor and the first 3 leads, so it is the fastest count check. For a full export, use REST or MCP. List flags (--industry, --country, --state, --seniority, --department, --company-country, --company-state, --not-industry) take commas.
REST
curl -s -G "https://app.scrapercity.com/api/v1/database/leads" \
-H "Authorization: Bearer $SCRAPERCITY_API_KEY" \
--data-urlencode "title=VP Sales, Head of Sales" \
--data-urlencode "companyCountry=United States" \
--data-urlencode "keywords=saas" --data-urlencode "notTitle=Assistant, Intern" \
--data-urlencode "minEmployees=50" --data-urlencode "maxEmployees=200" \
--data-urlencode "hasEmail=true" --data-urlencode "limit=100" --data-urlencode "after=0"
Arrays repeat the key (seniority=vp&seniority=director), so a GET with two seniorities sends the key twice. keywords and notKeywords also accept commas. POST /api/v1/database/leads with a JSON body takes the same parameters with arrays as JSON arrays.
Response fields to read
data[] (person fields plus company_industry, company_size, employees_count, company_website, company_annual_revenue, company_city, company_state, company_country, keywords), pagination (page, limit, total, totalPages, has_more, next_after), rate_limit, and search_translation when url was sent.
Lead Database or Apollo Scraper
| Factor | Lead Database | scrape_apollo |
|---|---|---|
| Price | Included with Growth and up, 100,000 new leads a day | $0.0039 per lead |
| Speed | Seconds per 100 rows | Hours, up to several days. Webhook or hourly polling only |
| Input | Filters or a people-search URL | A people-search URL in Filters 1.0 format |
| Volume per request | 100 per call, cursor for more | 500-50,000 per run |
| Plan | Growth or Scale | Any plan with wallet credit |
Rule: on Growth or Scale, start with the database. Use scrape_apollo when the URL relies on filters listed in not_supported and the user needs them, or when the account is on Starter. A scrape_apollo response can include a lead_database block with matches (leads with the same filters in the database that the account does not have), a dashboard url and the api call that returns them now. Pull those first and size the Apollo run to the remainder.
Worked cost estimate
ICP: VP or Head of Sales, US-headquartered SaaS, 50-200 employees, email required. The count check returns 4,812.
| Line | Units | Unit price | Cost |
|---|---|---|---|
| Lead Database pull (49 calls of up to 100) | 4,812 | included in Growth | $0.00 |
validate_emails on every email | 4,812 | $0.00169 | $8.13 |
find_mobiles on the 300 top-tier accounts (assume 40% found) | 120 found | $0.25 | $30.00 |
| Total paid | $38.13 |
The same 4,812 leads through scrape_apollo would cost 4,812 x $0.0039 = $18.77 plus the wait. On Growth the database costs nothing extra and finishes in minutes. The pull uses 4.8% of one day's 100,000 allowance. Show this table and get a go-ahead before the validation spend.
Output Format
A lead pull plan in Markdown, built from templates/output-template.md:
- Request Summary: ICP in one paragraph, job type, plan confirmed.
- Filter Spec: table of parameter, value, reason. Only parameter names the endpoint accepts.
- Count Check: total from the
limit: 1call, sample row notes,search_translationlists if a URL was used. - Pull Plan: paging method,
excludeDelivered, calls needed, days needed, daily new-lead count. - Cost and Allowance: table with $ figures and allowance share.
- Sample QA: the sample check results against the pass mark set before the sample.
- Next Steps: validation, segmenting, hand-off.
Run python3 scripts/check-output.py plan.md before sending.
- Each fact once; every call and script written out in full (no
"..."values, no loop described in a comment); no counts or results marked assumed. If nothing has run, say so once at the top. - What the reader receives is the deliverable only: no internal file paths, reference section numbers or runbook IDs; another skill is named only in a handoff line that tells the user what to run next; no tables of checks that were not run (one "Not checked:" line instead); and no repeated identical rows where one template plus a list will do.
Quality Check
- Every filter row uses a parameter that exists in
query_lead_database. - Person vs company location is stated for every geography filter.
- A count from a
limit: 1call is shown before any bulk pull. excludeDelivered: trueis paired withafterorpage=1, never withpageabove 1.- Daily new leads planned are at or below 100,000.
- Every
approximatedandnot_supporteditem fromsearch_translationis listed with what it means for the count. - The cost table uses catalog prices and the paid total is shown and approved before any paid step.
- Sample QA done against a pass mark set before the sample, and the sample meets it.
Common Pitfalls
| Mistake | Why it fails | Fix |
|---|---|---|
country: ["United States"] for "US companies" | Filters where the person lives. Remote staff of foreign companies slip in and US-based companies with foreign staff drop out | Use companyCountry; add country only if the person's location also has to match |
title: "Sales" alone | Partial match pulls Sales Assistants, Sales Engineers, Salesforce Admins | List exact title stems and add notTitle |
Paging page=2..N with excludeDelivered | Each page you take removes rows from the next query, so later pages skip leads | Keep page=1 and loop, or use after |
| One 300,000-lead mega query | 503 timeouts and a list too broad for one message | Split by state, size band or seniority |
Ignoring search_translation | The URL's tech or intent filters may be not_supported, so the count is broader than the user thinks | Report each list back and confirm |
| Treating 409 as a duplicate-request error | On this endpoint, 409 filters_not_applied_yet means the named company filters cannot be used yet | Retry later or drop the listed filters. Nothing was returned or counted |
| Running Apollo for leads already in the database | Pays $0.0039 per lead and waits 15 to 30 minutes | Read the lead_database block, pull matches first |
| Skipping validation | Bounces hurt the sending domain | validate_emails at $0.00169 each before any send |
Mixing seniority and a title list that conflicts | seniority: ["c_suite"] with title: "Director" returns almost nothing | Use one or the other, or make them agree |
More failure modes and fixes: references/troubleshooting.md.
Execution Artifacts
| File | Use it when |
|---|---|
references/framework-notes.md | You need to know which source backs a rule, or which reference to open. |
references/filter-cookbook.md | You need a ready filter set for a role, industry or geography (40+ recipes). |
references/filter-semantics.md | You need exact matching behavior, seniority and department values, or the person vs company field map. |
references/troubleshooting.md | A call returned 0, 400, 409, 429 or 503, or the sample looks wrong. |
templates/output-template.md | Start every lead pull plan from it. |
examples/worked-example.md | You want a finished plan to copy the shape of (VP Sales at US SaaS, 50-200 employees). |
scripts/check-output.py | Before handing the plan to the user: python3 scripts/check-output.py plan.md. |
references/scrapercity-catalog.md | Prices and schemas for every paid tool you chain after the pull. |
references/scrapercity-platform.md | Plan and allowance facts. |
references/list-quality-standard.md | The acceptance bar for the finished list. |
references/scrapercity-agent-patterns.md | Wallet checks, polling and confirmation patterns shared by all ScraperCity skills. |
Related Skills
using-scrapercity-skills: router for every ScraperCity job.scrapercity-mcp,scrapercity-cli,scrapercity-api: access paths and setup.icp-list-builderandtam-builder: decide who to pull before you pull.decision-maker-finder: named-account people search.email-list-cleanerandcold-email-list: what happens to the file next.scrapercity-local-business-database: when the target is a local business, not a B2B role.
Files bundled with it
These load only when the skill asks for them, so they cost nothing until it runs.
Other skills for the same job
Different authors, same problem. Matched on the words in the skill name, across every library in the catalogue except this one.
- no-lead-left-behind-lead-treatment-audit by zapier · 354
- lead-magnets by coreyhaines31 · 57,918
- lead-dossier by ericosiu · 3,766
- lead-magnet-brainstorm by growthenginenowoslawski · 797
- lead-magnet by OpenClaudia · 724
- lead-scoring by shawnpang · 374
- daily-lead-steward by zapier · 354
- find-lead-account-owner by zapier · 354
Need help setting it up?
This page tells you what scrapercity-lead-database does and what it needs. Cheetah builds the agent setup it runs inside: data, CRM, sequencing and the guardrails.
Book a call →The directory stays free. There is nothing gated behind this.