# NetNest Design Fundamentals API

Company fundamentals from SEC filings, with the source filing attached to every number.
Data from SEC filings. Not investment advice.

**What you get**

* The latest annual, quarterly and trailing twelve month values for 13 metrics, for every company that files 10-K and 10-Q reports with US GAAP XBRL data.
* Every value carries its period dates, fiscal year and period, form, filing date, accession number, a link to the SEC filing, and the XBRL concept it came from.
* "Latest" means the most recent period end for the period type you ask for. Fiscal years that do not match the calendar (Apple, Microsoft, NVIDIA, Walmart, Oracle, Costco) are handled per company.
* Values that are calculated rather than reported are marked `derived: true` with the inputs used.
* Missing data comes back as `null` with a reason. We never estimate.

## Quickstart

Get a free key (100 calls a day, no card):

```bash
curl -X POST https://api.netnestdesign.com/v1/signup -H "Content-Type: application/json" -d '{"email":"you@example.com"}'
```

Call the API:

```bash
curl -H "Authorization: Bearer YOUR_KEY" "https://api.netnestdesign.com/v1/fundamentals/AAPL?metrics=revenue,net_income,eps_diluted&period=quarterly"
```

Python:

```python
import requests
r = requests.get("https://api.netnestdesign.com/v1/fundamentals/MSFT", params={"metrics": "revenue,free_cash_flow", "period": "ttm"},
                 headers={"Authorization": "Bearer YOUR_KEY"}, timeout=30)
for v in r.json()["data"]:
    print(v["metric"], v["value"], v["period_end"], v["form"], v["source_url"])
```

JavaScript:

```js
const r = await fetch('https://api.netnestdesign.com/v1/history/NVDA/revenue?period=annual&limit=5', { headers: { Authorization: 'Bearer YOUR_KEY' } });
const { data } = await r.json();
```

## Pay per call with x402

