Most LinkedIn company research starts the same way: a set of criteria — industry, size, location — and a one-time search. The problem shows up a month later, when someone re-runs the same search by hand because there's no way to tell which results are new since last time. Either the search gets re-run and someone scrolls through 200 familiar names looking for the handful that weren't there before, or it just doesn't get re-run at all, and whichever companies started matching the criteria in the meantime never show up on anyone's radar.
Below is how to turn a criteria-based company search into something that runs on a schedule and only ever surfaces what changed.
If you're an agent (or building one) reading this rather than a human, the full machine-readable schema for every endpoint below lives at mindcase.co/skills.md.
What does "automating" a company search actually mean here?
If you already have a named list of target accounts, refreshing their data on a schedule is a different problem — see LinkedIn Company Data for Account-Based Marketing for that walkthrough. This post is about the other case: you don't have a fixed list. You have criteria — "Series B-sized fintech companies in Bangalore" — and new companies match that criteria over time. Automating this means running the same search on a schedule and getting told only what's new, not re-reading the same 200 results every week to spot the three that weren't there before.
How do you search for companies by criteria instead of a fixed list?
LinkedIn Companies API supports this directly — keywords and filters instead of a list of company URLs:
curl -X POST "https://api.mindcase.co/v1/data/linkedin/companies/run?wait=true" \
-H "Authorization: Bearer $MINDCASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"params": {
"query": "fintech startup",
"locations": ["Bangalore"],
"companySize": ["201-500", "501-1000"],
"maxResults": 200
}
}'
# $0.004 per companyEach row returns 27 fields, including a linkedinUrl that's unique per
company — that field is what makes the next step possible.
How do you avoid re-processing companies you've already seen?
Mindcase doesn't run your schedule for you — there's no built-in cron or
webhook here, so this part is on whatever scheduler you already use (a
cron job, a workflow tool, a CI job that runs nightly). What Mindcase gives
you is a clean way to tell new from old once each run finishes: store the
linkedinUrl values you've already seen (a spreadsheet column, a database
table, a flat file — the storage doesn't matter), and after each scheduled
run, keep only the rows whose linkedinUrl isn't already in that set.
Run the same search weekly and the diff against your stored list is your actual output — not 200 companies again, just the handful that are genuinely new since last time. That's the entire mechanism: the API stays identical on every run, and the only new work is the comparison.
What does that look like across two actual runs?
Say the first run of that Bangalore fintech search returns 200 companies.
You store all 200 linkedinUrl values. Two weeks later the same search
runs again — same query, same locations, same companySize — and this
time it returns 204 companies. 198 of those URLs are already in your
stored set; 6 aren't. Those 6 are the only output that matters: new
companies that started matching your criteria since the last run, whether
because they grew into the size band, moved into the category, or simply
didn't exist on LinkedIn two weeks ago. The other 198 aren't wasted API
calls to review — they're just confirmation that nothing about them
changed relative to what you already have.
How do you turn a new company into contacts automatically?
Once a company clears the dedup check, pulling its employees is the same Company Employees API call covered in the ABM post above — one company URL per call, filtered to the roles you care about:
curl -X POST "https://api.mindcase.co/v1/data/linkedin/company-employees/run?wait=true" \
-H "Authorization: Bearer $MINDCASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"params": {
"companies": "https://www.linkedin.com/company/example-fintech",
"jobTitles": ["Founder", "Head of Product"]
}
}'
# $0.004 per profile returnedWire that call to run only on the new rows from the previous step, and a weekly criteria search becomes a weekly list of newly-matching companies with contacts already attached — without anyone re-running the same search by hand to check what changed.
What can't you get from Mindcase?
Two cases.
A scheduler. Mindcase returns data on request; it doesn't run your cron, trigger a webhook when a new company appears, or store your dedup list for you. All of that is real infrastructure you already have — a scheduler, a database, a script — Mindcase is the data call inside it, not the pipeline around it.
Data on a company between your runs. If a company's headcount band changes twice between two weekly pulls, you only see its state at each snapshot, not the path between them. Coverage is always "as of the moment you called," not continuous monitoring.
Which endpoint should you use for which job?
| Endpoint | Input | Price | Best for |
|---|---|---|---|
| LinkedIn Companies | Keywords/filters, or company URLs | $0.004 / company | Recurring criteria-based discovery |
| Company Employees | One company URL | $0.004 / profile | Pulling contacts once a company clears your dedup check |
FAQ
No. You bring your own scheduler — a cron job, a workflow tool, anything that can make an HTTP call on a timer. Mindcase is the data call each run makes, not the thing doing the scheduling.
Compare each run's linkedinUrl values against a stored list of URLs you've already processed. Anything not already in that list is new since your last run.
Yes. Industries are also filterable on the same endpoint, alongside the keyword query and location and size filters shown above.
$0.004 per company returned from a search, and $0.004 per employee profile once you pull contacts for a company. A weekly run of 200 companies costs $0.80 in search calls alone, before any employee pulls.
The search just won't return it on a future run. There's no separate 'removed' signal — a dedup-by-URL approach only tells you what's newly present, not what dropped out, since the endpoint returns a fresh match set each time rather than a diff.
