Documentation
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
| Need | Call | Pick when |
|---|---|---|
| Resolve a brand to legal entities | edgar/entities | Start every company-scoped EDGAR task here. |
| One company’s complete filing history | edgar/filings | The authoritative sweep — complete where full-text search is ranked and paged. |
| Phrase search across all filings | edgar/fulltext | SPV discovery, cross-issuer phrase hunts, person-name Form 4 sweeps. |
| One financial number for a public company | edgar/concept | Revenue, net income, assets — never scrape a 10-K for a number this has. |
| Every filing on a given day | edgar/index | “All Form Ds this week” — the enumeration tool search actions can’t be. |
| Who is suing / being sued by X | courtlistener/dockets | Use party_name, not q — see below. |
| Nonprofit financials by name or sector | propublica/nonprofit_search → propublica/nonprofit | Revenue, expenses, salaries, 990 links, 501(c)(3) confirmation. |
| What a company pays a role | h1bdata.info via firecrawl/scrape | H-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 only — D, 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/fulltexthits are per-document — exhibits often outrank the primary doc, and the default page is 10 relevance-ranked hits (frompaginates). An issuer’s own filing can be buried under dozens of SPVs, producing a false “never filed”. Confirm negatives viaedgar/filings.edgar/document: prefer.xml/.htm/.txt— PDFs come back unreadable. WhenprimaryDocumentlooks likexslF345X06/wk-form4_….xml, strip thexslF345X06/prefix to get the raw XML.edgar/conceptrevenue tags to try in order:RevenueFromContractWithCustomerExcludingAssessedTax→Revenues; alsoNetIncomeLoss,Assets.edgar/index404s on weekends and holidays — that means no filings, not an error.- Form D:
totalOfferingAmount,totalAmountSold, anddateOfFirstSalelive inprimary_doc.xml.relatedPersonsListis 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_namecall over exploratoryqcalls, 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
qmatches org names, not causes. A cause/sector sweep needsntee(major group 1–10; human services = 6) or a web-search step that names the orgs first.compnsatncurrofcris 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.