Primitive/company-data3 min read

Introducing /company-data: funding, headcount and tech stack in one record

Search private companies by industry and geography, then enrich one into a single record — firmographics from LinkedIn, funding, investors and a real detected tech stack from Crunchbase and BuiltWith, with sources reported per response.

Company data primitive →Read the docs →

Primitive/company-data
TL;DR
  • /company-data search private companies by industry and geography; enrich one by domain, name or Crunchbase id
  • One vendor, several datasets: LinkedIn firmographics, plus Crunchbase funding and a BuiltWith tech stack behind include_signals
  • Every response reports `sources`, so you can tell a full record from a degraded one
  • Search REFUSES funding, stage and headcount filters instead of dropping them, because the search dataset has no such fields
  • A search result is a strict subset of an enrich result, so the cheap endpoint cannot be used to get the dear one's data

Most company-data APIs make you choose: funding history from one vendor, technographics from another, and a join you write yourself. /company-data does the join, on one token and one bill.

One vendor, several datasets — and the response says which

provider is always apify: one vendor, one credential, one invoice. sources is a different question — which datasets contributed:

FieldsDataset
name, domain, industry, headcount, founded, company type, locationLinkedIn
stage, total funding, round count, last round date, investors, tech stackCrunchbase (+ BuiltWith)

That distinction is not pedantry. Calling Crunchbase a "provider" would claim a commercial relationship Naïve does not have; collapsing the field to apify would throw away the one thing a caller needs from it — whether the funding lookup matched.

naive company-data enrich --domain stripe.com --include-signals

The funding overlay is best-effort, and admits it

It is keyed on a Crunchbase slug derived from the company name, and derivation is inexact: a company whose slug diverges from its name will not match. A miss degrades the record to firmographics rather than failing the call, and sources reports what actually contributed — so a caller can tell an absent field from an unattempted one.

The same honesty applies to the tech stack. tech_stack used to be filled from market-category tags — "payments", "api" — which are not technologies. That mapping was deleted rather than left to look plausible, and tags is now its own never-populated field so the two can never be confused.

Search refuses what it cannot do

Search filters on industry and geo. Pass stage, funding_min or employee_count_min and the call is refused before any actor starts.

The alternatives were worse. Honouring a headcount filter would mean enriching every candidate — silently multiplying the bill for one call — and dropping it silently would return "no companies match" when the truth is "that filter is not supported here". Refusing costs nothing and is the only answer that is true.

Failures that used to be invisible

The funding-and-tech run is separate from firmographics, and a transient failure still returns the firmographics. But an account-level failure — a bad token, an unpaid invoice — now errors the whole call. It used to be swallowed, which meant a suspended account reported "0 technologies" for every company on earth and looked exactly like a company with no measurable stack.

Pricing shape

Metered on 3× what the provider run actually cost, not a per-record list price: a no-match is billed at the same rate because it is the same provider run, and an enrich with signals costs more only because it really does start more runs. Every settlement records the provider_usd it was derived from and the multiplier applied, so a charge can be checked rather than taken on trust.

Search is cheaper than enrich with no arbitrage to guard, because a search result is a strict subset of an enrich result: no funding, no investors, no tech stack, no headcount.

What it does not do

  • recent_news, employee_growth_6m and tags are never populated. No actor in the set returns news, headcount growth needs two observations over time, and category tags are not a tech stack.
  • cb_id is accepted but not used for lookup — the funding actor keys on a slug, not a uuid. It stays on the contract so callers who stored one are not broken.
  • Batch scope is capped pending licence confirmation. PRIMITIVE_BATCH_MAX defaults to 1,000 records.

Full reference: Company Data docs. Current gaps, in one place: what is not done.

Frequently Asked Questions
What is /company-data?+
The Naïve primitive for private-company firmographics: headcount, industry, location, funding, investors and detected technology stack.
Is this the same as the companies API?+
No. /v1/company is the tenant control plane — the companies you own inside Naïve. /v1/company-data returns third-party data about companies you do not own.
How is it different from Reviews & Listings?+
Reviews & Listings covers a company's reputation and local presence — Google, Trustpilot and TripAdvisor. Company Data covers the company itself. They are siblings, not alternatives.
What happens if the funding lookup misses?+
The record degrades to firmographics rather than failing, and the `sources` array names which datasets actually contributed.
A
AshleyEngineering

Engineering at Naïve. Owns the data primitives.

@ashley_naive