Products
Alt-Data
Alternative and licensed-research datasets that show what a company is doing before it reaches a filing: monthly workforce momentum and WARN-Act layoff notices, the supply-chain graph and revenue dependence, geographic revenue exposure, board and audit governance with forensic accounting flags, plus lobbying spend, federal contracts, patents, executive pay and r/wallstreetbets sentiment.
What's inside
- Workforce. A monthly employment panel per company (headcount, hiring and attrition rates, average salary) and US WARN-Act layoff filings, which employers must file weeks before a cut. Two cross-sectional screens rank who is hiring and who is filing layoff notices.
- Supply chain. The relationship graph around a company (customers, suppliers, competitors and partners, from 2003 on), two-sided revenue dependence, and estimated revenue by region and country for each fiscal period.
- Governance and accounting quality. Board size and independence, director interlocks, restatement record, auditor changes and executive pay in one dossier, and graded forensic red flags with the evidence rows attached.
- Political and government exposure. Quarterly lobbying spend and federal contract awards per company, the awards as quarterly totals rather than individual contracts (2,318 tickers covered), plus a cross-ticker contracts feed.
- Innovation, pay and retail attention. USPTO patents tagged to a company, annual executive compensation, and daily r/wallstreetbets mentions and sentiment with up to 365 days of history.
Other licensed-research datasets bill as Alt-Data but are documented with their families: point-in-time financials on Fundamentals, the identifier crosswalk on Reference Data, insider flow split by 10b5-1 plans, Form 144 notices, current top shareholders and the licensed 13F dataset (/api/v3/ownership/*) on Funds & Institutional, and the macro history (/api/v3/macro_history/*) and estimates history (/api/v3/estimates_) on Macro, Rates & FX.
Access
3 credits/call · Pro and up: Alt-Data is not available on Free or Starter, and there is no standalone Alt-Data add-on. Upgrade to Pro ($499/mo) to unlock it.
Endpoints
Workforce
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | workforce_momentum | Monthly employment momentum for one company. momentum has the latest month's headcount, hiring_, attrition_, net_ (plus annualized twins), hire_to_departure_ratio, headcount_growth_1m/3m/12m and direction; latest repeats the newest month's row; history[] is the monthly series, oldest first (month, headcount, hires, departures, net_change, salary_avg_usd, ...), so the last element is the newest month. Query: months (2–120, default 24; months counted back from the panel's newest month), employer_id (pin one of the employers listed in symbol_collisions when the call is refused on identity grounds). |
GET | /api/ | workforce_layoffs | WARN-Act layoff filings for one company, newest first: notice date, effective date, employees_affected, site city/state, layoff_type. Also n_filings, employees_ and largest_ for the whole window, a by_month series and a states list, and (with with_workforce) vs_workforce, which sizes the total against estimated headcount. Query: months (look-back, 1–480, default 24), limit (filing rows, 1–2000, default 200; totals always cover the full window), with_workforce (bool, default true), employer_id. by_month and states are built from the returned rows only, so when truncated is true they describe that page, not the window; page_scoped_fields lists every field scoped this way. Raise limit for the full breakdown. |
GET | /api/ | workforce_layoff_screen | Which listed companies filed WARN-Act notices in the last N days, ranked by employees noticed. One row per company: ticker, employer_id, company, isin, n_filings, employees_affected, largest_, first_event_date, latest_event_date, n_states. Query: days (1–1825, default 90), min_employees (0–1000000, default 0), state (optional; the full state name exactly as filed, for example California or New York, not a two-letter code such as CA), limit (1–1000, default 100). |
GET | /api/ | workforce_ | Rank listed employers by headcount growth between the panel's latest month and N months earlier: headcount_now, headcount_prior, headcount_change, headcount_growth_pct, latest hiring and attrition rates, salary_avg_usd, with hq_country, cusip, isin and gvkey on every row. Query: months_back (1–36, default 1), min_headcount (≥0, default 1000), order (fastest_growing|fastest_shrinking, default fastest_growing), limit (1–500, default 100). |
Workforce caveats.
- Headcount, flows and salary are modelled vendor estimates, not company-reported figures.
unitsin each response says what every field measures. - The panel's newest month can sit well behind today: in August 2026 the panel held 2024-01 to 2024-10. Before treating a figure as current, read
coverage.panel_, and onlast_ month momentum_screenreadfrom_monthandto_month, which are the two panel months being compared, not today and an earlier month. - The monthly panel is still being backfilled. Every response carries a
coverageblock with the months held,supported_,lookback_ months trailing_12m_availableandyoy_available. A growth figure the loaded window cannot support comes back asvalue_pct: nullwith areason, never interpolated; amonths_backthe screen cannot support returnswarning: "lookback_withnot_ loaded" available_months_back. - Coverage leans to large companies.
coverage.universe_reports the live share of the tradable universe the panel reaches andcoverage coverage.coverage_breaks it down by size.by_ market_ cap - A ticker is not unique across venues. The symbol is resolved to a security first and the employer matched on its identifiers.
warning: "ambiguous_withsymbol" candidatesmeans more than one current security shares the symbol. Re-ask with an unambiguous identifier.- When no employer can be proven to be the resolved company, the call is refused with a
warningsuch asno_,identity_ matched_ employer identity_(unverifiable_ ambiguous_ panel identity_on layoffs) orunverifiable_ ambiguous_ filings identity_. The employers filed under that symbol are listed innot_ proven_ string_ match_ only symbol_collisions, with identity fields only and no figures. - A served answer also lists any other employers under the same string in
symbol_collisions. - To read one of those employers, pass its
employer_id. If its identity still cannot be proven, the figures come back underunverified_rather thanemployer_ figures latestormomentum, andidentity_verifiedisfalse.
- Layoff filings are site-level, so one restructuring appears as many rows: read
employees_, not the row count. Coverage is US WARN notices from 1989, including forward-dated notices. Only employers matched to a listed symbol are reachable, so an empty result is not proof there were no layoffs.affected_ total - The screen's
statefilter matches the filed spelling exactly. A value that matches no filing returns awarning(state_case_mismatchwithdid_you_mean, orstate_not_a_filed_valuewithfiled_states) instead of an empty result.
Supply chain and geographic revenue
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | supply_ | The supply-chain graph around one company in one call: relationships.customers, .suppliers, .competitors, .partners. Each entry names the counterparty (ticker, id, whether listed), start and end dates, is_current, reported_from (company or counterparty) and revenue_percent where estimated. counts per group gives record and counterparty counts and revenue-percent coverage. Query: rel_type (customers|suppliers|competitors|partners; omit for all four), status (current|all, default current), as_of (YYYY-MM-DD point-in-time view; overrides status), listed_only (bool, default false), group_by (counterparty|record, default counterparty), limit (per group, 1–500, default 50), company_id (pin an entity when the symbol is ambiguous). |
GET | /api/ | supply_ | Revenue at risk, both sides. customer_concentration: how much of this company's revenue each customer accounts for (disclosed_, largest_customer_pct, customers[]). dependents_on_company: other companies whose own revenue depends on this one (most_dependent_pct, companies[]). Query: status (current|all, default current), as_of (YYYY-MM-DD), min_percent (0–100, default 0), limit (per side, 1–500, default 50), company_id. |
GET | /api/ | supply_ | Estimated revenue by region and country for one fiscal period, with a per-row confidence and certainty_class: regions[] (the requested hierarchy layer), countries[] (country leaves), concentration (largest country and region shares, country_hhi), the served period and available_periods. Query: period (fiscal period end, YYYY-MM-DD; default latest), layer (0–4, default 1; 0 = world, 4 = country), country (comma-separated ISO alpha-2 codes; adds a per-period country_history), top_countries (0–250, default 25), company_id. |
Supply-chain caveats.
revenue_percentis always a share of the source company's revenue, andrevenue_names whose revenue it is, so the number is never read backwards. Every value is a vendor estimate, and only a minority of relationships carry one: a missing percent means unknown, never zero.percent_ of_ ticker disclosed_is a floor on customer concentration and does not add to 100.revenue_ pct_ total - History is not yet point-in-time. A relationship's knowledge date is its start date, but the vendor records relationships retroactively, so history can claim a relationship was known years before it reached the feed (median about six years). Current relationships are correct. New pulls are stamped when fetched from 2026-09-27; older history will be restated.
- The default view is current relationships only; most history is closed. Pass
status=alloras_of=for history, andgroup_by=recordto see every underlying record. - Geographic layers each sum to 100 on their own, so never add a region to a country. Amounts carry no currency code and the reporting currency can change between periods: compare on percent. These are estimates, not company-reported segments; for reported segments use
/api/on Fundamentals.v3/ fundamentals/ segments/ {ticker} - The symbol is resolved to a security and the vendor matched on its own identifiers. A security the vendor does not carry (often an ADR, whose local line has different identifiers) returns
warning: "not_with the identifiers tried. A symbol shared by more than one current security is refused withcovered_ by_ vendor" warning: "ambiguous_. When several vendor companies match equally well, the call is refused withsymbol" warning: "ambiguous_and the matches invendor_ company" candidates; passcompany_idto pick one. On a served answer,alternateslists other companies that matched only on a weaker identifier. They are listed, not served.
Governance and accounting quality
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/v3/governance/{ticker} | governance_dossier | One-call governance dossier: board (board_size, n_independent, n_executive_directors, n_senior_managers, current members[]), interlocks (links to other boards, top_connectors by board-seat interlocks), restatements (n, last_file_date, latest rows), auditor_changes (n, latest change with from, to, resigned) and exec_comp (latest year: CEO and CFO pay and the top five named officers, in $ thousands). Blocks degrade independently: a missing dataset returns an error in its block, never a failed call. |
GET | /api/ | accounting_flags | Forensic accounting red flags, each with flag, severity and a plain-language reason. The restatement and auditor flags also carry first_event_date, last_event_date and n_events_last_5y, and their reason names the latest filing date, so an old event is not read as a current one. Plus the evidence: restatements, auditor_changes and audit_fees_by_year. Query: limit (max rows per evidence block, 1–500, default 50). An empty flags list on a covered name is a genuinely clean record. |
The flags accounting_flags can raise:
flag | severity | Raised when |
|---|---|---|
fraud_ | high | A restatement is tagged as fraud-related |
sec_ | high | A restatement is associated with an SEC investigation |
auditor_resigned | high | The auditor resigned |
going_ | high | An auditor change came with a going-concern opinion outstanding |
auditor_disagreement | high | An auditor change involved a reported disagreement |
adverse_restatement | medium | A restatement reduced previously reported results |
repeated_ | medium | Two or more restatements filed in the last 5 years |
auditor_churn | medium | Two or more auditor changes in the last 10 years |
audit_fee_anomaly | medium | Audit fees moved more than 50% year over year |
non_audit_fee_dominance | low | Non-audit fees exceeded half of total auditor fees |
Governance evidence is filed per issuer. If the ticker cannot be pinned to one SEC CIK, accounting_flags returns error: "cik_not_linked" with an empty flags list rather than guessing, and the dossier's restatement and auditor blocks say the same.
Political and government exposure
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | intel_lobbying | Corporate lobbying filings, newest first, one row per filing with client, registrant (on warehouse rows), amount, issue and date. Query: limit (1–500, default 50). Returns {ticker, items, count, source}, plus the warehouse clocks below. The warehouse copy holds filings from 2025-01-19; older filings may exist at the source and are not included. |
GET | /api/ | intel_gov_contracts | Federal government contract awards as quarterly totals, not individual awards, newest quarter first. year and quarter are on the US federal fiscal year (Q1 is October to December), and each warehouse item carries fiscal_, period_start and period_end. The newest quarter may still be in progress, and recent quarters keep growing for months as awards are reported. Query: limit (1–500, default 50). Returns {ticker, items, count, source}; a warehouse answer adds granularity: "quarterly_, quarter_ and the warehouse clocks below. |
GET | /api/ | intel_ | Cross-ticker quarterly federal-contracts feed for "which companies win government money?" screens: top-line award totals only (ticker, amount, quarter, year), without agency or description fields. Query: ticker (optional filter), limit (1–500, default 50). Returns {ticker, items, count}. |
Innovation, pay and retail attention
| Method | Path | MCP tool | Description |
|---|---|---|---|
GET | /api/ | intel_patents | Issued USPTO patents tagged to the company: date, title, IPC class, claim count and abstract. Query: limit (1–200, default 25). A watchlist of tickers is served from a warehouse copy loaded once, holding a recent window per ticker, so data_from says where this ticker's copy begins; other tickers use the live feed. Returns {ticker, items, count, source}, plus the warehouse clocks below. |
GET | /api/ | intel_exec_compensation | Annual executive compensation history: CEO and named officers with name, role, year, salary, bonus, stock and option awards and total compensation. Query: limit (1–200, default 25). Returns {ticker, items, count}. |
GET | /api/v3/intel/wsb/{ticker} | intel_wsb | Daily r/wallstreetbets mentions, sentiment and rank. Query: limit (days, 1–365, default 60). Returns {ticker, items, count}. |
Warehouse copies and refusals. lobbying, gov_contracts and patents read a warehouse copy of the alternative-data feed first, and the live feed only for a ticker the copy does not hold. A warehouse answer has source: "warehouse:<product>-archive" and its own clocks: as_of and archive_ingested_at (when the copy last carried the rows), data_through (the newest item date, or for contracts the newest snapshot), data_from (the oldest item held for the ticker), history_floor (where the copy begins for every ticker) and a coverage_note. Records dated before data_from or history_floor may exist at the source and are not included, so do not describe the answer as the complete history.
When neither the copy nor the live feed can answer, these routes, and exec_compensation, wsb and gov_contracts_live, return 503 with error: "upstream_ instead of an empty list, not billed. The body has no items field. error_code says why: upstream_ (the live feed failed and no copy holds the ticker, Retry-After: 900), archive_read_timeout (the copy's read ran out of time and keeps running, so a retry in about a minute is usually served; Retry-After: 60), archive_read_failed (Retry-After: 120) or build_busy (the read was not started; Retry-After: 30). A 503 means the data could not be retrieved, not that the company has no lobbying, contracts or patents.
Examples
Example 1: Lobbying spend (bash)
curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \ "https://firm.wealthnow.io/api/v3/intel/lobbying/AAPL?limit=20" # Response:# {# "ok": true,# "timestamp": "2026-09-24T14:22:00Z",# "ticker": "AAPL",# "items": [# {# "ticker": "AAPL",# "client": "Apple Inc.",# "amount": 2330000.0,# "issue": "...",# "date": "2026-07-18"# },# ...# ],# "count": 20# }Example 2: Government contracts (Python)
import os, requests r = requests.get( "https://firm.wealthnow.io/api/v3/intel/gov_contracts/MSFT", headers={"Authorization": f"Bearer {os.environ['WEALTHNOW_API_KEY']}"}, params={"limit": 10}, timeout=30,)r.raise_for_status()data = r.json() # envelope: {"ok": true, "timestamp": ..., "ticker": "MSFT", "items": [...], "count": N, "granularity": "quarterly_total", "source": "..."}contracts = data["items"]print(f"Latest {len(contracts)} quarters of contract awards for MSFT")for contract in contracts[:3]: print(f" {contract['year']}Q{contract['quarter']}: ${contract['amount']:,.0f}")Example 3: Is a company hiring or shrinking? (bash)
curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \ "https://firm.wealthnow.io/api/v3/workforce/momentum/NVDA?months=12" # Response (abridged):# {# "ok": true,# "timestamp": "2026-09-24T14:30:00Z",# "company": "NVIDIA Corp",# "employer_id": 123456,# "identity_verified": true,# "identity_match": {"matched_on": "CUSIP9", "grain": "security", ...},# "coverage": {"supported_lookback_months": [1, 2, 3, ...], "trailing_12m_available": false, "yoy_available": false, ...},# "latest": {"month": "2024-10", "headcount": 36120.4, "hires": 612.0, "departures": 301.5, "net_change": 310.5, "salary_avg_usd": 198000, ...},# "momentum": {# "available": true,# "as_of_month": "2024-10",# "headcount": 36120.4,# "hiring_rate_pct_per_month": 1.694,# "attrition_rate_pct_per_month": 0.835,# "net_hiring_rate_pct_per_month": 0.86,# "hire_to_departure_ratio": 2.03,# "headcount_growth_3m": {"value_pct": 2.412, "from_month": "2024-07", "to_month": "2024-10", ...},# "headcount_growth_12m": {"value_pct": null, "reason": "no_panel_month:2023-10", "from_month": "2023-10"},# "direction": "expanding"# },# "history": [...],# "units": {...},# "source": "warehouse:workforce-panel"# }headcount_growth_12m is null with a reason because the panel does not hold that month yet; it is never estimated. The newest month here is 2024-10, not last month: check coverage.panel_ before reading the result as current.
Example 4: Who filed layoff notices this quarter (Python)
import os, requests r = requests.get( "https://firm.wealthnow.io/api/v3/workforce/layoff_screen", params={"days": 90, "min_employees": 500, "limit": 25}, headers={"Authorization": f"Bearer {os.environ['WEALTHNOW_API_KEY']}"}, timeout=60,)r.raise_for_status()data = r.json()# {# "ok": true,# "window": {"since": "2026-06-26", "days": 90},# "filters": {"min_employees": 500, "state": null},# "n_companies": 25,# "truncated": true,# "companies": [# {"ticker": "...", "employer_id": ..., "company": "...", "isin": "...", "n_filings": 14,# "employees_affected": 2310, "largest_filing_employees": 640,# "first_event_date": "2026-07-02", "latest_event_date": "2026-09-30", "n_states": 5},# ...# ],# "source": "warehouse:layoff-filings"# }for c in data["companies"]: # Join on employer_id / isin, not on the ticker string: a symbol can belong to several employers. print(c["ticker"], c["company"], c["employees_affected"], "employees across", c["n_filings"], "filings")Example 5: Customers, suppliers and who depends on them (bash)
curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \ "https://firm.wealthnow.io/api/v3/supply_chain/relationships/AAPL?rel_type=suppliers&limit=10" # Response (abridged):# {# "ok": true,# "ticker": "AAPL",# "company": "Apple Inc.",# "company_id": "...",# "status": "current",# "counts": {# "suppliers": {"n_records": 441, "n_counterparties": 402, "n_reported_by_company": 24,# "n_reported_by_counterparty": 417, "n_returned": 10, "truncated": true,# "n_with_revenue_percent": 51, "revenue_percent_coverage_pct": 11.56}# },# "relationships": {# "suppliers": [# {"counterparty": "Cirrus Logic Inc.", "counterparty_ticker": "CRUS", "counterparty_is_listed": true,# "role": "supplier", "is_current": true, "reported_from": ["counterparty"],# "revenue_percent": 89.0, "revenue_percent_of_ticker": "CRUS",# "revenue_percent_of_company": "Cirrus Logic Inc.", "revenue_percent_estimated": true, ...},# ...# ]# },# ...# }Here revenue_percent: 89.0 is 89% of Cirrus Logic's revenue coming from Apple, not the reverse.
Example 6: How much revenue comes from China and Taiwan (Python)
import os, requests r = requests.get( "https://firm.wealthnow.io/api/v3/supply_chain/geo_revenue/NVDA", params={"country": "CN,TW", "top_countries": 10}, headers={"Authorization": f"Bearer {os.environ['WEALTHNOW_API_KEY']}"}, timeout=60,)r.raise_for_status()geo = r.json()# geo["period"] -> {"period_end_date": "2026-01-25", "period_start_date": "2025-01-27", "mode": "latest_available"}# geo["countries"] -> [{"region": "United States", "iso_alpha_2": "US", "revenue_percent": 44.1,# "confidence": 0.82, "certainty_class": "...", ...}, ...]# geo["concentration"] -> {"largest_country": "United States", "largest_country_pct": 44.1, "country_hhi": 0.27, ...}# geo["country_history"] -> per-period exposure to exactly CN and TWfor row in geo["countries"]: print(f"{row['region']:<20} {row['revenue_percent']:>6.2f}% (confidence {row['confidence']})")Example 7: Forensic accounting flags (bash)
curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \ "https://firm.wealthnow.io/api/v3/intel/accounting_flags/SMCI?limit=10" # Response (abridged):# {# "ok": true,# "ticker": "SMCI",# "cik": "...",# "n_flags": 3,# "flags": [# {"flag": "auditor_resigned", "severity": "high",# "reason": "auditor RESIGNED 1 time(s); auditors walking away is a classic precursor of accounting trouble"},# ...# ],# "restatements": {"n": ..., "rows": [...]},# "auditor_changes": {"n": ..., "rows": [...]},# "audit_fees_by_year": [...],# "identity_verified": true,# "grain": "issuer",# "source": "warehouse:forensic-audit-archive"# }