API reference
Venture capital data over HTTP: startups, investors, funding rounds, valuations, the people behind them, and the news that mentions them. Everything the site shows, plus a good deal it does not.
GET https://vcapi.parsers.vc/v2/startups?$top=5 with an
X-Api-Key header. Everything below is detail.
1. Getting a key and using it
Two hosts. The data lives on https://vcapi.parsers.vc/v2; the endpoints that hand
out keys live on https://parsers.vc/api/v1.
Create a key at https://parsers.vc/account/. It looks
like pk_live_… and is shown once — we store only its digest, so if you
lose it the remedy is a new one. You can revoke a key at any time from the same page; revocation
takes effect within a minute.
GET https://vcapi.parsers.vc/v2/funds?$top=25&$filter=Country in ('Germany')
X-Api-Key: pk_live_…
Authorization: Bearer <key> works too, if that is what your HTTP client makes
easy.
Letting an assistant get its own key
An AI assistant can register on your behalf without you filling in anything. It calls
POST /api/v1/auth/register with your address; we e-mail you a six digit code and a
sign-in link. Read the code back to it and it finishes with
POST /api/v1/auth/verify — or, if you would rather not share the code, open
the link, create a key at your account page and paste
that instead. Either way you end up with the same 500 requests a month, on an account you own
and can revoke from.
A key minted that way expires after 30 days, because it was created inside a conversation. Registering again against the same address gives a fresh key on the same account, not a second allowance. Keys you create yourself on the account page do not expire.
What a request costs
A credit buys a record, not a call. A page of a hundred companies costs a hundred; the
same call returning one costs one. Search, facets and dictionaries are the exception —
those are a flat credit whatever they return, which is why resolving a name through
/search is the cheap way to do it. The rate card is in
section 7. 500 credits a month are free.
Every response tells you where you stand, so checking never costs a call:
X-Credits-Charged: 25 X-RateLimit-Limit: 500 X-RateLimit-Remaining: 462 X-RateLimit-Reset: 1791244800
GET https://parsers.vc/api/v1/usage with the same header returns the same numbers
as JSON, and your account page shows 30 days of usage
broken down by endpoint.
2. Query conventions
| Parameter | What it does |
|---|---|
$top | Page size, and on a record-priced endpoint the bill with it. The ceiling is your plan's: 100 on Free, up to 5,000 on Enterprise. Defaults to 25. |
$skip | Offset into the result. |
$filter | Field eq 'value', and ne gt ge lt le like in notin, joined with and / or. Lists are quoted: Tag in ('fintech','insurtech'). |
$select | Which fields to return. Worth using: fewer fields is a faster query and a smaller response, for the same credit. |
$expand | Pull related objects in the same request — a company with its rounds, a signal with its subject — instead of paying for a second call. |
$orderby | Field or Field desc. |
$count | Return the number of matches instead of the rows. |
Dates are ISO 8601 in UTC. Money is US dollars, normalised from whatever currency the source used, as a whole number of dollars.
3. Browsing by category
The collections answer tell me about this company. This part answers the question that usually comes first: what is actually in here, how is it divided up, and how big is each piece — before you commit to a query and find out there were four matches.
3.1 What axes exist
GET /v2/categories GET /v2/categories?entity=funds
A dimension is one way of slicing the data. Some are closed — a fixed list, and this endpoint gives you every value up front. Others are open: whatever the data happens to contain, which you list separately.
| Dimension | Kind | Applies to | What it is |
|---|---|---|---|
industry | open | startups, funds | Sector tags. A company usually carries several. |
country region city | open | startups, funds | Parts of a registered address. A company with offices in two countries appears under both. |
stage | closed | startups | Series of the most recent confirmed round. |
next_stage | closed | startups | Series expected next. A prediction, not a fact. |
investment_stage | closed | funds | Stages the fund says it writes cheques at. |
investor_type | closed | funds | Venture fund, accelerator, private equity, fund of funds. |
team_size | closed | startups, funds | Headcount bucket. |
operating_status | closed | startups, funds | Active or probably closed — inferred from the site and socials going quiet, not from a filing. |
exit_status | closed | startups | Held, exited or acquired. Recorded per investor, so a company can appear under more than one. |
founded_year | number | startups, funds | Year founded. |
fund_group | open | funds | Editorial groupings. |
round_series | open | rounds | Series as written in the source. |
round_year | number | rounds | Year the round was announced. |
Closed dimensions take the label, the slug or the code name interchangeably:
Series A, series-a and SeriesA all mean the same thing.
3.2 The values on one axis
GET /v2/categories/industry?entity=startups&top=50 GET /v2/categories/city?entity=startups&country=Germany&q=ber
Values come back most common first, each with a value to send back and a
label to show. q is a prefix search; put a * in front to
search anywhere in the value. counts=false skips the counting and is cheaper.
3.3 Several axes at once
GET /v2/categories/facets?entity=startups&dimensions=industry,stage,country&country=Germany
One request, one credit, one count per dimension. Use it to size a segment before you query it.
Leave dimensions out to get every closed dimension for that entity; at most ten per
request.
A dimension is never constrained by its own selection: asking for industry while
filtering on industry=fintech shows you the alternatives, which is what a filter
sidebar needs, rather than echoing your own choice back.
3.4 The companies themselves
GET /v2/categories/industry/fintech/startups?country=Germany&stage=series-a
&$top=25&$select=Name,Website,TotalRaised&$orderby=TotalRaised desc
This is /v2/startups with the category conditions applied — the same query,
not a second one that might drift — so $select, $expand,
$orderby, $filter and paging all behave exactly as they do there. The
path is /v2/categories/{dimension}/{value}/{startups|funds|rounds}, and extra
dimensions on the query string stack with the one in the path.
4. Following what changes
A single feed of everything that moved: rounds recorded, investors attached, portfolios updated, valuations disclosed, companies and funds appearing and changing. Use it to watch a sector, a country, a portfolio or one company without re-fetching anything.
4.1 Two clocks
Every signal carries both, and they are rarely the same day:
occurredAt— when it happened in the market. The date to show a reader.detectedAt— when this database recorded it.
detectedAt, always. Venture news arrives late and
out of order: a round announced three weeks ago is written down today. Poll on the market date
and you will never see it, because it sorts into the past. occurredAt is
filterable, and it is the honest date to display — but it can never be the cursor.
4.2 What you can watch
| Type | Carries | What it means |
|---|---|---|
round.recorded | amount, series | A confirmed round was recorded against a company. The highest-value signal here. |
round.updated | amount, series | A known round was corrected — usually the amount firming up once a primary source appeared. |
investor.joined_round | amount, series | An investor was attached to a round. Normally after the round itself: syndicates surface gradually. |
valuation.recorded | amount | A post-money valuation. Sparse — valuations are disclosed far less often than round sizes. |
portfolio.company_added | A company appeared in a fund's portfolio. Often the first public trace of an unannounced investment. | |
portfolio.exit_recorded | A holding was marked exited or acquired. | |
startup.added / fund.added | Something entered the database that was not there before. | |
startup.updated / fund.updated | A profile changed. The signal says that something moved, not which field. | |
team.person_added | Someone joined a fund's team. A new partner is a change of mandate more often than not. | |
news.mention | A company or investor was mentioned in a news item tied back to it. |
GET /v2/signals/types returns the same list with descriptions, machine-readable.
4.3 Reading the feed
GET /v2/signals?types=round.recorded&industry=fintech&country=Germany
&minAmount=5000000&order=asc&limit=100&expand=subject
| Parameter | What it does |
|---|---|
types | Comma-separated. Narrowing this is the biggest single saving. |
since until | Bounds on detectedAt. |
occurredSince occurredUntil | Bounds on occurredAt. |
subject | Company or fund ids, comma-separated. This is how you watch a portfolio. |
minAmount | US dollars. Excludes the types that carry no amount. |
cursor | The nextCursor from the previous page. |
order | asc to follow the feed forward, desc (default) to browse recent history. |
limit | Up to 200. |
expand | subject, object, or both — adds names so you do not need a lookup per row. |
| any dimension | The same vocabulary as section 3: ?industry=fintech&country=Germany. |
{
"signals": [{
"id": "8f2c1d3e-...",
"type": "round.recorded",
"detectedAt": "2026-09-04T11:02:19Z",
"occurredAt": "2026-08-28T00:00:00Z",
"subject": { "type": "startup", "id": "...", "name": "Acme", "domain": "acme.io" },
"object": { "type": "round", "id": "..." },
"amount": 12000000,
"label": "Series A"
}],
"nextCursor": "MTc5MTI0...",
"hasMore": true,
"order": "asc"
}
4.4 Keeping a watchlist in step
- First run:
order=ascwithsince=the date you started caring, no cursor. - Store
nextCursor— the cursor, not a timestamp. It never expires. - Next run: the same parameters plus
cursor=. Repeat whilehasMoreis true. -
idis derived from the change itself, not from when you read it, so re-reading an overlapping window is safe. Deduplicate onidand you cannot double-count.
Hourly is as often as it is worth polling; the crawlers do not produce meaningful change faster than that.
5. The collections
For when you already know what you are looking for.
GET /v2/startups GET /v2/startups/{id}
GET /v2/startups/search?query= GET /v2/startups/{id}/references
GET /v2/startups/fundingrounds GET /v2/startups/{id}/fundingrounds
GET /v2/startups/postvaluations GET /v2/startups/tags/search?contains=
GET /v2/funds GET /v2/funds/{id}
GET /v2/funds/search?query= GET /v2/funds/{id}/portfolio
GET /v2/persons GET /v2/persons/{id}
GET /v2/news GET /v2/companies/search?query=
To turn a name or a domain into an id, use /v2/companies/search?query=. Ids are
opaque; do not try to construct them.
Filter fields that are worth knowing because you would not guess them:
| Field | On | Takes |
|---|---|---|
Tag | startups, funds | An industry tag. |
Country Region City | startups, funds | Parts of an address. |
LastFundingStage NextFundingStage | startups | A stage. |
MembersCount | startups, funds | A headcount — we bucket it for you. |
MembersCountBucket | startups, funds | A bucket, as the categories API returns them. |
Status | startups | Exit status of an investor relationship. |
InvestmentStage InvestmentType | funds | The fund's stated mandate. |
Group.Name | funds | An editorial grouping. |
Keywords | startups, funds | Full text across the profile. |
Year Investor Startup | rounds | Round year, or the id of a participant. |
6. Errors and limits
| Status | Meaning |
|---|---|
400 | Something in the request is wrong. The body names the field and points at the endpoint that lists the valid values. Retrying unchanged will not help. |
401 | Key missing, revoked or expired. |
403 | The key is valid but not entitled to that endpoint. |
429 | Out of credits — not rate limiting. See below. |
{
"error": { "code": "credits_exhausted", "message": "..." },
"credits": { "limit": 500, "remaining": 12, "required": 100, "plan": "free",
"reset": "2026-10-01T00:00:00Z" },
"actions": [
{ "type": "purchase_credits", "url": "https://parsers.vc/api_page/pricing/" },
{ "type": "reduce_page_size", "parameter": "$top" },
{ "type": "wait", "until": "2026-10-01T00:00:00Z" }
]
}
It is a 429 rather than a 403 on purpose: this is a "come back later",
not a permissions problem, and clients — software and AI assistants alike — treat
the two very differently. The actions array is there so a program can offer the fix
without parsing English. required against remaining tells you
whether asking for a smaller page would get through.
7. What a request costs
A credit buys a record, not a call. The full table, plan by plan and endpoint by
endpoint, is at /api_page/pricing/, and
GET /v2/pricing returns the same thing as JSON, free. The short version:
| Per record | Endpoints |
|---|---|
| 1 flat | Search and autocomplete, /v2/categories and its facets, tag and location lookups, totals — whatever they return |
| 1 | Startups, funds, people |
| 0.5 | Funding rounds, valuations, portfolios, the people at a company |
| 0.25 | News, signals, mentions, tweets |
| 25 / 10 | /find (a live crawl) and /venturematching (an ML pass) |
| 0 | Dictionaries, /v2/pricing, and every error response |
Each $expand adds 25% to the per-record weight. The final figure comes back on
the response as X-Credits-Charged.
Spending credits well
- Size the segment first. One
/v2/categories/facetscall tells you how big every slice is, for one credit. Finding that out by fetching the rows costs one per row. - Resolve names through
/search. Turning a company name into an id is one credit however many candidates come back; pulling the same list out of/v2/startupsis one per row.$selectdoes not make a record cheaper. - Use
$expandrather than a second pass. A company with its investors is 1.25 credits; fetching them separately is 1 plus a round each. - Ask for the page you will actually read.
$topis the bill. An unread hundred is a hundred credits. - Narrow
typeson the feed. An unfiltered feed spends its page on profile updates, and you pay again for the page that had the round in it.
8. Worked examples
A map of a sector before you commit to it
# How big is European fintech, and where is it?
GET /v2/categories/facets?entity=startups&dimensions=country,stage,team_size&industry=fintech
# Then the cities, within the country that looked interesting
GET /v2/categories/city?entity=startups&industry=fintech&country=Germany&top=20
# Then the companies
GET /v2/categories/industry/fintech/startups?country=Germany&stage=seed
&$select=Name,Website,Founded,TotalRaised&$orderby=TotalRaised desc&$top=50
Three calls, three credits, and you never guessed at a value.
A deal-flow watchlist
# Every seed and Series A round in German fintech over $1m, oldest first
GET /v2/signals?types=round.recorded&industry=fintech&country=Germany
&minAmount=1000000&order=asc&since=2026-01-01&expand=subject
# Next run, and every run after that
GET /v2/signals?types=round.recorded&industry=fintech&country=Germany
&minAmount=1000000&order=asc&expand=subject&cursor=<stored nextCursor>
Watching a portfolio
# Anything at all about these twelve companies GET /v2/signals?subject=<id>,<id>,<id>&order=asc&cursor=<stored>&expand=subject,object
Rounds, valuations, exits, team changes and press for a whole portfolio in one poll. Signals
are a quarter credit each and the two $expands add half again, so a full page of
50 is 19 credits; drop the expands, or narrow types, and it is 13.
Researching an investor
GET /v2/funds/search?query=index%20ventures
GET /v2/funds/{id}?$expand=Tags,InvestmentStages,InvestmentTypes,Addresses
GET /v2/funds/{id}/portfolio?$top=100
GET /v2/signals?types=portfolio.company_added,investor.joined_round&subject={id}&limit=50
The last call is the interesting one: what this fund has been doing lately, rather than what it says about itself.
9. If you are handing this to an AI assistant
Point it at https://parsers.vc/api/v1/agents.md — the same API described in a flat, unambiguous form, including how to register itself, how to read the error bodies, and how not to waste your credits. There is a human-readable walkthrough of the same at /api_page/ai/, and a page for the person on the other side of the conversation — which assistants work, what the two minutes of setup look like, what to do when it gets stuck — at /api_page/assistants/.
A machine-readable description of every endpoint is at https://parsers.vc/api/v1/openapi.json (OpenAPI 3.0).
Questions: [email protected].