Company Dossier API — Domain to Full Company Answer
Pricing
from $4.80 / 1,000 company dossier returneds
Company Dossier API — Domain to Full Company Answer
Ask about one company and get one answer: firmographics from its own site, tech stack, company-level contacts, DNS and registrar, the ATS it hires through and its open roles, recent news, SEC filings, US federal awards, product recalls, Y Combinator batch and the apps it publishes. No API key.
Pricing
from $4.80 / 1,000 company dossier returneds
Rating
0.0
(0)
Developer
Insight Solutions
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Ask about one company and get one answer. Send a domain — or a company name, a ticker, a CIK or an email address — and get one row carrying twelve sections: who they are, what they run on, how to write to the company, who hosts and registers them, what they are hiring for, what the press said this month, what they file with the SEC, what the numbers say, what the US government has paid them, whether anything of theirs has been recalled, whether they went through Y Combinator, and what they ship in the app stores.
Every section is read from a first-party source — the company's own website, its own DNS, the
public ATS board it recruits through, and the registers that publish the rest — and every section is
stamped with the exact request that produced it. Read from the company's own website, its own DNS and
the public registers — never from a commercial database. Anything nobody publishes comes back null,
never a guess.
An empty section is an answer. "No recalls found, and here is the query that proves it" is the most
valuable cell in a vendor-risk dossier, and it is not the same thing as "we did not look". A section
the company simply has nothing in comes back status: "none" with its apiUrl; a section the run
could not reach comes back status: "unavailable" plus a free diagnostic row.
Company-level only. No names of individuals, in any section. No CEO, no founders, no directors, no
SEC officer tables, no Y Combinator founder records, no hiring managers. The email filter is a role
allowlist, so basecamp.com — which publishes exactly one address, a person's — returns zero
emails. There is a test for that.
At a glance
Input — this is the Store prefill; paste it and run:
{ "companies": ["stripe.com", "nike.com", "airbnb.com", "allbirds.com"],"sections": ["profile","tech","contacts","domain","jobs","news","filings","awards","recalls","yc","apps"],"maxItemsPerSection": 10, "includeSummary": true, "flattenSections": false,"maxConcurrency": 3, "maxRunSecs": 300, "proxyConfiguration": { "useApifyProxy": true } }
Output — one dossier row per company with twelve nested sections; the fields you will use most are
companyName, summary, sectionsFilled, identifiers, sections.jobs.openRoles,
sections.recalls.recallCount, sections.filings.cik (full list under Output reference). A section the
company simply has nothing in comes back status: "none" with the query that proves it — not a blank.
Anything that could not be fetched comes back as a free diagnostic row (ok: false, errorType, error)
instead of a charge. Each company's row is pushed the moment that company finishes, so a long list
fills the dataset as it goes rather than at the end.
Price — $8.00 per 1,000 companies on the FREE tier (+ $0.001 per run); company names that could not be
resolved, sections that could not be reached, every flat child row and every run that returns nothing are
free. Pay-per-event, no API key, no browser, limited permissions — works over the Apify MCP server
(mcp.apify.com) and with agentic (x402) payments.
From code — client.actor("insight.solutions/company-dossier-api").call(run_input={…}) with
apify-client, or
POST https://api.apify.com/v2/acts/insight.solutions~company-dossier-api/run-sync-get-dataset-items.
What you get
One row per company. Abridged, with nike.com as the input:
{"ok": true,"rowType": "dossier","input": "nike.com","domain": "nike.com","resolvedDomain": "nike.com","websiteUrl": "https://www.nike.com/","companyName": "Nike","legalName": "NIKE, Inc.","resolvedFrom": "input-domain","resolutionConfidence": 1,"country": "US","identifiers": {"domain": "nike.com","cik": "320187","tickers": ["NKE"],"sic": "3021","ycSlug": null,"ycBatch": null,"atsPlatform": "workday","atsBoardSlug": "nike.wd1.myworkdayjobs.com/nike","usaSpendingRecipients": ["NIKE USA, INC."]},"sectionsFilled": ["profile", "tech", "contacts", "domain", "jobs", "news", "filings", "awards", "recalls"],"sectionsEmpty": ["yc", "apps"],"sectionsUnavailable": [],"sectionCount": 9,"itemCount": 49,"requestCount": 23,"partial": false,"billable": true,"summary": "NIKE, Inc. is a company in Beaverton, OR. It runs on Akamai and Adobe Analytics. It recruits through Workday. SEC filer, CIK 320187 (NKE). 10 news items in the window.","sections": {"profile": {"status": "filled","sourceUrl": "https://www.nike.com/","fetchedAt": "2026-09-17T12:00:03.114Z","itemCount": 1,"companyName": "Nike","companyNameRule": "jsonld.Organization.name","legalName": "NIKE, Inc.","hqCity": "Beaverton","hqRegion": "OR","hqCountry": "US","foundedYear": 1964},"jobs": {"status": "filled","sourceUrl": "https://nike.wd1.myworkdayjobs.com/nike","itemCount": 0,"atsPlatform": "workday","atsPlatformLabel": "Workday","atsBoardUrl": "https://nike.wd1.myworkdayjobs.com/nike","jobsSource": "site-detected","openRoles": null,"openRolesNote": "Workday lists postings through a POST with a paged JSON body and a per-tenant site path; the board and its URL are on the row, the open-role count is not."},"yc": {"status": "none","reason": "not-a-yc-company","sourceUrl": "https://www.ycombinator.com/companies?query=Nike","apiUrl": "https://www.ycombinator.com/companies?query=Nike","fetchedAt": "2026-09-17T12:00:03.114Z","itemCount": 0}}}
That yc block is the point of the product. It is not a null. It is "we asked the Y Combinator
directory for Nike, here is the query, and the answer is no" — and for the two sections nobody else
sells, recalls and awards, that answer is what a vendor-risk questionnaire actually needs:
"recalls": {"status": "none","reason": "no-results","sourceUrl": "https://www.saferproducts.gov/PublicSearch","apiUrl": "https://www.saferproducts.gov/RestWebServices/Recall?format=json&Manufacturer=Stripe%2C+LLC&RecallDateStart=2016-09-19&RecallDateEnd=2026-09-17","fetchedAt": "2026-09-17T12:00:03.114Z","itemCount": 0,"recallCount": 0,"byAgency": { "cpsc": 0, "fda": 0 },"items": []}
The twelve sections
| # | Section | What it answers | Source | Requests |
|---|---|---|---|---|
| 1 | profile | Who are they? | The company's own website | 6 |
| 2 | tech | What do they run on? | The pages already fetched, 232 own signatures | 0 |
| 3 | contacts | How do I write to the company? | The company's own website + security.txt | 0 |
| 4 | domain | Who hosts, mails and registers them, and since when? | DNS over HTTPS, RDAP, TLS | 5 + 1 socket |
| 5 | jobs | What are they hiring for? | The public ATS board they recruit through | 1, up to 4 |
| 6 | news | What was said about them this month? | Google News RSS | 1 |
| 7 | filings | What do they file, and under what CIK? | SEC EDGAR submissions | 1 |
| 8 | financials | What do the numbers say? (opt-in) | SEC EDGAR XBRL company facts | 1 |
| 9 | awards | Does the US government buy from them? | USAspending | 2 |
| 10 | recalls | Has anything of theirs been pulled? | CPSC SaferProducts + openFDA enforcement | 4 |
| 11 | yc | Did they go through Y Combinator? | The Y Combinator company directory | 1 |
| 12 | apps | What do they ship in the app stores? | iTunes Search + Google Play | 2 |
Per company: 23 HTTP requests and one TLS socket at the defaults, and never more than 27. Two more per run, once: the SEC ticker index and the Y Combinator directory's search credentials, both cached.
tech and contacts cost nothing because they read pages profile already fetched. profile,
domain and the eight off-site sections are what the budget goes on.
Two sections can spend more than their usual cost, and the run log publishes both numbers:
awardsis two POSTs, not one. USAspending refuses a single query that names both contract and grant award-type codes, so contracts and grants are two queries whose results are merged. A third POST is allowed once, if the endpoint refuses a field list.jobsis one GET when the site's own HTML names a board. When it does not, the slug-guess fallback below tries up to three more.
Coverage, as numbers. SEC's ticker index is ≈10,000 US filers. The Y Combinator directory is 6,213 companies. openFDA allows 1,000 requests a day per IP address without a key. USAspending carries awards from 2007-10-01 onward. Google News RSS returns about 100 items a query. There are 13 ATS platforms in the detector, 9 of which publish a list endpoint this Actor can count, and 232 technology signatures across 26 categories — our own signatures, not a GPL fingerprint database.
How a company name is resolved
You can send a domain. You can also send Nike, Inc., NKE, 320193 or press@stripe.com. A name
walks four rungs, cheapest first, and stops at the first one that gives a verified answer:
| Rung | Source | Requests | Covers |
|---|---|---|---|
| 0 | The entry is already a domain, a URL or an email address | 0 | every domain input |
| 1 | SEC's company_tickers.json | 1 per run, cached | ≈10,000 US filers, every ticker, every CIK |
| 2 | The Y Combinator directory's search index — its records carry a website | 1 per run + 1 search | 6,213 YC companies |
| 3 | <slug>.com → .io → .ai → .co, verified against the page's own identity | 1–4 | everything whose name maps to its domain |
Rung 3 accepts a candidate only when the page says who it is. The page's own name — JSON-LD
Organization.name, then og:site_name, then the <title> split, then the footer copyright — has to
match the name you sent. No identity match, no acceptance: a parked page, a domain squatter or an
unrelated company never becomes an answer. resolutionConfidence records which signal matched: 1.0
you sent the domain, 0.9 an exact SEC or YC match, 0.8 a candidate whose JSON-LD names the company,
0.6 a candidate confirmed only by og:site_name or a footer line.
Two answers is a question, not an answer. If two companies answer to the name — three SEC filers
share a prefix, or both acme.com and acme.io serve a page claiming it — you get a free
ambiguous diagnostic row listing every candidate with its evidence and its URL. If no rung matches,
you get a free unresolved row listing every candidate that was tried and why each was refused.
Neither is charged.
What the company is called
companyName is derived from the site with one rule, in this order:
- JSON-LD
Organization/Corporationname, then itslegalName og:site_name- the
<title>, split on-,|,—,–and:, taking the shortest segment that is not a generic page word (Home,Welcome,Official Site…) - the footer copyright holder
- and only then the domain label, title-cased —
gusto.com→Gusto
A meta description is never a name. The page's description and og:description are refused
outright, however they reached the field — some content systems copy the SEO title, description and
all, into the structured-data name. A The official website for … clause is cut off with whatever
separator introduced it. The result is capped at 80 characters, and a candidate that cannot be reduced
to a name is skipped so the next source gets its turn rather than being truncated into one.
sections.profile.companyNameRule records which rule produced the name.
A footer's navigation is never a name either, and every candidate has to clear three refusals before it reaches the row:
- prose — a sentence boundary inside it, or more than six words;
- navigation vocabulary anywhere in it: privacy, terms, cookie, accessibility, site map, sitemap, careers, contact, login, sign in, all rights reserved, and the rest of a short, published list;
- a menu shape — three or more capitalised words of which at least half are page labels.
The footer rung reads only the text immediately after a ©, (c) or Copyright mark, up to the first
comma, period, pipe or line break. The single exception is a legal form that owns the punctuation:
Notion Labs, Inc. and Apify Technologies s.r.o. keep theirs, while SEOMoz, a Ziff Davis company.
stops at SEOMoz. Every © on the page is tried in order, so a stray mark above the real line does
not cost you the real line. When every rung fails, the answer is the domain label. The same gate is
applied to legalName, which is the field a footer menu actually reached the row on before this rule
existed.
How the SEC index is matched
The filings section matches the company against SEC's ~10,000-filer ticker index without spending a
request. A ticker or a CIK is used as written. A name is matched on a normalised form — lower-case,
punctuation dropped, the legal form (Inc, Corp, Ltd, PLC, LLC, Holdings, Group…) dropped,
whitespace collapsed — so Airbnb reaches Airbnb, Inc., in three passes: the whole normalised name,
then the domain's own label against the first word of a filer's name, then the first word of the name
the site publishes.
Every pass requires exactly one filer. Two filers under one normalised name — Acme Corp and
Acme Holdings Ltd — makes the section none with reason: "ambiguous" and the candidates on the
row, because attaching a real company's filings to the wrong dossier is worse than a blank. A prefix is
still not an identity: Apple Hospitality REIT never answers for apple.com.
Why Google News cannot do this, and why we say so. A Google News RSS item's <source url="…"> is
the publisher's domain — reuters.com, bloomberg.com — never the subject company's. An earlier
draft of this Actor used it as a rung and it resolved Nike to nytimes.com. It is written down in
the source so the next person does not try it again.
A name that resolves to a domain you also sent is folded into it and charged once. stripe.com,
https://www.stripe.com/, press@stripe.com and Stripe in one list are one dossier, and the row's
input records all four spellings.
Quick start
One domain.
{ "companies": ["stripe.com"] }
One company name, for an interview or a first call.
{ "company": "Allbirds","sections": ["profile", "tech", "jobs", "news", "yc", "apps"],"includeSummary": true }
Forty domains, flat, for a spreadsheet.
{ "companies": ["stripe.com", "nike.com", "…38 more…"],"sections": ["profile", "jobs"],"flattenSections": true,"maxItemsPerSection": 25,"maxConcurrency": 5,"maxRunSecs": 900 }
Input reference
| Field | Type | Default | Notes |
|---|---|---|---|
companies | array of strings | — | Domains, URLs, email addresses, company names, tickers or CIKs — one per line |
sections | array (enum) | eleven of twelve | Which sections to fill. Turning sections off does not change the price |
maxItemsPerSection | integer 1–50 | 10 | Jobs, articles, filings, figures, awards, recalls and apps kept per company |
includeSummary | boolean | true | A free, deterministic one-paragraph summary. No model, no charge |
flattenSections | boolean | false | Also emit one free child row per item, for spreadsheets |
company | string | "" | Single-entry convenience for integrations that cannot send an array |
includeFinancials | boolean | false | Adds financials — normalised XBRL figures. Off by default: companyfacts is megabytes for a large filer |
financialsMaxPeriods | integer 1–40 | 8 | Periods kept when financials is on |
financialsPeriodKind | enum | annual | annual · quarterly · both |
filingForms | array of strings | ["10-K","10-Q","8-K","20-F","S-1"] | Empty means every form |
newsWindowDays | integer 1–365 | 90 | How far back the news query reaches |
newsSiteScope | boolean | false | Narrow the news query with the company's own domain |
awardsWindowDays | integer 30–7300 | 1825 | USAspending covers 2007-10-01 onward |
recallsWindowDays | integer 30–7300 | 3650 | Ten years, which is the vendor-risk window |
maxPagesPerSite | integer 1–12 | 4 | HTML pages per company site, including the home page |
includeAppDetails | boolean | false | Confirms a Play app's publisher website with one extra fetch per app (~2 MB a page) |
includePersonalEmails | boolean | false | Read the Privacy section first. Person-shaped addresses are dropped unless this is on |
secUserAgentContact | string | Insight Solutions austinhughhillis@gmail.com | Used by filings and financials. SEC asks for Company Name admin@yourdomain.com — a name and a reachable address, not an API key. If you don't set it, the Actor identifies itself with the default above, so an API or MCP run that sends only companies still gets its filings |
openFdaApiKey | string (secret) | "" | Optional. Raises openFDA's keyless 1,000-a-day-per-IP quota |
maxSecsPerCompany | integer 10–600 | 60 | Hard budget for one company. Sections still running when it expires are marked timed-out and the dossier is pushed with what it has |
maxConcurrency | integer 1–10 | 3 | Companies in flight; each gets its own proxy session |
sectionConcurrency | integer 1–8 | 4 | Sections in flight per company |
maxRunSecs | integer 60–3600 | 300 | Wall-clock budget for the run. No new company is started past 85% of it. Companies never started are never charged |
proxyConfiguration | object | { "useApifyProxy": true } | Apify datacenter proxy. CPSC and SEC are fetched direct first regardless |
Output reference
The flat columns
ok · rowType · input · error · errorType · scrapedAt · source · sourceUrl ·
domain · resolvedDomain · redirectedToDifferentDomain · websiteUrl · companyName ·
legalName · resolvedFrom · resolutionConfidence · country · identifiers ·
sectionsRequested · sectionsFilled · sectionsEmpty · sectionsUnavailable · sectionsTimedOut ·
sectionsSkipped · sectionCount · itemCount · requestCount · partial · billable · summary · sections
Child rows add section · companyDomain · itemType · itemId · itemTitle · itemUrl ·
itemDate · itemAmount · itemCurrency · itemParty · itemCategory · itemStatus ·
itemLocation · itemDetail. Diagnostic rows add candidates · triedCandidates · apiUrl.
Every row type carries every column, null where it does not apply, so a CSV export is one
rectangle.
identifiers — the join keys
domain · cik · tickers[] · exchanges[] · sic · ycSlug · ycBatch · atsPlatform ·
atsBoardSlug · appleDeveloperId · googlePlayDeveloper · usaSpendingRecipients[], in one flat
object so an agent can hand them to another tool. There is no DUNS — that is a commercial
identifier we have no licence to — and no professional-network profile URL, which is a decision rather
than an oversight and is stated in Limitations.
Every section carries the same five stamps
status · reason · sourceUrl (the page a human would read) · apiUrl (the exact request) ·
fetchedAt · itemCount.
status | Means |
|---|---|
filled | The source answered and had content |
none | The source answered and this company has nothing there. This is an answer, and apiUrl proves it |
unavailable | The source could not be reached. A free diagnostic row names the request |
timed-out | The run stopped waiting for it — at the section's own 45-second deadline or at this company's maxSecsPerCompany. A free diagnostic row says so, and the rest of the dossier shipped without it |
skipped | Not requested, or a dependency is missing — a company resolved by name with no domain has no website to read |
reason on a none: no-results · no-ats-detected · not-a-filer · ambiguous (two SEC filers
answer to this name; the candidates are on the section) · not-a-yc-company · no-publisher-match ·
name-only-no-domain.
reason on an unavailable: blocked · rate-limited · timeout · upstream-fault ·
robots-disallowed · budget-stopped.
The child rows
flattenSections: true adds one row per item on top of the dossier row — never instead of it —
using one canonical twelve-column item shape, so seven different sources land in one table:
| Column | job | news | filing | award | recall | app |
|---|---|---|---|---|---|---|
itemId | posting id | — | accession no. | award id | recall id | app id |
itemTitle | role title | headline | form + document | award description | recall title | app title |
itemUrl | apply URL | Google News link | EDGAR document | usaspending.gov award | agency notice | store listing |
itemDate | posted | published | filed | start date | recall date | released |
itemAmount | — | — | — | award amount | units affected | price |
itemCurrency | — | — | — | USD | — | store currency |
itemParty | department | publisher | filer name | awarding agency | recalling firm | developer |
itemCategory | employment type | publisher domain | form family | award type | hazard | store category |
itemStatus | remote / on-site | — | amendment? | active / completed | classification | free / paid |
itemLocation | job location | — | state of incorporation | place of performance | firm country | — |
financial-period rows use itemTitle = statement + concept, itemAmount = value, itemDate =
period end. Every child row carries companyDomain so it joins back, and itemDetail carries the same
object as it appears nested in the dossier row, so nothing is lost by exporting the flat view.
Dataset views
dossiers (default) · jobs · news · filings · financials · awards · recalls · apps ·
problems.
Row size
A dossier row is kept under a 512 KB soft cap (Apify's item limit is 9 MB). Free text is clipped at
400 characters; if a row is still over, the longest items[] list is truncated first, the section
records truncated: n, and a free row-trimmed diagnostic says what was cut. The counts and totals on
each section are computed before the cut, so recallCount is the real number even when items is
shorter.
How a run is bounded, and when a row reaches you
A row is pushed the moment its company finishes — not at the end of the run, not at the end of a batch. A 25-company run starts filling the dataset within seconds of the first company completing, and you can read it while the rest are still going.
That only holds if a company always finishes, so there are three nested clocks and each is strictly shorter than the one above it:
| Clock | Default | What happens when it expires |
|---|---|---|
| One request, retries and backoff included | 30 s | The request fails; the section handles it as any other fault |
| One section | 45 s | The section is timed-out, with a free diagnostic row. The other ten carry on |
One company (maxSecsPerCompany) | 60 s | Sections still running are timed-out; the dossier is pushed with what it has, and charged on the usual rule — at least one section filled |
The run (maxRunSecs) | 300 s | No new company is started past 85% of it, so the ones in flight finish and reach the dataset. Companies never started get a free row |
Set maxRunSecs at or below the run's platform timeout. A value above it does not buy more time — the
platform aborts first — and the run then ends without the summary it would otherwise write.
Every completed company writes one INFO line to the run log with its domain, how many sections filled, how many requests it spent and how many milliseconds it took, so a slow source is visible in the log rather than inferred from a gap in it.
What fills, and what usually does not
This Actor has not had its first live run yet, so there are no measured fill rates here. When it
has, this section will publish them per section, as numbers, the way company-enrichment-api publishes
employeeCount 0 of 6 — and it will publish the skew honestly rather than the average, because the
skew is the honest weakness of a dossier: a US public manufacturer fills eleven sections and a European
private SaaS fills five.
What the offline suite already shows, against the source Actors' own captured fixtures:
profile,tech,contactsanddomainfill for every live site tested.filingsfills for a public filer and isnone/not-a-filerfor a private one. Stripe is private and itsfilingssection says so with the index that proves it.jobsfills when the site links to one of the nine boards with a list endpoint, isfilledwithopenRoles: nullon Workday and JazzHR, and isnone/no-ats-detectedwhen no board could be found or verified.ycisnonefor most companies, because most companies are not YC companies. That is the answer.appsisnone/no-publisher-matchfor a company that publishes no app — the stores returned results, none of them belonged to the company, and none was attributed.
employeeCount, foundedYear and industry are the three fields that are empty most often, on every
Actor in this family: most company websites do not state them, and this one does not guess.
What you are never charged for
A dossier is charged when both hold: the company resolved, and at least one enabled section
is filled. Everything else is free:
- every company name that could not be resolved — with the candidates listed;
- every ambiguous name — with every candidate, its evidence and its URL;
- every free-mail address (
gmail.com), IP address or non-domain entry; - every dead domain, bot wall and
robots.txtrefusal; - every section the run could not reach — one free
section-unavailablerow per section, naming the request; - every section the run stopped waiting for — one free
section-timed-outrow per section, saying which budget expired. The rest of the dossier ships and is charged as any other partial row is; - every company where no section returned anything;
- every flat child row, when
flattenSectionsis on — up to sixty per company; - every company the run never got to, because the time budget or your maximum total charge ran out —
including every company not started past 85% of
maxRunSecs; - and any run that returns no paid row at all, which finishes FAILED with nothing billed, start fee included.
A dossier where one section filled and ten came back empty IS charged. "We looked at eleven sources, here is the one that had something, and here are ten queries that prove the rest are empty" is the answer the vendor-risk buyer is paying for.
Pricing
| Event | What it is | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|---|
actor-start | Run started | $0.001 | $0.001 | $0.001 | $0.001 |
dossier | One company dossier returned | $0.008 | $0.008 | $0.0064 | $0.0048 |
$8.00 per 1,000 companies, and the start fee is charged once per run and only after the first paid row exists — so a run that returns nothing costs nothing at all.
One number you can multiply. There is one paid event. Turning sections off does not make it cheaper; it makes it faster. The flat child rows are free, because they contain nothing the dossier row does not already contain.
One run at $8.00 replaces nine runs that cost $44.10 across nine of our own Actors — company enrichment, news, ATS jobs, SEC filings, federal awards, product recalls, domain intelligence, the Y Combinator directory and app charts, each with its own start fee and its own schema — and it adds four sections that nothing else in this category sells at any price: recalls, federal awards, Y Combinator and apps published.
If you only want a profile, do not run this. A buyer who wants firmographics, tech stack, company-level contacts and DNS — sections 1 to 4 — should run Company Enrichment API at $3.50 per 1,000 instead. It is the same code doing the same work for less money, because it makes half the requests.
FAQ
Can I send company names instead of domains? Yes — names, tickers, CIKs, URLs and email addresses all work. See How a company name is resolved. A name that resolves nowhere is free.
What if two companies share a name? You get a free ambiguous row listing up to five candidates
with their evidence and URLs, and nothing is charged. Send one of their domains and the dossier runs.
Why is there no CEO name? Because this Actor returns company-level data only, in every section, permanently. See Privacy.
Why is there no professional-network profile column? Because the one everybody means forbids automated collection in its terms and sits behind an anti-bot wall. See Limitations.
Why is financials off by default? SEC's companyfacts document is the only payload in the run
measured in megabytes — several for a large filer. Turn includeFinancials on when you want it.
What does status: "none" mean? That the source answered and this company has nothing there.
apiUrl on the section is the query that proves it. It is not the same as unavailable, which means
the source could not be reached and which is reported as a free diagnostic row.
Can I get the rows flat? Yes — flattenSections: true adds one free child row per job, article,
filing, figure, award, recall and app, and the dataset views split them by type.
Does it work over MCP? Yes. It is a pay-per-event Actor with limited permissions and no standby
mode, which is what mcp.apify.com needs; there is no MCP-specific surface and no per-tool-call
charge.
Do I need an API key? No. secUserAgentContact is a contact string SEC asks every automated client
for — a name and an address it can reach — not a key: nothing is registered and nothing is issued.
openFdaApiKey is optional and only raises a quota.
Limitations
- Upstream formats change. Ten sources, ten ways for that to happen. A section whose payload stops
parsing comes back
unavailablewith a free diagnostic naming the request; one section's bad day never costs you the other ten, and never fails the dossier. - USAspending matches recipients on text, so a company with a common name can pull in a namesake.
recipientMatched[]shows the distinct names the endpoint actually returned andrecipientMatchQualityisexactorpartial, so you can see it happen. Its filter takes one spelling, so the shortest of the names known for the company is the one sent and the rest are used only to grade the match;recipientsSent[]says which went,recipientNamesConsidered[]says what was weighed. Contracts and grants are two queries because the endpoint refuses a single one that names both, andawardTypesRead[]says which of them answered. - A board this Actor had to guess at is labelled. When the site's own HTML names no ATS,
jobstriesgreenhouse:<domain label>,lever:<domain label>,ashby:<domain label>and, when it differs, Greenhouse for the company name's slug — at most four requests. A guess is accepted only when the board answers HTTP 200, parses as a job list with at least one posting, and is demonstrably that company's: a posting URL on the company's own registrable domain, or a company name on the board matching the company's name or domain label. A board that cannot be tied to the domain is discarded andnonestays the answer.sections.jobs.jobsSourceis"site-detected"when the marker was in the site's HTML and"slug-guess"when it was not, withatsGuessesTried[]andatsGuessEvidencebeside it. - Workday and JazzHR boards return no open-role count. Both are detected and named on the row with
their board URL; Workday needs a POST with a paged JSON body and a per-tenant site path, and JazzHR
publishes an HTML page rather than a feed.
openRolesNotesays so on the row. - Google News links resolve through Google. Decoding one to the publisher's own URL takes two more requests per article, which would double this Actor's whole request count. Items carry the publisher name and its domain; for decoded publisher URLs, run Google News Search, Topics & Real Article URLs.
- openFDA allows 1,000 requests a day per IP address without a key. Three requests a company means
a very large run on a shared exit can reach it.
openFdaApiKeyis optional and raises the quota. - No vehicle recalls and no USDA. NHTSA is indexed by year, make and model rather than by company, and USDA FSIS publishes one 13 MB list. Both are in Product & Vehicle Recalls API.
- No hiring velocity. "How many roles opened and closed this week" needs state across runs, which is New Job Postings Monitor.
- No LinkedIn column, by choice, and for two stated reasons: their terms of service forbid automated collection, and the site is behind an anti-bot wall a keyless, browserless Actor cannot pass honestly. A column we could only fill unreliably and impermissibly is a column we do not ship, so there is no such URL among the join keys and no such data in any section.
- No funding rounds, investors, competitor sets or revenue estimates for private companies. Every
source for those is a commercial database, and a revenue band derived from a guessed employee count
is a guess squared. For a public company,
financialsreturns the real figure from XBRL, sourced and dated. - No web-search fallback for an unresolvable name in v1. A search-engine rung would resolve the remainder but brings session tokens and a block path into an Actor that already reads ten sources. It is a v1.1 question.
- A company name that reads like a footer link is refused and falls back to the domain label. The
name rule rejects any candidate carrying navigation vocabulary — privacy, terms, cookie,
accessibility, site map, careers, contact, login, sign in, all rights reserved — because a footer
that renders its menu as bare words after a
©is otherwise indistinguishable from a copyright line. A realContact EnergyorPrivacy Dynamicsis therefore reported by its domain label rather than by its full name, andsections.profile.companyNameRulesaysdomain.labelwhen that happened. A plain, checkable name is worth more than a menu. - A slow source costs you the section, not the dossier. Every section has a 45-second deadline and
every company a
maxSecsPerCompanybudget (60 s by default). What is still running when one expires is markedtimed-outwith a free row, and the dossier is delivered with what it has. RaisemaxSecsPerCompanywhen you would rather wait; the sections that do answer are unaffected either way. - This Actor has no measured live run yet, so the fill rates above are unpublished and the launch price is modelled rather than measured. Both are fixed before it goes public.
Privacy
Company-level only. No names of individuals, in any section. This is a policy, not a default, and it is enforced at the parser rather than at the row builder — a personal name is never read into memory, so it cannot leak through a field nobody thought about.
| Section | The people-shaped field upstream | What we do |
|---|---|---|
profile / contacts | JSON-LD Person nodes, team pages, firstname.lastname@ | The JSON-LD walker skips Person and passes no inheritance; the email filter is a role allowlist. basecamp.com publishes exactly one address, a person's, and returns zero emails |
jobs | hiringManager, recruiter, creator, user on several ATS platforms | Not read by any adapter. A test walks every parsed field of every fixture and asserts no personal-name key survives |
filings | SEC submissions carry officer and signatory names in several arrays | Only the company fields are read. The business address is kept because it is a company address |
financials | — | XBRL facts are numbers |
awards | recipient_officers_* on USAspending's award detail endpoint | That endpoint is never called, and the search response carries no officer field |
recalls | CPSC ConsumerContact | Kept — it is a company phone number or URL, not a person. Nothing else is read |
yc | founders[], each with a full name, a title and social profile URLs | Those live on a company's YC page, and this Actor never fetches one. The code that would read it is not even vendored |
apps | Apple's artistName is usually a company but can be an individual | Kept as developer, because it is the publisher of record the store itself shows. An app matching no company signal is not attributed at all |
And, unchanged from the rest of this family: no email verification of any kind, no SMTP probe, no
guessed mailbox patterns, no third-party enrichment database. robots.txt is honoured on every page and
a refusal is reported rather than worked around. You are the controller of what happens next with
whatever this Actor returns to you.
Use it from an AI agent, or from code
This Actor is pay-per-event with limited permissions and no standby mode, which is exactly what the Apify MCP server needs, so an agent can call it as a tool with no extra setup and no per-tool-call surcharge. It is also eligible for agentic (x402) payments.
Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("insight.solutions/company-dossier-api").call(run_input={"companies": ["stripe.com", "Nike, Inc.", "NKE"],"sections": ["profile", "tech", "contacts", "domain", "jobs", "news", "filings", "recalls"],"includeSummary": True,})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row["rowType"] == "dossier":print(row["companyName"], row["sectionsFilled"], row["summary"])
HTTP, one call, rows back in the response
curl -X POST "https://api.apify.com/v2/acts/insight.solutions~company-dossier-api/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \-H 'Content-Type: application/json' \-d '{"company":"stripe.com","includeSummary":true}'
Every row says where it came from. sections.<name>.sourceUrl is the page a human would read and
sections.<name>.apiUrl is the exact request that produced it, so an answer an agent gives from this
data is one a person can check.
Our other Actors
Every Insight Solutions Actor is pay-per-result with no browser, no login and no API key, and every one of them returns free diagnostic rows instead of billing for failures. Prices are per 1,000 results.
Video, audio & social
- YouTube Transcript API — captions as timed segments, text, SRT or VTT, with language fallback and translation.
- YouTube Comments API — comments and replies with likes, pinned and hearted flags, newest or top sort.
- YouTube Channel API — a channel's videos, Shorts and live streams, plus YouTube search.
- Podcast Search, Episodes & Charts API — Apple Podcasts search, charts and full episode feeds.
- Bluesky Scraper — profiles, posts, followers and follows from the public AT Protocol API.
- Telegram Channel Scraper — posts, views and channel stats from public Telegram channels.
- Substack Scraper — posts with full free text, comments and publication profiles.
- Hacker News API — stories, comments, users, front page and a structured "Who is hiring?" parser from the official HN APIs.
News, documents & the web
- Google News Search, Topics & Real Article URLs — news search and topic feeds with the publisher's real URL decoded.
- Website to Markdown — Content Extractor for LLMs & RAG — any site as clean Markdown, text and heading-aware chunks.
- Internet Archive API — archive.org search, item metadata, files and reviews.
- Wayback Machine Toolkit — archived URL inventories, snapshots and text diffs between dates.
- Website Technology Detector — the tech stack behind any site, with the evidence for each detection.
- Domain Intelligence API — DNS, RDAP registration, TLS certificate and HTTP facts in one row per domain.
- SEO Page Audit — sitemap crawl with on-page checks, structured data and broken-link reports.
- Keyword Suggestions API — Google, YouTube, Bing, Amazon and eBay autocomplete with alphabet and question expansions.
- Website Contact Extractor — emails, phone numbers and social profiles from any list of websites.
- Web Search Results API — Bing and DuckDuckGo organic results with snippets, no key, no browser.
- Company Enrichment API — a domain in, a company profile out: firmographics, contacts, tech stack, DNS and hiring signal.
Business, finance & jobs
- Congress & Insider Trades API — STOCK Act periodic transaction reports and SEC Form 4 insider trades in one schema.
- Federal Contracts, Grants & Lobbying API — SAM.gov opportunities, USAspending awards, Grants.gov notices and Senate lobbying filings in one schema.
- SEC EDGAR API — filings, XBRL financials and full-text search by ticker or CIK.
- Clinical Trials & FDA API — ClinicalTrials.gov studies plus openFDA recalls, labels, approvals, 510(k)s and adverse-event reports.
- Product & Vehicle Recalls API — CPSC, NHTSA, FDA and USDA recalls, vehicle complaints and ratings, plus a VIN decoder.
- Y Combinator Companies, Batches & Founders — the YC directory with founders and social links, filterable by batch, industry and hiring status.
- Career Site Jobs API — jobs straight from Greenhouse, Lever, Ashby, Workable and 10+ other ATS career sites.
- New Job Postings Monitor — new, closed and changed postings on the career sites you watch.
- Remote Jobs API — RemoteOK, Remotive, We Work Remotely, Himalayas, Jobicy and more in one schema, deduplicated.
- Shopify Products API — any Shopify store's catalogue, variants, prices and stock signals.
- Shopify Store Monitor — price drops, sales, restocks, sell-outs and new products on any Shopify store, one row per change.
Apps & games
- App Store & Google Play Reviews API — reviews from both stores with ratings, versions and developer replies.
- App Store Top Charts & App Search API — Apple top charts by country and genre, plus app search and details.
- App Store Keyword Rank Tracker — where any app ranks for any keyword on the App Store and Google Play, with rank changes and ASO suggestions.
- Steam Reviews API — Steam reviews with playtime, helpfulness and game details.
- Steam Game Data API — prices, tags, review scores, live player counts and top charts.