The goal
Start with a thesis, not an endpoint
Most scouting workflows begin as a sentence. The useful work is turning each part of that sentence into a filter the API can apply consistently.
This guide resolves the three human-readable taxonomy values at runtime, sends one company list request, and sorts the result by signal score. The live query currently finds 16 companies and returns the top eight.
Why a list endpoint?
The output is a list of companies. Use GET /data/companies. Aggregate endpoints are for grouped metrics such as funding by year or company count by country.
Step 1
Authenticate once, then let the client refresh
Create a Programmatic M2M key in Dealroom and keep both credentials on the server. The downloadable script uses OAuth2 client credentials and retries once with a fresh token after a 401 response.
DEALROOM_CLIENT_ID=your_client_id
DEALROOM_CLIENT_SECRET=your_client_secret
DEALROOM_USER_AGENT=your-company-thesis-shortlist/1.0
Install the three small dependencies used by the example:
pip install authlib requests python-dotenv
Do not put a Programmatic M2M secret in browser code. Run this script on a server, in a scheduled job, or locally.
Step 2
Resolve names to taxonomy IDs
Filters use stable IDs, but a thesis uses names such as Europe, Industrial Automation, and Artificial Intelligence. Resolve those names before constructing the filter instead of copying IDs into your application.
def exact_value(items, label, source_type=None):
for item in items:
item_label = item.get("label") or item.get("name", "")
item_type = item.get("source_type") or item.get("type")
if item_label.casefold() == label.casefold() and (
source_type is None or item_type == source_type
):
return str(item.get("value") or item["id"])
raise LookupError(f"Could not resolve {label!r}")
europe_id = resolve_location("Europe", "continent")
industrial_id = resolve_tag("Industrial Automation", "sector")
ai_id = resolve_tag("Artificial Intelligence", "technology")
Location discovery returns name/id. Cross-filter search returns label/value. The helper accepts both response shapes, then requires an exact case-insensitive label and the expected taxonomy type.
Resolved for this run
Europe is location 34. Industrial Automation is sector tag 99301. Artificial Intelligence is technology tag 202. The code still discovers them each time so taxonomy changes fail visibly.
Step 3
Translate each thesis clause into a filter
The filter DSL keeps the query readable. Each clause corresponds to one decision in the thesis.
| Thesis clause | API filter |
|---|---|
| Industrial automation and AI | tag_id[in_all]:99301|202 |
| Headquartered in Europe | hq_location[eq]:34 |
| Startup and still operating | is_startup[eq]:true + company_status[eq]:operational |
| Founded since 2020 | launch_date[gte]:2020 |
| No more than $50M raised | total_funding[lte]:50000000 |
| Signal score of at least 65 | signal_rating[gte]:65 |
filters = [
f"tag_id[in_all]:{industrial_id}|{ai_id}",
f"hq_location[eq]:{europe_id}",
"is_startup[eq]:true",
"company_status[eq]:operational",
"launch_date[gte]:2020",
"total_funding[lte]:50000000",
"signal_rating[gte]:65",
]
company_filter = f"and({','.join(filters)})"
The in_all operator matters here. It requires both tags. Using in_any would also return general AI companies and industrial automation companies without AI.
Step 4
Rank on the server
Ask the list endpoint for the top eight records ordered by descending signal score. Set include_total=true so the response also tells you how many companies matched before the limit was applied.
result = client.get(
"/data/companies",
params={
"filter": company_filter,
"sort": "-signal_rating",
"limit": 8,
"include_total": "true",
},
)
print(result["page"]["total"])
print(result["data"][0]["name"])
Company rows already include the fields needed for a first-pass shortlist, including the tagline, headquarters, founding year, funding summary, team size, tags, hiring status, founders, and signal score.
The output
A shortlist you can inspect
Top eight of 16 matches, ranked by signal score.
Loading the result snapshot...
Snapshot generated 2 Sep 2026. Funding values are shown in USD. Dealroom signal scores are discovery aids, not investment recommendations.
Next steps
Turn the shortlist into a workflow
This example stops at a ranked list. A production scouting workflow can add a small amount of state and human judgment:
- Run the query on a schedule and store the company UUIDs you have already reviewed.
- Flag newly matched companies and meaningful changes in funding, headcount, or hiring.
- Add your own score for thesis fit instead of treating the Dealroom signal score as a final decision.
- Write analyst notes and decisions to your CRM, database, or internal scouting tool.
Complete example
Run the full Python script
The download includes authentication, runtime taxonomy discovery, the complete filter, and clean JSON output.