Agents can pay for each call in USDC on Base with the [x402 protocol](https://x402.org). No account or key is needed.
Call a paid endpoint without a key and you get HTTP 402 with the payment requirements; an x402 client pays and retries.

Every paid endpoint costs $0.02 a call: `/v1/company/{ticker}`, `/v1/fundamentals/{ticker}` and
`/v1/history/{ticker}/{metric}`.

Network: `eip155:8453`. Payment settles only when the response succeeds (status below 400).

```ts
import { x402Client } from '@x402/core/client';
import { ExactEvmScheme } from '@x402/evm/exact/client';
import { wrapFetchWithPayment } from '@x402/fetch';
import { privateKeyToAccount } from 'viem/accounts';

const client = new x402Client();
client.register('eip155:*', new ExactEvmScheme(privateKeyToAccount(process.env.EVM_PRIVATE_KEY)));
const pay = wrapFetchWithPayment(fetch, client);
const res = await pay('https://api.netnestdesign.com/v1/fundamentals/AAPL?metrics=revenue,net_income&period=quarterly');
console.log(await res.json());
```

## Endpoints

| Method and path | Cost | What it returns |
|---|---|---|
| `GET /v1/search?q=apple` | Free | Ticker and company name lookup |
| `GET /v1/company/{ticker}` | Paid | Company profile plus the latest values of key metrics for every period type |
| `GET /v1/fundamentals/{ticker}?metrics=a,b&period=annual` | Paid | The latest value of each requested metric for one period type (annual, quarterly or ttm) |
| `GET /v1/history/{ticker}/{metric}?period=quarterly&limit=20` | Paid | One metric over time, newest first, up to 200 periods |
| `POST /v1/signup` | Free | Creates a free account and returns a key |
| `GET /v1/account` | Free | Your plan, usage and keys |
| `POST /v1/keys/rotate` | Free | Issues a new key and revokes the one you used |
| `DELETE /v1/keys/current` | Free | Revokes the key you used |
| `DELETE /v1/account` | Free | Deletes your account, keys and usage records |
| `GET /v1/status` | Free | Data refresh health |
| `GET /v1/accuracy` | Free | Today's accuracy check against the filings themselves |

Tickers accept `BRK.B`, `BRK-B` and `brk.b`. The machine readable spec is at [/openapi.json](https://api.netnestdesign.com/openapi.json).

## Metrics

| Key | Metric | Unit | XBRL concepts, in order of preference |
|---|---|---|---|
| `revenue` | Revenue | Currency of the filing | `us-gaap:Revenues`, `us-gaap:RevenueFromContractWithCustomerExcludingAssessedTax`, `us-gaap:SalesRevenueNet`, `us-gaap:RevenueFromContractWithCustomerIncludingAssessedTax`, `us-gaap:RevenuesNetOfInterestExpense` |
| `net_income` | Net income | Currency of the filing | `us-gaap:NetIncomeLoss`, `us-gaap:ProfitLoss`, `us-gaap:NetIncomeLossAvailableToCommonStockholdersBasic` |
| `eps_basic` | Basic EPS | USD/shares | `us-gaap:EarningsPerShareBasic`, `us-gaap:EarningsPerShareBasicAndDiluted` |
| `eps_diluted` | Diluted EPS | USD/shares | `us-gaap:EarningsPerShareDiluted`, `us-gaap:EarningsPerShareBasicAndDiluted` |
| `operating_income` | Operating income | Currency of the filing | `us-gaap:OperatingIncomeLoss` |
| `total_assets` | Total assets | Currency of the filing | `us-gaap:Assets` |
| `total_liabilities` | Total liabilities | Currency of the filing | `us-gaap:Liabilities` |
| `equity` | Stockholders equity | Currency of the filing | `us-gaap:StockholdersEquity`, `us-gaap:StockholdersEquityIncludingPortionAttributableToNoncontrollingInterest` |
| `cash` | Cash and cash equivalents | Currency of the filing | `us-gaap:CashAndCashEquivalentsAtCarryingValue`, `us-gaap:CashCashEquivalentsRestrictedCashAndRestrictedCashEquivalents` |
| `operating_cash_flow` | Operating cash flow | Currency of the filing | `us-gaap:NetCashProvidedByUsedInOperatingActivities`, `us-gaap:NetCashProvidedByUsedInOperatingActivitiesContinuingOperations` |
| `capex` | Capital expenditures | Currency of the filing | `us-gaap:PaymentsToAcquirePropertyPlantAndEquipment` |
| `free_cash_flow` | Free cash flow | Currency of the filing | Derived: operating cash flow minus capex |
| `shares_outstanding` | Shares outstanding | shares | `dei:EntityCommonStockSharesOutstanding`, `us-gaap:WeightedAverageNumberOfSharesOutstandingBasic` |
| `revenue_contract` | Contract revenue (ASC 606) | Currency of the filing | `us-gaap:RevenueFromContractWithCustomerExcludingAssessedTax`, `us-gaap:RevenueFromContractWithCustomerIncludingAssessedTax` |

revenue = total revenue as reported on the income statement. For commercial banks it is total net revenue (net interest income plus noninterest income).
`revenue_contract` (revenue from contracts with customers under ASC 606) is optional: it is returned only when you ask for it by name, for companies that report it.

## Every value

```json
{
  "metric": "revenue",
  "value": 109417000000,
  "unit": "USD",
  "period_type": "quarterly",
  "period_start": "2026-03-29",
  "period_end": "2026-06-27",
  "fiscal_year": 2026,
  "fiscal_period": "Q3",
  "form": "10-Q",
  "filed_date": "2026-07-31",
  "accession_number": "0000320193-26-000020",
  "source_url": "https://www.sec.gov/Archives/edgar/data/320193/000032019326000020/0000320193-26-000020-index.htm",
  "concept": "us-gaap:RevenueFromContractWithCustomerExcludingAssessedTax",
  "derived": false,
  "stale": false
}
```

* `derived: true` values include a `derivation` object with the formula and every input, each with its own filing.
* `stale: true` means the company is past its expected filing date by more than 30 days, or this value is far older than the company's newest report.
* `restated: true` means a later filing changed the originally reported number; you get the most recently filed value.
* A `null` value always has a `reason`.
* Revenue values carry `revenue_standard`: `ASC 605`, `ASC 606` or `null`.
  * Method from filing text: we read each company's adoption of ASC 606 from its own SEC filings, including the annual report exhibits that hold its financial statements: the date it adopted and the transition method it states (full retrospective or modified retrospective).
  * Date rules: a stated adoption date is used when it falls within 7 days of the start of one of the company's fiscal quarters, or before the company's first reported fiscal year; otherwise we use the period of the filing that states the adoption. A date that conflicts with the company's own earlier filings, or falls outside the possible range, is not used.
  * Periods that begin on or after adoption read `ASC 606`, and a period that spans adoption is `null`. A period before adoption reads `ASC 605` when its value comes from a filing for a period that ended before adoption. When it comes from a later filing, it reads `ASC 606` if the company states the full retrospective method, `ASC 605` if it states the modified retrospective method, and `null` if it states no method or its filings disagree.
  * Certain `ASC 605`: a value from a filing whose fiscal year began before December 16, 2016 reads `ASC 605` for every company, because no company could adopt ASC 606 that early.
  * Certain `ASC 606`: annual periods beginning after December 15, 2019, and every period beginning after December 15, 2020, read `ASC 606` for every company.
  * Tag dating after adoption: where we find no usable adoption statement, `ASC 606` starts with the first fiscal year in which the company's own filing reports revenue from contracts with customers for its current period, and never before its first fiscal year beginning after December 15, 2017 unless the company states it adopted early and its filings do not conflict.
  * `null` means we can't state the standard, and `revenue_standard_reason` says why: "period spans adoption", "adoption date unknown", "inputs reported under different standards", "transition method pending a check of the filing text", "transition method not found in the adoption filing", "transition method differs between the company filings", "adoption filing not found", "adoption date in the filing text is outside the possible range", "adoption date conflicts with the company's own filings", "period before SEC registration, method unknown", "before adoption or tagging error, unconfirmed".
* Revenue history uses one reported concept per company where possible. When the concept changes and the periods reported under both concepts differ by more than 1 percent (or no period is reported under both and the change is not the usual switch to the ASC 606 concept), the affected values carry `concept_changed: true` and `concept_change` with the old concept, the new concept and the difference, and the history response adds a note.

## How the numbers are built

* Source: SEC company facts data, refreshed nightly, plus each new 10-K and 10-Q read from the filing's own XBRL within about an hour on weekdays.
* When SEC's company facts data has not picked up a filing yet, we read that filing's XBRL directly.
* Quarterly values are the three month figures. When a filing reports only year to date figures, the quarter is the difference between year to date periods and is marked derived.
* Fiscal Q4 equals the annual value minus the nine month value, marked derived. EPS is never derived this way, because per share figures do not add up across periods.
* Trailing twelve months adds the last four quarters (marked derived), or uses the annual value when it is the most recent.
* Amended filings win for the same period.
* Values are in the currency the company reports in, shown in `unit`.

## Errors

| Status | Code | Meaning |
|---|---|---|
| 400 | `invalid_request` | A parameter is wrong; `fieldErrors` says which |
| 401 | `invalid_key`, `auth_required` | Missing, unknown or revoked key |
| 402 | | Payment required (x402) |
| 404 | `unknown_ticker` | No SEC registrant for that ticker |
| 422 | `no_financial_data` | The company files no 10-K or 10-Q data (for example foreign issuers filing 20-F) |
| 422 | `no_data` | The company files, but reports none of the values you asked for |
| 429 | `rate_limited`, `quota_exceeded` | Slow down, or the plan limit is reached |
| 500 | `internal_error` | Our fault; retry |

Calls that return an error do not count toward your quota.

## Plans

| Plan | Price | Included | Beyond that | Rate limit |
|---|---|---|---|---|
| Free | Free | 100 calls a day | Hard daily cap | 2 per second |
| Starter | $19 a month or $190 a year | 10,000 calls a month | $2 per 1,000 extra calls | 10 per second |
| Pro | $49 a month or $490 a year | 50,000 calls a month | $1 per 1,000 extra calls | 25 per second |
| Scale | $99 a month or $990 a year | 200,000 calls a month | $0.5 per 1,000 extra calls | 50 per second |

Annual billing is 10 times the monthly price (two months free).

## Changelog

* 2026-10-20: First release. 13 metrics, annual, quarterly and TTM, for 5,388 companies with US GAAP XBRL data.

## Legal

Data from SEC filings. Not investment advice. NetNest Design LLC.
Company names and tickers are trademarks of their owners, used only to identify the companies; we are not affiliated with or endorsed by them.
[Terms](https://api.netnestdesign.com/terms), [Privacy](https://api.netnestdesign.com/privacy), [DMCA](https://api.netnestdesign.com/dmca). Contact: registrations@netnestdesign.com.
