Owler Company Intelligence API
Most company APIs tell you what a company is. This one also tells you who it competes with, by name, with a follow-on profile link for every rival so a second pass maps the whole market. Alongside that: a numeric revenue estimate and a banded range, employee count and band, total funding, acquisitions, industry, SIC codes, headquarters address, and exchange and ticker for public companies. Pay per company record, MCP-ready for Claude and other agents.
RECORDS2
MEDIAN LAGon demand
FIELDS35
Input parameters
| PARAMETER | TYPE | REQ | DEFAULT | DESCRIPTION |
|---|---|---|---|---|
| companyUrls | string[] | yes | — | One or more company profile URLs, for example https://www.owler.com/company/stripe. A bare company slug such as stripe is accepted as shorthand. Up to 1000 per run, collected in chunks of 20. Malformed entries are rejected locally with a warning instead of being sent upstream. Duplicates are removed before collection, so a list with repeats is not billed twice. One charge per company record returned; an input that yields no record is free. — drives your bill |
Output schema
| FIELD | TYPE | DESCRIPTION | NULLABLE |
|---|---|---|---|
| result_type | string | company for a collected record, error for an input that could not be collected. Filter on this before doing anything else. | no |
| companyId | string | Stable identifier for the company on the source directory. Example: 100441 for Stripe. | yes |
| companyName | string | Registered or commonly used name, usually with the legal suffix, for example Stripe, Inc. | yes |
| profileUrl | string | The profile page the record came from. Also present on error rows, so you can tell which input failed. | yes |
| website | string | The company's own website, including scheme and trailing slash. | yes |
| domain | string | Bare primary domain. The most reliable join key against a CRM or another dataset. | yes |
| description | string | One or two sentences of prose on what the company does. | yes |
| industry | string | First listed industry classification, for example Banking, Financial Services and Insurance. | yes |
| industries | string[] | Every industry classification on the profile. In practice this is usually a single-element array. | yes |
| founded | integer | Year founded, as a four-digit number. | yes |
| ownership | string | Private or Public. Reliable in testing, and the cleanest way to split a list before pulling filings for the public half. | yes |
| status | string | A source-side label. It came back as NEW for every company tested, including decades-old public ones, so do not read it as an operating status. | yes |
| city | string | Headquarters city. | yes |
| state | string | Headquarters state, province or region, spelled out rather than abbreviated. | yes |
| country | string | Headquarters country code. Not consistently ISO 3166-1 alpha-2: US companies come back as USA while others come back two-letter, so normalise before grouping. | yes |
| zipcode | string | Headquarters postal code, as a string so leading zeros survive. | yes |
| streetAddress | string | Headquarters street address. | yes |
| phoneNumber | string | Main listed phone number. Formatting varies by country and is not normalised. | yes |
| revenue | integer | Estimated annual revenue in US dollars as a number. An estimate, not a filed figure, and the field to use when you need arithmetic. | yes |
| estimatedAnnualRevenue | string | The same estimate as a banded range, for example $5B - 10B. The field to use when you need to group or segment. | yes |
| employeeCount | integer | Estimated headcount as a number. | yes |
| estimatedEmployees | string | Headcount as a banded range, for example 1,000 - 5,000. Note the thousands separator inside the string. | yes |
| totalFunding | integer | Total disclosed funding raised, in US dollars. | yes |
| totalAcquisitions | integer | Number of acquisitions the company has made. | yes |
| totalCompetitors | integer | The source's own competitor count. It does not equal the length of the competitors array; treat the two as separate figures. | yes |
| competitors | object[] | The named competitor set. Each entry has a name and a profileUrl you can feed straight back into companyUrls for a second pass. Around 30 names come back per company. | yes |
| ceoName | string | Chief executive, when the profile lists one. Frequently absent: it was empty on every company tested, so treat it as a bonus rather than a column you can rely on. | yes |
| followers | integer | How many people follow the company on the source directory. A rough attention proxy, nothing more. | yes |
| exchange | string | Stock exchange for public companies, for example NYSE. Absent for private companies. | yes |
| ticker | string | Ticker symbol for public companies. Pairs with exchange as the handoff key into market data. | yes |
| sicCode | string[] | Standard Industrial Classification codes listed for the company, for example 7372. | yes |
| summary | string | One-line plain-language recap of the record, so an agent can read a company without post-processing. | yes |
| error_message | string | On error rows only: why this input produced no company record. | yes |
| error_type | string | On error rows only: machine-readable category, such as CollectionError or MissingRequiredParameter. | yes |
| fetched_at | string | UTC ISO-8601 timestamp for the row. Run the same list on a schedule and this turns the dataset into a size and funding history. | no |
Worked examples
{
"companyUrls": [
"https://www.owler.com/company/stripe"
]
}
{
"companyUrls": [
"https://www.owler.com/company/figma",
"salesforce",
"stripe"
]
}
{
"companyUrls": [
"https://www.owler.com/company/moneytor",
"https://www.owler.com/company/blockrize",
"https://www.owler.com/company/duespayment",
"https://www.owler.com/company/bondaval"
]
}
{
"companyUrls": [
"https://www.owler.com/company/salesforce",
"https://www.owler.com/company/figma"
]
}
{
"companyUrls": [
"https://www.owler.com/company/stripe",
"https://www.owler.com/company/adyen",
"https://www.owler.com/company/gocardless"
]
}
POWER-USER TIP
Map a market in two passes, not one — Run one seed company, collect the profileUrl of every entry in its competitors array, dedupe that list, and run it back through companyUrls. Pass two is where the map actually appears. Budget for it first: roughly 30 names come back per company, so one seed costs about 30 charged records on the second pass.
POWER-USER TIP
totalCompetitors and the competitors array disagree, and that is expected — Stripe returned totalCompetitors of 23 alongside 30 named entries. The count is the source's own figure and the array has its own ceiling. Use the array when you need names, use the count only as a rough signal, and never assert one from the other.
POWER-USER TIP
The competitor set is sharpest on mid-market companies — For a household name the returned set mixes real rivals with small, loosely related firms: Stripe's list included Morgan Stanley next to several companies nobody would call a payments competitor. On mid-market and niche companies it is far tighter. Eyeball the first run before you build a pipeline on it.
POWER-USER TIP
Only company rows cost money — One charge fires per row with result_type of company. Error rows, rejected URLs and empty runs cost nothing, so a list with dead profiles in it is safe to submit. A slug that does not exist comes back as an error row reading "The data service could not return a record for this company." rather than vanishing from the output. The run also reads its own budget cap first and collects only what it can pay for, rather than fetching records it would have to discard.
POWER-USER TIP
Two numbers for revenue, and they are for different jobs — revenue is an integer you can sum and sort; estimatedAnnualRevenue is a band you can group by. Both are estimates rather than filed figures, which is the whole point for private companies, so present them as ranges when the number reaches a customer.
POWER-USER TIP
Read the dataset through its saved views — Append ?view=overview to the dataset items URL for the firmographics table, or ?view=competitors for company, competitor count and the named set. Neither needs a transformation written by hand, and both export to CSV or Excel.
POWER-USER TIP
Join on domain, not on name — companyName carries legal suffixes that vary by record, for example Stripe, Inc. and Figma, Inc. The domain field is the bare host and is the field to match against a CRM.
POWER-USER TIP
The per-record price falls with your platform tier — $0.006 on the free tier, $0.0057 at bronze, $0.005415 at silver, and $0.005144 at gold and above. A 1,000-company run therefore lands between $5.14 and $6.00.
Coverage
35
fields per company row — including error fields
1,000
companies per run — hard cap, raised per account on request
30
competitor names per company — observed ceiling on the array
20
companies per collection chunk — pushed and charged before the next chunk
2
saved dataset views — overview and competitors
7
published example tasks — each one a saved, runnable input
Tasks
Saved runs with the inputs already filled in — each one a standalone page and a working configuration example.
Written about this source
Walkthroughs, worked examples and posts about this source.
TASK
Owler Company Data API: Revenue, Size, Competitors
TASK
Find Company Competitors with Revenue and Headcount
TASK
Look Up Company Revenue and Employee Counts
TASK
Track Competitor Revenue and Headcount Monthly
TASK
Get Company Competitor Data in Claude via MCP
TASK
Enrich Company Records in an n8n Workflow
TASK
Map a Talent Market from Competitor Companies
Code
curl
curl -X POST "https://api.apify.com/v2/acts/johnvc~owler-company-api/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"companyUrls": ["https://www.owler.com/company/stripe"]}'
Python
from apify_client import ApifyClient
client = ApifyClient("APIFY_TOKEN")
run = client.actor("johnvc/owler-company-api").call(
run_input={"companyUrls": ["https://www.owler.com/company/stripe"]}
)
for item in client.dataset(run.default_dataset_id).iterate_items():
if item.get("result_type") != "company":
continue
print(item["companyName"], item.get("estimatedAnnualRevenue"),
item.get("employeeCount"), item.get("totalCompetitors"))
Python - competitor map in two passes
from apify_client import ApifyClient
client = ApifyClient("APIFY_TOKEN")
actor = client.actor("johnvc/owler-company-api")
seed = actor.call(run_input={"companyUrls": ["https://www.owler.com/company/stripe"]})
rivals = []
for item in client.dataset(seed.default_dataset_id).iterate_items():
for c in item.get("competitors") or []:
rivals.append(c["profileUrl"])
rivals = list(dict.fromkeys(rivals)) # dedupe, keep order
print(f"pass two will charge for up to {len(rivals)} records")
mapped = actor.call(run_input={"companyUrls": rivals})
for item in client.dataset(mapped.default_dataset_id).iterate_items():
if item.get("result_type") == "company":
print(item["companyName"], item.get("domain"), item.get("estimatedEmployees"))
MCP - add to Claude Code
claude mcp add --transport http owler \ "https://mcp.apify.com/?tools=actors,docs,johnvc/owler-company-api"
Changelog
2026-08-08
0.0.8 Rebuilt after a platform-wide dataset type fix; the MCP tool call was re-verified against the hosted server.
2026-08-07
Published on the Apify Store with seven example tasks.
2026-08-05
Pay-per-event pricing set at $0.0057 per company record, with the standard tier ladder down to $0.005144.
What people use it for
- map a competitive set from a single company
- estimate revenue for a private company
- enrich a CRM account list with firmographics
- track competitor headcount and funding over time
- size sales territories by employee count
- market mapping for recruiters
- qualify inbound leads by company size
- find the ticker and exchange for a company
Alternatives
Crunchbase Company API — better when you need the funding rounds and the investors behind them, round by roundours
PitchBook Company API — private-market financials, valuation and deal history on the same accountsours
LinkedIn Company API — a second, independent read on headcount when the estimate mattersours
Startup Investor Database — use this instead when the question is who funds a segment rather than who competes in itours
Owler's own subscription product — genuinely better if you want curated alerts, a news feed and analyst-maintained competitor lists rather than raw rowscompeting
Older Owler scrapers on the same marketplace — cheaper on paper, but no documented field list and a visibly lower run success rate on their store cardscompeting