Documentation

vaaya / docs / reference

Public records

Facts people assume are secret, sitting in free public filings: SEC EDGAR, federal court dockets via CourtListener, nonprofit 990s via ProPublica, and H-1B salary disclosures. Every action is 1¢ flat — the scarce resource is upstream rate limits, not money, so the routing rules below are about spending quota well.

When to use which

NeedCallPick when
Resolve a brand to legal entitiesedgar/entitiesStart every company-scoped EDGAR task here.
One company’s complete filing historyedgar/filingsThe authoritative sweep — complete where full-text search is ranked and paged.
Phrase search across all filingsedgar/fulltextSPV discovery, cross-issuer phrase hunts, person-name Form 4 sweeps.
One financial number for a public companyedgar/conceptRevenue, net income, assets — never scrape a 10-K for a number this has.
Every filing on a given dayedgar/index“All Form Ds this week” — the enumeration tool search actions can’t be.
Who is suing / being sued by Xcourtlistener/docketsUse party_name, not q — see below.
Nonprofit financials by name or sectorpropublica/nonprofit_searchpropublica/nonprofitRevenue, expenses, salaries, 990 links, 501(c)(3) confirmation.
What a company pays a roleh1bdata.info via firecrawl/scrapeH-1B salary disclosures — see Web scraping.

EDGAR — SEC filings

Price
1¢ per action
Rate budget
10 req/s upstream — cap document fetches at ~5 per answer
Full-text coverage
2001 onward

Six actions cover the whole registry. edgar/entities { q } maps a name to registrant CIKs — it resolves brand → legal entity (“Mercury” → Mercury Technologies, Inc.), lists SPV families, and proves “never registered” negatives that full-text search can’t. edgar/filings { cik } returns the registrant’s complete history (form, date, accession, primaryDocument). edgar/fulltext { q, forms?, startdt?, enddt?, from? } searches filing text. edgar/document { cik, accession, filename } fetches one document. edgar/concept { cik, concept } returns one XBRL concept across all periods. edgar/index { date } returns the daily index of every filing of every form type for one business day (~145 Form Ds on a typical day).

curl -X POST https://vaaya.ai/api/run/edgar/entities \
  -H "Authorization: Bearer $VAAYA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q": "Mercury Technologies"}'
curl -X POST https://vaaya.ai/api/run/edgar/fulltext \
  -H "Authorization: Bearer $VAAYA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q": "\"Anthropic\"", "forms": "D", "startdt": "2026-01-01"}'

The forms rule

Pass root form types onlyD, C,C-AR,1-K,1-SA, 4, 10-K, S-1. Root forms match their /A amendments automatically. Never list an amendment: D,D/A returns amendments-only, which produces false zeros on every company with plain Form Ds.

Gotchas

  • edgar/fulltext hits are per-document — exhibits often outrank the primary doc, and the default page is 10 relevance-ranked hits (from paginates). An issuer’s own filing can be buried under dozens of SPVs, producing a false “never filed”. Confirm negatives via edgar/filings.
  • edgar/document: prefer .xml/.htm/.txt — PDFs come back unreadable. When primaryDocument looks like xslF345X06/wk-form4_….xml, strip the xslF345X06/ prefix to get the raw XML.
  • edgar/concept revenue tags to try in order: RevenueFromContractWithCustomerExcludingAssessedTaxRevenues; also NetIncomeLoss, Assets.
  • edgar/index 404s on weekends and holidays — that means no filings, not an error.
  • Form D: totalOfferingAmount, totalAmountSold, and dateOfFirstSale live in primary_doc.xml. relatedPersonsList is the issuer’s officers/directors/promoters — not the round’s investors; investor names are not in Form D at all.
  • No Form D ≠ no raise (§4(a)(2) exemptions exist); filings lag closings by up to 15 days. Foreign issuers usually have no EDGAR presence at all.

CourtListener — federal dockets and opinions

Price
1¢ per action
Rate budget
scarce — budget ≤3 calls per answer
Coverage
federal courts via RECAP; state coverage varies

courtlistener/dockets searches RECAP federal dockets; courtlistener/cases searches opinions. The one rule that matters: q matches document text — mentions, not litigants. For “who is suing X” use party_name; for a specific known case use docket_number (plus court) or case_name.

curl -X POST https://vaaya.ai/api/run/courtlistener/dockets \
  -H "Authorization: Bearer $VAAYA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"party_name": "Coinbase"}'
  • Measured difference: q: "Coinbase" returned forfeiture-case noise where the company was merely mentioned; party_name: "Coinbase" returned the real cases.
  • order_by: "dateFiled desc" ranks by case filing date — it buries old-but-active dockets. Don’t use it to find “latest activity”.
  • The upstream free tier is genuinely scarce (per-minute, per-hour, and per-day caps). Prefer one precise party_name call over exploratory q calls, and triage which questions deserve quota at all.

ProPublica — nonprofit 990s

Price
1¢ per action
Rate budget
~1 req/s courtesy — cap at ~3 search pages + ~4 org pulls per answer

propublica/nonprofit_search { q, state?, ntee? } finds EINs; propublica/nonprofit { ein } returns year-by-year financials — totrevenue, totfuncexpns, compnsatncurrofcr, othrsalwages, assets — plus 990 PDF links. Credit results as “IRS data via ProPublica Nonprofit Explorer”, and label the entity: a Foundation, an Endowment, and an OpCo with the same brand are different filers.

curl -X POST https://vaaya.ai/api/run/propublica/nonprofit_search \
  -H "Authorization: Bearer $VAAYA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q": "Urban Alchemy"}'

Enrichment mode

The most common real shape: you already have a list of org names (from city data, a news article, a spreadsheet). Per name: nonprofit_search { q: "<name>" } → pick the right EIN by matching city/state → nonprofit { ein } for financials and 501(c)(3) confirmation. This turns any external list into cited nonprofit records in two calls per org.

Gotchas

  • q matches org names, not causes. A cause/sector sweep needs ntee (major group 1–10; human services = 6) or a web-search step that names the orgs first.
  • compnsatncurrofcr is all officers combined — not any one person’s pay. Per-person exec comp lives in 990 Part VII, which the API does not expose; fall back to web search and label it.
  • A 990 cannot tell you who funded an org — it shows revenue in aggregate, never the funder’s name. “NGOs funded by X” is answered by the funder’s own data (city open-data payments and contracts, grants.gov, a foundation’s grants schedule), not the recipient’s 990.
  • A 990 cannot tell you what an org actually does on the ground — NTEE is a broad category, not an activity. Use the org’s website or web search for program specifics.
  • Don’t hot-link the rate-limited 990 PDFs; link the ProPublica org page instead.
  • Sector sweeps paginate at 25/page with no city filter — filter city client-side.

H-1B salaries

h1bdata.info aggregates H-1B salary disclosures and is scraped via firecrawl/scrape (see Web scraping). It supports em= (employer), job=, city=, and year= URL params.

  • Always add job= for big employers — all-years pages for Google-scale filers come back silently empty or 10MB+.
  • One page per query; cache results and label the data vintage.