gohiam.com

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.

In a hurry? Get a key at your account page, then 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

ParameterWhat it does
$topPage 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.
$skipOffset into the result.
$filterField eq 'value', and ne gt ge lt le like in notin, joined with and / or. Lists are quoted: Tag in ('fintech','insurtech').
$selectWhich fields to return. Worth using: fewer fields is a faster query and a smaller response, for the same credit.
$expandPull related objects in the same request — a company with its rounds, a signal with its subject — instead of paying for a second call.
$orderbyField or Field desc.
$countReturn 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.

DimensionKindApplies toWhat it is
industryopenstartups, fundsSector tags. A company usually carries several.
country region cityopenstartups, fundsParts of a registered address. A company with offices in two countries appears under both.
stageclosedstartupsSeries of the most recent confirmed round.
next_stageclosedstartupsSeries expected next. A prediction, not a fact.
investment_stageclosedfundsStages the fund says it writes cheques at.
investor_typeclosedfundsVenture fund, accelerator, private equity, fund of funds.
team_sizeclosedstartups, fundsHeadcount bucket.
operating_statusclosedstartups, fundsActive or probably closed — inferred from the site and socials going quiet, not from a filing.
exit_statusclosedstartupsHeld, exited or acquired. Recorded per investor, so a company can appear under more than one.
founded_yearnumberstartups, fundsYear founded.
fund_groupopenfundsEditorial groupings.
round_seriesopenroundsSeries as written in the source.
round_yearnumberroundsYear 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.

Any other dimension narrows the set first. That second example above is cities in Germany, beginning with "ber", counted over German companies only — not cities everywhere and, separately, Germany. Combine as many as you like. This is what turns a list into a facet, and it is the most useful thing on this page.

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.
The feed is ordered and paged by 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

TypeCarriesWhat it means
round.recordedamount, seriesA confirmed round was recorded against a company. The highest-value signal here.
round.updatedamount, seriesA known round was corrected — usually the amount firming up once a primary source appeared.
investor.joined_roundamount, seriesAn investor was attached to a round. Normally after the round itself: syndicates surface gradually.
valuation.recordedamountA post-money valuation. Sparse — valuations are disclosed far less often than round sizes.
portfolio.company_addedA company appeared in a fund's portfolio. Often the first public trace of an unannounced investment.
portfolio.exit_recordedA holding was marked exited or acquired.
startup.added / fund.addedSomething entered the database that was not there before.
startup.updated / fund.updatedA profile changed. The signal says that something moved, not which field.
team.person_addedSomeone joined a fund's team. A new partner is a change of mandate more often than not.
news.mentionA 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
ParameterWhat it does
typesComma-separated. Narrowing this is the biggest single saving.
since untilBounds on detectedAt.
occurredSince occurredUntilBounds on occurredAt.
subjectCompany or fund ids, comma-separated. This is how you watch a portfolio.
minAmountUS dollars. Excludes the types that carry no amount.
cursorThe nextCursor from the previous page.
orderasc to follow the feed forward, desc (default) to browse recent history.
limitUp to 200.
expandsubject, object, or both — adds names so you do not need a lookup per row.
any dimensionThe 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

  1. First run: order=asc with since= the date you started caring, no cursor.
  2. Store nextCursor — the cursor, not a timestamp. It never expires.
  3. Next run: the same parameters plus cursor=. Repeat while hasMore is true.
  4. id is derived from the change itself, not from when you read it, so re-reading an overlapping window is safe. Deduplicate on id and 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:

FieldOnTakes
Tagstartups, fundsAn industry tag.
Country Region Citystartups, fundsParts of an address.
LastFundingStage NextFundingStagestartupsA stage.
MembersCountstartups, fundsA headcount — we bucket it for you.
MembersCountBucketstartups, fundsA bucket, as the categories API returns them.
StatusstartupsExit status of an investor relationship.
InvestmentStage InvestmentTypefundsThe fund's stated mandate.
Group.NamefundsAn editorial grouping.
Keywordsstartups, fundsFull text across the profile.
Year Investor StartuproundsRound year, or the id of a participant.

6. Errors and limits

StatusMeaning
400Something 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.
401Key missing, revoked or expired.
403The key is valid but not entitled to that endpoint.
429Out 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 recordEndpoints
1 flatSearch and autocomplete, /v2/categories and its facets, tag and location lookups, totals — whatever they return
1Startups, funds, people
0.5Funding rounds, valuations, portfolios, the people at a company
0.25News, signals, mentions, tweets
25 / 10/find (a live crawl) and /venturematching (an ML pass)
0Dictionaries, /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/facets call 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/startups is one per row. $select does not make a record cheaper.
  • Use $expand rather 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. $top is the bill. An unread hundred is a hundred credits.
  • Narrow types on 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].