dealroom-early-access-api
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDealroom API consumer guide
Dealroom API 使用指南
How to build against the Dealroom next-gen REST API: authenticate, pick the right
endpoint, and discover filters from the live API instead of guessing.
This skill covers Programmatic (M2M) API usage. Application (PKCE) keys for browser
SPAs also exist (read-only, created from the same settings page), but this skill does not
cover that flow.
This skill holds only the durable parts (auth, endpoint judgment, discovery mechanism,
pointers). Endpoint shapes, the full filter catalog, and field lists live in the API
itself and the docs, which are the single source of truth. Always read those for
specifics rather than relying on memory.
如何基于Dealroom下一代REST API进行开发:认证、选择合适的端点,并从实时API中发现过滤器,而非猜测。
本技能涵盖程序化(M2M)API使用。适用于浏览器SPA的应用(PKCE)密钥也存在(只读,从同一设置页面创建),但本技能不涵盖该流程。
本技能仅保留持久化内容(认证、端点判断、发现机制、指引)。端点结构、完整过滤器目录和字段列表存储在API本身及文档中,它们是唯一的事实来源。如需具体细节,请始终查阅这些内容,而非依赖记忆。
Read this before building anything
开始构建前必读
Two failure modes cause almost every stuck integration. Avoid both:
- Don't guess endpoint paths, filter keys, or operator syntax. Hallucinated names
that "look right" return empty results or s. Discover filters at runtime with
400and confirm shapes against the OpenAPI spec.GET /reference/filters?scope=<scope> - Don't default to aggregate endpoints. This is the most common mistake. Most questions want records, not a computed statistic. See below.
This is an early-access API and can change without notice. If the live behavior conflicts
with this skill, trust the API and flag it: see
When the API disagrees with this skill.
两种失败模式几乎导致了所有集成受阻。请避免这两种情况:
- 不要猜测端点路径、过滤器键或运算符语法。 那些“看起来正确”的虚构名称会返回空结果或错误。通过
400在运行时发现过滤器,并根据OpenAPI规范确认结构。GET /reference/filters?scope=<scope> - 不要默认使用聚合端点。 这是最常见的错误。大多数问题需要的是记录,而非计算得出的统计数据。请见下文。
这是一个早期访问API,可能会随时更改,恕不另行通知。如果实时行为与本技能描述冲突,请以API为准并标记问题:请查看当API与本技能描述不符时。
Choosing the right endpoint
选择合适的端点
The most important decision. Pick by what the answer is, not by how analytical the
question sounds.
Rule of thumb: If the user wants to see things (a list of companies, the rounds of one startup, who invested in X), use a transactional / list endpoint. If they want a number or a chart of numbers computed across many rows (count, sum, average, median, distribution, trend, cross-tab), use an aggregate endpoint. When in doubt, start transactional.
List endpoints already return rich nested objects (funding summary, latest valuation,
tags, founders) and a count, so you rarely need a separate aggregate just to
enrich or count a result set.
page.total| The user wants | Use | Not |
|---|---|---|
| A list of companies / investors / people matching criteria | | aggregate |
| The "top N by funding / valuation / signal" | list + | aggregate group_by |
| Everything about one entity | | aggregate |
| One entity's rounds / valuations / investors / portfolio / team | typed collections (see below): | aggregate |
| All funding rounds matching criteria | | aggregate |
| All valuations matching criteria (cross-entity) | | aggregate |
| Fund vehicles investor firms have raised (cross-manager) | | |
| Points to plot on a map | | a full list call you then thin client-side |
| How many entities match (just the count) | the list call's | an aggregate for a bare count |
| A count / sum / avg / median grouped by a dimension | | paging the list and reducing client-side |
| Several metrics at once (KPIs, leaderboards) | | many separate calls |
| A 2D matrix, stage transitions, or a per-year trend | | |
| Fuzzy name lookup ("find Stripe") | | a |
| Ranked investor recommendations for a target company | | hand-rolled portfolio-overlap queries |
| Companies / investors similar to a given one | | building your own tag-overlap ranking |
Anti-patterns:
- Ranking entities via aggregate. groups by a dimension (country, year, sector), not by entity. To rank companies, use the list endpoint with
group_by.sort - Aggregating to count. A list response already returns .
page.total - Aggregating one entity. Profile data lives on the typed-collection sub-resources (see below).
- The reverse mistake: paging thousands of list rows to sum/average client-side. That
is exactly what is for.
GET /analytics/aggregate/{source}
Relationship sub-resources are facet-scoped by entity type. They are not on
(that path carries only the detail record plus ).
Read the entity's / / / flags
from the detail payload, then call the matching typed collection. The paths are static
and knowable:
/data/entities/{id}lp-fundstypeorganization_subtypeis_investoris_founder- Companies ():
/data/companies/{id}/,funding-rounds,valuations,financials,investors,team,headcount-breakdown,web-trafficsimilar - Investors ():
/data/investors/{id}/,portfolio,funds,lp-funds,teamsimilar - People / founders / universities: ,
/data/people/{id}/career,/data/founders/{id}/founded-companies, and/data/universities/{id}/alumnion universities / gov-ngoteam
The collections rank by weighted tag overlap (force-sorted by score), accept
the full company/investor filter DSL to narrow the pool, and use offset pagination
capped at .
similaroffset + limit <= 1000Map points have their own slim lens.
returns one point per entity (id, name, coordinates) instead of the full list payload, takes
the same as its list endpoint, and accepts (e.g.
, , , ,
, , ) to return each point's
for proportional sizing. also sorts descending, so a capped response keeps
the highest-value points; entities without usable coordinates are omitted. For per-area
counts (a choropleth rather than dots) use
instead. The older
generic still exists (no , higher limits) but prefer
the per-collection endpoints.
GET /data/{companies,investors,universities}/geofiltersize_by=<numeric dimension>total_fundingemployee_countlatest_valuationtotal_investedtotal_investments_countalumni_countalumni_founder_countvaluesize_byGET /analytics/aggregate/companies?metric=count&group_by=map_areaGET /data/entities/geosize_by这是最重要的决策。应根据答案是什么来选择,而非问题听起来有多具分析性。
经验法则: 如果用户想要查看内容(公司列表、某初创企业的融资轮次、谁投资了X),请使用事务型/列表端点。如果他们想要基于多行数据计算得出的数字或数字图表(计数、求和、平均值、中位数、分布、趋势、交叉表),请使用聚合端点。如有疑问,从事务型端点开始。
列表端点已返回丰富的嵌套对象(融资摘要、最新估值、标签、创始人)和计数,因此你很少需要单独使用聚合端点来丰富或计数结果集。
page.total| 用户需求 | 使用端点 | 不使用 |
|---|---|---|
| 符合条件的公司/投资者/人物列表 | | 聚合端点 |
| “按融资/估值/信号排名前N的实体” | 列表端点 + | 聚合端点的group_by功能 |
| 某实体的所有信息 | | 聚合端点 |
| 某实体的融资轮次/估值/投资者/投资组合/团队 | 类型化集合(见下文): | 聚合端点 |
| 符合条件的所有融资轮次 | | 聚合端点 |
| 符合条件的所有估值(跨实体) | | 聚合端点 |
| 投资公司筹集的基金载体(跨管理人) | | |
| 要在地图上绘制的点 | | 获取完整列表后在客户端精简数据的调用 |
| 符合条件的实体数量(仅计数) | 列表调用的 | 用于单纯计数的聚合端点 |
| 按维度分组的计数/求和/平均值/中位数 | | 分页获取列表后在客户端计算 |
| 多个指标(KPI、排行榜) | | 多次单独调用 |
| 二维矩阵、阶段转换或年度趋势 | | |
| 模糊名称查找(“查找Stripe”) | | |
| 针对目标公司的投资者推荐排名 | | 手动编写的投资组合重叠查询 |
| 与给定实体相似的公司/投资者 | | 自行构建标签重叠排名 |
反模式:
- 通过聚合端点对实体排名。 是按维度(国家、年份、行业)分组,而非按实体。要对公司排名,请使用带
group_by参数的列表端点。sort - 使用聚合端点进行计数。 列表响应已返回。
page.total - 对单个实体使用聚合端点。 实体详情数据存储在类型化集合的子资源中(见下文)。
- 反向错误: 分页获取数千条列表数据后在客户端求和/平均。这正是的用途。
GET /analytics/aggregate/{source}
关系子资源按实体类型的维度划分范围。 它们不在路径下(该路径仅携带详情记录及)。从详情负载中读取实体的///标志,然后调用匹配的类型化集合。路径是固定且可知的:
/data/entities/{id}lp-fundstypeorganization_subtypeis_investoris_founder- 公司():
/data/companies/{id}/、funding-rounds、valuations、financials、investors、team、headcount-breakdown、web-trafficsimilar - 投资者():
/data/investors/{id}/、portfolio、funds、lp-funds、teamsimilar - 人物/创始人/大学:、
/data/people/{id}/career、/data/founders/{id}/founded-companies,以及大学/政府非盈利组织的/data/universities/{id}/alumniteam
similaroffset + limit <= 1000地图点有专门的精简视图。 返回每个实体的一个点(ID、名称、坐标),而非完整的列表负载,接受与其列表端点相同的参数,并支持(例如、、、、、、)来返回每个点的以进行比例缩放。还会按降序排序,因此限制数量的响应会保留最高值的点;没有可用坐标的实体将被省略。如需按区域计数( choropleth地图而非点),请改用。旧的通用仍存在(无,更高限制),但优先使用按集合划分的端点。
GET /data/{companies,investors,universities}/geofiltersize_by=<numeric dimension>total_fundingemployee_countlatest_valuationtotal_investedtotal_investments_countalumni_countalumni_founder_countvaluesize_byGET /analytics/aggregate/companies?metric=count&group_by=map_areaGET /data/entities/geosize_bySetup
设置步骤
Steps 1-2 apply to both modes; run them on the first turn and skip what is already done.
Step 3 is only for app builds (see Two ways to call the API).
- Generate an API key (the user must do this). Auth0 needs a logged-in browser, so
you cannot do it for them. Tell them: open
https://beta.dealroom.app/settings/api, click + Create key, choose
Programmatic (M2M), and copy both and
client_id(the secret is shown only once). The API is in closed beta: if that page shows a waitlist sign-up instead of + Create key, the account has no API access yet - the user should join the waitlist and wait for the enablement email; there is no way around this gate.client_secret - Store the credentials in . Copy
.envand fill inassets/.env.exampleandDEALROOM_CLIENT_ID. Optionally setDEALROOM_CLIENT_SECRETfor server-side observability. ConfirmDEALROOM_USER_AGENTis in.env..gitignore - App builds only - copy a client snippet. Python: then
cp <skill-path>/assets/snippets/dealroom.py ./. Node/TS: copypip install authlib requests python-dotenvplusdealroom.tsandassets/package.json(the ESM config the snippet needs), thenassets/tsconfig.jsonand verify withnpm install. Both readnpm run sanity, send the headers, and mint and refresh tokens automatically. For one-off conversational queries, skip this and use curl (next section)..env
步骤1-2适用于两种模式;在首次使用时执行,跳过已完成的步骤。步骤3仅适用于应用构建(见两种调用API的方式)。
- 生成API密钥(必须由用户操作)。 Auth0需要已登录的浏览器,因此你无法代劳。请告知用户:打开https://beta.dealroom.app/settings/api,点击**+ Create key**,选择Programmatic (M2M),并复制和
client_id(密钥仅显示一次)。此API处于封闭测试阶段:如果该页面显示等待列表注册而非**+ Create key**,则该账户尚未获得API访问权限——用户应加入等待列表并等待启用邮件;无法绕过此限制。client_secret - 将凭据存储在文件中。 复制
.env并填写assets/.env.example和DEALROOM_CLIENT_ID。可选设置DEALROOM_CLIENT_SECRET以便服务器端可观测性。确认DEALROOM_USER_AGENT已添加到.env中。.gitignore - 仅适用于应用构建 - 复制客户端代码片段。 Python:,然后执行
cp <skill-path>/assets/snippets/dealroom.py ./。Node/TS:复制pip install authlib requests python-dotenv以及dealroom.ts和assets/package.json(代码片段所需的ESM配置),然后执行assets/tsconfig.json并通过npm install验证。两者均读取npm run sanity文件、发送请求头,并自动生成和刷新令牌。对于一次性对话式查询,请跳过此步骤并使用curl(下一节)。.env
Two ways to call the API
两种调用API的方式
Match the tool to the job. Do not scaffold a project or write a script just to answer a
question; do not hand-mint tokens in a loop inside a real program.
Conversational / ad-hoc - you answering a question now: run curl directly. This is the
default when the user asks you to look something up, explore, or sanity-check data. Mint one
token per session, reuse it across calls, and pass each filter with so the , , and metacharacters survive the shell. No files, no
project, no snippet.
curl -G --data-urlencode[]|bash
undefined根据任务选择合适的工具。不要仅为回答问题而搭建项目或编写脚本;不要在实际程序中循环手动生成令牌。
对话式/临时查询 - 你现在需要回答问题:直接运行curl。 当用户要求你查询、探索或验证数据时,默认使用此方式。每个会话生成一次令牌,在多次调用中复用,并通过传递每个过滤器,以便、和元字符在shell中保留。无需文件、项目或代码片段。
curl -G --data-urlencode[]|bash
undefinedLoad credentials and mint a token ONCE per session (24h lifetime); reuse $TOKEN after.
加载凭据并生成令牌(每个会话仅执行一次,令牌有效期24小时);之后复用$TOKEN。
NOTE: the audience is NOT the API base URL - it stays the legacy Auth0 API
注意:audience不是API基础URL - 即使请求发送到api.beta.dealroom.app,它仍保留旧版Auth0 API标识符(https://api-next.beta.dealroom.co)。请见下方环境表。
identifier (https://api-next.beta.dealroom.co) even though requests go to
—
api.beta.dealroom.app. See the environment table below.
—
set -a && . ./.env && set +a
TOKEN=$(curl -s https://accounts.beta.dealroom.co/oauth/token
-H 'Content-Type: application/json'
-d "{"grant_type":"client_credentials","client_id":"$DEALROOM_CLIENT_ID","client_secret":"$DEALROOM_CLIENT_SECRET","audience":"https://api-next.beta.dealroom.co\"}"
| jq -r .access_token)
-H 'Content-Type: application/json'
-d "{"grant_type":"client_credentials","client_id":"$DEALROOM_CLIENT_ID","client_secret":"$DEALROOM_CLIENT_SECRET","audience":"https://api-next.beta.dealroom.co\"}"
| jq -r .access_token)
curl -s -G 'https://api.beta.dealroom.app/data/entities'
--data-urlencode 'filter=and(organization_subtype[eq]:company,tag_id[in_any]:42|99)'
--data-urlencode 'sort=-total_funding' --data-urlencode 'limit=5'
-H "Authorization: Bearer $TOKEN" -H "X-Client-Id: $DEALROOM_CLIENT_ID" | jq
--data-urlencode 'filter=and(organization_subtype[eq]:company,tag_id[in_any]:42|99)'
--data-urlencode 'sort=-total_funding' --data-urlencode 'limit=5'
-H "Authorization: Bearer $TOKEN" -H "X-Client-Id: $DEALROOM_CLIENT_ID" | jq
**Building an app or anything repeated - code that outlives the session: use the snippet.**
Copy `dealroom.py` / `dealroom.ts` into the project. It reads `.env`, sends the headers, and
re-mints the token on a `401` automatically - which raw curl will not do when the 24h token
expires mid-run. This is the right path inside any program, loop, or multi-query tool.
**Pitfall either way: never put raw `[ ] |` in a curl URL string.** Use `-G
--data-urlencode` per parameter (or the snippet's structured params). Bare brackets in the
URL are the single biggest cause of agents writing throwaway escape scripts.set -a && . ./.env && set +a
TOKEN=$(curl -s https://accounts.beta.dealroom.co/oauth/token
-H 'Content-Type: application/json'
-d "{"grant_type":"client_credentials","client_id":"$DEALROOM_CLIENT_ID","client_secret":"$DEALROOM_CLIENT_SECRET","audience":"https://api-next.beta.dealroom.co\"}"
| jq -r .access_token)
-H 'Content-Type: application/json'
-d "{"grant_type":"client_credentials","client_id":"$DEALROOM_CLIENT_ID","client_secret":"$DEALROOM_CLIENT_SECRET","audience":"https://api-next.beta.dealroom.co\"}"
| jq -r .access_token)
curl -s -G 'https://api.beta.dealroom.app/data/entities'
--data-urlencode 'filter=and(organization_subtype[eq]:company,tag_id[in_any]:42|99)'
--data-urlencode 'sort=-total_funding' --data-urlencode 'limit=5'
-H "Authorization: Bearer $TOKEN" -H "X-Client-Id: $DEALROOM_CLIENT_ID" | jq
--data-urlencode 'filter=and(organization_subtype[eq]:company,tag_id[in_any]:42|99)'
--data-urlencode 'sort=-total_funding' --data-urlencode 'limit=5'
-H "Authorization: Bearer $TOKEN" -H "X-Client-Id: $DEALROOM_CLIENT_ID" | jq
**构建应用或重复执行的任务 - 代码需长期存在:使用代码片段。** 将`dealroom.py`/`dealroom.ts`复制到项目中。它会读取`.env`文件、发送请求头,并在收到`401`错误时自动刷新令牌——而原始curl在24小时令牌过期时不会执行此操作。这是任何程序、循环或多查询工具中的正确选择。
**两种方式的陷阱:永远不要在curl URL字符串中直接使用原始的`[ ] |`。** 对每个参数使用`-G --data-urlencode`(或代码片段的结构化参数)。URL中的裸括号是导致代理编写一次性转义脚本的最常见原因。Authentication
认证
- Flow: OAuth2 client-credentials (machine-to-machine). Exchange /
client_idfor a Bearer token, then send it on every call. The snippets do this for you.client_secret - Two mandatory headers on every request: and
Authorization: Bearer <token>(missing it is aX-Client-Id: <client_id>). A custom400is optional and useful for server-side observability, but it is not part of authentication.User-Agent - Token lifetime: 24h. Cache and reuse; do not mint per call. Snippets refresh on
. A key deactivated in the UI is rejected on its next request even while its token is still inside that 24h window, so a
401that survives one refresh means the key is dead, not expired: stop and tell the user rather than re-minting in a loop.401 - Mutations (POST / PATCH / PUT / DELETE) additionally need the relevant write/delete permission on the key.
- 流程: OAuth2客户端凭证(机器到机器)。将/
client_id兑换为Bearer令牌,然后在每次调用时发送。代码片段会自动完成此操作。client_secret - 每次请求必须包含两个请求头: 和
Authorization: Bearer <token>(缺少会返回X-Client-Id: <client_id>错误)。自定义400是可选的,有助于服务器端可观测性,但不属于认证的一部分。User-Agent - 令牌有效期: 24小时。缓存并复用;不要每次调用都生成。代码片段会在收到时刷新。即使令牌仍在24小时有效期内,在UI中已停用的密钥也会在下次请求时被拒绝,因此如果刷新一次后仍收到
401,则表示密钥已失效,而非过期:请停止操作并告知用户,而非循环生成令牌。401 - 修改操作(POST/PATCH/PUT/DELETE)还需要密钥具备相应的写入/删除权限。
A missing token does not fail loudly - check that your auth applied
缺少令牌不会明显报错 - 请检查认证是否生效
Read endpoints also serve anonymous callers (that is how public ecosystem pages work), so
a request with no or a dropped header returns with a thinner row rather
than . Two markers tell you which principal the API actually saw:
Authorization200401- -
page.tier/anonymous/free, alongsidepremiumandpage.capped. Present only for non-M2M callers on capped resources.page.ecosystem - - a top-level array of
locked[]for fields redacted (nulled, not omitted) at that tier, e.g.{ field, reason, unlock }. Added only when something was actually redacted.{ "field": "website", "reason": "ACCOUNT_REQUIRED", "unlock": "signup" }
A of or a on a call you made with a key means your
credentials did not apply. Fix the headers; do not report the nulls as missing data. M2M
callers are exempt from field redaction and from the per-tier page-size and pagination-depth
caps below, so a correctly authenticated response has neither marker.
page.tieranonymouslocked[]The default environment is beta. For other environments, swap the base URL, Auth0
host, and audience per this table. The OAuth2 is NOT the API base URL on
beta/production: the platform moved to but the Auth0 API identifier kept
its legacy value. Minting a token with the base URL as audience
fails.
audiencedealroom.appapi-next.*.dealroom.co| Environment | API base URL | Auth0 host | OAuth2 |
|---|---|---|---|
| Beta | | | |
| Production | | | |
| Staging | | | |
The former / hosts are retired
and no longer serve traffic - update any old base URLs to the hosts. The
strings live on only as Auth0 audience identifiers.
api-next.beta.dealroom.coapi-next.dealroom.codealroom.app读取端点也为匿名调用者提供服务(这是公共生态系统页面的工作方式),因此没有或丢失头的请求会返回,但返回的数据行更精简,而非错误。有两个标记可告诉你API实际识别的身份:
Authorization200401- -
page.tier/anonymous/free,与premium和page.capped一起返回。仅在非M2M调用者访问受限资源时出现。page.ecosystem - - 顶层数组,包含因当前层级而被编辑(设为null,而非省略)的字段,例如
locked[]。仅当实际有字段被编辑时才会添加。{ "field": "website", "reason": "ACCOUNT_REQUIRED", "unlock": "signup" }
如果使用密钥调用时返回为或出现,则表示你的凭据未生效。 请修复请求头;不要将null值报告为缺失数据。M2M调用者不受字段编辑限制,也不受下文所述的每层页面大小和分页深度限制,因此正确认证的响应不会包含这两个标记。
page.tieranonymouslocked[]默认环境为beta。对于其他环境,请根据下表替换基础URL、Auth0主机和audience。在beta/生产环境中,OAuth2的不是API基础URL:平台已迁移到,但Auth0 API标识符仍保留旧版的值。使用基础URL作为audience生成令牌会失败。
audiencedealroom.appapi-next.*.dealroom.co| 环境 | API基础URL | Auth0主机 | OAuth2 |
|---|---|---|---|
| Beta | | | |
| 生产环境 | | | |
| Staging | | | |
旧版/主机已停用,不再提供服务——请将任何旧的基础URL更新为主机。这些字符串仅作为Auth0 audience标识符保留。
api-next.beta.dealroom.coapi-next.dealroom.codealroom.appAPI versioning
API版本控制
The API is date-versioned (Stripe-style). Send an optional
header to pin behavior; omit it to get the latest version (what new integrations
should do). Clients pinned to an older date keep their old request/response shapes via
server-side transforms until that version's sunset date, so existing code does not break
when the API moves.
API-Version: YYYY-MM-DDThere is no path prefix. Every namespace is served at the root of the API
host: , , , , . Old
URLs from earlier integrations are permanently redirected (, all
versions, no sunset), so they still work - but write new code against the root paths
and drop from any base URL you find in existing code.
/api/data/*/analytics/*/reference/*/platform/*/system/*/api/*308/apiEvery breaking change, deprecation, and addition is listed in the
changelog with the version
date and affected endpoints. If you are returning to a project built against an earlier
version of this skill, or anything here looks stale, read the changelog first - it is
the fastest way to see what moved. This skill deliberately keeps no per-version change
list: the live changelog is the single source of truth for what changed when.
API采用日期版本控制(Stripe风格)。发送可选的头以固定行为;省略该头将获取最新版本(新集成应采用此方式)。固定到旧版本的客户端将通过服务器端转换保留其旧的请求/响应结构,直到该版本的终止日期,因此现有代码不会因API更新而中断。
API-Version: YYYY-MM-DD没有路径前缀。 所有命名空间都在API主机的根目录下提供:、、、、。早期集成中的旧版URL会被永久重定向(,所有版本,无终止日期),因此它们仍然有效——但请针对根路径编写新代码,并从现有代码中删除前缀。
/api/data/*/analytics/*/reference/*/platform/*/system/*/api/*308/api所有重大变更、弃用和新增功能都列在**变更日志**中,包含版本日期和受影响的端点。如果你回到基于本技能早期版本构建的项目,或者此处内容看起来过时,请首先阅读变更日志——这是查看变更内容的最快方式。本技能刻意不保留每个版本的变更列表:实时变更日志是变更内容的唯一事实来源。
Constructing queries
构建查询
Filter grammar
过滤器语法
All list and aggregate endpoints take a query parameter:
filtertext
filter=key[op]:value # single
filter=and(key1[op]:val1,key2[op]:val2) # AND (comma-separated args)
filter=or(key1[op]:val1,key2[op]:val2) # OR
filter=and(tag_id[eq]:42,or(location[eq]:1234,location[eq]:5678)) # nestedOperators: , , , , , , and the multi-value /
/ / (pipe-separated, e.g. ). /
apply only to junction filters (tags, growth stages). Booleans are strings ( /
). Relationship-path filters reach related entities with (one hop) and
(two hops), e.g. , .
eqneqgtgteltltein_anyin_allnin_anynin_alltag_id[in_any]:1|2|3in_allnin_alltruefalse.__founder.gender[eq]:femalefunding_round__investor.total_invested[gt]:1000000Entity classification (the legacy flags were removed): is
or ; is , , ,
or ; role flags / / / stack
on top. So "companies" is , "investment firms" is
, "people" is . (The investor-firm
subtype was renamed from to ; now refers only to the investment
vehicle and is no longer a valid value.)
is_companytypeorganizationpersonorganization_subtypecompanyinvestoruniversitygov_ngois_investoris_founderis_executiveis_partnerorganization_subtype[eq]:companyorganization_subtype[eq]:investortype[eq]:personfundinvestorfundorganization_subtypeThe exact key list, operators, and value types per scope are not memorized here. Discover
them live (next section) or read the
Filters & Sorting reference.
所有列表和聚合端点都接受查询参数:
filtertext
filter=key[op]:value # 单个条件
filter=and(key1[op]:val1,key2[op]:val2) # AND(逗号分隔参数)
filter=or(key1[op]:val1,key2[op]:val2) # OR
filter=and(tag_id[eq]:42,or(location[eq]:1234,location[eq]:5678)) # 嵌套条件运算符:、、、、、,以及多值运算符///(竖线分隔,例如)。/仅适用于关联过滤器(标签、成长阶段)。布尔值为字符串(/)。关系路径过滤器使用(单跳)和(双跳)访问关联实体,例如、。
eqneqgtgteltltein_anyin_allnin_anynin_alltag_id[in_any]:1|2|3in_allnin_alltruefalse.__founder.gender[eq]:femalefunding_round__investor.total_invested[gt]:1000000实体分类(旧版标志已移除):为或;为、、或;角色标志///可叠加。因此“公司”对应,“投资公司”对应,“人物”对应。(投资公司子类型已从重命名为;现在仅指投资载体,不再是有效的值。)
is_companytypeorganizationpersonorganization_subtypecompanyinvestoruniversitygov_ngois_investoris_founderis_executiveis_partnerorganization_subtype[eq]:companyorganization_subtype[eq]:investortype[eq]:personfundinvestorfundorganization_subtype每个范围的准确键列表、运算符和值类型未在此处记忆。请在运行时发现(下一节)或阅读过滤器与排序参考。
Discover filters and resolve IDs (do not guess)
发现过滤器并解析ID(不要猜测)
There are two ID families - never mix them up:
- Taxonomy IDs are numeric (locations, industries, tags, degrees, backgrounds), not
strings: returns nothing;
location[eq]:United+Statesworks.location[eq]:233 - Entity IDs are UUIDs - every path param and every entity-reference filter (
{id},entity_id,investor_id,company_investor_id, and relationshipportfolio_company_idpaths like.id). An integer where a UUID is expected fails validation or matches nothing.founder__university.id
Discover and resolve at runtime:
bash
GET /reference/filters?scope=companies # valid filter keys, operators, types, data status
GET /reference/filters/location/values?q=netherlands # resolve a location to its ID
GET /reference/filters/tag_id/values?q=climate # resolve a tag across ALL taxonomy types
GET /reference/filters/search?q=climate&scope=companies # one-shot value search across every filter keyValid scopes: , , , , , ,
. Cache resolved IDs in your app; taxonomy changes rarely.
companiesinvestorstransactionspeopleuniversitiesnewsjobsBuild filters from , not the displayed . returns tag
entries whose is category-qualified (, ,
, ...) but whose is the bare . The filter grammar
only accepts the bare form: works; throws
("Expected LBRACKET but got COLON"). Always construct filter
expressions from each entry's .
filter_keykey/reference/filterskeytag_id:sectortag_id:industrytag_id:technologyfilter_keytag_idtag_id[eq]:2181301tag_id:sector[eq]:2181301FILTER_PARSE_ERRORfilter_keyResolve tags without forcing a . A tag's category is not always what you expect -
"Climate Tech" is a , not an , so
returns . Omit to search every taxonomy at once; each result is labelled with its
own . Only pass to disambiguate. Note: do not trust from these
value lookups (it can read even for tags that match hundreds of entities on beta) -
confirm real counts with the list call's .
typesectorindustry…/values?q=climate&type=industry[]typetypetypeentity_count0page.total有两类ID——切勿混淆:
- 分类ID为数字(地点、行业、标签、学位、背景),而非字符串:返回空结果;
location[eq]:United+States有效。location[eq]:233 - 实体ID为UUID——每个路径参数和每个实体引用过滤器(
{id}、entity_id、investor_id、company_investor_id,以及关系路径如portfolio_company_id)。在需要UUID的位置使用整数会导致验证失败或无匹配结果。founder__university.id
在运行时发现并解析:
bash
GET /reference/filters?scope=companies # 有效的过滤器键、运算符、类型、数据状态
GET /reference/filters/location/values?q=netherlands # 将地点解析为ID
GET /reference/filters/tag_id/values?q=climate # 跨所有分类类型解析标签
GET /reference/filters/search?q=climate&scope=companies # 一次性搜索所有过滤器键的值有效范围:、、、、、、。在应用中缓存解析后的ID;分类变更很少见。
companiesinvestorstransactionspeopleuniversitiesnewsjobs从构建过滤器,而非显示的。 返回的标签条目其带有类别限定(、、等),但为裸。过滤器语法仅接受裸形式:有效;会抛出(“Expected LBRACKET but got COLON”)。始终从每个条目的构建过滤器表达式。
filter_keykey/reference/filterskeytag_id:sectortag_id:industrytag_id:technologyfilter_keytag_idtag_id[eq]:2181301tag_id:sector[eq]:2181301FILTER_PARSE_ERRORfilter_key无需指定即可解析标签。 标签的类别并非总是如你预期——“Climate Tech”是,而非,因此返回。省略以搜索所有分类;每个结果都会标记其自身的。仅在需要消除歧义时传递。注意:不要信任这些值查找中的(在beta环境中,即使标签匹配数百个实体,它也可能显示为)——请通过列表调用的确认真实计数。
typesectorindustry…/values?q=climate&type=industry[]typetypetypeentity_count0page.totalPagination, sorting, currency
分页、排序、货币
- Pagination: offset-based (/
limit). Some list responses also returnoffsetfor keyset pagination; round-trip it opaquely.page.next_cursorskips the count for faster lists.include_total=false - Pagination depth is capped for non-M2M callers. above the caller's tier ceiling (anonymous 750 / free 5,000 / premium 50,000, raisable per ecosystem) is a
offset + limit400on both the offset and cursor paths - an error, not a silent clamp. M2M keys are exempt. Page size, by contrast, clamps silently for non-M2M callers and reports it viaPAGINATION_DEPTH_EXCEEDED.page.capped - Sorting: (prefix
sort=-total_funding,namefor descending, comma-separated).- - Currency: converts thresholds and amounts (default USD). Field names stay base names (no
?currency=<ISO 4217>suffix); every response has a top-level_usd.currency
Limit maximums, sort columns, and response field lists vary by endpoint and are documented
in the OpenAPI spec, not here.
- 分页: 基于偏移量(/
limit)。某些列表响应还返回offset用于键集分页;请直接往返传递该值。page.next_cursor可跳过计数以加快列表加载速度。include_total=false - 非M2M调用者的分页深度受限。 超过调用者层级上限(匿名用户750/免费用户5,000/付费用户50,000,可按生态系统提升)会在偏移量和游标路径上返回
offset + limit错误400——这是错误,而非静默截断。M2M密钥不受此限制。相比之下,页面大小会对非M2M调用者进行静默截断,并通过PAGINATION_DEPTH_EXCEEDED报告。page.capped - 排序: (前缀
sort=-total_funding,name表示降序,逗号分隔)。- - 货币: 转换阈值和金额(默认USD)。字段名称保持基础名称(无
?currency=<ISO 4217>后缀);每个响应都包含顶层_usd字段。currency
限制最大值、排序列和响应字段列表因端点而异,记录在OpenAPI规范中,而非此处。
Live references
实时参考
These are the single source of truth. Fetch the slice you need ( or ); do
not paste whole pages or the full spec into context.
WebFetchcurl| Need | Where |
|---|---|
| Enumerate namespaces / resources at runtime | |
| Exact request/response shape for any endpoint | |
| Browsable endpoint reference | the API Reference tab on |
| Guides + concepts (filtering, aggregates, pagination, rate limits) | |
| Full filter + sorting catalog | |
| Known limitations (stub / no-data endpoints + filters) | |
| Changelog (breaking changes, deprecations, new features per version) | |
| MCP server (Dealroom data as MCP tools for agent clients) | |
Some advertised endpoints and filters are stubbed or not fully data-loaded yet, and the
set changes over time. Check the known-limitations page, the extension in
the OpenAPI spec, or the field from
before relying on a surface in production.
x-data-statusdata_statusGET /reference/filters?scope=<scope>这些是唯一的事实来源。获取你需要的部分(或);不要将整个页面或完整规范粘贴到上下文中。
WebFetchcurl| 需求 | 来源 |
|---|---|
| 在运行时枚举命名空间/资源 | |
| 任何端点的确切请求/响应形状 | |
| 可浏览的端点参考 | |
| 指南+概念(过滤、聚合、分页、速率限制) | |
| 完整过滤器+排序目录 | |
| 已知限制(存根/无数据端点+过滤器) | |
| 变更日志(重大变更、弃用、每个版本的新功能) | |
| MCP服务器(作为代理客户端MCP工具的Dealroom数据) | |
某些宣传的端点和过滤器是存根或尚未完全加载数据,且集合会随时间变化。在生产环境中依赖某个功能之前,请检查已知限制页面、OpenAPI规范中的扩展,或返回的字段。
x-data-statusGET /reference/filters?scope=<scope>data_statusCommon errors
常见错误
| Symptom | Cause and fix |
|---|---|
| Token expired (24h). The snippet auto-refreshes. |
| The key was deactivated or deleted. Re-minting will not help; ask the user to check https://beta.dealroom.app/settings/api. |
| The required client-id header is missing or does not match the token. |
| Filter key wrong for this scope. Call |
| Enum filter value outside the known set ( |
| |
| The call was treated as anonymous or free. Your credentials did not apply - fix the headers. |
Empty | The value did not resolve to a real ID. Look it up via |
| Rate limit. Back off, honor |
| 15s query timeout. Narrow the filter or set |
| 症状 | 原因及修复 |
|---|---|
| 令牌过期(24小时)。代码片段会自动刷新。 |
刷新一次后仍返回 | 密钥已停用或删除。重新生成令牌无济于事;请告知用户检查https://beta.dealroom.app/settings/api。 |
| 缺少必需的client-id请求头,或请求头与令牌不匹配。 |
| 过滤器键对当前范围无效。请调用 |
| 枚举过滤器值不在已知集合中( |
| |
| 调用被视为匿名或免费用户。你的凭据未生效——请修复请求头。 |
看似合理的过滤器返回空 | 值未解析为真实ID。请通过 |
| 速率限制。请后退,遵守 |
| 15秒查询超时。请缩小过滤器范围或设置 |
Early access: data caveat
早期访问:数据说明
This skill targets , where data may be refreshed or partially
loaded. If a single result looks off, say so honestly rather than inventing an explanation,
and sanity-check the same query in the production Dealroom UI before debugging further.
api.beta.dealroom.app本技能针对,其中数据可能会刷新或部分加载。如果单个结果看起来异常,请如实告知,而非编造解释,并在调试前在生产环境的Dealroom UI中验证相同查询。
api.beta.dealroom.appWhen the API disagrees with this skill
当API与本技能描述不符时
This is an early-access API: endpoints, filter keys, fields, response shapes, and auth
details can change without notice. The live API and its docs are authoritative; this
skill is not. When reality and this skill conflict, trust the API and surface the gap.
Treat these as drift signals (not normal data issues):
- A path documented here returns /
404, or a method that worked is rejected.405 - A filter key this skill names returns on a scope where it should work.
UNKNOWN_FILTER - The response envelope differs from what is described (e.g. renamed, fields missing or restructured,
pageshape changed).data - Valid credentials no longer authenticate (header names, audience, or token flow changed).
- or the published OpenAPI spec (
GET /reference/filters?scope=<scope>) advertise endpoints/filters this skill does not mention, or omit ones it does.developers.beta.dealroom.co/openapi.yaml
When you hit one:
- Do not paper over it with hardcoded values, guessed keys, or silent workarounds.
- Confirm against the source of truth: for filters, the published OpenAPI spec (
GET /reference/filters?scope=<scope>) for paths and shapes. A one-offdevelopers.beta.dealroom.co/openapi.yaml/400or empty result is usually data, not drift; a structural mismatch is reproducible.5xx - If the live state genuinely diverges from this skill, stop and tell the user
plainly, for example: "The Dealroom API now behaves differently from what the
skill describes (
dealroom-early-access-api). I verified this against<what changed>and the published OpenAPI spec. The skill looks out of date." Then proceed using the live behavior, and recommend the user update the skill (or open a PR to/reference/filters) so it stays accurate.dealroom-ai/agent-skills
这是一个早期访问API:端点、过滤器键、字段、响应结构和认证详情可能会随时更改,恕不另行通知。实时API及其文档具有权威性;本技能不具备。 当实际情况与本技能描述冲突时,请以API为准并指出差异。
将这些视为漂移信号(而非正常数据问题):
- 此处记录的路径返回/
404,或曾经有效的方法被拒绝。405 - 本技能提及的过滤器键在其应适用的范围中返回。
UNKNOWN_FILTER - 响应结构与描述不符(例如重命名、字段缺失或重构、
page结构更改)。data - 有效的凭据不再能通过认证(请求头名称、audience或令牌流程更改)。
- 或已发布的OpenAPI规范(
GET /reference/filters?scope=<scope>)宣传了本技能未提及的端点/过滤器,或省略了本技能提及的内容。developers.beta.dealroom.co/openapi.yaml
当遇到上述情况时:
- 不要用硬编码值、猜测的键或静默变通方法掩盖问题。
- 根据事实来源确认: 过滤器请查看,路径和结构请查看已发布的OpenAPI规范(
GET /reference/filters?scope=<scope>)。一次性的developers.beta.dealroom.co/openapi.yaml/400错误或空结果通常是数据问题,而非漂移;结构不匹配是可重现的。5xx - 如果实际状态确实与本技能描述不符,请直接告知用户,例如:“Dealroom API现在的行为与技能描述的不同(<变更内容>)。我已通过
dealroom-early-access-api和已发布的OpenAPI规范验证了这一点。该技能已过时。”然后按照实际行为继续操作,并建议用户更新该技能(或向/reference/filters提交PR)以保持准确性。dealroom-ai/agent-skills