How to Find Every Digital Agency in a City, With Email
2026-09-08
Quick answer: Write one sentence describing the agencies you want, name the city, and Searchbase plans the search, reads the pages it finds and streams rows into a table with website, email and a source link on every cell. Milan takes a few minutes and around 120 to 200 credits for a first pass of 100 to 150 agencies. Describe your ideal customer. Searchbase finds them across Europe in one prompt, with the source on every cell.
Most people build this list twice. The first time they buy a database export, find that half the Milanese agencies in it closed in 2023, and the other half are missing. The second time they do it by hand: Google, directory, agency site, contact page, copy the email, repeat. That is a week of work that goes stale in a month.
What follows is the third way. It is the same job done as a research task rather than a data purchase, and the reason it works for European cities in particular is that a Milanese agency almost always has a website, a portfolio page and a public contact address, and almost never has a row in a contact database assembled around US B2B.
Step 1. Write the prompt as a sentence, not as filters
Open a new chat and type what you actually want:
"Find every digital agency in Milan with a website and a contact email. I want agency name, website, email, city, number of employees if it is public, and the services they list."
Notice what this is not. There is no industry code to pick, no employee range slider, no saved search. You are describing the outcome, and the columns you named in the sentence become the columns of the table.
Be specific about the boundary of the word "agency". If you mean web development studios and not media buying shops, say so. If you want both, say both. The agent takes the sentence literally, which is a feature: a vague prompt returns a vague list, and you will see that in the first ten rows rather than after the export.
Step 2. Read the plan before it runs
Before anything is fetched, the agent writes a short plan and shows it to you. For the Milan prompt it usually looks like this: search the web for Milan agency directories and rankings, search for agencies by service keyword in Italian and English, open each agency site, read the contact and about pages, extract the named fields, deduplicate by domain.
This is the moment to correct course, and it is cheap because nothing has been read yet. If the plan is going to lean on one directory you do not trust, say "do not rely on directory listings, go to the agency websites". If you want a hard cap, say "stop at 100 agencies". The plan is a draft, not a commitment.
Step 3. Let the search and the page reads happen
Now the work runs, and you can watch it. The agent runs web searches in Italian and English, because a Milan agency describes itself as a "web agency" and an "agenzia di comunicazione" on the same site and searching in only one language loses a third of the market. It collects candidate URLs, then it opens them.
Reading is where the accuracy comes from. The agent does not infer that an agency has an email because agencies usually do. It opens the site, looks at the contact page, the footer, the imprint, and takes the address that is actually there. Public company registries, portfolio pages and press mentions get read the same way when the prompt needs a field the homepage does not carry.
Step 4. Watch rows stream into the table
Rows appear as they are confirmed, not in one batch at the end. The first agencies show up in seconds and the table fills while the agent keeps working. You are not waiting on a job queue with a spinner.
This matters more than it sounds. If row 8 is a freelancer rather than an agency, you see it at row 8 and can say "exclude solo freelancers, I want companies with at least three people". The run adjusts. You have spent maybe ten credits finding out that your definition was loose, instead of exporting 400 rows and discovering it in your CRM.
Step 5. Fill the gaps with a follow up prompt
The first pass will leave holes. Some agencies publish a contact form and no address. Some hide the team size. Blank cells are honest, and you can attack them directly:
"For the rows with no email, check their LinkedIn and Instagram pages and their imprint page, and fill in a public contact address if there is one."
This is a second, cheaper pass over a smaller set. Social profiles cost more to read than a plain page, so a targeted gap fill on 30 rows is a much better trade than asking for social data on all 150 up front.
Step 6. Change the city and run it again
The prompt is portable. This is the part teams underestimate:
"Same thing for Berlin."
Berlin, Madrid, Lyon, Amsterdam, Barcelona and Zurich all work from the same sentence. The agent adapts the search language to the market automatically, so Berlin gets searched in German and Lyon in French without you asking. The columns stay identical, which means the four tables stack into one file with no reconciliation work.
If you want the whole set in one shot, say so: "Do the same for Berlin, Madrid and Lyon, and keep the columns identical." One run, four markets, one export.
Step 7. Export, then draft the outreach
Export is JSON on every plan, CSV from Starter upward, the API from Pro and webhooks on Business. From the table you can also ask the agent to write the first message:
"Draft a short first email for the agencies that list Shopify work, mentioning the specific client project on their site."
The agent writes the drafts and stops. Nothing leaves your account. You review, edit and send from your own tool. Today teams use Apollo for the sending layer, and drafts export cleanly into it.
What you get back
A table, one agency per row, with the columns you named in your sentence. For the Milan prompt that is agency name, website, email, city, employee count and services.
Every cell carries three things. A link to the exact page the value came from, so you can click and see it. A freshness badge saying when it was collected. And the extraction method used, so you know whether a number was read from a page or pulled from a structured field.
When a value cannot be verified, the cell says n/a. It is not filled with a guess, a pattern-generated address or a plausible number. A blank cell in this table is information: it tells you that agency does not publish that thing, which is often worth knowing on its own.
Rows are deduplicated by domain, so an agency that appears in three directories under two spellings arrives once.
What it costs in credits
Reading a normal web page costs about 1 credit. Reading a social profile costs about 3. A Deep Research report costs 20 to 40.
So a Milan run that finds and reads roughly 150 agency sites plus the search pages that led to them lands somewhere around 120 to 200 credits. A gap-fill pass over 30 social profiles adds about 90. Adding Berlin, Madrid and Lyon roughly quadruples the first number.
Against the plans: Free gives you 150 credits a month, which is one city, once, and is enough to judge whether the output is worth paying for. Starter is €29 a month for 1,000 credits, which covers a handful of cities and their gap fills. Pro is €79 for 4,000 credits and adds API access, which is where you are if this list gets rebuilt monthly. Business is €199 for 12,000 credits with webhooks.
Prices are in euros, billed by a European company, so there is no exchange rate on the invoice.
Limits and honesty
It cannot find what is not published. If an agency uses a contact form and no address anywhere, no tool can produce their email honestly. Ours leaves it blank. Anything that hands you a confident address for that agency guessed it.
No private data, ever. Public pages, public profiles, public registries. Nothing behind a login, nothing behind a paywall, no personal data that the person did not publish themselves.
Completeness is a claim we will not make. "Every digital agency in Milan" is the ambition and the article title, but the honest version is every agency with a discoverable public web presence. A studio with no site and a private Instagram is invisible to this method and to every other one.
Values that cannot be verified stay blank. Employee counts are the usual casualty. Many agencies simply do not publish one.
Outreach is drafted, never sent. The agent writes the sequences, you approve and send. There is no button here that mails 150 agencies on your behalf.
Under the GDPR, a public email is still personal data. Being able to collect it is not the same as being allowed to mail it. Italian marketing email needs a lawful basis regardless of where the address came from. That is your call to make, and none of this is legal advice.
Frequently asked questions
How long does a city take? Minutes, not hours. Rows begin appearing within seconds of the plan being approved, and a 150-agency Milan run typically finishes in a few minutes. You can read the first rows while the rest are still arriving.
Will it work for a small city? Yes, and the output is usually more complete, because there are fewer businesses and they are easier to enumerate. What changes is that the total row count is smaller, which people sometimes read as a failure. Twenty agencies in Verona may well be all of them.
Can I get phone numbers and LinkedIn pages too? Ask for them in the prompt and they become columns. Social profiles cost about 3 credits each rather than 1, so add them for a filtered subset rather than for the whole list if budget matters.
How is this different from a lead database? A database tells you what was true when it was compiled. This reads the live web when you ask, and puts the link to the page on the cell so you can check. The trade is that a database returns instantly and this takes a few minutes.
What if I want agencies that use a specific technology? Say it: "only agencies whose site mentions Shopify Plus". The agent reads the pages anyway, so a content condition is cheaper than it sounds. Conditions that require a private signal, like their revenue, are not answerable and will come back blank.
Can I re-run it monthly to catch new agencies? Yes. Run the same prompt and compare the exports on the website column. The freshness badge on each cell tells you which values were re-read rather than carried over.
Prices checked on 2026-09-08 on searchbase.org.