# Income Statements

> Returns annual or quarterly income statements.

`GET https://api.bavest.co/v2/equities/income-statement`

Group: Equities. Route id: `v2_equities_income_statement`. Included in: Startup, Pro, Growth.

## Authentication

Send your API key in the `x-api-key` header on every request. No key yet? Sign up at https://dashboard.bavest.co/sign-up (free trial). The examples read the key from the `BAVEST_API_KEY` environment variable.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | Stock ticker symbol (e.g., `AAPL`, `MSFT`, `GOOGL`). Provide exactly one of symbol or isin. Example `AAPL`. |
| `isin` | query | string | one of symbol, isin | ISIN code (e.g., `US0378331005`). Provide exactly one of symbol or isin. Clear the symbol example before using an ISIN. |
| `freq` | query | string | no | Reporting frequency. One of `annual`, `quarterly`. Default `annual`. |
| `provenance` | query | boolean | no | When true, the response carries a `provenance` block with one entry per served statement date: where the numbers come from, when we got them, and whether they changed since. Entries are explicit nulls while ledger coverage has not begun for the security. Default `false`. |
| `fields` | query | string | no | Comma-separated list of income statement line items to include. When provided, each statement is reduced to the named line items. Names that are not income statement line items match nothing, so a statement reduced by them comes back empty. Example when explicitly filtering: `revenue,netIncome,eps`. |

Required: one of `symbol`, `isin`.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.currency` | string | no | Currency of reported values (ISO 4217) Example: `USD`. |
| `data.financials` | array of FinancialPeriodMeta | no |  |
| `data.financials[].date` | string (date) | no | Period end date. Example: `2025-09-27`. |
| `data.financials[].frequency` | string | no | Reporting frequency. One of `annual`, `quarterly`. |
| `data.financials[].reportedCurrency` | string | no | Currency of reported values (ISO 4217) Example: `USD`. |
| `data.financials[].cik` | string | no | SEC Central Index Key (10-digit) Example: `320193`. |
| `data.financials[].filingDate` | string (date) | no | SEC filing submission date. |
| `data.financials[].acceptedDate` | string (date-time) | no | SEC acceptance timestamp. |
| `data.financials[].calendarYear` | string | no | Calendar year. Example: `2025`. |
| `data.financials[].period` | string | no | Period code: FY, Q1, Q2, Q3, Q4. Example: `FY`. |
| `data.financials[].link` | string (uri) | no | SEC EDGAR filing index URL. |
| `data.financials[].finalLink` | string (uri) | no | Direct SEC filing document URL. |
| `data.financials[].isGapData` | boolean \| null | no | Whether this period was interpolated to fill a gap. |
| `data.financials[].revenue` | number (double) | no | Total revenue. |
| `data.financials[].costOfGoodsSold` | number (double) | no | Cost of goods sold. |
| `data.financials[].grossIncome` | number (double) | no | Gross income (revenue - COGS) |
| `data.financials[].grossProfitRatio` | number (double) | no | Gross profit margin (0-1 decimal) |
| `data.financials[].researchDevelopment` | number (double) | no | R&D expenses. |
| `data.financials[].sgaExpense` | number (double) | no | SG&A expenses. |
| `data.financials[].generalAndAdministrativeExpenses` | number (double) | no | G&A expenses. |
| `data.financials[].sellingAndMarketingExpenses` | number (double) | no | Sales & marketing expenses. |
| `data.financials[].totalOperatingExpense` | number (double) | no | Total operating expenses. |
| `data.financials[].costAndExpenses` | number (double) | no | Total costs and expenses. |
| `data.financials[].ebit` | number (double) | no | Earnings before interest & taxes. |
| `data.financials[].ebitda` | number (double) | no | EBITDA. |
| `data.financials[].ebitdaRatio` | number (double) | no | EBITDA / Revenue. |
| `data.financials[].operatingIncomeRatio` | number (double) | no | Operating margin. |
| `data.financials[].interestIncome` | number (double) | no | Interest income. |
| `data.financials[].interestExpense` | number (double) | no | Interest expense. |
| `data.financials[].totalOtherIncomeExpensesNet` | number (double) | no | Other income/expenses. |
| `data.financials[].pretaxIncome` | number (double) | no | Pre-tax income. |
| `data.financials[].incomeBeforeTaxRatio` | number (double) | no | Pre-tax margin. |
| `data.financials[].provisionForIncomeTaxes` | number (double) | no | Tax provision. |
| `data.financials[].netIncome` | number (double) | no | Net income. |
| `data.financials[].netIncomeRatio` | number (double) | no | Net income margin. |
| `data.financials[].eps` | number (double) | no | Basic EPS. |
| `data.financials[].dilutedEps` | number (double) | no | Diluted EPS. |
| `data.financials[].weightedAverageShsOut` | number (double) | no | Weighted average shares outstanding. |
| `data.financials[].dilutedAverageSharesOutstanding` | number (double) | no | Diluted average shares outstanding. |
| `data.financials[].depreciationAndAmortization` | number (double) | no | D&A expense. |
| `data.financials[].otherExpenses` | number (double) | no | Other expenses. |
| `data.financials[].symbol` | string \| null | no | Ticker symbol the statement belongs to. Example: `AAPL`. |
| `data.provenance` | StatementProvenance | no | Present only when provenance=true. Keyed by statement date, one entry per row served in `financials`, answering when we got each statement and whether it changed since. Clients must tolerate unknown enum values and additional fields: the vocabulary grows when filing-sourced numbers ship. |
| `data.provenance.source` | string | no | Where the numbers come from. Only `vendor` is served today; `filing` is reserved for filing-sourced numbers (which stay under /filings/reports for now). Tolerate unknown values. One of `vendor`. |
| `data.provenance.knownAt` | string (date-time) \| null | no | When the currently served statement became known to us (our honest first-seen axis). Null before ledger coverage begins for this security. |
| `data.provenance.firstKnownAt` | string (date-time) \| null | no | When we first observed any version of this statement. |
| `data.provenance.restated` | boolean | no | True when THIS statement has more than one distinct observed version in our ledger for the period. Per statement — income statement, balance sheet and cash flow are tracked separately. |
| `data.provenance.acceptedDate` | string (date-time) \| null | no | The vendor's claimed acceptance date. FABRICATED for non-SEC filers (~96-99% of EU rows equal the period end); never our knowledge axis. |
| `data.provenance.filingDate` | string (date) \| null | no | The vendor's claimed filing date, subject to the same fabrication caveat as acceptedDate. |
| `data.provenance.filing` | any \| null | no | Reserved. Null until filing-sourced numbers ship. |
| `data.provenance.fields` | any \| null | no | Reserved. Null until filing-sourced numbers ship. |
| `meta` | ResponseMeta | no | Response envelope metadata. Always present on a 200: `time` is set by `core/response.py` on every successful response. Errors carry the same block, built by the same code, so a client parses one meta shape whether the call succeeded or failed. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |

## Example request

```bash
curl 'https://api.bavest.co/v2/equities/income-statement?symbol=AAPL&freq=annual' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "financials": [
      {
        "date": "2025-09-27",
        "frequency": "annual",
        "reportedCurrency": "USD",
        "cik": 320193,
        "filingDate": "2025-10-31",
        "acceptedDate": "2025-10-31T06:01:26",
        "calendarYear": "2025",
        "period": "FY",
        "revenue": 416161000000,
        "grossProfitRatio": 0.4691,
        "generalAndAdministrativeExpenses": 8077000000,
        "sellingAndMarketingExpenses": 19524000000,
        "otherExpenses": 0,
        "costAndExpenses": 283111000000,
        "interestIncome": 0,
        "interestExpense": 0,
        "depreciationAndAmortization": 11698000000,
        "ebitda": 144427000000,
        "ebitdaRatio": 0.347,
        "operatingIncomeRatio": 0.3197,
        "totalOtherIncomeExpensesNet": -321000000,
        "incomeBeforeTaxRatio": 0.3189,
        "netIncome": 112010000000,
        "netIncomeRatio": 0.2692,
        "eps": 7.49,
        "weightedAverageShsOut": 14948500000,
        "costOfGoodsSold": 220960000000,
        "dilutedAverageSharesOutstanding": 15004697000,
        "dilutedEps": 7.46,
        "ebit": 133050000000,
        "grossIncome": 195201000000,
        "pretaxIncome": 132729000000,
        "provisionForIncomeTaxes": 20719000000,
        "researchDevelopment": 34550000000,
        "sgaExpense": 27601000000,
        "totalOperatingExpense": 62151000000,
        "link": "https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/0000320193-25-000079-index.htm",
        "finalLink": "https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/aapl-20250927.htm",
        "isGapData": false,
        "symbol": "AAPL"
      },
      {
        "date": "2024-09-28",
        "frequency": "annual",
        "reportedCurrency": "USD",
        "cik": 320193,
        "filingDate": "2024-11-01",
        "acceptedDate": "2024-11-01T06:01:36",
        "calendarYear": "2024",
        "period": "FY",
        "revenue": 391035000000,
        "grossProfitRatio": 0.4621,
        "generalAndAdministrativeExpenses": 7458000000,
        "sellingAndMarketingExpenses": 18639000000,
        "otherExpenses": 0,
        "costAndExpenses": 267819000000,
        "interestIncome": 0,
        "interestExpense": 0,
        "depreciationAndAmortization": 11445000000,
        "ebitda": 134930000000,
        "ebitdaRatio": 0.3451,
        "operatingIncomeRatio": 0.3151,
        "totalOtherIncomeExpensesNet": 269000000,
        "incomeBeforeTaxRatio": 0.3158,
        "netIncome": 93736000000,
        "netIncomeRatio": 0.2397,
        "eps": 6.11,
        "weightedAverageShsOut": 15343783000,
        "costOfGoodsSold": 210352000000,
        "dilutedAverageSharesOutstanding": 15408095000,
        "dilutedEps": 6.08,
        "ebit": 123216000000,
        "grossIncome": 180683000000,
        "pretaxIncome": 123485000000,
        "provisionForIncomeTaxes": 29749000000,
        "researchDevelopment": 31370000000,
        "sgaExpense": 26097000000,
        "totalOperatingExpense": 57467000000,
        "link": "https://www.sec.gov/Archives/edgar/data/320193/000032019324000123/0000320193-24-000123-index.htm",
        "finalLink": "https://www.sec.gov/Archives/edgar/data/320193/000032019324000123/aapl-20240928.htm",
        "isGapData": false,
        "symbol": "AAPL"
      }
    ],
    "currency": "USD"
  },
  "meta": {
    "parameters": {
      "freq": "annual",
      "symbol": "AAPL"
    },
    "time": 18
  }
}
```

## Errors

| Status | Meaning |
|---|---|
| 400 | Invalid request parameters. Returned when required query parameters are missing, have invalid types, or violate constraints (e.g., providing both symbol and isin when they are mutually exclusive). |
| 401 | Missing or invalid API key. |
| 404 | Resource not found. |
| 429 | Rate limit exceeded. Retry after the `Retry-After` header interval. |
| 500 | An unexpected error occurred on the server. If the issue persists, contact support with the X-Request-Id header value. |
| 502 | Upstream data provider returned an error or is temporarily unavailable. Retry after a short delay. |
| 504 | The request timed out waiting for a response from the upstream data provider. This may occur for complex queries or during peak load. |
| default | An unexpected error occurred on the server. If the issue persists, contact support with the X-Request-Id header value. |

- `403` from the gateway: the API key is invalid or switched off.
- `429` with message `Limit Exceeded`: the monthly quota of the key is used up. With `Too Many Requests`: the key is throttled, or this route is not in the key's plan. Wait for `Retry-After` when it is sent.

## Links

- HTML page: https://dashboard.bavest.co/docs/v2_equities_income_statement
- OpenAPI: https://dashboard.bavest.co/openapi.json (YAML: https://dashboard.bavest.co/openapi.yaml)
- Authentication: https://dashboard.bavest.co/docs/authentication.md
- MCP server for AI agents: https://dashboard.bavest.co/docs/mcp.md
- All routes: https://dashboard.bavest.co/llms.txt
