# Bavest API

> REST API for financial market data: equities, ETFs, funds, dividends, estimates, economic indicators, news, filings and portfolio analytics. Base URL https://api.bavest.co/v2. Authenticate with the `x-api-key` header; get a key at https://dashboard.bavest.co/sign-up.

This file lists all 99 routes. Each link is a Markdown page with the route's parameters, response fields, a cURL example, an example response and its errors. Every Markdown link is the twin of an HTML page at the same URL without `.md` (`https://dashboard.bavest.co/docs/<route id>`, `https://dashboard.bavest.co/docs/authentication`, `https://dashboard.bavest.co/docs/mcp`), which returns the same Markdown when requested with `Accept: text/markdown`. Each route page says which plans include it (`Included in: ...` or `Free in every plan`).

Essentials:

- Every request needs the header `x-api-key: <your key>`. Responses are JSON with the result in a `data` field.
- `403`: the key is invalid or switched off. `429` `Limit Exceeded`: monthly quota used up. `429` `Too Many Requests`: throttled, or the route is not in your plan.
- ETFs and funds are best identified by ISIN (`isin=IE00B4L5Y983`), stocks by ticker (`symbol=AAPL`) or ISIN.
- AI agents can call the data routes as tools through the MCP server https://api.bavest.co/v2/mcp (the MCP page lists which route each tool wraps).

## Start here

- [Authentication](https://dashboard.bavest.co/docs/authentication.md): the `x-api-key` header and how to get a key.
- [MCP server](https://dashboard.bavest.co/docs/mcp.md): connect Claude, ChatGPT, Cursor or your own agent to https://api.bavest.co/v2/mcp.
- [OpenAPI (JSON)](https://dashboard.bavest.co/openapi.json): OpenAPI 3.1 spec of every route listed here.
- [OpenAPI (YAML)](https://dashboard.bavest.co/openapi.yaml): the same spec as YAML.
- [All routes in one file](https://dashboard.bavest.co/llms-full.txt): every route page below, concatenated.

## 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.

## Common errors

Most routes answer with these statuses; each route below lists only the ones that differ.

| 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. |
| 503 | Bavest cannot read its data store right now. The security may well have data; retry after the `Retry-After` header interval. |
| 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.

---

# Usage Quota

> Returns current monthly usage count, limit, and remaining calls for the API key.

`GET https://api.bavest.co/v2/account/quota`

Group: Account. Route id: `v2_account_quota`. Free in every plan, including the trial.

## Parameters

None.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.apiKey` | string | no | API Gateway key identifier. Example: `ut4lshj85e`. |
| `data.usage` | integer | no | API calls used in current billing period. Example: `4521`. |
| `data.limit` | integer \| null | no | Monthly request limit (null if unlimited) Example: `100000`. |
| `data.remaining` | integer \| null | no | Remaining API calls (null if unlimited) Example: `95479`. |
| `data.period` | string | no | Current billing period (YYYY-MM) Example: `2026-03`. |
| `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/account/quota' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "apiKey": "xl1yekalmh",
    "usage": 289762,
    "limit": 10000000,
    "remaining": 9710238,
    "period": "2026-03"
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_account_quota

---

# API Status

> Returns API health status.

`GET https://api.bavest.co/v2/account/status`

Group: Account. Route id: `v2_account_status`. Free in every plan, including the trial.

## Description

Returns API health status. Use for connectivity checks and uptime monitoring.

## Parameters

None.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.status` | string | no | One of `not_active`, `active`. |
| `data.version` | string | no | API version identifier. Example: `v2`. |
| `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/account/status' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "status": "active",
    "version": "v2"
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_account_status

---

# MCP Server

> Model Context Protocol (MCP) server for AI agents.

`POST https://api.bavest.co/v2/mcp`

Group: AI. Route id: `v2_mcp`. Free in every plan, including the trial.

## Description

Model Context Protocol (MCP) server for AI agents. Connect any MCP client (Claude, ChatGPT, Cursor, VS Code, Windsurf or your own agent) to one URL, `https://api.bavest.co/v2/mcp`, and use the Bavest v2 data routes as tools.

### Quick start

```json
{
  "mcpServers": {
    "bavest": {
      "url": "https://api.bavest.co/v2/mcp",
      "headers": { "x-api-key": "YOUR_API_KEY" }
    }
  }
}
```

### Tools

Each tool wraps one REST route and is named after the route's `operationId` in snake case: `equities.profile` is `equities_profile`, `etfs.topHoldings` is `etfs_top_holdings`. `initialize` and `tools/list` work without a key and return the exact names and input schemas. A tool call counts against your plan like the REST call it wraps; a route outside your plan answers with an error.

### Authentication

Send your API key in the `x-api-key` header, as on every REST route. Connectors that can only take a URL (Claude custom connectors, ChatGPT developer mode) may pass the same key as the optional `api_key` query parameter instead. URLs end up in logs and settings exports, so prefer the header.

## Parameters

None besides the API key: send it in the `x-api-key` header (preferred). Connectors that cannot set headers may send it as the optional `api_key` query parameter instead; URLs end up in logs, so use that only where no header is possible.

## Request body

JSON, required. JSON-RPC 2.0 request following the MCP specification.

| Field | Type | Always present | Description |
|---|---|---|---|
| `jsonrpc` | string | yes | JSON-RPC protocol version. One of `2.0`. |
| `id` | string | no | Request identifier (omit for notifications) |
| `method` | string | yes | MCP method to invoke. One of `initialize`, `tools/list`, `tools/call`, `ping`. |
| `params` | object | no | Method parameters (varies by method) |

## Response

200 MCP server response. The response format follows the Model Context Protocol specification and varies based on the MCP method invoked by the client. (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `jsonrpc` | string | no | JSON-RPC version. Example: `2.0`. |
| `id` | string | no | Request identifier. |
| `result` | object | no | MCP response payload (varies by method) |
| `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 -X POST 'https://api.bavest.co/v2/mcp' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"jsonrpc":"2.0","id":"1","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"my-agent","version":"1.0"}}}'
```

## Example response

```json
{
  "jsonrpc": "2.0",
  "id": "1",
  "result": {
    "tools": [
      {
        "name": "equities_profile",
        "description": "Get company profile by symbol or ISIN",
        "inputSchema": {
          "type": "object",
          "properties": {
            "symbol": {
              "type": "string",
              "description": "Ticker symbol (e.g. AAPL)"
            }
          },
          "required": [
            "symbol"
          ]
        }
      }
    ]
  }
}
```

## Errors

Also `401`, `429`, `500`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_mcp

---

# QuantOS Allocation Exposure

> Compute optimal allocation weights for a portfolio.

`POST https://api.bavest.co/v2/quant-os/allocate`

Group: Bavest QuantOS. Route id: `v2_quant_os_allocate`. Included in: Growth.

## Parameters

None.

## Request body

JSON, required. Symbols, weights, and date range for analysis.

| Field | Type | Always present | Description |
|---|---|---|---|
| `portfolioItems` | array of object | yes | Portfolio positions with symbol, allocation weight, and purchase date. |
| `portfolioItems[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `portfolioItems[].weight` | number | yes | Allocation weight (all weights must sum to 1.0) Example: `0.4`. |
| `portfolioItems[].buyDate` | string (date) | yes | Purchase date (YYYY-MM-DD). Converted to Unix timestamp internally. Example: `2026-09-01`. |
| `portfolioItems[].amount` | number | no | Number of shares held. |
| `startDate` | string (date) | no | Analysis start date (YYYY-MM-DD) Example: `2026-09-01`. |
| `endDate` | string (date) | no | Analysis end date (YYYY-MM-DD) Example: `2026-09-30`. |
| `currency` | string | no | Target currency for valuation (ISO 4217) Example: `USD`. |
| `resolution` | string | no | Data resolution for time series. One of `D`, `W`, `M`. Example: `D`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of object | no |  |
| `data[].symbol` | string | no |  |
| `data[].percentage` | number (double) | no |  |
| `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 -X POST 'https://api.bavest.co/v2/quant-os/allocate' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"portfolioItems":[{"symbol":"AAPL","weight":0.4,"buyDate":"2026-09-01"},{"symbol":"MSFT","weight":0.35,"buyDate":"2026-09-01"},{"symbol":"GOOGL","weight":0.25,"buyDate":"2026-09-01"}],"startDate":"2026-09-01","endDate":"2026-09-30","currency":"USD","resolution":"D"}'
```

## Example response

```json
{
  "data": [
    {
      "symbol": "AAPL",
      "percentage": 40
    },
    {
      "symbol": "MSFT",
      "percentage": 35
    }
  ],
  "meta": {
    "parameters": {
      "startDate": "2026-09-01",
      "endDate": "2026-09-30",
      "currency": "USD",
      "resolution": "D",
      "portfolio_items": [
        {
          "symbol": "AAPL",
          "weight": 0.4,
          "buy_date": 1788220800000
        },
        {
          "symbol": "MSFT",
          "weight": 0.35,
          "buy_date": 1788220800000
        },
        {
          "symbol": "GOOGL",
          "weight": 0.25,
          "buy_date": 1788220800000
        }
      ],
      "from": 1788220800,
      "to": 1790726400
    },
    "time": 5130
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_quant_os_allocate

---

# QuantOS Performance Chart

> Generate performance chart data for a portfolio over a date range.

`POST https://api.bavest.co/v2/quant-os/chart`

Group: Bavest QuantOS. Route id: `v2_quant_os_chart`. Included in: Growth.

## Parameters

None.

## Request body

JSON, required. Symbols, weights, and date range for analysis.

| Field | Type | Always present | Description |
|---|---|---|---|
| `portfolioItems` | array of object | yes | Portfolio positions with symbol, allocation weight, and purchase date. |
| `portfolioItems[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `portfolioItems[].weight` | number | yes | Allocation weight (all weights must sum to 1.0) Example: `0.4`. |
| `portfolioItems[].buyDate` | string (date) | yes | Purchase date (YYYY-MM-DD). Converted to Unix timestamp internally. Example: `2026-09-01`. |
| `portfolioItems[].amount` | number | no | Number of shares held. |
| `startDate` | string (date) | no | Analysis start date (YYYY-MM-DD) Example: `2026-09-01`. |
| `endDate` | string (date) | no | Analysis end date (YYYY-MM-DD) Example: `2026-09-30`. |
| `currency` | string | no | Target currency for valuation (ISO 4217) Example: `USD`. |
| `resolution` | string | no | Data resolution for time series. One of `D`, `W`, `M`. Example: `D`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | QuantOSChart | no | Total portfolio performance chart as a candle series. |
| `data.t` | array of number | no | Unix timestamps (seconds) |
| `data.c` | array of number | no | Closing values at each timestamp. |
| `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 -X POST 'https://api.bavest.co/v2/quant-os/chart' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"portfolioItems":[{"symbol":"AAPL","weight":0.4,"buyDate":"2026-09-01"},{"symbol":"MSFT","weight":0.35,"buyDate":"2026-09-01"},{"symbol":"GOOGL","weight":0.25,"buyDate":"2026-09-01"}],"startDate":"2026-09-01","endDate":"2026-09-30","currency":"USD","resolution":"D"}'
```

## Example response

```json
{
  "data": {
    "t": [
      1788220800,
      1788264000
    ],
    "c": [
      389.164,
      388.6575
    ]
  },
  "meta": {
    "parameters": {
      "startDate": "2026-09-01",
      "endDate": "2026-09-30",
      "currency": "USD",
      "resolution": "D",
      "portfolio_items": [
        {
          "symbol": "AAPL",
          "weight": 0.4,
          "buy_date": 1788220800000
        },
        {
          "symbol": "MSFT",
          "weight": 0.35,
          "buy_date": 1788220800000
        },
        {
          "symbol": "GOOGL",
          "weight": 0.25,
          "buy_date": 1788220800000
        }
      ],
      "from": 1788220800,
      "to": 1790726400,
      "enable_portfolio_chart": true
    },
    "time": 6794
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_quant_os_chart

---

# QuantOS Valuation

> Calculate current portfolio position value.

`POST https://api.bavest.co/v2/quant-os/price`

Group: Bavest QuantOS. Route id: `v2_quant_os_price`. Included in: Growth.

## Parameters

None.

## Request body

JSON, required. Symbols, weights, and date range for analysis.

| Field | Type | Always present | Description |
|---|---|---|---|
| `portfolioItems` | array of object | yes | Portfolio positions with symbol, allocation weight, and purchase date. |
| `portfolioItems[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `portfolioItems[].weight` | number | yes | Allocation weight (all weights must sum to 1.0) Example: `0.4`. |
| `portfolioItems[].buyDate` | string (date) | yes | Purchase date (YYYY-MM-DD). Converted to Unix timestamp internally. Example: `2026-09-01`. |
| `portfolioItems[].amount` | number | no | Number of shares held. |
| `startDate` | string (date) | no | Analysis start date (YYYY-MM-DD) Example: `2026-09-01`. |
| `endDate` | string (date) | no | Analysis end date (YYYY-MM-DD) Example: `2026-09-30`. |
| `currency` | string | no | Target currency for valuation (ISO 4217) Example: `USD`. |
| `resolution` | string | no | Data resolution for time series. One of `D`, `W`, `M`. Example: `D`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | QuantOSPrice | no | Current portfolio valuation. |
| `data.change` | number (double) | no | Absolute change (alias for d) |
| `data.changePercent` | number (double) | no | Change percentage (alias for dp) |
| `data.currentPrice` | number (double) | no | Current portfolio value (alias for c) |
| `data.high` | number (double) | no | Day high (alias for h) |
| `data.low` | number (double) | no | Day low (alias for l) |
| `data.open` | number (double) | no | Opening portfolio value (alias for o) |
| `data.previousClose` | number (double) | no | Previous close value (alias for pc) |
| `data.timestamp` | integer (int64) | no | Timestamp (Unix epoch seconds, alias for t) |
| `data.failed` | array of string | no | Symbols whose quote could not be resolved; empty when all resolved. |
| `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 -X POST 'https://api.bavest.co/v2/quant-os/price' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"portfolioItems":[{"symbol":"AAPL","weight":0.4,"buyDate":"2026-09-01"},{"symbol":"MSFT","weight":0.35,"buyDate":"2026-09-01"},{"symbol":"GOOGL","weight":0.25,"buyDate":"2026-09-01"}],"startDate":"2026-09-01","endDate":"2026-09-30","currency":"USD","resolution":"D"}'
```

## Example response

```json
{
  "data": {
    "currentPrice": 396.168,
    "open": 401.6555,
    "low": 393.461,
    "high": 404.2945,
    "changePercent": -0.2518,
    "change": -2.575,
    "previousClose": 398.743,
    "timestamp": 1790950835,
    "failed": []
  },
  "meta": {
    "parameters": {
      "startDate": "2026-09-01",
      "endDate": "2026-09-30",
      "currency": "USD",
      "resolution": "D",
      "portfolio_items": [
        {
          "symbol": "AAPL",
          "weight": 0.4,
          "buy_date": 1788220800000
        },
        {
          "symbol": "MSFT",
          "weight": 0.35,
          "buy_date": 1788220800000
        },
        {
          "symbol": "GOOGL",
          "weight": 0.25,
          "buy_date": 1788220800000
        }
      ],
      "from": 1788220800,
      "to": 1790726400
    },
    "time": 5936
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_quant_os_price

---

# QuantOS Region Breakdown

> Break down portfolio holdings by geographic region.

`POST https://api.bavest.co/v2/quant-os/region`

Group: Bavest QuantOS. Route id: `v2_quant_os_region`. Included in: Growth.

## Parameters

None.

## Request body

JSON, required. Symbols, weights, and date range for analysis.

| Field | Type | Always present | Description |
|---|---|---|---|
| `portfolioItems` | array of object | yes | Portfolio positions with symbol, allocation weight, and purchase date. |
| `portfolioItems[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `portfolioItems[].weight` | number | yes | Allocation weight (all weights must sum to 1.0) Example: `0.4`. |
| `portfolioItems[].buyDate` | string (date) | yes | Purchase date (YYYY-MM-DD). Converted to Unix timestamp internally. Example: `2026-09-01`. |
| `portfolioItems[].amount` | number | no | Number of shares held. |
| `startDate` | string (date) | no | Analysis start date (YYYY-MM-DD) Example: `2026-09-01`. |
| `endDate` | string (date) | no | Analysis end date (YYYY-MM-DD) Example: `2026-09-30`. |
| `currency` | string | no | Target currency for valuation (ISO 4217) Example: `USD`. |
| `resolution` | string | no | Data resolution for time series. One of `D`, `W`, `M`. Example: `D`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of object | no |  |
| `data[].region` | string | no | Geographic region name. |
| `data[].percentage` | number (double) | no | Allocation percentage. |
| `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 -X POST 'https://api.bavest.co/v2/quant-os/region' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"portfolioItems":[{"symbol":"AAPL","weight":0.4,"buyDate":"2026-09-01"},{"symbol":"MSFT","weight":0.35,"buyDate":"2026-09-01"},{"symbol":"GOOGL","weight":0.25,"buyDate":"2026-09-01"}],"startDate":"2026-09-01","endDate":"2026-09-30","currency":"USD","resolution":"D"}'
```

## Example response

```json
{
  "data": [
    {
      "region": "US",
      "percentage": 100
    }
  ],
  "meta": {
    "parameters": {
      "startDate": "2026-09-01",
      "endDate": "2026-09-30",
      "currency": "USD",
      "resolution": "D",
      "portfolio_items": [
        {
          "symbol": "AAPL",
          "weight": 0.4,
          "buy_date": 1788220800000
        },
        {
          "symbol": "MSFT",
          "weight": 0.35,
          "buy_date": 1788220800000
        },
        {
          "symbol": "GOOGL",
          "weight": 0.25,
          "buy_date": 1788220800000
        }
      ],
      "from": 1788220800,
      "to": 1790726400
    },
    "time": 6138
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_quant_os_region

---

# QuantOS Portfolio Return

> Calculate portfolio return over a specified period.

`POST https://api.bavest.co/v2/quant-os/return`

Group: Bavest QuantOS. Route id: `v2_quant_os_return`. Included in: Growth.

## Parameters

None.

## Request body

JSON, required. Symbols, weights, and date range for analysis.

| Field | Type | Always present | Description |
|---|---|---|---|
| `portfolioItems` | array of object | yes | Portfolio positions with symbol, allocation weight, and purchase date. |
| `portfolioItems[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `portfolioItems[].weight` | number | yes | Allocation weight (all weights must sum to 1.0) Example: `0.4`. |
| `portfolioItems[].buyDate` | string (date) | yes | Purchase date (YYYY-MM-DD). Converted to Unix timestamp internally. Example: `2026-09-01`. |
| `portfolioItems[].amount` | number | no | Number of shares held. |
| `startDate` | string (date) | no | Analysis start date (YYYY-MM-DD) Example: `2026-09-01`. |
| `endDate` | string (date) | no | Analysis end date (YYYY-MM-DD) Example: `2026-09-30`. |
| `currency` | string | no | Target currency for valuation (ISO 4217) Example: `USD`. |
| `resolution` | string | no | Data resolution for time series. One of `D`, `W`, `M`. Example: `D`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | QuantOSReturn | no | Portfolio return calculation. |
| `data.totalReturn` | number (double) | no | Cumulative return over period (decimal) |
| `data.annualizedReturn` | number (double) | no | Annualized return (decimal) |
| `data.beta` | number (double) | no | Portfolio beta. Example: `0`. |
| `data.dividendPerShareAnnual` | number (double) | no | Annual dividend per share (USD) Example: `0`. |
| `data.performanceOneWeek` | number (double) | no | One-week return. Example: `0`. |
| `data.performanceOneYear` | number (double) | no | One-year return. Example: `0`. |
| `data.performanceSixMonths` | number (double) | no | Six-month return. Example: `0`. |
| `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 -X POST 'https://api.bavest.co/v2/quant-os/return' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"portfolioItems":[{"symbol":"AAPL","weight":0.4,"buyDate":"2026-09-01"},{"symbol":"MSFT","weight":0.35,"buyDate":"2026-09-01"},{"symbol":"GOOGL","weight":0.25,"buyDate":"2026-09-01"}],"startDate":"2026-09-01","endDate":"2026-09-30","currency":"USD","resolution":"D"}'
```

## Example response

```json
{
  "data": {
    "beta": 0,
    "performanceSixMonths": 15.7361,
    "performanceOneWeek": 0.2813,
    "performanceOneYear": 13.9087,
    "dividendPerShareAnnual": 0
  },
  "meta": {
    "parameters": {
      "startDate": "2026-09-01",
      "endDate": "2026-09-30",
      "currency": "USD",
      "resolution": "D",
      "portfolio_items": [
        {
          "symbol": "AAPL",
          "weight": 0.4,
          "buy_date": 1788220800000
        },
        {
          "symbol": "MSFT",
          "weight": 0.35,
          "buy_date": 1788220800000
        },
        {
          "symbol": "GOOGL",
          "weight": 0.25,
          "buy_date": 1788220800000
        }
      ],
      "from": 1788220800,
      "to": 1790726400
    },
    "time": 7337
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_quant_os_return

---

# QuantOS Sector Breakdown

> Break down portfolio holdings by GICS sector.

`POST https://api.bavest.co/v2/quant-os/sector`

Group: Bavest QuantOS. Route id: `v2_quant_os_sector`. Included in: Growth.

## Parameters

None.

## Request body

JSON, required. Symbols, weights, and date range for analysis.

| Field | Type | Always present | Description |
|---|---|---|---|
| `portfolioItems` | array of object | yes | Portfolio positions with symbol, allocation weight, and purchase date. |
| `portfolioItems[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `portfolioItems[].weight` | number | yes | Allocation weight (all weights must sum to 1.0) Example: `0.4`. |
| `portfolioItems[].buyDate` | string (date) | yes | Purchase date (YYYY-MM-DD). Converted to Unix timestamp internally. Example: `2026-09-01`. |
| `portfolioItems[].amount` | number | no | Number of shares held. |
| `startDate` | string (date) | no | Analysis start date (YYYY-MM-DD) Example: `2026-09-01`. |
| `endDate` | string (date) | no | Analysis end date (YYYY-MM-DD) Example: `2026-09-30`. |
| `currency` | string | no | Target currency for valuation (ISO 4217) Example: `USD`. |
| `resolution` | string | no | Data resolution for time series. One of `D`, `W`, `M`. Example: `D`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of object | no |  |
| `data[].sector` | string | no | GICS sector name. |
| `data[].percentage` | number (double) | no | Allocation percentage. |
| `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 -X POST 'https://api.bavest.co/v2/quant-os/sector' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"portfolioItems":[{"symbol":"AAPL","weight":0.4,"buyDate":"2026-09-01"},{"symbol":"MSFT","weight":0.35,"buyDate":"2026-09-01"},{"symbol":"GOOGL","weight":0.25,"buyDate":"2026-09-01"}],"startDate":"2026-09-01","endDate":"2026-09-30","currency":"USD","resolution":"D"}'
```

## Example response

```json
{
  "data": [
    {
      "sector": "Technology",
      "percentage": 75
    },
    {
      "sector": "Communication Services",
      "percentage": 25
    }
  ],
  "meta": {
    "parameters": {
      "startDate": "2026-09-01",
      "endDate": "2026-09-30",
      "currency": "USD",
      "resolution": "D",
      "portfolio_items": [
        {
          "symbol": "AAPL",
          "weight": 0.4,
          "buy_date": 1788220800000
        },
        {
          "symbol": "MSFT",
          "weight": 0.35,
          "buy_date": 1788220800000
        },
        {
          "symbol": "GOOGL",
          "weight": 0.25,
          "buy_date": 1788220800000
        }
      ],
      "from": 1788220800,
      "to": 1790726400
    },
    "time": 5962
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_quant_os_sector

---

# QuantOS Statistics

> Returns comprehensive portfolio statistics including returns, risk, and ratios.

`POST https://api.bavest.co/v2/quant-os/stats`

Group: Bavest QuantOS. Route id: `v2_quant_os_stats`. Included in: Growth.

## Parameters

None.

## Request body

JSON, required. Symbols, weights, and date range for analysis.

| Field | Type | Always present | Description |
|---|---|---|---|
| `portfolioItems` | array of object | yes | Portfolio positions with symbol, allocation weight, and purchase date. |
| `portfolioItems[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `portfolioItems[].weight` | number | yes | Allocation weight (all weights must sum to 1.0) Example: `0.4`. |
| `portfolioItems[].buyDate` | string (date) | yes | Purchase date (YYYY-MM-DD). Converted to Unix timestamp internally. Example: `2026-09-01`. |
| `portfolioItems[].amount` | number | no | Number of shares held. |
| `startDate` | string (date) | no | Analysis start date (YYYY-MM-DD) Example: `2026-09-01`. |
| `endDate` | string (date) | no | Analysis end date (YYYY-MM-DD) Example: `2026-09-30`. |
| `currency` | string | no | Target currency for valuation (ISO 4217) Example: `USD`. |
| `resolution` | string | no | Data resolution for time series. One of `D`, `W`, `M`. Example: `D`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | QuantOSStats | no | Comprehensive portfolio statistics keyed by position index and total. |
| `data.sharpeRatio` | string | no | Sharpe ratio for this position or total portfolio. |
| `data.correlation` | object | no | Correlation matrix entries. |
| `data.series` | object | no | Time series data. |
| `data.series.t` | array of number | no |  |
| `data.series.c` | array of number | no |  |
| `data.series.h` | array of number | no |  |
| `data.series.l` | array of number | no |  |
| `data.series.o` | array of number | no |  |
| `data.series.s` | string | no |  |
| `data.series.v` | array of number | no |  |
| `data.stats` | object | no | Detailed performance statistics. |
| `data.stats.riskFree` | number (double) | no |  |
| `data.stats.totalReturn` | number (double) | no |  |
| `data.stats.cagr` | number (double) | no |  |
| `data.stats.maxDrawdown` | number (double) | no |  |
| `data.stats.calmar` | number (double) | no |  |
| `data.stats.mtd` | number (double) | no |  |
| `data.stats.threeMonth` | number (double) | no |  |
| `data.stats.sixMonth` | number (double) | no |  |
| `data.stats.ytd` | number (double) | no |  |
| `data.stats.oneYear` | number (double) | no |  |
| `data.stats.threeYear` | number (double) \| null | no |  |
| `data.stats.fiveYear` | number (double) \| null | no |  |
| `data.stats.tenYear` | number (double) \| null | no |  |
| `data.stats.inception` | number (double) | no |  |
| `data.stats.dailySharpe` | number (double) | no |  |
| `data.stats.dailySortino` | number (double) | no |  |
| `data.stats.dailyMean` | number (double) | no |  |
| `data.stats.dailyVolume` | number (double) | no |  |
| `data.stats.dailySkew` | number (double) | no |  |
| `data.stats.dailyKurt` | number (double) | no |  |
| `data.stats.bestDay` | number (double) | no |  |
| `data.stats.worstDay` | number (double) | no |  |
| `data.stats.monthlySharpe` | number (double) | no |  |
| `data.stats.monthlySortino` | number (double) | no |  |
| `data.stats.monthlyMean` | number (double) | no |  |
| `data.stats.monthlyVol` | number (double) | no |  |
| `data.stats.monthlySkew` | number (double) | no |  |
| `data.stats.monthlyKurt` | number (double) | no |  |
| `data.stats.bestMonth` | number (double) | no |  |
| `data.stats.worstMonth` | number (double) | no |  |
| `data.stats.yearlySharpe` | number (double) | no |  |
| `data.stats.yearlySortino` | number (double) | no |  |
| `data.stats.yearlyMean` | number (double) | no |  |
| `data.stats.yearlyVol` | number (double) | no |  |
| `data.stats.yearlySkew` | number (double) \| null | no |  |
| `data.stats.yearlyKurt` | number (double) \| null | no |  |
| `data.stats.bestYear` | number (double) | no |  |
| `data.stats.worstYear` | number (double) | no |  |
| `data.stats.avgDrawdown` | number (double) | no |  |
| `data.stats.avgDrawdownDays` | number (double) | no |  |
| `data.stats.avgUpMonth` | number (double) | no |  |
| `data.stats.avgDownMonth` | number (double) | no |  |
| `data.stats.winYearPerc` | number (double) | no |  |
| `data.stats.twelveMonthWinPerc` | number (double) | no |  |
| `data.error` | string \| null | no | Error message if computation failed for this position. |
| `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 -X POST 'https://api.bavest.co/v2/quant-os/stats' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"portfolioItems":[{"symbol":"AAPL","weight":0.4,"buyDate":"2026-09-01"},{"symbol":"MSFT","weight":0.35,"buyDate":"2026-09-01"},{"symbol":"GOOGL","weight":0.25,"buyDate":"2026-09-01"}],"startDate":"2026-09-01","endDate":"2026-09-30","currency":"USD","resolution":"D"}'
```

## Example response

```json
{
  "data": {
    "0": {
      "sharpeRatio": "0.86",
      "correlation": {
        "0": 1,
        "1": "0.23",
        "total": "0.61"
      },
      "series": {
        "t": [
          1735819200
        ],
        "c": [
          -0.001
        ],
        "h": [],
        "l": [],
        "o": [],
        "s": "ok",
        "v": []
      },
      "stats": {
        "riskFree": 0.7,
        "totalReturn": 3.1483,
        "cagr": 2.1732,
        "maxDrawdown": -0.2838,
        "calmar": 7.6564,
        "mtd": -0.0437,
        "threeMonth": -0.0752,
        "sixMonth": -0.0094,
        "ytd": -0.0691,
        "oneYear": 0.1356,
        "threeYear": 2.1732,
        "fiveYear": null,
        "tenYear": null,
        "inception": 2.1732,
        "dailySharpe": 0.5308,
        "dailySortino": 6.8143,
        "dailyMean": 1.341,
        "dailyVolume": 1.5257,
        "dailySkew": 20.0825,
        "dailyKurt": 416.0306,
        "bestDay": 2,
        "worstDay": -0.0831,
        "monthlySharpe": 0.7119,
        "monthlySortino": 12.0393,
        "monthlyMean": 2.3582,
        "monthlyVol": 2.5504,
        "monthlySkew": 3.8309,
        "monthlyKurt": 14.7666,
        "bestMonth": 2.8494,
        "worstMonth": -0.0769,
        "yearlySharpe": 0.3986,
        "yearlySortino": 1.8269,
        "yearlyMean": 1.6935,
        "yearlyVol": 2.4926,
        "yearlySkew": null,
        "yearlyKurt": null,
        "bestYear": 3.456,
        "worstYear": -0.0691,
        "avgDrawdown": -0.0681,
        "avgDrawdownDays": 45.4444,
        "avgUpMonth": 0.4627,
        "avgDownMonth": -0.0364,
        "winYearPerc": 0.5,
        "twelveMonthWinPerc": 1
      },
      "error": null
    },
    "1": {
      "sharpeRatio": "0.76",
      "correlation": {
        "0": "0.23",
        "1": 1,
        "total": "0.91"
      },
      "series": {
        "t": [
          1736164800
        ],
        "c": [
          -0.0064
        ],
        "h": [],
        "l": [],
        "o": [],
        "s": "ok",
        "v": []
      },
      "stats": {
        "riskFree": 0.7,
        "totalReturn": 2.4973,
        "cagr": 1.7626,
        "maxDrawdown": -0.3245,
        "calmar": 5.4312,
        "mtd": -0.075,
        "threeMonth": -0.2495,
        "sixMonth": -0.2852,
        "ytd": -0.2391,
        "oneYear": -0.0623,
        "threeYear": 1.7626,
        "fiveYear": null,
        "tenYear": null,
        "inception": 1.7626,
        "dailySharpe": 0.4671,
        "dailySortino": 6.7901,
        "dailyMean": 1.2436,
        "dailyVolume": 1.5252,
        "dailySkew": 20.1235,
        "dailyKurt": 416.9528,
        "bestDay": 2,
        "worstDay": -0.0561,
        "monthlySharpe": 0.6578,
        "monthlySortino": 9.3706,
        "monthlyMean": 2.2948,
        "monthlyVol": 2.6637,
        "monthlySkew": 3.8205,
        "monthlyKurt": 14.7093,
        "bestMonth": 2.9598,
        "worstMonth": -0.1125,
        "yearlySharpe": 0.3608,
        "yearlySortino": 1.4736,
        "yearlyMean": 1.6785,
        "yearlyVol": 2.7118,
        "yearlySkew": null,
        "yearlyKurt": null,
        "bestYear": 3.596,
        "worstYear": -0.2391,
        "avgDrawdown": -0.0378,
        "avgDrawdownDays": 21.5,
        "avgUpMonth": 0.5558,
        "avgDownMonth": -0.0518,
        "winYearPerc": 0.5,
        "twelveMonthWinPerc": 0.8
      },
      "error": null
    },
    "total": {
      "sharpeRatio": "0.80",
      "correlation": {
        "0": "0.61",
        "1": "0.91",
        "total": 1
      },
      "series": {
        "t": [
          1736164800
        ],
        "c": [
          -0.0061
        ],
        "h": [],
        "l": [],
        "o": [],
        "s": "ok",
        "v": []
      },
      "stats": {
        "riskFree": 0.7,
        "totalReturn": 2.7369,
        "cagr": 1.9153,
        "maxDrawdown": -0.2371,
        "calmar": 8.0793,
        "mtd": -0.0625,
        "threeMonth": -0.1869,
        "sixMonth": -0.1934,
        "ytd": -0.1777,
        "oneYear": 0.0096,
        "threeYear": 1.9153,
        "fiveYear": null,
        "tenYear": null,
        "inception": 1.9153,
        "dailySharpe": 0.4899,
        "dailySortino": 8.2368,
        "dailyMean": 1.2772,
        "dailyVolume": 1.5227,
        "dailySkew": 20.2169,
        "dailyKurt": 419.6071,
        "bestDay": 2,
        "worstDay": -0.0489,
        "monthlySharpe": 0.675,
        "monthlySortino": 11.2402,
        "monthlyMean": 2.3096,
        "monthlyVol": 2.618,
        "monthlySkew": 3.8472,
        "monthlyKurt": 14.8585,
        "bestMonth": 2.9191,
        "worstMonth": -0.0811,
        "yearlySharpe": 0.3736,
        "yearlySortino": 1.5845,
        "yearlyMean": 1.6834,
        "yearlyVol": 2.632,
        "yearlySkew": null,
        "yearlyKurt": null,
        "bestYear": 3.5445,
        "worstYear": -0.1777,
        "avgDrawdown": -0.0428,
        "avgDrawdownDays": 28.4286,
        "avgUpMonth": 0.3995,
        "avgDownMonth": -0.0441,
        "winYearPerc": 0.5,
        "twelveMonthWinPerc": 0.8
      },
      "error": null
    }
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_quant_os_stats

---

# Bulk Endpoint

> Fan out a single endpoint across up to 100 symbols or ISINs in one request.

`POST https://api.bavest.co/v2/bulk`

Group: Bulk. Route id: `v2_bulk`. Included in: Growth.

## Description

Fan out a single endpoint across up to 100 symbols or ISINs in one request. Each entry is invoked concurrently against the target Lambda and results are returned as an array in the same order as the input.

Provide exactly one of `symbols` or `isins`. The `params` object is merged into every invocation for shared parameters (e.g., currency, date range).

## Parameters

None.

## Request body

JSON, required. Bulk invocation request with symbols/ISINs, target endpoint, and optional shared parameters.

| Field | Type | Always present | Description |
|---|---|---|---|
| `symbols` | array of object | no | List of per-symbol parameter objects. Each object is merged with `params` and sent to the target endpoint. Provide exactly one of `symbols` or `isins`. |
| `symbols[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `symbols[].currency` | string | no | Target currency (ISO 4217) |
| `isins` | array of object | no | List of per-ISIN parameter objects. Each object is merged with `params` and sent to the target endpoint. Provide exactly one of `symbols` or `isins`. |
| `isins[].isin` | string | yes | ISIN code. |
| `endpoint` | string | no | Target endpoint key. Determines which Lambda is invoked for each entry. market_cap routes by the resolved bavest.security type to equity metrics (STOCK/EQUITY/ADR), ETF metrics (ETF/ETP), or fund metrics (MUTUAL_FUND). Returns the target metrics response with its metric names, units, currency, and pagination, selecting market_cap for equities and aum/fund_aum for funds by default. Fund AUM is not equity market capitalization. Use params.fields to override this selection and params.limit/offset to page it. dividends_history is an alias for dividend and etf_dividend and uses the dividend-history endpoint. One of `search`, `etf_country`, `etf_profile`, `etf_top_holdings`, `etf_top_sectors`, `etf_holdings`, `etf_sector`, `etf_metrics`, `fund_metrics`, `etf_dividend`, `crypto_price`, `dividend`, `stock_profile`, `stock_metric`, `balance_sheet`, `cash_flow`, `income_statement`, `financials_ttm`, `estimates_consensus`, `estimates_recommendations`, `dividends_history`, `news_stock`, `market_cap`. Example: `etf_profile`. |
| `params` | object | no | Additional parameters passed to every invocation. Merged with each symbol/ISIN entry. Use for shared parameters like date ranges. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of BulkResultItem | no |  |
| `data[].symbol` | string | no | Echoed back from the request entry. Example: `AAPL`. |
| `data[].isin` | string | no | Echoed back from the request entry. Example: `US0378331005`. |
| `data[].valid` | boolean | no | Present and `false` when the invocation failed. |
| `data[].error` | string | no | Error code (only on failure). Example: `LAMBDA_INVOCATION_FAILED`. |
| `data[].message` | string | no | Error detail (only on failure). |
| `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 -X POST 'https://api.bavest.co/v2/bulk' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"symbols":[{"symbol":"BTCUSD"},{"symbol":"ETHUSD"}],"endpoint":"crypto_price","params":{}}'
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_bulk

---

# Earnings Calendar

> Returns upcoming and recent earnings events across all securities.

`GET https://api.bavest.co/v2/calendar/earnings`

Group: Calendar. Route id: `v2_calendar_earnings`. Included in: Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |
| `symbol` | query | string | no (at most one of symbol, isin) | Only this security's events (e.g., `BMW.DE`). Omit for the whole calendar. Provide at most one of symbol or isin. |
| `isin` | query | string | no (at most one of symbol, isin) | Only this security's events, resolved to its primary listing (e.g., `DE0005190003` is `BMW.DE`). An unknown ISIN is 404. Omit for the whole calendar. |

Optional, at most one of `symbol`, `isin`.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of EarningsCalendarRecord | no |  |
| `data[].eventType` | string | no | Type of corporate event. Example: `earnings`. |
| `data[].date` | string (date) | no | Event date. Example: `2026-05-27`. |
| `data[].symbol` | string | no | Ticker symbol. Example: `NVDA`. |
| `data[].eps` | number (double) \| null | no | Actual earnings per share. Example: `0.89`. |
| `data[].epsEstimated` | number (double) \| null | no | Estimated earnings per share. Example: `0.85`. |
| `data[].revenue` | number (double) \| null | no | Actual revenue. Example: `44000000000`. |
| `data[].revenueEstimated` | number (double) \| null | no | Estimated revenue. Example: `43500000000`. |
| `data[].fiscalDateEnding` | string (date) \| null | no | Fiscal period end date. Example: `2026-04-30`. |
| `data[].time` | string \| null | no | Time of day (bmo = before market open, amc = after market close) One of `bmo`, `amc`, `dmh`. Example: `bmo`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/calendar/earnings' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "eventType": "earnings",
      "date": "2026-10-02",
      "symbol": "2300.T",
      "eps": null,
      "epsEstimated": null,
      "revenue": null,
      "revenueEstimated": null,
      "fiscalDateEnding": "2026-08-31",
      "time": "amc"
    },
    {
      "eventType": "earnings",
      "date": "2026-10-02",
      "symbol": "3035.T",
      "eps": null,
      "epsEstimated": null,
      "revenue": null,
      "revenueEstimated": null,
      "fiscalDateEnding": "2026-08-31",
      "time": "amc"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 261,
    "totalCount": 26030,
    "parameters": {
      "limit": "100"
    },
    "time": 3
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_calendar_earnings

---

# IPO Calendar

> Returns upcoming and recent IPO events.

`GET https://api.bavest.co/v2/calendar/ipo`

Group: Calendar. Route id: `v2_calendar_ipo`. Included in: Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | no | Optional ticker filter (e.g., `AAPL`). Omit for all securities. Provide at most one of symbol or isin. |
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of IPORecord | no |  |
| `data[].symbol` | string | yes | Planned ticker symbol. |
| `data[].exchange` | string \| null | no | Target exchange for listing. |
| `data[].date` | string (date) | yes | Expected or actual IPO date. |
| `data[].name` | string | no | Company name. Example: `Guardian Metal Resources PLC Sponsored ADR`. |
| `data[].numberOfShares` | integer | no | Number of shares offered in the IPO. Example: `4444400`. |
| `data[].priceHigh` | number (double) \| null | no | Upper bound of the expected price range. |
| `data[].priceLow` | number (double) \| null | no | Lower bound of the expected price range. |
| `data[].status` | string | no | Current IPO status (e.g., Priced, Expected, Withdrawn) Example: `Priced`. |
| `data[].totalSharesValue` | number | no | Total value of shares offered. Example: `59999400`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/calendar/ipo' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "symbol": "CSQR",
      "date": "2026-07-16",
      "name": "Csquare, Inc.",
      "exchange": null,
      "numberOfShares": 50000000,
      "priceLow": 23,
      "priceHigh": 27,
      "status": "Expected",
      "totalSharesValue": 1552500000
    },
    {
      "symbol": "STDN",
      "date": "2026-07-16",
      "name": "Standard Nuclear, Inc.",
      "exchange": null,
      "numberOfShares": 18250000,
      "priceLow": 18,
      "priceHigh": 21,
      "status": "Expected",
      "totalSharesValue": 440737500
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 6,
    "totalCount": 593,
    "parameters": {
      "limit": "100"
    },
    "time": 6
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_calendar_ipo

---

# AGM Calendar

> Returns upcoming Annual General Meeting dates sourced from SEC DEF 14A proxy filings.

`GET https://api.bavest.co/v2/calendar/agm`

Group: Calendar. Route id: `v2_calendar_agm`. Included in: Growth.

## Description

Returns upcoming Annual General Meeting dates sourced from SEC DEF 14A proxy filings. Defaults to meetings from today onwards.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |
| `symbol` | query | string | no (at most one of symbol, isin) | Only this security's events (e.g., `BMW.DE`). Omit for the whole calendar. Provide at most one of symbol or isin. |
| `isin` | query | string | no (at most one of symbol, isin) | Only this security's events, resolved to its primary listing (e.g., `DE0005190003` is `BMW.DE`). An unknown ISIN is 404. Omit for the whole calendar. |

Optional, at most one of `symbol`, `isin`.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of AGMRecord | no |  |
| `data[].meetingDate` | string (date) | yes | Scheduled meeting date. Example: `2026-05-15`. |
| `data[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `data[].isin` | string \| null | no | ISIN identifier. Example: `US0378331005`. |
| `data[].recordDate` | string (date) \| null | no | Record date for shareholder eligibility. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/calendar/agm' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "meetingDate": "2027-06-24",
      "symbol": "GHI",
      "isin": "US02364V2060",
      "recordDate": null
    },
    {
      "meetingDate": "2027-05-06",
      "symbol": "MLI",
      "isin": "US6247561029",
      "recordDate": null
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 2,
    "totalCount": 191,
    "parameters": {
      "limit": "100"
    },
    "time": 3
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_calendar_agm

---

# Stock Splits Calendar

> Returns recent and upcoming stock split events sorted by date descending.

`GET https://api.bavest.co/v2/calendar/splits`

Group: Calendar. Route id: `v2_calendar_splits`. Included in: Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |
| `symbol` | query | string | no (at most one of symbol, isin) | Only this security's events (e.g., `BMW.DE`). Omit for the whole calendar. Provide at most one of symbol or isin. |
| `isin` | query | string | no (at most one of symbol, isin) | Only this security's events, resolved to its primary listing (e.g., `DE0005190003` is `BMW.DE`). An unknown ISIN is 404. Omit for the whole calendar. |

Optional, at most one of `symbol`, `isin`.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of SplitRecord | no |  |
| `data[].date` | string (date) | no | Event date. Example: `2020-08-31`. |
| `data[].symbol` | string | no | Ticker symbol. Example: `AAPL`. |
| `data[].fromFactor` | integer | no | Original share count. Example: `1`. |
| `data[].toFactor` | integer | no | New shares per original. Example: `4`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/calendar/splits' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "date": "2026-11-27",
      "symbol": "8976.T",
      "fromFactor": 1,
      "toFactor": 4
    },
    {
      "date": "2026-11-27",
      "symbol": "4616.T",
      "fromFactor": 1,
      "toFactor": 3
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 973,
    "totalCount": 97278,
    "parameters": {
      "limit": "100"
    },
    "time": 3
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_calendar_splits

---

# Earnings Events

> Returns historical and upcoming earnings announcement dates and results.

`GET https://api.bavest.co/v2/corporate-actions/earnings`

Group: Corporate Actions. Route id: `v2_corporate_actions_earnings`. Included in: Startup, Pro, Growth.

## 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. |
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of EarningsCalendarRecord | no |  |
| `data[].eventType` | string | no | Type of corporate event. Example: `earnings`. |
| `data[].date` | string (date) | no | Event date. Example: `2026-05-27`. |
| `data[].symbol` | string | no | Ticker symbol. Example: `NVDA`. |
| `data[].eps` | number (double) \| null | no | Actual earnings per share. Example: `0.89`. |
| `data[].epsEstimated` | number (double) \| null | no | Estimated earnings per share. Example: `0.85`. |
| `data[].revenue` | number (double) \| null | no | Actual revenue. Example: `44000000000`. |
| `data[].revenueEstimated` | number (double) \| null | no | Estimated revenue. Example: `43500000000`. |
| `data[].fiscalDateEnding` | string (date) \| null | no | Fiscal period end date. Example: `2026-04-30`. |
| `data[].time` | string \| null | no | Time of day (bmo = before market open, amc = after market close) One of `bmo`, `amc`, `dmh`. Example: `bmo`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/corporate-actions/earnings?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "eventType": "earnings",
      "date": "2026-10-29",
      "symbol": "AAPL",
      "eps": null,
      "epsEstimated": 1.98,
      "revenue": null,
      "revenueEstimated": 113210600000,
      "fiscalDateEnding": "2026-09-27",
      "time": "amc"
    },
    {
      "eventType": "earnings",
      "date": "2026-07-30",
      "symbol": "AAPL",
      "eps": 2.02,
      "epsEstimated": 1.89,
      "revenue": 109417000000,
      "revenueEstimated": 109038900000,
      "fiscalDateEnding": "2026-06-27",
      "time": "amc"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 1,
    "totalCount": 46,
    "parameters": {
      "limit": "100",
      "symbol": "AAPL"
    },
    "time": 13
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_corporate_actions_earnings

---

# Earnings Transcript

> Returns the earnings call transcript for a specific quarter.

`GET https://api.bavest.co/v2/corporate-actions/earnings/transcript`

Group: Corporate Actions. Route id: `v2_corporate_actions_earnings_transcript`. Included in: Startup, Pro, Growth.

## 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. |
| `year` | query | integer | yes | Fiscal year of the earnings call (e.g., 2026). Use the periods endpoint to discover available calls. Example `2026`. |
| `quarter` | query | integer | yes | Fiscal quarter (1-4) of the earnings call. One of `1`, `2`, `3`, `4`. Example `3`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of EarningsTranscript | no |  |
| `data[].date` | string (date) | no | Event date. |
| `data[].symbol` | string | no | Ticker symbol. |
| `data[].year` | integer \| null | no | Fiscal year. |
| `data[].quarter` | integer \| null | no | Fiscal quarter (1-4) |
| `data[].content` | string \| null | no | Full earnings call transcript text. |
| `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/corporate-actions/earnings/transcript?symbol=AAPL&year=2026&quarter=3' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "date": "2026-07-30",
      "symbol": "AAPL",
      "quarter": 3,
      "year": 2026,
      "content": "Suhasini Chandramouli: Good afternoon, welcome to the Apple Q3 fiscal year 2026 earnings conference call. My name is Suhasini Chandramouli, Director of Investor Relations. Today's call is being recorded. Speaking first today is Apple CEO Tim Cook, followed by CFO Kevan Parekh. Also joining us on today's call is incoming CEO John Ternus. After the prepared remarks, we'll open the call to questions from analysts. Please note that some of the information you'll hear during our discussion today will consist of forward-looking statements, including, without limitation, those regarding revenue, gros … [excerpt]"
    }
  ],
  "meta": {
    "parameters": {
      "quarter": "3",
      "symbol": "AAPL",
      "year": "2026"
    },
    "time": 36
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_corporate_actions_earnings_transcript

---

# Earnings Transcript Periods

> Returns the list of year/quarter combinations that have earnings transcripts available for a symbol.

`GET https://api.bavest.co/v2/corporate-actions/earnings/transcript/periods`

Group: Corporate Actions. Route id: `v2_corporate_actions_earnings_transcript_periods`. Free in every plan, including the trial.

## 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. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of TranscriptPeriod | no |  |
| `data[].year` | integer | no | Fiscal year. Example: `2024`. |
| `data[].quarter` | integer | no | Fiscal quarter (1-4) Example: `3`. |
| `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/corporate-actions/earnings/transcript/periods?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "year": 2026,
      "quarter": 3
    },
    {
      "year": 2026,
      "quarter": 2
    }
  ],
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 11
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_corporate_actions_earnings_transcript_periods

---

# Stock Splits

> Returns historical stock split records.

`GET https://api.bavest.co/v2/corporate-actions/splits`

Group: Corporate Actions. Route id: `v2_corporate_actions_splits`. Included in: Startup, Pro, Growth.

## 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. |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of SplitRecord | no |  |
| `data[].date` | string (date) | no | Event date. Example: `2020-08-31`. |
| `data[].symbol` | string | no | Ticker symbol. Example: `AAPL`. |
| `data[].fromFactor` | integer | no | Original share count. Example: `1`. |
| `data[].toFactor` | integer | no | New shares per original. Example: `4`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/corporate-actions/splits?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "date": "2020-08-31",
      "symbol": "AAPL",
      "fromFactor": 1,
      "toFactor": 4
    },
    {
      "date": "2014-06-09",
      "symbol": "AAPL",
      "fromFactor": 1,
      "toFactor": 7
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 1,
    "totalCount": 5,
    "parameters": {
      "limit": "100",
      "symbol": "AAPL"
    },
    "time": 10
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_corporate_actions_splits

---

# Crypto Quote

> Returns real-time cryptocurrency quote with price, change, volume, and market cap.

`GET https://api.bavest.co/v2/crypto/quote`

Group: Crypto. Route id: `v2_crypto_quote`. Included in: Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | yes | Cryptocurrency pair symbol (e.g., `BTCUSD`, `ETHUSD`, `SOLUSD`). Example `BTCUSD`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.symbol` | string | no | Cryptocurrency pair symbol. Example: `BTCUSD`. |
| `data.name` | string | no | Cryptocurrency name. Example: `Bitcoin USD`. |
| `data.price` | number | no | Current price. Example: `67542.31`. |
| `data.change` | number | no | Absolute price change. Example: `-1250.5`. |
| `data.changePercent` | number | no | Price change percentage. Example: `-1.82`. |
| `data.dayLow` | number | no | Intraday low. Example: `66800`. |
| `data.dayHigh` | number | no | Intraday high. Example: `68900`. |
| `data.open` | number | no | Opening price. Example: `68792.81`. |
| `data.previousClose` | number | no | Previous close price. Example: `68792.81`. |
| `data.volume` | number | no | 24h trading volume. Example: `28453120000`. |
| `data.marketCap` | number \| null | no | Market capitalization. Example: `1329000000000`. |
| `data.timestamp` | integer | no | Quote timestamp (Unix epoch seconds) Example: `1773352065`. |
| `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/crypto/quote?symbol=BTCUSD' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "symbol": "BTCUSD",
    "name": "Bitcoin USD",
    "price": 86756.99,
    "change": 1907.06,
    "changePercent": 2.2476,
    "dayLow": 84555.46,
    "dayHigh": 87209,
    "open": 84849.93,
    "previousClose": 84849.93,
    "volume": 41500573696,
    "marketCap": 1732761790904,
    "timestamp": 1790949957
  },
  "meta": {
    "parameters": {
      "symbol": "BTCUSD"
    },
    "time": 8
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_crypto_quote

---

# Crypto List

> Returns a paginated list of all available cryptocurrencies.

`GET https://api.bavest.co/v2/crypto/list`

Group: Crypto. Route id: `v2_crypto_list`. Free in every plan, including the trial.

## Description

Returns a paginated list of all available cryptocurrencies. Every pair is quoted in USD and its `symbol` can be passed to `/v2/crypto/quote` as-is.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of CryptoListItem | no |  |
| `data[].symbol` | string | yes | Cryptocurrency pair symbol. Example: `AAVE-CAD`. |
| `data[].name` | string | yes | Cryptocurrency pair name. Example: `Aave CAD`. |
| `data[].cryptocurrency` | string \| null | no | Base cryptocurrency ticker. Example: `AAVE`. |
| `data[].currency` | string \| null | no | Quote currency. Example: `CAD`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/crypto/list' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "symbol": "00USD",
      "name": "00 Token USD",
      "cryptocurrency": "00",
      "currency": "USD"
    },
    {
      "symbol": "0X0USD",
      "name": "0x0.ai USD",
      "cryptocurrency": "0X0",
      "currency": "USD"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 48,
    "totalCount": 4761,
    "parameters": {
      "limit": "100"
    },
    "time": 4
  }
}
```

## Errors

Also `400`, `401`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_crypto_list

---

# Annual Dividend Summary

> Returns aggregated annual dividend totals and payment frequency.

`GET https://api.bavest.co/v2/dividends/annual`

Group: Dividends. Route id: `v2_dividends_annual`. Included in: Startup, Pro, Growth.

## 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. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | AnnualDividendSummary | no | Aggregated annual dividend summary. |
| `data.currency` | string \| null | no | ISO 4217 currency of the dividend amounts. Example: `USD`. |
| `data.dividendFrequency` | integer | no | Annual payment frequency (1=annual, 2=semi-annual, 4=quarterly, 12=monthly) |
| `data.dividends` | array of object | no | List of annual dividend amounts. |
| `data.dividends[].year` | integer | no | Dividend payment year. |
| `data.dividends[].amount` | number | no | Total dividend amount paid in the year. |
| `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/dividends/annual?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "dividendFrequency": 4,
    "dividends": [
      {
        "year": 2026,
        "amount": 0.53
      },
      {
        "year": 2025,
        "amount": 1.03
      }
    ],
    "currency": "USD"
  },
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 10
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_dividends_annual

---

# Dividend Calendar

> Announced dividend events between `from` and `to`, soonest first.

`GET https://api.bavest.co/v2/dividends/calendar`

Group: Dividends. Route id: `v2_dividends_calendar`. Included in: Startup, Pro, Growth.

## Description

Announced dividend events between `from` and `to`, soonest first.

Defaults to **upcoming** events: with no `from`, the window starts today
(UTC). Pass an explicit `from` in the past to include events that have
already gone ex. Both dates are inclusive, so `from` equal to `to`
returns that single day. Every page, including the cursor pages that
follow page 1, is sorted by `date` ascending, then `symbol`.

Scope the feed to one instrument with `symbol` or `isin` instead of
paging the whole market. An identifier that does not resolve returns 404;
it never falls back to the whole market. Each row carries the resolved
`isin`, and `currency` is null when the instrument's currency is unknown.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | no (at most one of symbol, isin) | Optional ticker filter (e.g., `AAPL`). Omit for all securities. Provide at most one of symbol or isin. |
| `isin` | query | string | no (at most one of symbol, isin) | ISIN code (e.g., `US0378331005`). Provide exactly one of symbol or isin. Clear the symbol example before using an ISIN. |
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

Optional, at most one of `symbol`, `isin`.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of DividendRecord | no |  |
| `data[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `data[].isin` | string \| null | no | ISIN of the instrument, resolved from the symbol. Returned by /v2/dividends/calendar; null when the symbol does not map to a known security. Example: `US0378331005`. |
| `data[].date` | string (date) | yes | Dividend date. |
| `data[].adjustedAmount` | number (double) | no | Split-adjusted dividend per share. Example: `0.25`. |
| `data[].amount` | number (double) | yes | Actual payment per share. Example: `0.25`. |
| `data[].recordDate` | string (date) | no | Dividend record date. |
| `data[].payDate` | string (date) | no | Dividend payment date. |
| `data[].declarationDate` | string (date) \| null | no | Dividend declaration date. |
| `data[].exDate` | string (date) \| null | no | Ex-dividend date. |
| `data[].currency` | string \| null | no | Currency code the amounts are quoted in. /v2/dividends/calendar returns null when the instrument's currency is unknown. Example: `USD`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/dividends/calendar' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "symbol": "0038.HK",
      "date": "2026-10-02",
      "adjustedAmount": 0.08,
      "amount": 0.08,
      "recordDate": "2026-10-05",
      "payDate": "2026-11-13",
      "declarationDate": null,
      "exDate": "2026-09-30",
      "isin": "CNE100000320",
      "currency": "HKD"
    },
    {
      "symbol": "0311.HK",
      "date": "2026-10-02",
      "adjustedAmount": 0.0251,
      "amount": 0.0251,
      "recordDate": "2026-10-06",
      "payDate": "2026-10-30",
      "declarationDate": null,
      "exDate": "2026-10-05",
      "isin": "KYG5697P1046",
      "currency": "HKD"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 54,
    "totalCount": 5348,
    "parameters": {
      "limit": "100"
    },
    "time": 4
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_dividends_calendar

---

# Dividend History

> Dividend events for one instrument, newest first, including announced dividends that have not been paid yet (they sort to the top).

`GET https://api.bavest.co/v2/dividends/history`

Group: Dividends. Route id: `v2_dividends_history`. Included in: Startup, Pro, Growth.

## Description

Dividend events for one instrument, newest first, including announced
dividends that have not been paid yet (they sort to the top).

`from` and `to` narrow the window and are both inclusive: `from` set to
today returns only upcoming events, `to` set to today only past ones.
Without them the full history is returned. Cursor pages continue the
newest-first order.

## 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. |
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of DividendRecord | no |  |
| `data[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `data[].isin` | string \| null | no | ISIN of the instrument, resolved from the symbol. Returned by /v2/dividends/calendar; null when the symbol does not map to a known security. Example: `US0378331005`. |
| `data[].date` | string (date) | yes | Dividend date. |
| `data[].adjustedAmount` | number (double) | no | Split-adjusted dividend per share. Example: `0.25`. |
| `data[].amount` | number (double) | yes | Actual payment per share. Example: `0.25`. |
| `data[].recordDate` | string (date) | no | Dividend record date. |
| `data[].payDate` | string (date) | no | Dividend payment date. |
| `data[].declarationDate` | string (date) \| null | no | Dividend declaration date. |
| `data[].exDate` | string (date) \| null | no | Ex-dividend date. |
| `data[].currency` | string \| null | no | Currency code the amounts are quoted in. /v2/dividends/calendar returns null when the instrument's currency is unknown. Example: `USD`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/dividends/history?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "symbol": "AAPL",
      "date": "2026-05-11",
      "adjustedAmount": 0.27,
      "amount": 0.27,
      "recordDate": "2026-05-11",
      "payDate": "2026-05-14",
      "declarationDate": "2026-04-30",
      "exDate": "2026-05-11",
      "currency": "USD"
    },
    {
      "symbol": "AAPL",
      "date": "2026-02-09",
      "adjustedAmount": 0.26,
      "amount": 0.26,
      "recordDate": "2026-02-09",
      "payDate": "2026-02-12",
      "declarationDate": "2026-01-29",
      "exDate": "2026-02-09",
      "currency": "USD"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 1,
    "totalCount": 91,
    "parameters": {
      "limit": "100",
      "symbol": "AAPL"
    },
    "time": 15
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_dividends_history

---

# Dividend Estimates

> Bavest's per-share dividend forecast.

`GET https://api.bavest.co/v2/dividends/estimates`

Group: Dividends. Route id: `v2_dividends_estimates`. Included in: Startup, Pro, Growth.

## Description

Bavest's per-share dividend forecast. Returns a per-share `amount` with
`lower` and `upper` bounds, one annual estimate per `date`, newest first.
Covers equities and ETFs. These are Bavest model forecasts, separate from
the analyst consensus under Estimates.

## 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. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | DividendEstimatesResponse | no | Bavest's own per-share dividend forecast, newest first. |
| `data.meta` | object | no |  |
| `data.meta.as_of` | string (date) | no | Newest estimate date in the set. Example: `2027-01-01`. |
| `data.meta.years` | integer | no | Number of fiscal years returned. Example: `3`. |
| `data.estimates` | array of DividendEstimate | no |  |
| `data.estimates[].date` | string (date) | no | Jan 1 of the fiscal year. Example: `2026-01-01`. |
| `data.estimates[].fiscal_year` | integer | no | Example: `2026`. |
| `data.estimates[].fiscal_year_end` | string (date) \| null | no | Example: `2026-12-31`. |
| `data.estimates[].expected_payment_year` | integer \| null | no | Example: `2027`. |
| `data.estimates[].amount` | number (double) | no | Dividend per share (point estimate, or the declared amount). Example: `3.49`. |
| `data.estimates[].lower` | number (double) | no | Lower bound (10th percentile). Example: `2.37`. |
| `data.estimates[].upper` | number (double) | no | Upper bound (90th percentile). Example: `5.24`. |
| `data.estimates[].basis` | string | no | declared once the fiscal year's payments are in the dividend calendar. One of `estimate`, `declared`. Example: `estimate`. |
| `data.estimates[].is_estimate` | boolean | no | false when basis is declared. Example: `true`. |
| `data.estimates[].source` | string | no | What carried the estimate. payout_policy: EPS consensus x the company's stated payout corridor. consensus_model: declared dividend grown on the EPS consensus. dividend_trend: no analyst coverage, the company's own dividend run-rate and trend. fmf: the FMF model. One of `payout_policy`, `consensus_model`, `dividend_trend`, `fmf`. Example: `consensus_model`. |
| `data.estimates[].payout_ratio` | number (double) \| null | no | Implied payout (amount / EPS consensus) where dividend and EPS share a currency. Example: `0.45`. |
| `data.estimates[].currency` | string \| null | no | Currency of the listing's dividend line (GBp for London lines). Example: `EUR`. |
| `data.estimates[].model` | object \| null | no | The FMF model estimate for the same year next to a consensus_model estimate. |
| `data.estimates[].model.amount` | number (double) | no |  |
| `data.estimates[].model.lower` | number (double) | no |  |
| `data.estimates[].model.upper` | number (double) | no |  |
| `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/dividends/estimates?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "meta": {
      "as_of": "2028-01-01",
      "years": 3
    },
    "estimates": [
      {
        "date": "2028-01-01",
        "fiscal_year": 2028,
        "fiscal_year_end": "2028-09-27",
        "expected_payment_year": 2028,
        "amount": 1.1377,
        "lower": 0.9179,
        "upper": 1.659,
        "is_estimate": true,
        "basis": "estimate",
        "source": "consensus_model",
        "payout_ratio": 0.1064,
        "currency": "USD",
        "model": {
          "amount": 1.058,
          "lower": 1.038,
          "upper": 1.081
        }
      },
      {
        "date": "2027-01-01",
        "fiscal_year": 2027,
        "fiscal_year_end": "2027-09-27",
        "expected_payment_year": 2027,
        "amount": 1.08,
        "lower": 0.9785,
        "upper": 1.3983,
        "is_estimate": true,
        "basis": "estimate",
        "source": "consensus_model",
        "payout_ratio": 0.1125,
        "currency": "USD",
        "model": {
          "amount": 1.053,
          "lower": 1.039,
          "upper": 1.069
        }
      }
    ]
  },
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 2262
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_dividends_estimates

---

# CPI Data

> Returns Consumer Price Index data for a country, grouped by metric.

`GET https://api.bavest.co/v2/economy/cpi/{country}`

Group: Economic Indicators. Route id: `v2_economy_cpi_country`. Included in: Growth.

## Description

Returns Consumer Price Index data for a country, grouped by metric. For AE, SA, QA and KW this shortcut selects CPI_WB, the annual World Bank index (2010=100), not the inflation percentage. Availability starts after the country dimensions and observations have been loaded.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `country` | path | string | yes | ISO 3166-1 alpha-2 country code (e.g., `US`, `DE`, `JP`) Example `US`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | EconomyIndicatorResponse | no | Macroeconomic indicator data grouped by metric. |
| `data.category` | string \| null | no | Metric category. One of `business_confidence`, `consumer_confidence`, `consumer_spending`, `economic_sentiment`, `employment`, `gdp`, `government`, `housing`, `income`, `industrial_production`, `inflation`, `interest_rates`, `investment`, `manufacturing`, `money_supply`, `trade`. Example: `inflation`. |
| `data.country` | string \| null | no | ISO 3166-1 alpha-2 country code. Example: `US`. |
| `data.metrics` | array of EconomyMetric | yes | Metrics matching the query, each with its own data array. |
| `data.metrics[].code` | string | yes | Machine-readable metric code. Example: `CPI`. |
| `data.metrics[].name` | string | yes | Human-readable metric name. Example: `CPI All Urban Consumers`. |
| `data.metrics[].frequency` | string | no | Data release frequency. Example: `Monthly`. |
| `data.metrics[].data` | array of EconomyMetricObservation | yes | Time-series observations, ordered by referencePeriod descending. |
| `data.metrics[].data[].referencePeriod` | string (date) | yes | Observation date (YYYY-MM-DD) Example: `2026-02-01`. |
| `data.metrics[].data[].value` | number \| null | no | Observed value. Example: `326.785`. |
| `data.metrics[].seriesCode` | string | no | Data source series identifier (e.g. CUUR0000SA0) Example: `CUUR0000SA0`. |
| `data.metrics[].unit` | string | no | Measurement unit (e.g. PCT, INDEX_1982, USD_REAL_BN) Example: `INDEX_1982`. |
| `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/economy/cpi/US' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "category": "inflation",
    "country": "US",
    "metrics": [
      {
        "code": "CPI",
        "name": "CPI All Urban Consumers (Index 1982-1984=100)",
        "frequency": "Monthly",
        "unit": "INDEX_1982",
        "seriesCode": "CPIAUCSL",
        "data": [
          {
            "referencePeriod": "2026-08-01",
            "value": 334.131
          },
          {
            "referencePeriod": "2026-07-01",
            "value": 332.813
          }
        ]
      },
      {
        "code": "CPI",
        "name": "CPI All Urban Consumers (Index 2015=100)",
        "frequency": "Monthly",
        "unit": "INDEX_2015",
        "seriesCode": "DSD_PRICES@DF_PRICES_ALL/{CC}.M.N.CPI.PA._T.N.GY",
        "data": [
          {
            "referencePeriod": "2026-02-01",
            "value": 2.414113
          },
          {
            "referencePeriod": "2026-01-01",
            "value": 2.386431
          }
        ]
      }
    ]
  },
  "meta": {
    "parameters": {
      "country": "US",
      "metric": "CPI"
    },
    "time": 40
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_economy_cpi_country

---

# GDP Data

> Returns real gross domestic product data for a country, grouped by metric.

`GET https://api.bavest.co/v2/economy/gdp/{country}`

Group: Economic Indicators. Route id: `v2_economy_gdp_country`. Included in: Growth.

## Description

Returns real gross domestic product data for a country, grouped by metric. For AE, SA, QA and KW this shortcut selects GDP_REAL_WB: annual GDP in constant 2015 US dollars, unscaled (not billions), rather than quarterly GDP_REAL. Source publication years can differ by country.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `country` | path | string | yes | ISO 3166-1 alpha-2 country code (e.g., `US`, `DE`, `JP`) Example `US`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | EconomyIndicatorResponse | no | Macroeconomic indicator data grouped by metric. |
| `data.category` | string \| null | no | Metric category. One of `business_confidence`, `consumer_confidence`, `consumer_spending`, `economic_sentiment`, `employment`, `gdp`, `government`, `housing`, `income`, `industrial_production`, `inflation`, `interest_rates`, `investment`, `manufacturing`, `money_supply`, `trade`. Example: `inflation`. |
| `data.country` | string \| null | no | ISO 3166-1 alpha-2 country code. Example: `US`. |
| `data.metrics` | array of EconomyMetric | yes | Metrics matching the query, each with its own data array. |
| `data.metrics[].code` | string | yes | Machine-readable metric code. Example: `CPI`. |
| `data.metrics[].name` | string | yes | Human-readable metric name. Example: `CPI All Urban Consumers`. |
| `data.metrics[].frequency` | string | no | Data release frequency. Example: `Monthly`. |
| `data.metrics[].data` | array of EconomyMetricObservation | yes | Time-series observations, ordered by referencePeriod descending. |
| `data.metrics[].data[].referencePeriod` | string (date) | yes | Observation date (YYYY-MM-DD) Example: `2026-02-01`. |
| `data.metrics[].data[].value` | number \| null | no | Observed value. Example: `326.785`. |
| `data.metrics[].seriesCode` | string | no | Data source series identifier (e.g. CUUR0000SA0) Example: `CUUR0000SA0`. |
| `data.metrics[].unit` | string | no | Measurement unit (e.g. PCT, INDEX_1982, USD_REAL_BN) Example: `INDEX_1982`. |
| `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/economy/gdp/US' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "category": "gdp",
    "country": "US",
    "metrics": [
      {
        "code": "GDP_REAL",
        "name": "Real GDP (Billions of chained 2017 USD)",
        "frequency": "Quarterly",
        "unit": "USD_REAL_BN",
        "seriesCode": "GDPC1",
        "data": [
          {
            "referencePeriod": "2026-04-01",
            "value": 24269.613
          },
          {
            "referencePeriod": "2026-01-01",
            "value": 24180.419
          }
        ]
      }
    ]
  },
  "meta": {
    "parameters": {
      "country": "US",
      "metric": "GDP_REAL"
    },
    "time": 47
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_economy_gdp_country

---

# Inflation Data

> Returns inflation indicator data for a country, grouped by metric (CPI, HICP, PPI, etc.).

`GET https://api.bavest.co/v2/economy/inflation/{country}`

Group: Economic Indicators. Route id: `v2_economy_inflation_country`. Included in: Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `country` | path | string | yes | ISO 3166-1 alpha-2 country code (e.g., `US`, `DE`, `JP`) Example `US`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | EconomyIndicatorResponse | no | Macroeconomic indicator data grouped by metric. |
| `data.category` | string \| null | no | Metric category. One of `business_confidence`, `consumer_confidence`, `consumer_spending`, `economic_sentiment`, `employment`, `gdp`, `government`, `housing`, `income`, `industrial_production`, `inflation`, `interest_rates`, `investment`, `manufacturing`, `money_supply`, `trade`. Example: `inflation`. |
| `data.country` | string \| null | no | ISO 3166-1 alpha-2 country code. Example: `US`. |
| `data.metrics` | array of EconomyMetric | yes | Metrics matching the query, each with its own data array. |
| `data.metrics[].code` | string | yes | Machine-readable metric code. Example: `CPI`. |
| `data.metrics[].name` | string | yes | Human-readable metric name. Example: `CPI All Urban Consumers`. |
| `data.metrics[].frequency` | string | no | Data release frequency. Example: `Monthly`. |
| `data.metrics[].data` | array of EconomyMetricObservation | yes | Time-series observations, ordered by referencePeriod descending. |
| `data.metrics[].data[].referencePeriod` | string (date) | yes | Observation date (YYYY-MM-DD) Example: `2026-02-01`. |
| `data.metrics[].data[].value` | number \| null | no | Observed value. Example: `326.785`. |
| `data.metrics[].seriesCode` | string | no | Data source series identifier (e.g. CUUR0000SA0) Example: `CUUR0000SA0`. |
| `data.metrics[].unit` | string | no | Measurement unit (e.g. PCT, INDEX_1982, USD_REAL_BN) Example: `INDEX_1982`. |
| `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/economy/inflation/US' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "category": "inflation",
    "country": "US",
    "metrics": [
      {
        "code": "CPI",
        "name": "CPI All Urban Consumers (Index 1982-1984=100)",
        "frequency": "Monthly",
        "unit": "INDEX_1982",
        "seriesCode": "CPIAUCSL",
        "data": [
          {
            "referencePeriod": "2026-08-01",
            "value": 334.131
          },
          {
            "referencePeriod": "2026-07-01",
            "value": 332.813
          }
        ]
      },
      {
        "code": "CPI",
        "name": "CPI All Urban Consumers (Index 2015=100)",
        "frequency": "Monthly",
        "unit": "INDEX_2015",
        "seriesCode": "DSD_PRICES@DF_PRICES_ALL/{CC}.M.N.CPI.PA._T.N.GY",
        "data": [
          {
            "referencePeriod": "2026-02-01",
            "value": 2.414113
          },
          {
            "referencePeriod": "2026-01-01",
            "value": 2.386431
          }
        ]
      }
    ]
  },
  "meta": {
    "parameters": {
      "country": "US",
      "category": "inflation"
    },
    "time": 991
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_economy_inflation_country

---

# Interest Rate Data

> Returns central bank policy interest rate data for a country, grouped by metric.

`GET https://api.bavest.co/v2/economy/interest-rates/{country}`

Group: Economic Indicators. Route id: `v2_economy_interest_rates_country`. Included in: Growth.

## Description

Returns central bank policy interest rate data for a country, grouped by metric. SA and KW use the BIS POLICY_RATE series (percent per annum). AE and QA are not covered by this BIS feed; no US-rate proxy is substituted.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `country` | path | string | yes | ISO 3166-1 alpha-2 country code (e.g., `US`, `DE`, `JP`) Example `US`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | EconomyIndicatorResponse | no | Macroeconomic indicator data grouped by metric. |
| `data.category` | string \| null | no | Metric category. One of `business_confidence`, `consumer_confidence`, `consumer_spending`, `economic_sentiment`, `employment`, `gdp`, `government`, `housing`, `income`, `industrial_production`, `inflation`, `interest_rates`, `investment`, `manufacturing`, `money_supply`, `trade`. Example: `inflation`. |
| `data.country` | string \| null | no | ISO 3166-1 alpha-2 country code. Example: `US`. |
| `data.metrics` | array of EconomyMetric | yes | Metrics matching the query, each with its own data array. |
| `data.metrics[].code` | string | yes | Machine-readable metric code. Example: `CPI`. |
| `data.metrics[].name` | string | yes | Human-readable metric name. Example: `CPI All Urban Consumers`. |
| `data.metrics[].frequency` | string | no | Data release frequency. Example: `Monthly`. |
| `data.metrics[].data` | array of EconomyMetricObservation | yes | Time-series observations, ordered by referencePeriod descending. |
| `data.metrics[].data[].referencePeriod` | string (date) | yes | Observation date (YYYY-MM-DD) Example: `2026-02-01`. |
| `data.metrics[].data[].value` | number \| null | no | Observed value. Example: `326.785`. |
| `data.metrics[].seriesCode` | string | no | Data source series identifier (e.g. CUUR0000SA0) Example: `CUUR0000SA0`. |
| `data.metrics[].unit` | string | no | Measurement unit (e.g. PCT, INDEX_1982, USD_REAL_BN) Example: `INDEX_1982`. |
| `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/economy/interest-rates/US' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "category": "interest_rates",
    "country": "US",
    "metrics": [
      {
        "code": "FED_FUNDS",
        "name": "Federal Funds Rate (Percent per annum)",
        "frequency": "Per decision",
        "unit": "PCT_PA",
        "seriesCode": "FEDFUNDS",
        "data": [
          {
            "referencePeriod": "2026-09-01",
            "value": 3.75
          },
          {
            "referencePeriod": "2026-08-01",
            "value": 3.63
          }
        ]
      },
      {
        "code": "DTB3",
        "name": "3-Month Treasury Bill: Secondary Market Rate (Percent per annum)",
        "frequency": "Daily",
        "unit": "PCT_PA",
        "seriesCode": "DTB3",
        "data": [
          {
            "referencePeriod": "2026-05-19",
            "value": 3.59
          },
          {
            "referencePeriod": "2026-05-18",
            "value": 3.6
          }
        ]
      }
    ]
  },
  "meta": {
    "parameters": {
      "country": "US",
      "category": "interest_rates"
    },
    "time": 3326
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_economy_interest_rates_country

---

# Unemployment Data

> Returns unemployment rate data for a country, grouped by metric.

`GET https://api.bavest.co/v2/economy/unemployment/{country}`

Group: Economic Indicators. Route id: `v2_economy_unemployment_country`. Included in: Growth.

## Description

Returns unemployment rate data for a country, grouped by metric. For AE, SA, QA and KW this shortcut selects UNEMPLOYMENT_WB, the annual World Bank unemployment estimate, not a monthly national release.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `country` | path | string | yes | ISO 3166-1 alpha-2 country code (e.g., `US`, `DE`, `JP`) Example `US`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | EconomyIndicatorResponse | no | Macroeconomic indicator data grouped by metric. |
| `data.category` | string \| null | no | Metric category. One of `business_confidence`, `consumer_confidence`, `consumer_spending`, `economic_sentiment`, `employment`, `gdp`, `government`, `housing`, `income`, `industrial_production`, `inflation`, `interest_rates`, `investment`, `manufacturing`, `money_supply`, `trade`. Example: `inflation`. |
| `data.country` | string \| null | no | ISO 3166-1 alpha-2 country code. Example: `US`. |
| `data.metrics` | array of EconomyMetric | yes | Metrics matching the query, each with its own data array. |
| `data.metrics[].code` | string | yes | Machine-readable metric code. Example: `CPI`. |
| `data.metrics[].name` | string | yes | Human-readable metric name. Example: `CPI All Urban Consumers`. |
| `data.metrics[].frequency` | string | no | Data release frequency. Example: `Monthly`. |
| `data.metrics[].data` | array of EconomyMetricObservation | yes | Time-series observations, ordered by referencePeriod descending. |
| `data.metrics[].data[].referencePeriod` | string (date) | yes | Observation date (YYYY-MM-DD) Example: `2026-02-01`. |
| `data.metrics[].data[].value` | number \| null | no | Observed value. Example: `326.785`. |
| `data.metrics[].seriesCode` | string | no | Data source series identifier (e.g. CUUR0000SA0) Example: `CUUR0000SA0`. |
| `data.metrics[].unit` | string | no | Measurement unit (e.g. PCT, INDEX_1982, USD_REAL_BN) Example: `INDEX_1982`. |
| `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/economy/unemployment/US' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "category": "employment",
    "country": "US",
    "metrics": [
      {
        "code": "UNEMPLOYMENT_RATE",
        "name": "Unemployment Rate (Percent)",
        "frequency": "Monthly",
        "unit": "PCT",
        "seriesCode": "UNRATE",
        "data": [
          {
            "referencePeriod": "2026-08-01",
            "value": 4.1
          },
          {
            "referencePeriod": "2026-07-01",
            "value": 4.1
          }
        ]
      }
    ]
  },
  "meta": {
    "parameters": {
      "country": "US",
      "metric": "UNEMPLOYMENT_RATE"
    },
    "time": 42
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_economy_unemployment_country

---

# Economy Indicator

> Returns macro-economic indicator data for a country, filtered by metric code or category.

`GET https://api.bavest.co/v2/economy/indicator`

Group: Economic Indicators. Route id: `v2_economy_indicator`. Included in: Growth.

## Description

Returns macro-economic indicator data for a country, filtered by metric code or category. Either `metric` or `category` is required. Available categories: business_confidence, consumer_confidence, consumer_spending, economic_sentiment, employment, gdp, government, housing, income, industrial_production, inflation, interest_rates, investment, manufacturing, money_supply, trade.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `metric` | query | string | one of metric, category | Metric code to query. Either metric or category is required. See EconomyMetricCode schema for all 63 available codes. One of `BUSINESS_CONFIDENCE_EU`, `EXPORT_ORDERS`, `IFO_BUSINESS_CLIMATE`, `IFO_EXPECTATIONS`, `CONSUMER_CONFIDENCE_US`, `GFK_CONSUMER`, `UMICH_SENTIMENT`, `CONSUMER_EXPENDITURE`, `HOUSEHOLD_CONSUMPTION_WB`, `PCE`, `RETAIL_SALES`, `ZEW_SENTIMENT`, `CRUDE_OIL_IMPORTS`, `CRUDE_OIL_STOCKS`, `DISTILLATE_PRODUCTION`, `DISTILLATE_STOCKS`, `GASOLINE_STOCKS`, `REFINERY_CRUDE_RUNS`, `REFINERY_UTILIZATION`, `EMPLOYED_PERSONS`, `INITIAL_CLAIMS`, `JOB_OPENINGS`, `LABOR_FORCE_PARTICIPATION`, `LABOR_FORCE_WB`, `NONFARM_PAYROLLS`, `UNEMPLOYMENT_ILO`, `UNEMPLOYMENT_RATE`, `UNEMPLOYMENT_WB`, `GDP_GROWTH_WB`, `GDP_NOMINAL`, `GDP_NOMINAL_WB`, `GDP_PER_CAPITA_WB`, `GDP_REAL`, `GDP_REAL_WB`, `GOVT_CONSUMPTION`, `BUILDING_PERMITS`, `CONSTRUCTION_PRICE_INDEX`, `HOME_PRICE_INDEX`, `HOUSE_PRICE_INDEX`, `HOUSING_STARTS`, `NEW_HOME_SALES`, `AVG_HOURLY_EARNINGS`, `INCOME_STATISTICS`, `PERSONAL_INCOME`, `INDUSTRIAL_PRODUCTION`, `MANUFACTURING_IP`, `CPI`, `CPI_WB`, `CPI_CORE`, `GDP_DEFLATOR`, `HICP`, `HICP_CORE`, `HICP_CORE_INDEX`, `HICP_INDEX`, `INFLATION_WB`, `PCE_PRICE_INDEX`, `PPI`, `PPI_FINAL_DEMAND`, `BOC_RATE`, `BOE_RATE`, `BOJ_RATE`, `BOK_RATE`, `DE_10Y_YIELD`, `DE_3M_RATE`, `ECB_DFR`, `ECB_MRR`, `FED_FUNDS`, `PBOC_RATE`, `POLICY_RATE`, `RBA_RATE`, `BUSINESS_INVESTMENT`, `GROSS_CAPITAL_FORMATION_WB`, `PRIVATE_INVESTMENT`, `DURABLE_GOODS_ORDERS`, `M2_PCT_GDP_WB`, `MONEY_SUPPLY_M1`, `MONEY_SUPPLY_M2`, `MONEY_SUPPLY_M3`, `EXPORTS_GOODS_SERVICES`, `IMPORTS_GOODS_SERVICES`, `TRADE_BALANCE`, `WHOLESALE_TRADE`. Example `CPI`. |
| `category` | query | string | one of metric, category | Filter by category. Returns all metrics in the category. Either metric or category is required. Example when explicitly filtering: `inflation`. One of `business_confidence`, `consumer_confidence`, `consumer_spending`, `economic_sentiment`, `employment`, `gdp`, `government`, `housing`, `income`, `industrial_production`, `inflation`, `interest_rates`, `investment`, `manufacturing`, `money_supply`, `trade`. |
| `country` | query | string | yes | ISO 3166-1 alpha-2 country code (e.g. US, DE, GB, JP) Example `US`. |

Required: one of `metric`, `category`.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | EconomyIndicatorResponse | no | Macroeconomic indicator data grouped by metric. |
| `data.category` | string \| null | no | Metric category. One of `business_confidence`, `consumer_confidence`, `consumer_spending`, `economic_sentiment`, `employment`, `gdp`, `government`, `housing`, `income`, `industrial_production`, `inflation`, `interest_rates`, `investment`, `manufacturing`, `money_supply`, `trade`. Example: `inflation`. |
| `data.country` | string \| null | no | ISO 3166-1 alpha-2 country code. Example: `US`. |
| `data.metrics` | array of EconomyMetric | yes | Metrics matching the query, each with its own data array. |
| `data.metrics[].code` | string | yes | Machine-readable metric code. Example: `CPI`. |
| `data.metrics[].name` | string | yes | Human-readable metric name. Example: `CPI All Urban Consumers`. |
| `data.metrics[].frequency` | string | no | Data release frequency. Example: `Monthly`. |
| `data.metrics[].data` | array of EconomyMetricObservation | yes | Time-series observations, ordered by referencePeriod descending. |
| `data.metrics[].data[].referencePeriod` | string (date) | yes | Observation date (YYYY-MM-DD) Example: `2026-02-01`. |
| `data.metrics[].data[].value` | number \| null | no | Observed value. Example: `326.785`. |
| `data.metrics[].seriesCode` | string | no | Data source series identifier (e.g. CUUR0000SA0) Example: `CUUR0000SA0`. |
| `data.metrics[].unit` | string | no | Measurement unit (e.g. PCT, INDEX_1982, USD_REAL_BN) Example: `INDEX_1982`. |
| `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/economy/indicator?country=US' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "category": "inflation",
    "country": "US",
    "metrics": [
      {
        "code": "CPI",
        "name": "CPI All Urban Consumers (Index 1982-1984=100)",
        "frequency": "Monthly",
        "unit": "INDEX_1982",
        "seriesCode": "CPIAUCSL",
        "data": [
          {
            "referencePeriod": "2026-08-01",
            "value": 334.131
          },
          {
            "referencePeriod": "2026-07-01",
            "value": 332.813
          }
        ]
      },
      {
        "code": "CPI",
        "name": "CPI All Urban Consumers (Index 2015=100)",
        "frequency": "Monthly",
        "unit": "INDEX_2015",
        "seriesCode": "DSD_PRICES@DF_PRICES_ALL/{CC}.M.N.CPI.PA._T.N.GY",
        "data": [
          {
            "referencePeriod": "2026-02-01",
            "value": 2.414113
          },
          {
            "referencePeriod": "2026-01-01",
            "value": 2.386431
          }
        ]
      }
    ]
  },
  "meta": {
    "parameters": {
      "country": "US",
      "metric": "CPI"
    },
    "time": 983
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_economy_indicator

---

# List Available Countries

> Returns all countries that have macroeconomic data in the Bavest database.

`GET https://api.bavest.co/v2/economy/countries`

Group: Economic Indicators. Route id: `v2_economy_countries`. Free in every plan, including the trial.

## Description

Returns all countries that have macroeconomic data in the Bavest database. Use the returned ISO-2 codes as the `country` parameter for other economy endpoints.

## Parameters

None.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | EconomyCountriesResponse | no | List of countries with macroeconomic data available. |
| `data.countries` | array of EconomyCountry | yes | Countries in the Bavest macro database, sorted by ISO-2 code. |
| `data.countries[].iso2` | string | yes | ISO 3166-1 alpha-2 country code. Example: `US`. |
| `data.countries[].iso3` | string | yes | ISO 3166-1 alpha-3 country code. Example: `USA`. |
| `data.countries[].name` | string | yes | Country display name. Example: `United States`. |
| `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/economy/countries' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "countries": [
      {
        "iso2": "AU",
        "iso3": "AUS",
        "name": "Australia"
      },
      {
        "iso2": "BR",
        "iso3": "BRA",
        "name": "Brazil"
      }
    ]
  },
  "meta": {
    "time": 3543
  }
}
```

## Errors

Also `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_economy_countries

---

# Metric History

> Returns the full time-series history for a specific macroeconomic metric and country.

`GET https://api.bavest.co/v2/metrics/{metric_code}/history`

Group: Economic Indicators. Route id: `v2_metrics_metric_code_history`. Included in: Growth.

## Description

Returns the full time-series history for a specific macroeconomic metric and country. Supports cursor-based pagination for large result sets.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `metric_code` | path | string | yes | Metric code to retrieve history for. See EconomyMetricCode schema for all 63 available codes (e.g. CPI, GDP_REAL, UNEMPLOYMENT_RATE). One of `BUSINESS_CONFIDENCE_EU`, `EXPORT_ORDERS`, `IFO_BUSINESS_CLIMATE`, `IFO_EXPECTATIONS`, `CONSUMER_CONFIDENCE_US`, `GFK_CONSUMER`, `UMICH_SENTIMENT`, `CONSUMER_EXPENDITURE`, `HOUSEHOLD_CONSUMPTION_WB`, `PCE`, `RETAIL_SALES`, `ZEW_SENTIMENT`, `CRUDE_OIL_IMPORTS`, `CRUDE_OIL_STOCKS`, `DISTILLATE_PRODUCTION`, `DISTILLATE_STOCKS`, `GASOLINE_STOCKS`, `REFINERY_CRUDE_RUNS`, `REFINERY_UTILIZATION`, `EMPLOYED_PERSONS`, `INITIAL_CLAIMS`, `JOB_OPENINGS`, `LABOR_FORCE_PARTICIPATION`, `LABOR_FORCE_WB`, `NONFARM_PAYROLLS`, `UNEMPLOYMENT_ILO`, `UNEMPLOYMENT_RATE`, `UNEMPLOYMENT_WB`, `GDP_GROWTH_WB`, `GDP_NOMINAL`, `GDP_NOMINAL_WB`, `GDP_PER_CAPITA_WB`, `GDP_REAL`, `GDP_REAL_WB`, `GOVT_CONSUMPTION`, `BUILDING_PERMITS`, `CONSTRUCTION_PRICE_INDEX`, `HOME_PRICE_INDEX`, `HOUSE_PRICE_INDEX`, `HOUSING_STARTS`, `NEW_HOME_SALES`, `AVG_HOURLY_EARNINGS`, `INCOME_STATISTICS`, `PERSONAL_INCOME`, `INDUSTRIAL_PRODUCTION`, `MANUFACTURING_IP`, `CPI`, `CPI_WB`, `CPI_CORE`, `GDP_DEFLATOR`, `HICP`, `HICP_CORE`, `HICP_CORE_INDEX`, `HICP_INDEX`, `INFLATION_WB`, `PCE_PRICE_INDEX`, `PPI`, `PPI_FINAL_DEMAND`, `BOC_RATE`, `BOE_RATE`, `BOJ_RATE`, `BOK_RATE`, `DE_10Y_YIELD`, `DE_3M_RATE`, `ECB_DFR`, `ECB_MRR`, `FED_FUNDS`, `PBOC_RATE`, `POLICY_RATE`, `RBA_RATE`, `BUSINESS_INVESTMENT`, `GROSS_CAPITAL_FORMATION_WB`, `PRIVATE_INVESTMENT`, `DURABLE_GOODS_ORDERS`, `M2_PCT_GDP_WB`, `MONEY_SUPPLY_M1`, `MONEY_SUPPLY_M2`, `MONEY_SUPPLY_M3`, `EXPORTS_GOODS_SERVICES`, `IMPORTS_GOODS_SERVICES`, `TRADE_BALANCE`, `WHOLESALE_TRADE`. Example `CPI`. |
| `country` | query | string | yes | ISO 3166-1 alpha-2 country code (e.g. US, DE, JP) Example `US`. |
| `from` | query | string (date) | no | Start date for the time series (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date for the time series (YYYY-MM-DD) |
| `source` | query | string | no | Filter by data source code (e.g. BLS, FRED, EUROSTAT) Example when explicitly filtering: `BLS`. |
| `vintage` | query | string | no | Vintage date for revision tracking. Returns the data as it was known on this date. Example when explicitly filtering: `2026-01-15`. |
| `cursor` | query | string | no | Pagination cursor (reference_period value from previous response's next_cursor). Use instead of from for subsequent pages. |
| `limit` | query | integer (int32) | no | Maximum number of observations to return per page (default 1000, max 1000) Default `1000`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | MetricsHistoryResponse | no | Full time-series history for a macroeconomic metric in a single country. |
| `data.category` | string \| null | no | Metric category (e.g. inflation, gdp, employment) Example: `inflation`. |
| `data.country` | string | no | ISO 3166-1 alpha-2 country code. Example: `US`. |
| `data.from` | string (date) \| null | no | Earliest reference period in the returned data. Example: `2020-01-01`. |
| `data.to` | string (date) \| null | no | Latest reference period in the returned data. Example: `2026-02-01`. |
| `data.next_cursor` | string \| null | no | Cursor for the next page of results. Pass as the cursor query parameter to fetch the next page. Null when there are no more pages. Example: `2020-01-01`. |
| `data.metrics` | array of MetricsHistoryMetric | no | Metric time-series data (always a single-element array for the requested metric) |
| `data.metrics[].code` | string | yes | Machine-readable metric code. Example: `CPI`. |
| `data.metrics[].name` | string \| null | no | Human-readable metric name. Example: `CPI All Urban Consumers`. |
| `data.metrics[].frequency` | string \| null | no | Data release frequency (e.g. Monthly, Quarterly, Annual) Example: `Monthly`. |
| `data.metrics[].source` | string \| null | no | Data source code (e.g. BLS, FRED, EUROSTAT) Example: `BLS`. |
| `data.metrics[].count` | integer | yes | Number of observations in the data array. Example: `74`. |
| `data.metrics[].data` | array of MetricsHistoryObservation | yes | Time-series observations ordered by reference_period ascending. |
| `data.metrics[].data[].reference_period` | string (date) | yes | Reference period for the observation (YYYY-MM-DD) Example: `2026-02-01`. |
| `data.metrics[].data[].period_end` | string (date) \| null | no | End date of the observation period (for quarterly/annual data) |
| `data.metrics[].data[].value` | number (double) \| null | no | Observed metric value. Example: `326.785`. |
| `data.metrics[].data[].is_revised` | boolean | no | Whether this observation has been revised from a previously published value. Example: `false`. |
| `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/metrics/CPI/history?country=US' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "category": "inflation",
    "country": "US",
    "from": "1947-01-01",
    "to": "2026-08-01",
    "next_cursor": null,
    "metrics": [
      {
        "code": "CPI",
        "name": "CPI All Urban Consumers",
        "frequency": "Monthly",
        "unit": "INDEX_1982",
        "count": 956,
        "data": [
          {
            "reference_period": "2026-07-01",
            "period_end": null,
            "value": 333.918,
            "is_revised": false
          },
          {
            "reference_period": "2026-08-01",
            "period_end": null,
            "value": 334.98,
            "is_revised": false
          }
        ]
      },
      {
        "code": "CPI",
        "name": "CPI All Urban Consumers",
        "frequency": "Monthly",
        "unit": "INDEX_2015",
        "count": 841,
        "data": [
          {
            "reference_period": "2026-01-01",
            "period_end": null,
            "value": 2.3864,
            "is_revised": false
          },
          {
            "reference_period": "2026-02-01",
            "period_end": null,
            "value": 2.4141,
            "is_revised": false
          }
        ]
      }
    ]
  },
  "meta": {
    "parameters": {
      "metric_code": "CPI",
      "country": "US",
      "limit": "1000"
    },
    "time": 2022
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_metrics_metric_code_history

---

# Balance Sheets

> Returns annual or quarterly balance sheet statements with full line-item detail.

`GET https://api.bavest.co/v2/equities/balance-sheets`

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

## 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 balance sheet line items to include. When provided, each statement is reduced to the named line items. Names that are not balance sheet line items match nothing, so a statement reduced by them comes back empty. Example when explicitly filtering: `totalAssets,totalLiabilities,totalEquity`. |

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[].cashAndCashEquivalents` | number (double) | no | Cash and cash equivalents. |
| `data.financials[].shortTermInvestments` | number (double) | no | Short-term investments. |
| `data.financials[].cashShortTermInvestments` | number (double) | no | Cash + short-term investments (derived) |
| `data.financials[].inventory` | number (double) | no | Inventory. |
| `data.financials[].otherCurrentAssets` | number (double) | no | Other current assets. |
| `data.financials[].currentAssets` | number (double) | no | Total current assets (derived) |
| `data.financials[].totalReceivables` | number (double) | no | Total receivables. |
| `data.financials[].propertyPlantEquipment` | number (double) | no | PP&E net of depreciation. |
| `data.financials[].goodwill` | number (double) | no | Goodwill. |
| `data.financials[].intangibleAssets` | number (double) | no | Intangible assets. |
| `data.financials[].goodwillAndIntangibleAssets` | number (double) | no | Goodwill + intangibles. |
| `data.financials[].longTermInvestments` | number (double) | no | Long-term investments. |
| `data.financials[].taxAssets` | number (double) | no | Tax assets. |
| `data.financials[].otherNonCurrentAssets` | number (double) | no | Other non-current assets. |
| `data.financials[].totalNonCurrentAssets` | number (double) | no | Total non-current assets. |
| `data.financials[].otherAssets` | number (double) | no | Other assets. |
| `data.financials[].totalInvestments` | number (double) | no | Total investments. |
| `data.financials[].totalAssets` | number (double) | no | Total assets. |
| `data.financials[].accountsPayable` | number (double) | no | Accounts payable. |
| `data.financials[].shortTermDebt` | number (double) | no | Short-term debt. |
| `data.financials[].taxPayables` | number (double) | no | Tax payables. |
| `data.financials[].deferredRevenue` | number (double) | no | Deferred revenue (current) |
| `data.financials[].otherCurrentLiabilities` | number (double) | no | Other current liabilities. |
| `data.financials[].currentLiabilities` | number (double) | no | Total current liabilities. |
| `data.financials[].longTermDebt` | number (double) | no | Long-term debt. |
| `data.financials[].deferredRevenueNonCurrent` | number (double) | no | Deferred revenue (non-current) |
| `data.financials[].deferredTaxLiabilitiesNonCurrent` | number (double) | no | Deferred tax liabilities. |
| `data.financials[].otherNonCurrentLiabilities` | number (double) | no | Other non-current liabilities. |
| `data.financials[].totalNonCurrentLiabilities` | number (double) | no | Total non-current liabilities. |
| `data.financials[].otherLiabilities` | number (double) | no | Other liabilities. |
| `data.financials[].capitalLeaseObligations` | number (double) | no | Capital lease obligations. |
| `data.financials[].totalLiabilities` | number (double) | no | Total liabilities. |
| `data.financials[].totalDebt` | number (double) | no | Total debt (short + long term) |
| `data.financials[].netDebt` | number (double) | no | Net debt (debt minus cash) |
| `data.financials[].preferredStock` | number (double) | no | Preferred stock. |
| `data.financials[].commonStock` | number (double) | no | Common stock. |
| `data.financials[].retainedEarnings` | number (double) | no | Retained earnings. |
| `data.financials[].otherTotalStockholdersEquity` | number (double) | no | Other stockholders' equity. |
| `data.financials[].totalStockholdersEquity` | number (double) | no | Total stockholders' equity. |
| `data.financials[].minorityInterest` | number (double) | no | Minority interest. |
| `data.financials[].totalEquity` | number (double) | no | Total equity. |
| `data.financials[].totalLiabilitiesAndTotalEquity` | number (double) | no | Total liabilities + equity (= totalAssets) |
| `data.financials[].liabilitiesShareholdersEquity` | number (double) | no | Total liabilities and shareholders' equity. |
| `data.financials[].otherEquity` | number (double) | no | Other equity components. |
| `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/balance-sheets?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",
        "cashAndCashEquivalents": 35934000000,
        "shortTermInvestments": 18763000000,
        "inventory": 5718000000,
        "otherCurrentAssets": 14585000000,
        "goodwill": 0,
        "intangibleAssets": 0,
        "goodwillAndIntangibleAssets": 0,
        "longTermInvestments": 77723000000,
        "taxAssets": 20777000000,
        "otherNonCurrentAssets": 62950000000,
        "totalNonCurrentAssets": 211284000000,
        "otherAssets": 0,
        "totalAssets": 359241000000,
        "shortTermDebt": 22446000000,
        "taxPayables": 0,
        "deferredRevenue": 9055000000,
        "otherCurrentLiabilities": 64270000000,
        "longTermDebt": 89931000000,
        "deferredRevenueNonCurrent": 0,
        "deferredTaxLiabilitiesNonCurrent": 0,
        "otherNonCurrentLiabilities": 29946000000,
        "totalNonCurrentLiabilities": 119877000000,
        "otherLiabilities": 0,
        "capitalLeaseObligations": 13720000000,
        "totalLiabilities": 285508000000,
        "preferredStock": 0,
        "commonStock": 93568000000,
        "retainedEarnings": -14264000000,
        "otherTotalStockholdersEquity": 0,
        "totalStockholdersEquity": 73733000000,
        "minorityInterest": 0,
        "totalEquity": 73733000000,
        "totalLiabilitiesAndTotalEquity": 359241000000,
        "totalInvestments": 96486000000,
        "totalDebt": 112377000000,
        "netDebt": 76443000000,
        "accountsPayable": 69860000000,
        "cashShortTermInvestments": 54697000000,
        "currentAssets": 147957000000,
        "currentLiabilities": 165631000000,
        "liabilitiesShareholdersEquity": 359241000000,
        "otherEquity": -5571000000,
        "propertyPlantEquipment": 49834000000,
        "totalReceivables": 72957000000,
        "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",
        "cashAndCashEquivalents": 29943000000,
        "shortTermInvestments": 35228000000,
        "inventory": 7286000000,
        "otherCurrentAssets": 14287000000,
        "goodwill": 0,
        "intangibleAssets": 0,
        "goodwillAndIntangibleAssets": 0,
        "longTermInvestments": 91479000000,
        "taxAssets": 19499000000,
        "otherNonCurrentAssets": 55335000000,
        "totalNonCurrentAssets": 211993000000,
        "otherAssets": 0,
        "totalAssets": 364980000000,
        "shortTermDebt": 22511000000,
        "taxPayables": 26601000000,
        "deferredRevenue": 8249000000,
        "otherCurrentLiabilities": 50071000000,
        "longTermDebt": 96548000000,
        "deferredRevenueNonCurrent": 0,
        "deferredTaxLiabilitiesNonCurrent": 0,
        "otherNonCurrentLiabilities": 35090000000,
        "totalNonCurrentLiabilities": 131638000000,
        "otherLiabilities": 0,
        "capitalLeaseObligations": 12430000000,
        "totalLiabilities": 308030000000,
        "preferredStock": 0,
        "commonStock": 83276000000,
        "retainedEarnings": -19154000000,
        "otherTotalStockholdersEquity": 0,
        "totalStockholdersEquity": 56950000000,
        "minorityInterest": 0,
        "totalEquity": 56950000000,
        "totalLiabilitiesAndTotalEquity": 364980000000,
        "totalInvestments": 126707000000,
        "totalDebt": 119059000000,
        "netDebt": 89116000000,
        "accountsPayable": 68960000000,
        "cashShortTermInvestments": 65171000000,
        "currentAssets": 152987000000,
        "currentLiabilities": 176392000000,
        "liabilitiesShareholdersEquity": 364980000000,
        "otherEquity": -7172000000,
        "propertyPlantEquipment": 45680000000,
        "totalReceivables": 66243000000,
        "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": 14
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_balance_sheets

---

# Cash Flow Statements

> Returns annual or quarterly cash flow statements.

`GET https://api.bavest.co/v2/equities/cash-flow`

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

## 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 cash flow line items to include. When provided, each statement is reduced to the named line items. Names that are not cash flow line items match nothing, so a statement reduced by them comes back empty. Example when explicitly filtering: `netOperatingCashFlow,capex,freeCashFlow`. |

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[].netIncome` | number (double) | no | Net income. |
| `data.financials[].depreciationAmortization` | number (double) | no | Depreciation and amortization. |
| `data.financials[].stockBasedCompensation` | number (double) | no | Stock-based compensation. |
| `data.financials[].accountsReceivables` | number (double) | no | Change in accounts receivables. |
| `data.financials[].inventory` | number (double) | no | Change in inventory. |
| `data.financials[].accountsPayables` | number (double) | no | Change in accounts payables. |
| `data.financials[].deferredTaxesInvestmentTaxCredit` | number (double) | no | Deferred taxes. |
| `data.financials[].otherNonCashItems` | number (double) | no | Other non-cash items. |
| `data.financials[].changesInWorkingCapital` | number (double) | no | Total working capital changes. |
| `data.financials[].otherWorkingCapital` | number (double) | no | Other working capital items. |
| `data.financials[].netCashProvidedByOperatingActivities` | number (double) | no | Net operating cash flow. |
| `data.financials[].capex` | number (double) | no | Capital expenditures (negative) |
| `data.financials[].investmentsInPropertyPlantAndEquipment` | number (double) | no | PP&E investments. |
| `data.financials[].acquisitionsNet` | number (double) | no | Net acquisitions. |
| `data.financials[].purchasesOfInvestments` | number (double) | no | Investment purchases (negative) |
| `data.financials[].salesMaturitiesOfInvestments` | number (double) | no | Investment sales (positive) |
| `data.financials[].otherInvestingActivities` | number (double) | no | Other investing activities. |
| `data.financials[].netInvestingCashFlow` | number (double) | no | Net investing cash flow. |
| `data.financials[].commonStockIssued` | number (double) | no | Stock issuance proceeds. |
| `data.financials[].issuanceReductionCapitalStock` | number (double) | no | Net buybacks (negative for repurchases) |
| `data.financials[].debtRepayment` | number (double) | no | Debt repayment (negative) |
| `data.financials[].cashDividendsPaid` | number (double) | no | Dividends paid (negative) |
| `data.financials[].otherFinancingActivities` | number (double) | no | Other financing activities. |
| `data.financials[].netCashFinancingActivities` | number (double) | no | Net financing cash flow. |
| `data.financials[].effectOfForexChangesOnCash` | number (double) | no | FX impact on cash. |
| `data.financials[].changeInCash` | number (double) | no | Net change in cash. |
| `data.financials[].cashAtBeginningOfPeriod` | number (double) | no | Opening cash balance. |
| `data.financials[].cashAtEndOfPeriod` | number (double) | no | Closing cash balance. |
| `data.financials[].netOperatingCashFlow` | number (double) | no | Net operating cash flow (alias) |
| `data.financials[].freeCashFlow` | number (double) | no | Free cash flow (operating - capex) |
| `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/cash-flow?symbol=AAPL&freq=annual' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "financials": [
      {
        "date": "2025-09-27",
        "frequency": "annual",
        "salesMaturitiesOfInvestments": 53797000000,
        "commonStockIssued": 0,
        "otherWorkingCapital": -20273000000,
        "cik": 320193,
        "cashAtBeginningOfPeriod": 29943000000,
        "filingDate": "2025-10-31",
        "link": "https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/0000320193-25-000079-index.htm",
        "changeInCash": 5991000000,
        "inventory": 1400000000,
        "acceptedDate": "2025-10-31T06:01:26",
        "stockBasedCompensation": 12863000000,
        "accountsReceivables": -7029000000,
        "freeCashFlow": 98767000000,
        "netCashProvidedByOperatingActivities": 111482000000,
        "purchasesOfInvestments": -24407000000,
        "otherFinancingActivities": -6071000000,
        "changesInWorkingCapital": -25000000000,
        "issuanceReductionCapitalStock": -90711000000,
        "netCashFinancingActivities": -120686000000,
        "otherInvestingActivities": -1480000000,
        "debtRepayment": -8483000000,
        "acquisitionsNet": 0,
        "cashAtEndOfPeriod": 35934000000,
        "otherNonCashItems": -89000000,
        "period": "FY",
        "effectOfForexChangesOnCash": 0,
        "capex": -12715000000,
        "calendarYear": "2025",
        "depreciationAmortization": 11698000000,
        "cashDividendsPaid": -15421000000,
        "netInvestingCashFlow": 15195000000,
        "reportedCurrency": "USD",
        "netIncome": 112010000000,
        "investmentsInPropertyPlantAndEquipment": -12715000000,
        "finalLink": "https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/aapl-20250927.htm",
        "deferredTaxesInvestmentTaxCredit": 0,
        "accountsPayables": 902000000,
        "netOperatingCashFlow": 111482000000,
        "isGapData": false,
        "symbol": "AAPL"
      },
      {
        "date": "2024-09-28",
        "frequency": "annual",
        "salesMaturitiesOfInvestments": 62346000000,
        "commonStockIssued": 0,
        "otherWorkingCapital": 3821000000,
        "cik": 320193,
        "cashAtBeginningOfPeriod": 30737000000,
        "filingDate": "2024-11-01",
        "link": "https://www.sec.gov/Archives/edgar/data/320193/000032019324000123/0000320193-24-000123-index.htm",
        "changeInCash": -794000000,
        "inventory": -1046000000,
        "acceptedDate": "2024-11-01T06:01:36",
        "stockBasedCompensation": 11688000000,
        "accountsReceivables": -5144000000,
        "freeCashFlow": 108807000000,
        "netCashProvidedByOperatingActivities": 118254000000,
        "purchasesOfInvestments": -48656000000,
        "otherFinancingActivities": -5802000000,
        "changesInWorkingCapital": 3651000000,
        "issuanceReductionCapitalStock": -94949000000,
        "netCashFinancingActivities": -121983000000,
        "otherInvestingActivities": -1308000000,
        "debtRepayment": -5998000000,
        "acquisitionsNet": 0,
        "cashAtEndOfPeriod": 29943000000,
        "otherNonCashItems": -2266000000,
        "period": "FY",
        "effectOfForexChangesOnCash": 0,
        "capex": -9447000000,
        "calendarYear": "2024",
        "depreciationAmortization": 11445000000,
        "cashDividendsPaid": -15234000000,
        "netInvestingCashFlow": 2935000000,
        "reportedCurrency": "USD",
        "netIncome": 93736000000,
        "investmentsInPropertyPlantAndEquipment": -9447000000,
        "finalLink": "https://www.sec.gov/Archives/edgar/data/320193/000032019324000123/aapl-20240928.htm",
        "deferredTaxesInvestmentTaxCredit": 0,
        "accountsPayables": 6020000000,
        "netOperatingCashFlow": 118254000000,
        "isGapData": false,
        "symbol": "AAPL"
      }
    ],
    "currency": "USD"
  },
  "meta": {
    "parameters": {
      "freq": "annual",
      "symbol": "AAPL"
    },
    "time": 17
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_cash_flow

---

# Company Logo

> Returns the company logo as a PNG image.

`GET https://api.bavest.co/v2/equities/logo`

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

## 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. |

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

## Response

200 Company logo (image/png) (`image/png`).

## Example request

```bash
curl 'https://api.bavest.co/v2/equities/logo?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'accept: image/png' \
  --output response.png
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_logo

---

# Company Profile

> Returns company identity, classification, and market data.

`GET https://api.bavest.co/v2/equities/profile`

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

## Description

Returns company identity, classification, and market data.

> This endpoint is equity-specific. For ETF or fund profiles, use the ETF or Fund domain.

## 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. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | CompanyProfile | no | Company identity and classification. Equity-specific — no ETF/fund flags. |
| `data.symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `data.companyName` | string | yes | Legal company name. Example: `Apple Inc.`. |
| `data.description` | string | no | Business summary of the company. |
| `data.ceo` | string | no | Chief Executive Officer name. Example: `Timothy D. Cook`. |
| `data.sector` | string | no | GICS sector. Example: `Technology`. |
| `data.industry` | string | no | GICS industry. Example: `Consumer Electronics`. |
| `data.country` | string | no | ISO 3166-1 alpha-2. Example: `US`. |
| `data.state` | string | no | State or province of headquarters. Example: `CA`. |
| `data.city` | string | no | City of headquarters. Example: `Cupertino`. |
| `data.address` | string | no | Street address of headquarters. Example: `One Apple Park Way`. |
| `data.zip` | string | no | Postal or ZIP code. Example: `95014`. |
| `data.phone` | string | no | Primary contact phone number. Example: `(408) 996-1010`. |
| `data.website` | string (uri) | no | Company website URL. Example: `https://www.apple.com`. |
| `data.exchange` | string | no | Full name of the listing exchange. Example: `NASDAQ Global Select`. |
| `data.exchangeShortName` | string | no | Abbreviated exchange name. Example: `NASDAQ`. |
| `data.isin` | string | no | International Securities Identification Number. Example: `US0378331005`. |
| `data.cik` | string \| null | no | SEC Central Index Key. Example: `320193`. |
| `data.ipo` | string (date) \| null | no | Initial public offering date. Example: `1980-12-12`. |
| `data.currency` | string | no | Primary trading currency (ISO 4217) Example: `USD`. |
| `data.employeeTotal` | integer \| null | no | Total number of employees. Example: `164000`. |
| `data.isActivelyTrading` | boolean | no | Whether the security is currently actively traded. Example: `true`. |
| `data.isAdr` | boolean | no | Whether the security is an American Depositary Receipt. Example: `false`. |
| `data.isReit` | boolean \| null | no | Whether the company is a REIT (real estate investment trust): its industry starts with "REIT", e.g. Realty Income "REIT - Retail". Never true for ETFs or funds. `null` when no industry is known. Example: `true`. |
| `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/profile?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "symbol": "AAPL",
    "companyName": "Apple Inc.",
    "description": "Apple Inc. is a global technology corporation that specializes in the conceptualization, production, and sale of a diverse suite of electronic devices. Its comprehensive hardware lineup features the well-known iPhone smartphones, Mac personal computers, and versatile iPad tablets. The company also supplies a range of wearables, smart home products, and accessories, including AirPods, Apple TV, Apple Watch, items from the Beats brand, and HomePod speakers. Beyond its device offerings, Apple delivers essential support services like AppleCare and robust cloud solutions. It oversees key digital platforms, prominently the App Store, which acts as a central hub for customers to discover and download countless applications and digital content, from e-books and music to videos, games, and podcasts. The company also generates revenue via advertising, leveraging both its proprietary ad platforms and third-party licensing deals. Apple's ecosystem is further bolstered by a wide array of subscription-based services: Apple Arcade for gaming, Apple Fitness+ for personalized wellness, Apple Music for curated audio experiences and on-demand radio, Apple News+ for access to news and magazines, and Apple TV+ for exclusive original video programming. Its financial services portfolio includes the co-branded Apple Card and the mobile payment system, Apple Pay. Additionally, Apple strategically licenses its intellectual property. The company serves a broad clientele that spans individual consumers, small and medium-sized enterprises, as well as institutional clients in the education, corporate, and governmental sectors. Products are distributed through a multi-channel strategy, utilizing Apple's own physical retail locations and online storefronts, a dedicated direct sales team, and collaborations with external partners such as mobile network providers, wholesalers, general retailers, and authorized resellers. The App Store additionally functions as the primary conduit for third-party applications designed for its devices. Founded in 1976, Apple Inc. is headquartered in Cupertino, California.",
    "ceo": "John Ternus",
    "sector": "Technology",
    "industry": "Consumer Electronics",
    "country": "US",
    "state": "CA",
    "city": "Cupertino",
    "address": "One Apple Park Way",
    "zip": "95014",
    "phone": "(408) 996-1010",
    "website": "https://www.apple.com",
    "exchange": "NASDAQ Global Select",
    "exchangeShortName": "NASDAQ",
    "isin": "US0378331005",
    "cik": 320193,
    "ipo": "1980-12-12",
    "currency": "USD",
    "employeeTotal": 166000,
    "isActivelyTrading": true,
    "isAdr": false
  },
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 13
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_profile

---

# Equity Metric Names

> Returns registered equity metric names with their unit, description and -- per name -- which reporting bases GET /equities/metrics/history can actually serve.

`GET https://api.bavest.co/v2/equities/metrics/names`

Group: Equities. Route id: `v2_equities_metrics_names`. Free in every plan, including the trial.

## Description

Returns registered equity metric names with their unit, description and -- per name -- which reporting bases GET /equities/metrics/history can actually serve. Every name here is available as a latest value on GET /equities/metrics; `bases` is narrower, because history is materialized per basis. Filter with `hasHistory` or `basis` to get only the names a history integration can rely on. No security identifier required.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `hasHistory` | query | boolean | no | When true, return only names with at least one materialized basis; when false, only names without one. Omit for all names. |
| `basis` | query | string | no | Return only names materialized on this reporting basis. A basis that is valid but not yet materialized returns an empty list with count 0 rather than an error, mirroring how the history endpoint answers with a warning instead of a 404. One of `FY`, `Q1`, `Q2`, `Q3`, `Q4`, `H1`, `H2`, `TTM`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.count` | integer | no | Number of metric names in this response, after any hasHistory/basis filter. Example: `103`. |
| `data.metrics` | array of object | no |  |
| `data.metrics[].name` | string | no | Canonical metric name (snake_case) Example: `pe_ratio`. |
| `data.metrics[].unit` | string | no | Unit type for the metric. Example: `ratio`. |
| `data.metrics[].description` | string | no | Human-readable description of the metric. Example: `Price-to-Earnings Ratio (P/E)`. |
| `data.metrics[].bases` | array of string | no | Reporting bases GET /equities/metrics/history can serve for this name. Empty means the name has a latest value but no history yet. A *_ttm name carries TTM and nothing else, since no other basis exists for it. |
| `data.metrics[].hasHistory` | boolean | no | Convenience flag, true exactly when `bases` is non-empty. Example: `true`. |
| `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/metrics/names' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "count": 192,
    "metrics": [
      {
        "name": "10y_dividend_growth",
        "unit": "percentage",
        "description": "Dividend Growth (10Y)",
        "bases": [],
        "hasHistory": false
      },
      {
        "name": "10y_equity_growth",
        "unit": "percentage",
        "description": "Equity Growth (10Y)",
        "bases": [
          "FY"
        ],
        "hasHistory": true
      }
    ]
  },
  "meta": {
    "time": 2106
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_metrics_names

---

# Equity Metrics History Export

> Returns time-limited download links for this account's pre-materialized equity-metrics history export (Parquet, one part per metric) plus its manifest.

`GET https://api.bavest.co/v2/equities/exports`

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

## Description

Returns time-limited download links for this account's pre-materialized equity-metrics history export (Parquet, one part per metric) plus its manifest. The export is produced by a batch job and scoped to the caller's API key; no identifier is required. If no export has been materialized yet, the response contains an empty parts list and a warning.

## Parameters

None.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.clientId` | string | no | The account (API-key id) the export is scoped to. |
| `data.generatedAt` | string | no | When the export was materialized (ISO-8601) |
| `data.format` | string | no | Example: `parquet`. |
| `data.schema` | array of string | no | Column order of every part file. |
| `data.rows` | integer | no | Total rows across all parts. |
| `data.expiresInSeconds` | integer | no | Lifetime of the returned presigned URLs. Example: `3600`. |
| `data.manifestUrl` | string | no | Presigned URL for the manifest.json. |
| `data.parts` | array of object | no |  |
| `data.parts[].metricName` | string | no | Example: `roe_ttm`. |
| `data.parts[].url` | string | no | Presigned URL for that metric's Parquet part. |
| `data.warning` | string | no | Present only when no export is materialized yet. |
| `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/exports' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Errors

Also `401`, `429` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_export_latest

---

# Submit Equity Data Export

> Submit an asynchronous export job for this account.

`POST https://api.bavest.co/v2/equities/exports`

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

## Description

Submit an asynchronous export job for this account. Choose symbols and/or isins (at least one, at most 100 together), optional metrics and a from/to window; a batch worker materialises the Parquet export, then poll GET /equities/exports/{exportId} for signed download links. symbols and isins union. A request with neither is a 400. Scoped to the caller's API key.

## Parameters

None.

## Request body

JSON, optional.

| Field | Type | Always present | Description |
|---|---|---|---|
| `metrics` | array of string | no |  |
| `symbols` | array of string | no |  |
| `isins` | array of string | no |  |
| `from` | string (date) | no |  |
| `to` | string (date) | no |  |

## Response

200 Job accepted (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.exportId` | string | no |  |
| `data.assetClass` | string | no | Example: `equity`. |
| `data.status` | string | no | Example: `pending`. |
| `data.poll` | string | no | Poll this path for status and links. |
| `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 -X POST 'https://api.bavest.co/v2/equities/exports' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"metrics":["string"],"symbols":["string"],"isins":["string"],"from":"2026-01-02","to":"2026-01-02"}'
```

## Errors

Also `400`, `401`, `429` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_export_submit

---

# Comprehensive Metrics

> Returns comprehensive per-metric financial data with validity flags, descriptions, and units.

`GET https://api.bavest.co/v2/equities/metrics`

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

## Description

Returns comprehensive per-metric financial data with validity flags, descriptions, and units. Supports optional currency conversion. Results are paginated (default 50 metrics per page, max 200).

## 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. |
| `currency` | query | string | no | Target currency for monetary values (ISO 4217). Converts from reporting currency if different. Example when explicitly filtering: `USD`. |
| `fields` | query | string | no | Comma-separated list of metric ids to return. Unlike the statement endpoints, this filters metrics by `metricId`, not by response key. Valid ids are served by `/v2/equities/metrics/names`. Ids that do not exist match nothing, so the metrics list comes back empty. Example when explicitly filtering: `market_cap,roe_ttm`. |
| `limit` | query | integer (int32) | no | Maximum number of metrics to return per page (default 50, max 200) Default `50`. |
| `offset` | query | integer (int32) | no | Number of metrics to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | EquityMetrics | no | Comprehensive equity metrics response with per-metric metadata. |
| `data.latestDate` | string (date) \| null | no | Most recent observation date across all metrics. Example: `2025-09-27`. |
| `data.metrics` | array of object | no | Array of individual metric entries. |
| `data.metrics[].metricId` | string | no | Metric identifier (camelCase) Example: `peRatio`. |
| `data.metrics[].date` | string (date) \| null | no | Observation date of this metric value. Example: `2025-09-27`. |
| `data.metrics[].metricName` | string | no | Raw metric name from the data source. Example: `pe_ratio`. |
| `data.metrics[].value` | number (double) \| null | no | Metric value (null if unavailable) Example: `32.13`. |
| `data.metrics[].valid` | boolean | no | Whether the metric value is available. Example: `true`. |
| `data.metrics[].reason` | string \| null | no | Reason if value is null or flagged. |
| `data.metrics[].rootCause` | string \| null | no | Root cause for null or anomalous values. |
| `data.metrics[].description` | string \| null | no | Human-readable metric description. Example: `Price to earnings ratio`. |
| `data.metrics[].unit` | string \| null | no | Metric unit (e.g., ratio, USD, percent) Example: `ratio`. |
| `data.metrics[].currency` | string \| null | no | Currency of monetary values (ISO 4217) Example: `USD`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

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

## Example response

```json
{
  "data": {
    "latestDate": "2026-10-02",
    "metrics": [
      {
        "metricId": "10y_dividend_growth",
        "metricName": "10y_dividend_growth",
        "value": 85.8023,
        "date": "2025-09-27",
        "valid": true,
        "reason": null,
        "rootCause": null,
        "description": "Dividend Growth (10Y) = (dps_last - dps_first) / |dps_first| * 100",
        "unit": "PERCENTAGE",
        "currency": "USD"
      },
      {
        "metricId": "10y_equity_growth",
        "metricName": "10y_equity_growth",
        "value": -38.2238,
        "date": "2025-09-27",
        "valid": true,
        "reason": null,
        "rootCause": null,
        "description": "Equity Growth (10Y) = (equity_last - equity_first) / |equity_first| * 100",
        "unit": "PERCENTAGE",
        "currency": "USD"
      }
    ]
  },
  "meta": {
    "page": 1,
    "pageSize": 50,
    "totalPages": 4,
    "totalCount": 189,
    "parameters": {
      "limit": "50",
      "symbol": "AAPL"
    },
    "time": 70
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_metrics

---

# Metric History

> Returns one statement-derived metric (ratios, margins, growth and every *_ttm name) as a series of points, one per fiscal period end, newest first.

`GET https://api.bavest.co/v2/equities/metrics/history`

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

## Description

Returns one statement-derived metric (ratios, margins, growth and every *_ttm name) as a series of points, one per fiscal period end, newest first. Suppressed periods are returned as explicit null points with a reason instead of being omitted, so point counts stay stable for mirrors; see the Metric History guide for basis, vintage and TTM-overlap semantics.

## 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. |
| `name` | query | string | yes | Metric name. Discover valid names via GET /equities/metrics/names. Example `roe_ttm`. |
| `basis` | query | string | no | Reporting basis. Defaults to TTM for *_ttm names, FY otherwise. One of `FY`, `Q1`, `Q2`, `Q3`, `Q4`, `H1`, `H2`, `TTM`. |
| `vintage` | query | string | no | MR = most recent restated statements. AR / as_of point-in-time replay is not yet enabled. One of `MR`. Default `MR`. |
| `from` | query | string (date) | no | Earliest period end (inclusive). |
| `to` | query | string (date) | no | Latest period end (inclusive). |
| `provenance` | query | boolean | no | When true, each point carries a provenance block (knownAt, restated, and the vendor's acceptedDate/filingDate claim). Empty while ledger coverage has not begun for the security. Default `false`. |
| `changedSince` | query | string (date-time) | no | Incremental sync. Returns only points whose value changed at or after this ISO-8601 timestamp. Pass the `syncCursor` of the previous response; points upsert on periodEnd, so re-pulling an overlap is harmless. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.metric` | object | no |  |
| `data.metric.id` | string | no | Example: `roe_ttm`. |
| `data.metric.name` | string | no | Example: `roe_ttm`. |
| `data.metric.unit` | string \| null | no | Example: `RATIO`. |
| `data.metric.currency` | string \| null | no | Example: `USD`. |
| `data.metric.calcVersion` | string \| null | no | Example: `2026.08`. |
| `data.basis` | string | no | One of `FY`, `Q1`, `Q2`, `Q3`, `Q4`, `H1`, `H2`, `TTM`. |
| `data.vintage` | string | no | One of `MR`. |
| `data.warning` | string | no | Present when no history is materialized yet for this security/metric/basis. |
| `data.syncCursor` | string (date-time) \| null | no | Latest change time across the whole series (not only the returned points). Pass it as `changedSince` on the next call. Null when no history is materialized. Example: `2026-07-22T21:42:19.701813+00:00`. |
| `data.points` | array of object | no |  |
| `data.points[].periodEnd` | string (date) | no |  |
| `data.points[].periodLabel` | string | no |  |
| `data.points[].calendarPeriod` | string | no | Calendar bucket the fiscal point belongs to, derived from the real filed period dates. Sub-annual points take the calendar quarter of their period end (CY2025Q3); annual points take the calendar year holding the majority of the fiscal year, so a non-December year-end aligns with December filers. Labeling only -- no value is interpolated across fiscal boundaries. Example: `CY2025Q3`. |
| `data.points[].value` | number \| null | no |  |
| `data.points[].valid` | boolean | no |  |
| `data.points[].updatedAt` | string (date-time) \| null | no | When this point's value last changed in our store. |
| `data.points[].reason` | string | no | Why the point is null (only on suppressed points). |
| `data.points[].rootCause` | string | no | Detail behind the suppression (only on suppressed points). |
| `data.points[].provenance` | object | no | Present only when provenance=true. |
| `data.points[].provenance.knownAt` | string (date-time) \| null | no | When we first knew the currently served value (our honest first-seen axis). Null before ledger coverage begins for this security. |
| `data.points[].provenance.firstKnownAt` | string (date-time) \| null | no | When we first observed any value for this period. |
| `data.points[].provenance.restated` | boolean | no | True when this period has more than one distinct observed version in our ledger. For TTM it flags the anchor quarter. |
| `data.points[].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.points[].provenance.filingDate` | string (date) \| null | no | The vendor's claimed filing date, subject to the same fabrication caveat as acceptedDate. |
| `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/metrics/history?symbol=AAPL&name=roe_ttm&vintage=MR' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "metric": {
      "id": "roe_ttm",
      "name": "roe_ttm",
      "unit": "RATIO",
      "currency": null,
      "calcVersion": "2026.07"
    },
    "basis": "TTM",
    "vintage": "MR",
    "syncCursor": "2026-08-31T07:51:48.126480+00:00",
    "points": [
      {
        "periodEnd": "2026-06-27",
        "periodLabel": "TTM",
        "calendarPeriod": "CY2026Q2",
        "value": 1.1991,
        "valid": true,
        "updatedAt": "2026-08-31T07:51:48.126480+00:00"
      },
      {
        "periodEnd": "2026-03-28",
        "periodLabel": "TTM",
        "calendarPeriod": "CY2026Q1",
        "value": 1.151,
        "valid": true,
        "updatedAt": "2026-08-31T07:51:47.732996+00:00"
      }
    ]
  },
  "meta": {
    "parameters": {
      "name": "roe_ttm",
      "symbol": "AAPL"
    },
    "time": 2276
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_metrics_history

---

# Financials Trailing Twelve Months

> Returns the most recent TTM snapshot across all three financial statements.

`GET https://api.bavest.co/v2/equities/financials-ttm`

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

## 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. |
| `fields` | query | string | no | Comma-separated list of line items to include. The filter is applied to each of the `bs`, `cf` and `ic` blocks, so a name is kept only in the statement that reports it. Names that no statement reports match nothing, so the blocks come back empty. Example when explicitly filtering: `totalAssets,freeCashFlow,revenue`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.bs` | FinancialPeriodMeta | no | Balance sheet (trailing twelve months) |
| `data.bs.date` | string (date) | no | Period end date. Example: `2025-09-27`. |
| `data.bs.frequency` | string | no | Reporting frequency. One of `annual`, `quarterly`. |
| `data.bs.reportedCurrency` | string | no | Currency of reported values (ISO 4217) Example: `USD`. |
| `data.bs.cik` | string | no | SEC Central Index Key (10-digit) Example: `320193`. |
| `data.bs.filingDate` | string (date) | no | SEC filing submission date. |
| `data.bs.acceptedDate` | string (date-time) | no | SEC acceptance timestamp. |
| `data.bs.calendarYear` | string | no | Calendar year. Example: `2025`. |
| `data.bs.period` | string | no | Period code: FY, Q1, Q2, Q3, Q4. Example: `FY`. |
| `data.bs.link` | string (uri) | no | SEC EDGAR filing index URL. |
| `data.bs.finalLink` | string (uri) | no | Direct SEC filing document URL. |
| `data.bs.isGapData` | boolean \| null | no | Whether this period was interpolated to fill a gap. |
| `data.bs.cashAndCashEquivalents` | number (double) | no | Cash and cash equivalents. |
| `data.bs.shortTermInvestments` | number (double) | no | Short-term investments. |
| `data.bs.cashShortTermInvestments` | number (double) | no | Cash + short-term investments (derived) |
| `data.bs.inventory` | number (double) | no | Inventory. |
| `data.bs.otherCurrentAssets` | number (double) | no | Other current assets. |
| `data.bs.currentAssets` | number (double) | no | Total current assets (derived) |
| `data.bs.totalReceivables` | number (double) | no | Total receivables. |
| `data.bs.propertyPlantEquipment` | number (double) | no | PP&E net of depreciation. |
| `data.bs.goodwill` | number (double) | no | Goodwill. |
| `data.bs.intangibleAssets` | number (double) | no | Intangible assets. |
| `data.bs.goodwillAndIntangibleAssets` | number (double) | no | Goodwill + intangibles. |
| `data.bs.longTermInvestments` | number (double) | no | Long-term investments. |
| `data.bs.taxAssets` | number (double) | no | Tax assets. |
| `data.bs.otherNonCurrentAssets` | number (double) | no | Other non-current assets. |
| `data.bs.totalNonCurrentAssets` | number (double) | no | Total non-current assets. |
| `data.bs.otherAssets` | number (double) | no | Other assets. |
| `data.bs.totalInvestments` | number (double) | no | Total investments. |
| `data.bs.totalAssets` | number (double) | no | Total assets. |
| `data.bs.accountsPayable` | number (double) | no | Accounts payable. |
| `data.bs.shortTermDebt` | number (double) | no | Short-term debt. |
| `data.bs.taxPayables` | number (double) | no | Tax payables. |
| `data.bs.deferredRevenue` | number (double) | no | Deferred revenue (current) |
| `data.bs.otherCurrentLiabilities` | number (double) | no | Other current liabilities. |
| `data.bs.currentLiabilities` | number (double) | no | Total current liabilities. |
| `data.bs.longTermDebt` | number (double) | no | Long-term debt. |
| `data.bs.deferredRevenueNonCurrent` | number (double) | no | Deferred revenue (non-current) |
| `data.bs.deferredTaxLiabilitiesNonCurrent` | number (double) | no | Deferred tax liabilities. |
| `data.bs.otherNonCurrentLiabilities` | number (double) | no | Other non-current liabilities. |
| `data.bs.totalNonCurrentLiabilities` | number (double) | no | Total non-current liabilities. |
| `data.bs.otherLiabilities` | number (double) | no | Other liabilities. |
| `data.bs.capitalLeaseObligations` | number (double) | no | Capital lease obligations. |
| `data.bs.totalLiabilities` | number (double) | no | Total liabilities. |
| `data.bs.totalDebt` | number (double) | no | Total debt (short + long term) |
| `data.bs.netDebt` | number (double) | no | Net debt (debt minus cash) |
| `data.bs.preferredStock` | number (double) | no | Preferred stock. |
| `data.bs.commonStock` | number (double) | no | Common stock. |
| `data.bs.retainedEarnings` | number (double) | no | Retained earnings. |
| `data.bs.otherTotalStockholdersEquity` | number (double) | no | Other stockholders' equity. |
| `data.bs.totalStockholdersEquity` | number (double) | no | Total stockholders' equity. |
| `data.bs.minorityInterest` | number (double) | no | Minority interest. |
| `data.bs.totalEquity` | number (double) | no | Total equity. |
| `data.bs.totalLiabilitiesAndTotalEquity` | number (double) | no | Total liabilities + equity (= totalAssets) |
| `data.bs.liabilitiesShareholdersEquity` | number (double) | no | Total liabilities and shareholders' equity. |
| `data.bs.otherEquity` | number (double) | no | Other equity components. |
| `data.cf` | FinancialPeriodMeta | no | Cash flow statement (trailing twelve months) |
| `data.cf.date` | string (date) | no | Period end date. Example: `2025-09-27`. |
| `data.cf.frequency` | string | no | Reporting frequency. One of `annual`, `quarterly`. |
| `data.cf.reportedCurrency` | string | no | Currency of reported values (ISO 4217) Example: `USD`. |
| `data.cf.cik` | string | no | SEC Central Index Key (10-digit) Example: `320193`. |
| `data.cf.filingDate` | string (date) | no | SEC filing submission date. |
| `data.cf.acceptedDate` | string (date-time) | no | SEC acceptance timestamp. |
| `data.cf.calendarYear` | string | no | Calendar year. Example: `2025`. |
| `data.cf.period` | string | no | Period code: FY, Q1, Q2, Q3, Q4. Example: `FY`. |
| `data.cf.link` | string (uri) | no | SEC EDGAR filing index URL. |
| `data.cf.finalLink` | string (uri) | no | Direct SEC filing document URL. |
| `data.cf.isGapData` | boolean \| null | no | Whether this period was interpolated to fill a gap. |
| `data.cf.netIncome` | number (double) | no | Net income. |
| `data.cf.depreciationAmortization` | number (double) | no | Depreciation and amortization. |
| `data.cf.stockBasedCompensation` | number (double) | no | Stock-based compensation. |
| `data.cf.accountsReceivables` | number (double) | no | Change in accounts receivables. |
| `data.cf.inventory` | number (double) | no | Change in inventory. |
| `data.cf.accountsPayables` | number (double) | no | Change in accounts payables. |
| `data.cf.deferredTaxesInvestmentTaxCredit` | number (double) | no | Deferred taxes. |
| `data.cf.otherNonCashItems` | number (double) | no | Other non-cash items. |
| `data.cf.changesInWorkingCapital` | number (double) | no | Total working capital changes. |
| `data.cf.otherWorkingCapital` | number (double) | no | Other working capital items. |
| `data.cf.netCashProvidedByOperatingActivities` | number (double) | no | Net operating cash flow. |
| `data.cf.capex` | number (double) | no | Capital expenditures (negative) |
| `data.cf.investmentsInPropertyPlantAndEquipment` | number (double) | no | PP&E investments. |
| `data.cf.acquisitionsNet` | number (double) | no | Net acquisitions. |
| `data.cf.purchasesOfInvestments` | number (double) | no | Investment purchases (negative) |
| `data.cf.salesMaturitiesOfInvestments` | number (double) | no | Investment sales (positive) |
| `data.cf.otherInvestingActivities` | number (double) | no | Other investing activities. |
| `data.cf.netInvestingCashFlow` | number (double) | no | Net investing cash flow. |
| `data.cf.commonStockIssued` | number (double) | no | Stock issuance proceeds. |
| `data.cf.issuanceReductionCapitalStock` | number (double) | no | Net buybacks (negative for repurchases) |
| `data.cf.debtRepayment` | number (double) | no | Debt repayment (negative) |
| `data.cf.cashDividendsPaid` | number (double) | no | Dividends paid (negative) |
| `data.cf.otherFinancingActivities` | number (double) | no | Other financing activities. |
| `data.cf.netCashFinancingActivities` | number (double) | no | Net financing cash flow. |
| `data.cf.effectOfForexChangesOnCash` | number (double) | no | FX impact on cash. |
| `data.cf.changeInCash` | number (double) | no | Net change in cash. |
| `data.cf.cashAtBeginningOfPeriod` | number (double) | no | Opening cash balance. |
| `data.cf.cashAtEndOfPeriod` | number (double) | no | Closing cash balance. |
| `data.cf.netOperatingCashFlow` | number (double) | no | Net operating cash flow (alias) |
| `data.cf.freeCashFlow` | number (double) | no | Free cash flow (operating - capex) |
| `data.ic` | FinancialPeriodMeta | no | Income statement (trailing twelve months) |
| `data.ic.date` | string (date) | no | Period end date. Example: `2025-09-27`. |
| `data.ic.frequency` | string | no | Reporting frequency. One of `annual`, `quarterly`. |
| `data.ic.reportedCurrency` | string | no | Currency of reported values (ISO 4217) Example: `USD`. |
| `data.ic.cik` | string | no | SEC Central Index Key (10-digit) Example: `320193`. |
| `data.ic.filingDate` | string (date) | no | SEC filing submission date. |
| `data.ic.acceptedDate` | string (date-time) | no | SEC acceptance timestamp. |
| `data.ic.calendarYear` | string | no | Calendar year. Example: `2025`. |
| `data.ic.period` | string | no | Period code: FY, Q1, Q2, Q3, Q4. Example: `FY`. |
| `data.ic.link` | string (uri) | no | SEC EDGAR filing index URL. |
| `data.ic.finalLink` | string (uri) | no | Direct SEC filing document URL. |
| `data.ic.isGapData` | boolean \| null | no | Whether this period was interpolated to fill a gap. |
| `data.ic.revenue` | number (double) | no | Total revenue. |
| `data.ic.costOfGoodsSold` | number (double) | no | Cost of goods sold. |
| `data.ic.grossIncome` | number (double) | no | Gross income (revenue - COGS) |
| `data.ic.grossProfitRatio` | number (double) | no | Gross profit margin (0-1 decimal) |
| `data.ic.researchDevelopment` | number (double) | no | R&D expenses. |
| `data.ic.sgaExpense` | number (double) | no | SG&A expenses. |
| `data.ic.generalAndAdministrativeExpenses` | number (double) | no | G&A expenses. |
| `data.ic.sellingAndMarketingExpenses` | number (double) | no | Sales & marketing expenses. |
| `data.ic.totalOperatingExpense` | number (double) | no | Total operating expenses. |
| `data.ic.costAndExpenses` | number (double) | no | Total costs and expenses. |
| `data.ic.ebit` | number (double) | no | Earnings before interest & taxes. |
| `data.ic.ebitda` | number (double) | no | EBITDA. |
| `data.ic.ebitdaRatio` | number (double) | no | EBITDA / Revenue. |
| `data.ic.operatingIncomeRatio` | number (double) | no | Operating margin. |
| `data.ic.interestIncome` | number (double) | no | Interest income. |
| `data.ic.interestExpense` | number (double) | no | Interest expense. |
| `data.ic.totalOtherIncomeExpensesNet` | number (double) | no | Other income/expenses. |
| `data.ic.pretaxIncome` | number (double) | no | Pre-tax income. |
| `data.ic.incomeBeforeTaxRatio` | number (double) | no | Pre-tax margin. |
| `data.ic.provisionForIncomeTaxes` | number (double) | no | Tax provision. |
| `data.ic.netIncome` | number (double) | no | Net income. |
| `data.ic.netIncomeRatio` | number (double) | no | Net income margin. |
| `data.ic.eps` | number (double) | no | Basic EPS. |
| `data.ic.dilutedEps` | number (double) | no | Diluted EPS. |
| `data.ic.weightedAverageShsOut` | number (double) | no | Weighted average shares outstanding. |
| `data.ic.dilutedAverageSharesOutstanding` | number (double) | no | Diluted average shares outstanding. |
| `data.ic.depreciationAndAmortization` | number (double) | no | D&A expense. |
| `data.ic.otherExpenses` | number (double) | no | Other expenses. |
| `data.currency` | string | no | Reporting currency (ISO 4217) |
| `data.date` | string (date) | no | TTM period end date. |
| `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/financials-ttm?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "bs": {
      "cashAndCashEquivalents": 39280750000,
      "shortTermInvestments": 23846750000,
      "cashShortTermInvestments": 63127500000,
      "inventory": 7358000000,
      "otherCurrentAssets": 15589000000,
      "currentAssets": 149998250000,
      "goodwill": 0,
      "intangibleAssets": 10419000000,
      "goodwillAndIntangibleAssets": 10419000000,
      "longTermInvestments": 79454250000,
      "taxAssets": 5194250000,
      "otherNonCurrentAssets": 77770750000,
      "totalNonCurrentAssets": 223223250000,
      "otherAssets": 0,
      "totalAssets": 373221500000,
      "shortTermDebt": 14886000000,
      "accountsPayable": 65580250000,
      "taxPayables": 0,
      "deferredRevenue": 9334250000,
      "otherCurrentLiabilities": 63190750000,
      "currentLiabilities": 152991250000,
      "longTermDebt": 78090000000,
      "deferredRevenueNonCurrent": 0,
      "deferredTaxLiabilitiesNonCurrent": 0,
      "otherNonCurrentLiabilities": 48156750000,
      "totalNonCurrentLiabilities": 126246750000,
      "otherLiabilities": 0,
      "capitalLeaseObligations": 3430000000,
      "totalLiabilities": 279238000000,
      "preferredStock": 0,
      "commonStock": 97249500000,
      "retainedEarnings": 1811000000,
      "otherTotalStockholdersEquity": 0,
      "totalStockholdersEquity": 93983500000,
      "minorityInterest": 0,
      "totalEquity": 93983500000,
      "otherEquity": -5077000000,
      "totalLiabilitiesAndTotalEquity": 373221500000,
      "liabilitiesShareholdersEquity": 373221500000,
      "totalInvestments": 103301000000,
      "totalDebt": 92976000000,
      "netDebt": 53695250000,
      "propertyPlantEquipment": 50385000000,
      "totalReceivables": 63923750000
    },
    "cf": {
      "inventory": -5284000000,
      "netIncome": 128930000000,
      "freeCashFlow": 136683000000,
      "depreciationAmortization": 13100000000,
      "stockBasedCompensation": 13706000000,
      "accountsReceivables": -12282000000,
      "accountsPayables": 14178000000,
      "otherNonCashItems": -378000000,
      "deferredTaxesInvestmentTaxCredit": 0,
      "changesInWorkingCapital": -8634000000,
      "otherWorkingCapital": -5246000000,
      "netCashProvidedByOperatingActivities": 146724000000,
      "netOperatingCashFlow": 146724000000,
      "acquisitionsNet": 0,
      "investmentsInPropertyPlantAndEquipment": -10041000000,
      "capex": -10041000000,
      "purchasesOfInvestments": -55568000000,
      "salesMaturitiesOfInvestments": 46496000000,
      "otherInvestingActivities": -2285000000,
      "netInvestingCashFlow": -21398000000,
      "debtRepayment": -17274000000,
      "commonStockIssued": 0,
      "issuanceReductionCapitalStock": -82226000000,
      "cashDividendsPaid": -15640000000,
      "otherFinancingActivities": -6911000000,
      "netCashFinancingActivities": -122051000000,
      "effectOfForexChangesOnCash": 0,
      "changeInCash": 3275000000,
      "cashAtBeginningOfPeriod": 40773000000,
      "cashAtEndOfPeriod": 41591750000
    },
    "ic": {
      "revenue": 466823000000,
      "costOfGoodsSold": 239700000000,
      "grossIncome": 227123000000,
      "generalAndAdministrativeExpenses": 2095000000,
      "sellingAndMarketingExpenses": 5397000000,
      "sgaExpense": 29363000000,
      "otherExpenses": 0,
      "costAndExpenses": 311964000000,
      "totalOperatingExpense": 72264000000,
      "researchDevelopment": 42901000000,
      "interestIncome": 0,
      "interestExpense": 0,
      "depreciationAndAmortization": 13100000000,
      "totalOtherIncomeExpensesNet": 1047000000,
      "ebit": 154859000000,
      "ebitda": 168486000000,
      "pretaxIncome": 155906000000,
      "provisionForIncomeTaxes": 26976000000,
      "netIncome": 128930000000,
      "eps": 8.76,
      "dilutedEps": 8.73,
      "weightedAverageShsOut": 14774972750,
      "dilutedAverageSharesOutstanding": 14833367500,
      "grossProfitRatio": 0.4867,
      "operatingIncomeRatio": 0.3298,
      "incomeBeforeTaxRatio": 0.3322,
      "netIncomeRatio": 0.2748,
      "ebitdaRatio": 0.3595
    },
    "currency": "USD",
    "date": "2026-06-27"
  },
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 35
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_financials_ttm

---

# 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.

## 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

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_income_statement

---

# Market Capitalization

> Returns the current market capitalization for an equity.

`GET https://api.bavest.co/v2/equities/market-cap`

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

## Description

Returns the current market capitalization for an equity.

The currency is not fixed per security: since 1 Sep 2026 new values are
in the filer's reporting currency where one is on file, otherwise EUR;
not the listing currency. Read `metricCurrency` rather than assuming
EUR, USD or the listing currency. It is the same series
served as `market_cap` by `/v2/equities/metrics`.

## 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. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | MarketCapSnapshot | no | Current market capitalization. |
| `data.metricCurrency` | string | yes | Currency of the market capitalization value (ISO 4217) Example: `USD`. |
| `data.metricDate` | string | no | Observation date. Example: `2026-03-24T00:00:00`. |
| `data.metricValue` | number (double) | yes | Market capitalization value. Example: `3690170000000`. |
| `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/market-cap?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "metricValue": 4884824000000,
    "metricCurrency": "USD",
    "metricDate": "2026-10-01T00:00:00"
  },
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 16
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_market_cap

---

# Market Capitalization History

> Returns historical market capitalization values for an equity.

`GET https://api.bavest.co/v2/equities/market-cap/history`

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

## Description

Returns historical market capitalization values for an equity.

Each point carries its own `metricCurrency`. The currency can change
within one history (earlier points may be in the listing currency or
EUR, points from 1 Sep 2026 in the filer's reporting currency where one
is on file, otherwise EUR), so do not compare values across points
without reading it.

## 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. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of MarketCapRecord | no |  |
| `data[].metricDate` | string | yes | Observation date. Example: `2026-03-24T00:00:00`. |
| `data[].metricValue` | number (double) | yes | Market capitalization value, in `metricCurrency` Example: `3690170000000`. |
| `data[].metricCurrency` | string \| null | no | Currency of this point's `metricValue` (ISO 4217). A history can change currency from one point to the next, so read it per point. Example: `USD`. |
| `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/market-cap/history?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "metricValue": 4884824000000,
      "metricDate": "2026-10-01T00:00:00"
    },
    {
      "metricValue": 4806746300000,
      "metricDate": "2026-09-30T00:00:00"
    }
  ],
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 20
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_market_cap_history

---

# Peer Companies

> Returns a list of peer company tickers based on sector and market cap similarity.

`GET https://api.bavest.co/v2/equities/peers`

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

## 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. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of string | no |  |
| `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/peers?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    "GOOGL",
    "NVDA"
  ],
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 13
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_peers

---

# Equities Metrics History Export Status

> Poll a submitted export job.

`GET https://api.bavest.co/v2/equities/exports/{exportId}`

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

## Description

Poll a submitted export job. 'ready' returns presigned download links for each Parquet part plus the manifest; 'pending' is still materialising; 'failed' includes an error. Scoped to the caller's API key.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `exportId` | path | string | yes | The exportId returned by the submit call. |

## Response

200 Export status (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.exportId` | string | no |  |
| `data.status` | string | no | One of `ready`, `pending`, `failed`. |
| `data.rows` | integer | no |  |
| `data.requested` | integer | no | Count of explicitly-requested securities (absent for full-universe exports). |
| `data.returned` | integer | no | Requested securities that returned >=1 row. |
| `data.missing` | array of object | no | Requested securities that returned no rows. |
| `data.missing[].id` | string | no |  |
| `data.missing[].reason` | string | no | One of `NO_DATA`, `UNKNOWN_SECURITY`. |
| `data.schema` | array of string | no |  |
| `data.expiresInSeconds` | integer | no | Example: `3600`. |
| `data.manifestUrl` | string | no |  |
| `data.parts` | array of object | no |  |
| `data.parts[].metricName` | string | no |  |
| `data.parts[].url` | string | no |  |
| `data.error` | string | no | Present only when status=failed. |
| `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

`GET https://api.bavest.co/v2/equities/exports/{exportId}` with the parameters above and the `x-api-key` header.

## Errors

Also `400`, `401`, `404`, `429` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_equities_export_status

---

# Analyst Consensus Estimates

> Returns consensus EPS, EBITDA, and EBIT estimates across fiscal periods.

`GET https://api.bavest.co/v2/estimates/consensus`

Group: Estimates. Route id: `v2_estimates_consensus`. Included in: Startup, Pro, Growth.

## Description

Returns consensus EPS, EBITDA, and EBIT estimates across fiscal periods.

Estimates are on the basis the covering analysts forecast, which for most companies is adjusted (non-GAAP): one-off items such as restructuring charges, impairments or tax effects are left out. EPS and net income therefore differ from the reported figures in `/v2/equities/income-statement` and from reported-basis series of other vendors. Tesla FY2025: consensus EPS 1.66 USD, reported 1.18 USD. SAP FY2024: consensus 4.44 EUR, reported 2.68 EUR.

## 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. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of EstimatePeriod | no |  |
| `data[].date` | string (date) | no | Fiscal period end date. Same value as `fiscalYearEnd`; kept for existing clients. Do not read the year of this date as the fiscal year, use `fiscalYear`. Example: `2026-09-27`. |
| `data[].fiscalYearEnd` | string (date) | no | Last day of the fiscal year the estimates cover. Example: `2027-01-25`. |
| `data[].fiscalYear` | integer | no | Fiscal year label as FactSet prints it. A fiscal year ending in January, or in the first seven days of February (52/53-week years), carries the year it started in: NVIDIA's year ending 2027-01-25 is 2026. Every other fiscal year carries the year it ends in (Toyota's year ending 2026-03-31 is 2026). Example: `2026`. |
| `data[].currency` | string \| null | no | ISO 4217 currency of all monetary values and EPS in this row: the company's reporting currency, also on foreign listings (Toyota in JPY on Xetra and NYSE, ASML in EUR on NASDAQ). Null when no annual report is on file. Example: `USD`. |
| `data[].symbol` | string | no | Ticker symbol of the company. Example: `AAPL`. |
| `data[].estimatedEbitAvg` | number (double) \| null | no | Consensus average EBIT estimate. Example: `194822900000`. |
| `data[].estimatedEbitHigh` | number (double) \| null | no | Highest EBIT estimate among analysts. Example: `205228900000`. |
| `data[].estimatedEbitLow` | number (double) \| null | no | Lowest EBIT estimate among analysts. Example: `187009450000`. |
| `data[].estimatedEbitdaAvg` | number (double) \| null | no | Consensus average EBITDA estimate. Example: `209951540000`. |
| `data[].estimatedEbitdaHigh` | number (double) \| null | no | Highest EBITDA estimate among analysts. Example: `221165600000`. |
| `data[].estimatedEbitdaLow` | number (double) \| null | no | Lowest EBITDA estimate among analysts. Example: `201531340000`. |
| `data[].estimatedEpsAvg` | number (double) \| null | no | Consensus average EPS estimate. Example: `13.33`. |
| `data[].estimatedEpsHigh` | number (double) \| null | no | Highest EPS estimate among analysts. Example: `14.2556`. |
| `data[].estimatedEpsLow` | number (double) \| null | no | Lowest EPS estimate among analysts. Example: `12.635`. |
| `data[].estimatedNetIncomeAvg` | number (double) \| null | no | Consensus average net income estimate. Example: `200012610000`. |
| `data[].estimatedNetIncomeHigh` | number (double) \| null | no | Highest net income estimate among analysts. Example: `213900800000`. |
| `data[].estimatedNetIncomeLow` | number (double) \| null | no | Lowest net income estimate among analysts. Example: `189584490000`. |
| `data[].estimatedRevenueAvg` | number (double) \| null | no | Consensus average revenue estimate. Example: `581688000000`. |
| `data[].estimatedRevenueHigh` | number (double) \| null | no | Highest revenue estimate among analysts. Example: `612757500000`. |
| `data[].estimatedRevenueLow` | number (double) \| null | no | Lowest revenue estimate among analysts. Example: `558359200000`. |
| `data[].estimatedSgaExpenseAvg` | number (double) \| null | no | Consensus average SGA expense estimate. Example: `37438870000`. |
| `data[].estimatedSgaExpenseHigh` | number (double) \| null | no | Highest SGA expense estimate among analysts. Example: `39438578000`. |
| `data[].estimatedSgaExpenseLow` | number (double) \| null | no | Lowest SGA expense estimate among analysts. Example: `35937370000`. |
| `data[].numberAnalystsEstimatedEps` | integer \| null | no | Number of analysts providing EPS estimates. Example: `14`. |
| `data[].numberAnalystsEstimatedRevenue` | integer \| null | no | Number of analysts providing revenue estimates. |
| `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/estimates/consensus?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "date": "2030-09-27",
      "symbol": "AAPL",
      "estimatedRevenueLow": 619792040000,
      "estimatedRevenueHigh": 698463300000,
      "estimatedRevenueAvg": 647707000000,
      "estimatedEbitdaLow": 235875650000,
      "estimatedEbitdaHigh": 272618100000,
      "estimatedEbitdaAvg": 248913020000,
      "estimatedEbitLow": 220967960000,
      "estimatedEbitHigh": 257710390000,
      "estimatedEbitAvg": 234005330000,
      "estimatedNetIncomeLow": 182786620000,
      "estimatedNetIncomeHigh": 213361690000,
      "estimatedNetIncomeAvg": 193635610000,
      "estimatedSgaExpenseLow": 39891337000,
      "estimatedSgaExpenseHigh": 44954812000,
      "estimatedSgaExpenseAvg": 41688015000,
      "estimatedEpsLow": 12.182,
      "estimatedEpsHigh": 14.2197,
      "estimatedEpsAvg": 12.905,
      "numberAnalystsEstimatedRevenue": null,
      "numberAnalystsEstimatedEps": 15,
      "currency": "USD",
      "fiscalYearEnd": "2030-09-27",
      "fiscalYear": 2030
    },
    {
      "date": "2029-09-27",
      "symbol": "AAPL",
      "estimatedRevenueLow": 591422900000,
      "estimatedRevenueHigh": 666493200000,
      "estimatedRevenueAvg": 618060100000,
      "estimatedEbitdaLow": 223721370000,
      "estimatedEbitdaHigh": 258569800000,
      "estimatedEbitdaAvg": 236086720000,
      "estimatedEbitLow": 209645360000,
      "estimatedEbitHigh": 244493800000,
      "estimatedEbitAvg": 222010700000,
      "estimatedNetIncomeLow": 173364580000,
      "estimatedNetIncomeHigh": 202363550000,
      "estimatedNetIncomeAvg": 183654330000,
      "estimatedSgaExpenseLow": 38065430000,
      "estimatedSgaExpenseHigh": 42897140000,
      "estimatedSgaExpenseAvg": 39779873000,
      "estimatedEpsLow": 11.554,
      "estimatedEpsHigh": 13.4867,
      "estimatedEpsAvg": 12.2398,
      "numberAnalystsEstimatedRevenue": null,
      "numberAnalystsEstimatedEps": 11,
      "currency": "USD",
      "fiscalYearEnd": "2029-09-27",
      "fiscalYear": 2029
    }
  ],
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 20
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_estimates_consensus

---

# Analyst Recommendations

> Returns how many analysts currently hold each rating on the security, with the consensus label derived from that distribution.

`GET https://api.bavest.co/v2/estimates/recommendations`

Group: Estimates. Route id: `v2_estimates_recommendations`. Included in: Startup, Pro, Growth.

## 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. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | RecommendationRecord | no | How many analysts currently hold each rating on the security, with the consensus label derived from that distribution. These are covering analysts, not rating changes found in the news: BMW (DE0005190003) reports 23 here. |
| `data.symbol` | string | no | Ticker symbol. Example: `AAPL`. |
| `data.consensus` | string | no | Consensus recommendation label. Example: `Buy`. |
| `data.date` | string (date) | no | Date of the recommendation snapshot. |
| `data.buy` | integer | yes | Number of buy recommendations. |
| `data.strongBuy` | integer | no | Number of strong buy recommendations. |
| `data.hold` | integer | yes | Number of hold recommendations. |
| `data.sell` | integer | yes | Number of sell recommendations. |
| `data.strongSell` | integer | no | Number of strong sell recommendations. |
| `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/estimates/recommendations?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "symbol": "AAPL",
    "strongBuy": 6,
    "buy": 19,
    "hold": 14,
    "sell": 3,
    "strongSell": 3,
    "consensus": "Hold"
  },
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 11
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_estimates_recommendations

---

# Price Target Consensus

> Returns analyst price target consensus including high, low, median and consensus values, and the currency they are quoted in.

`GET https://api.bavest.co/v2/estimates/price-target`

Group: Estimates. Route id: `v2_estimates_price_target`. Included in: Startup, Pro, Growth.

## 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. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | PriceTargetConsensus | no | Analyst price target consensus for a security. |
| `data.symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `data.date` | string (date) \| null | no | Date of the price-target consensus snapshot. Example: `2025-09-27`. |
| `data.targetHigh` | number (double) \| null | no | Highest analyst price target. Example: `325`. |
| `data.targetLow` | number (double) \| null | no | Lowest analyst price target. Example: `183.86`. |
| `data.targetConsensus` | number (double) \| null | no | Mean analyst price target. Example: `256.14`. |
| `data.targetMedian` | number (double) \| null | no | Median analyst price target. Example: `260`. |
| `data.currency` | string \| null | no | ISO 4217 currency the four target values are quoted in — the currency the listing itself trades in. Targets are served for US venues only, so this is USD today. Example: `USD`. |
| `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/estimates/price-target?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "date": "2026-09-27",
    "symbol": "AAPL",
    "targetHigh": 400,
    "targetLow": 245,
    "targetConsensus": 342.13,
    "targetMedian": 362,
    "currency": "USD"
  },
  "meta": {
    "parameters": {
      "symbol": "AAPL"
    },
    "time": 11
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_estimates_price_target

---

# Upgrades & Downgrades

> Returns analyst rating changes (upgrades, downgrades, initiations).

`GET https://api.bavest.co/v2/estimates/upgrades-downgrades`

Group: Estimates. Route id: `v2_estimates_upgrades_downgrades`. Included in: Startup, Pro, Growth.

## Description

Returns analyst rating changes (upgrades, downgrades, initiations).
Each item is a weekly snapshot that lists every rating action known on
its `date`, so the newest snapshot holds the full history. By default
only the newest snapshot is returned; page back with `offset` or
`cursor`, at most 10 snapshots per request.

## 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. |
| `limit` | query | integer (int32) | no | Number of snapshots to return, newest first (default 1, max 10) Default `1`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of UpgradeDowngradeRecord | no |  |
| `data[].date` | string (date) | yes | Date of the rating change. |
| `data[].symbol` | string | yes | Ticker symbol of the company. Example: `AAPL`. |
| `data[].ratings` | array of object | no | Detailed list of individual rating entries. |
| `data[].ratings[].url` | string \| null | no | URL to the full rating article or report. Null since the switch to the vendor's grade endpoint, which serves no article. Example: `https://www.streetinsider.com/Analyst+Comments/KeyBanc+Sidelined+on+Apple+%28AAPL%29%3A+%27don%27t+see+a+catalyst+with+the+stock+trading+in+line+with+its+historical+valuation%27/26148368.html`. Deprecated. |
| `data[].ratings[].title` | string \| null | no | Headline of the rating report. Null since the switch to the vendor's grade endpoint, which serves no article. Example: `KeyBanc Sidelined on Apple (AAPL): 'don't see a catalyst with the stock trading in line with its historical valuation'`. Deprecated. |
| `data[].ratings[].action` | string | no | Rating action described in this entry. Example: `hold`. |
| `data[].ratings[].newGrade` | string | no | New rating grade assigned. Example: `Sector Weight`. |
| `data[].ratings[].previousGrade` | string \| null | no | Previous rating grade before the change. Example: `Sector Weight`. |
| `data[].ratings[].publishedDate` | string | no | ISO 8601 timestamp when the rating was published. Example: `2026-03-12T09:50:00.000Z`. |
| `data[].ratings[].gradingCompany` | string | no | Name of the firm that issued the rating. Example: `KeyBanc`. |
| `data[].ratings[].priceWhenPosted` | number \| null | no | Stock price when the rating was published. Null since the switch to the vendor's grade endpoint, which serves no price. Example: `260.81`. Deprecated. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/estimates/upgrades-downgrades?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "date": "2026-09-27",
      "symbol": "AAPL",
      "ratings": [
        {
          "url": null,
          "title": null,
          "action": "maintain",
          "newGrade": "Buy",
          "previousGrade": "Buy",
          "publishedDate": "2026-09-23",
          "gradingCompany": "B of A Securities",
          "priceWhenPosted": null
        },
        {
          "url": null,
          "title": null,
          "action": "maintain",
          "newGrade": "Outperform",
          "previousGrade": "Outperform",
          "publishedDate": "2026-09-18",
          "gradingCompany": "Evercore ISI Group",
          "priceWhenPosted": null
        }
      ]
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 1,
    "totalPages": 29,
    "totalCount": 29,
    "parameters": {
      "limit": "1",
      "symbol": "AAPL"
    },
    "time": 23
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_estimates_upgrades_downgrades

---

# AI Estimates

> Bavest's own AI estimates for a security across task types (regression, classification, sequence, hazard).

`POST https://api.bavest.co/v2/estimates/ai-estimates`

Group: Estimates. Route id: `v2_estimates_ai_estimates`. Included in: Startup, Pro, Growth.

## Description

Bavest's own AI estimates for a security across task types (regression,
classification, sequence, hazard). Filter with `metrics` and `task_types`.
Omit both to return everything.

One prediction per metric, task type, target and frequency: the newest.
A target whose period ended more than 120 days ago without an actual is
left out, its figure is reported by then; earlier forecasts are on
`/v2/estimates/ai-estimates-history`. Annual targets are calendar years
(January to December) for every company, also where the fiscal year ends
in another month: MSFT 2026 covers January to December 2026, not the
fiscal year ending June 2026.

## Parameters

None.

## Request body

JSON, required.

| Field | Type | Always present | Description |
|---|---|---|---|
| `symbol` | string | yes | Ticker symbol, ISIN, or CUSIP. Resolved server-side. Example: `AAPL`. |
| `metrics` | array of string | no | Restrict to these metrics. Omit for all. Also accepts a comma-separated string. |
| `task_types` | array of string | no | Restrict to these task types. Omit for all. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | PredictionsResponse | no | Model predictions for a security. |
| `data.meta` | ForecastMeta | no | Freshness summary for the returned forecast set. |
| `data.meta.as_of` | string (date) | no | Most recent prediction_date across the returned rows. Example: `2026-05-20`. |
| `data.meta.model_version` | string | no | Model version of the newest returned row. Example: `fmf-eps-v1.4`. |
| `data.predictions` | array of PredictionRecord | no |  |
| `data.predictions[].symbol` | string | no | Ticker symbol (rows are self-describing). Example: `AAPL`. |
| `data.predictions[].metric` | string | no | Forecast metric, e.g. eps, revenue, ebitda, dividend. Example: `eps`. |
| `data.predictions[].task_type` | string | no | Prediction task type. One of `regression`, `classification`, `sequence`, `hazard`. Example: `regression`. |
| `data.predictions[].target_date` | string (date) | no | Period the forecast is for. Example: `2026-09-30`. |
| `data.predictions[].prediction_date` | string (date) | no | Point-in-time the forecast was generated. Example: `2026-05-20`. |
| `data.predictions[].model_version` | string | no | Example: `fmf-eps-v1.4`. |
| `data.predictions[].frequency` | string | no | Reporting frequency of the target. Example: `quarterly`. |
| `data.predictions[].prediction` | RegressionPrediction \| ClassificationPrediction \| HazardPrediction | no | Payload shape varies by task_type. Uses anyOf, not oneOf: the three variants overlap (all carry point/lower/upper) and nothing in the payload discriminates them, so oneOf rejected every real response. |
| `data.predictions[].prediction.point` | number (double) | no | Example: `2.41`. |
| `data.predictions[].prediction.lower` | number (double) | no | Example: `2.18`. |
| `data.predictions[].prediction.upper` | number (double) | no | Example: `2.65`. |
| `data.predictions[].prediction.components` | object | no | Forecast decomposition (e.g. trend/seasonal). |
| `data.predictions[].prediction.direction` | string \| null | no | Direction of the forecast against the trailing value. Null without a trailing value. One of `up`, `down`. Example: `up`. |
| `data.predictions[].prediction.direction_score` | number (double) \| null | no | Forecast minus trailing value, in the metric's own unit (not normalized). Example: `0.12`. |
| `data.predictions[].prediction.nowcast` | object \| null | no | Intra-year breakdown for annual targets once quarters of the year are reported. Null otherwise. |
| `data.predictions[].explainability` | ForecastExplainability \| null | no | Top contributing features for the prediction (SHAP), when available. |
| `data.predictions[].explainability.top_features` | array of object | no |  |
| `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 -X POST 'https://api.bavest.co/v2/estimates/ai-estimates' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"symbol":"AAPL","metrics":["eps","revenue"],"task_types":["regression"]}'
```

## Example response

```json
{
  "data": {
    "meta": {
      "as_of": "2026-05-20",
      "model_version": "ai-eps-v1.4"
    },
    "predictions": [
      {
        "symbol": "AAPL",
        "metric": "eps",
        "task_type": "regression",
        "target_date": "2026-09-30",
        "prediction_date": "2026-05-20",
        "model_version": "ai-eps-v1.4",
        "frequency": "quarterly",
        "prediction": {
          "point": 2.41,
          "lower": 2.18,
          "upper": 2.65,
          "components": {
            "trend": 2.3,
            "seasonal": 0.11
          }
        },
        "explainability": {
          "top_features": [
            {
              "name": "revenue_ttm",
              "shap": 0.42
            },
            {
              "name": "gross_margin",
              "shap": 0.19
            }
          ]
        }
      }
    ]
  },
  "meta": {
    "parameters": {
      "symbol": "AAPL",
      "metrics": [
        "eps"
      ],
      "task_types": [
        "regression"
      ]
    },
    "time": 12
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_estimates_ai_estimates

---

# AI Estimates History

> Returns how an AI estimate for one metric evolved over time.

`GET https://api.bavest.co/v2/estimates/ai-estimates-history`

Group: Estimates. Route id: `v2_estimates_ai_estimates_history`. Included in: Startup, Pro, Growth.

## Description

Returns how an AI estimate for one metric evolved over time. Each
`prediction_date` snapshot is a revision. Revisions are attributed to
realized quarters, curated overrides, and the residual model re-estimate.

## 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. |
| `metric` | query | string | yes | Single metric to trace, e.g. revenue, eps, ebitda. Example `revenue`. |
| `fiscal_year` | query | integer | no | Pin to one target fiscal year (target_date = Dec-31 of that year). Omit for all. Example when explicitly filtering: `2026`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | PredictionHistoryResponse | no | How a security's forecast for one metric evolved over time. |
| `data.metric` | string | no | Example: `revenue`. |
| `data.targets` | array of PredictionHistoryTarget | no |  |
| `data.targets[].target_date` | string (date) | no | Example: `2026-12-31`. |
| `data.targets[].fiscal_year` | integer | no | Calendar year of the target (January to December), for every company. Kept under this name for existing clients; read `calendar_year`. Example: `2026`. |
| `data.targets[].calendar_year` | integer | no | Calendar year of the target (January to December). Example: `2026`. |
| `data.targets[].realized` | boolean | no | Whether the calendar year has closed. Example: `false`. |
| `data.targets[].actual` | number (double) \| null | no | Realized actual once the year closes. |
| `data.targets[].current` | PredictionSnapshotDetail | no | A forecast snapshot with its nowcast decomposition. |
| `data.targets[].current.prediction_date` | string (date) | no | Example: `2026-08-01`. |
| `data.targets[].current.model_version` | string \| null | no | Example: `fmf-revenue-ensemble-v2`. |
| `data.targets[].current.point` | number (double) | no | Example: `105`. |
| `data.targets[].current.lower` | number (double) | no | Example: `95`. |
| `data.targets[].current.upper` | number (double) | no | Example: `115`. |
| `data.targets[].current.realized` | boolean \| null | no | Example: `false`. |
| `data.targets[].current.realized_sum` | number (double) \| null | no | Sum of realized (reported) quarters to date. Example: `45`. |
| `data.targets[].current.model_annual` | number (double) \| null | no | Model estimate of the full-year figure. Example: `100`. |
| `data.targets[].current.override_delta` | number (double) \| null | no | Net curated override applied. Example: `10`. |
| `data.targets[].current.overrides` | array of PredictionOverride \| null | no |  |
| `data.targets[].previous` | PredictionSnapshotDetail \| any \| null | no | Previous snapshot; null until at least one revision exists. |
| `data.targets[].previous.prediction_date` | string (date) | no | Example: `2026-08-01`. |
| `data.targets[].previous.model_version` | string \| null | no | Example: `fmf-revenue-ensemble-v2`. |
| `data.targets[].previous.point` | number (double) | no | Example: `105`. |
| `data.targets[].previous.lower` | number (double) | no | Example: `95`. |
| `data.targets[].previous.upper` | number (double) | no | Example: `115`. |
| `data.targets[].previous.realized` | boolean \| null | no | Example: `false`. |
| `data.targets[].previous.realized_sum` | number (double) \| null | no | Sum of realized (reported) quarters to date. Example: `45`. |
| `data.targets[].previous.model_annual` | number (double) \| null | no | Model estimate of the full-year figure. Example: `100`. |
| `data.targets[].previous.override_delta` | number (double) \| null | no | Net curated override applied. Example: `10`. |
| `data.targets[].previous.overrides` | array of PredictionOverride \| null | no |  |
| `data.targets[].revisions` | array of PredictionRevision | no |  |
| `data.targets[].revisions[].from_date` | string (date) | no | Example: `2026-05-01`. |
| `data.targets[].revisions[].to_date` | string (date) | no | Example: `2026-08-01`. |
| `data.targets[].revisions[].from_point` | number (double) | no | Example: `95`. |
| `data.targets[].revisions[].to_point` | number (double) | no | Example: `105`. |
| `data.targets[].revisions[].delta` | number (double) | no | Example: `10`. |
| `data.targets[].revisions[].drivers` | object | no | Attribution of the delta — realized quarters, curated overrides, and the residual model re-estimate (reconciles to delta). |
| `data.targets[].snapshots` | array of PredictionSnapshot | no | Full snapshot series, oldest first. |
| `data.targets[].snapshots[].prediction_date` | string (date) | no | Example: `2026-02-01`. |
| `data.targets[].snapshots[].model_version` | string \| null | no | Example: `fmf-revenue-ensemble-v2`. |
| `data.targets[].snapshots[].point` | number (double) | no | Example: `100`. |
| `data.targets[].snapshots[].lower` | number (double) \| null | no | Example: `90`. |
| `data.targets[].snapshots[].upper` | number (double) \| null | no | Example: `110`. |
| `data.targets[].snapshots[].realized` | boolean \| null | no | Example: `false`. |
| `data.targets[].snapshots[].realized_sum` | number (double) \| null | no | Sum of realized (reported) quarters to date. |
| `data.targets[].snapshots[].model_annual` | number (double) \| null | no | Model estimate of the full-year figure. |
| `data.targets[].snapshots[].override_delta` | number (double) \| null | no | Net curated override applied. |
| `data.targets[].snapshots[].overrides` | array of PredictionOverride \| null | no |  |
| `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/estimates/ai-estimates-history?symbol=AAPL&metric=revenue' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "metric": "revenue",
    "targets": [
      {
        "target_date": "2026-12-31",
        "fiscal_year": 2026,
        "calendar_year": 2026,
        "realized": false,
        "current": {
          "prediction_date": "2026-10-02",
          "model_version": "revenue_lgb_purged_20261001",
          "point": 507772463812.5977,
          "lower": 466333211250.3338,
          "upper": 549211716374.8616,
          "realized": false,
          "realized_sum": 220601000000,
          "model_annual": 520839081098.4933,
          "override_delta": 0,
          "overrides": []
        },
        "previous": {
          "prediction_date": "2026-10-01",
          "model_version": "revenue_lgb_purged_20261001",
          "point": 507772463812.5977,
          "lower": 466333211250.3338,
          "upper": 549211716374.8616,
          "realized": false,
          "realized_sum": 220601000000,
          "model_annual": 520839081098.4933,
          "override_delta": 0,
          "overrides": []
        },
        "actual": null,
        "revisions": [
          {
            "from_date": "2026-05-22",
            "to_date": "2026-09-29",
            "from_point": 273563944311.7156,
            "to_point": 474072675596.5948,
            "delta": 200508731284.8792,
            "drivers": {
              "model": 200508731284.8792
            }
          },
          {
            "from_date": "2026-09-29",
            "to_date": "2026-09-30",
            "from_point": 474072675596.5948,
            "to_point": 499387888309.2173,
            "delta": 25315212712.6225,
            "drivers": {
              "realized": 220601000000,
              "override": 0,
              "model": -195285787287.3775
            }
          }
        ],
        "snapshots": [
          {
            "prediction_date": "2026-05-22",
            "model_version": "fmf-revenue-ensemble-v2",
            "point": 273563944311.7156,
            "lower": 173461359907.0481,
            "upper": 373666528716.3831,
            "realized": null,
            "realized_sum": null,
            "model_annual": null,
            "override_delta": null,
            "overrides": null
          },
          {
            "prediction_date": "2026-09-29",
            "model_version": "revenue_lgb_auto_20260526",
            "point": 474072675596.5948,
            "lower": 405663311114.142,
            "upper": 542482040079.0475,
            "realized": false,
            "realized_sum": 0,
            "model_annual": 474072675596.5948,
            "override_delta": 0,
            "overrides": []
          }
        ]
      },
      {
        "target_date": "2025-12-31",
        "fiscal_year": 2025,
        "calendar_year": 2025,
        "realized": false,
        "current": {
          "prediction_date": "2026-06-10",
          "model_version": "revenue_lgb_auto_20260526",
          "point": 438596944379.3873,
          "lower": 417422737937.1071,
          "upper": 459771150821.6675,
          "realized": false,
          "realized_sum": 291861000000,
          "model_annual": 466321780248.617,
          "override_delta": 0,
          "overrides": []
        },
        "previous": {
          "prediction_date": "2026-06-09",
          "model_version": "revenue_lgb_growth_20260527",
          "point": 407304071346.03,
          "lower": 390645471196.2831,
          "upper": 423962671495.777,
          "realized": false,
          "realized_sum": 291861000000,
          "model_annual": 366874106921.3515,
          "override_delta": 0,
          "overrides": []
        },
        "actual": null,
        "revisions": [
          {
            "from_date": "2026-06-04",
            "to_date": "2026-06-05",
            "from_point": 407270732407.1996,
            "to_point": 407270732407.1996,
            "delta": 0,
            "drivers": {
              "realized": 0,
              "override": 0,
              "model": 0
            }
          },
          {
            "from_date": "2026-06-05",
            "to_date": "2026-06-06",
            "from_point": 407270732407.1996,
            "to_point": 407270732407.1996,
            "delta": 0,
            "drivers": {
              "realized": 0,
              "override": 0,
              "model": 0
            }
          }
        ],
        "snapshots": [
          {
            "prediction_date": "2026-06-04",
            "model_version": "revenue_lgb_growth_20260527",
            "point": 407270732407.1996,
            "lower": 390616943113.9633,
            "upper": 423924521700.436,
            "realized": false,
            "realized_sum": 291861000000,
            "model_annual": 366768156921.3515,
            "override_delta": 0,
            "overrides": []
          },
          {
            "prediction_date": "2026-06-05",
            "model_version": "revenue_lgb_growth_20260527",
            "point": 407270732407.1996,
            "lower": 390616943113.9633,
            "upper": 423924521700.436,
            "realized": false,
            "realized_sum": 291861000000,
            "model_annual": 366768156921.3515,
            "override_delta": 0,
            "overrides": []
          }
        ]
      }
    ]
  },
  "meta": {
    "parameters": {
      "metric": "revenue",
      "symbol": "AAPL"
    },
    "time": 2524
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_estimates_ai_estimates_history

---

# ETF Category

> Returns ETF classification and categorization including asset class, focus, and niche.

`GET https://api.bavest.co/v2/etfs/category`

Group: ETFs. Route id: `v2_etfs_category`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | ETFCategory | no | ETF classification and categorization. |
| `data.assetClass` | string | yes | Broad asset class (e.g. Equity, Fixed Income, Commodity) Example: `Equity`. |
| `data.category` | string | no | Investment category within the asset class (e.g. U.S. Equity) Example: `U.S. Equity`. |
| `data.focus` | string | no | Investment focus or strategy (e.g. Broad Market, Growth, Value) Example: `Broad Market`. |
| `data.niche` | string | no | Specific niche or investment approach (e.g. Index Tracking) Example: `Index Tracking`. |
| `data.index` | string \| null | no | Name of the tracked index as published by the issuer. Same value as `indice` on `/v2/etfs/profile`: free text, not normalised, either the index family (`MSCI World`) or the full variant (`STOXX Europe 600 NR EUR`). Intended for display; do not join or filter on it. Example: `MSCI World`. |
| `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/etfs/category?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "assetClass": "Equity",
    "category": "Global Equity",
    "focus": "Broad Market",
    "niche": "MSCI World Index Exposure",
    "index": "MSCI World"
  },
  "meta": {
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 25
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_category

---

# ETF Country Exposure

> Returns geographic allocation percentages.

`GET https://api.bavest.co/v2/etfs/countries`

Group: ETFs. Route id: `v2_etfs_countries`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |
| `view` | query | string | no | Allocation view. `display` (default) hides rows with negative exposure and scales the remainder to 100. `raw` returns the stored rates, where swap/bond legs and short positions are legitimately negative. Unrecognized values fall back to `display`. One of `display`, `raw`. Default `display`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.atDate` | string (date) | no | Observation date for the exposure data. |
| `data.countryExposure` | array of ETFCountryExposure | no |  |
| `data.countryExposure[].country` | string | yes | Country name. Example: `United States`. |
| `data.countryExposure[].exposure` | number (double) | yes | Exposure percentage. Example: `97.57`. |
| `data.countryExposure[].synthetic` | boolean | no | `true` when the row is Bavest-generated rather than scraped from an issuer breakdown. Applies to products with no published geographic allocation to scrape — chiefly crypto and commodity funds. Example: `false`. |
| `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/etfs/countries?isin=IE00B4L5Y983&view=display' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "atDate": "2026-10-02",
    "countryExposure": [
      {
        "country": "United States",
        "exposure": 72.68,
        "synthetic": false
      },
      {
        "country": "Japan",
        "exposure": 5.91,
        "synthetic": false
      }
    ]
  },
  "meta": {
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 192
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_countries

---

# ETF Documents Catalog

> Returns a paginated catalog of all available ETF documents (KID/KIID) for a given language.

`GET https://api.bavest.co/v2/etfs/documents/catalog`

Group: ETFs. Route id: `v2_etfs_documents_catalog`. Included in: Pro, Growth.

## Description

Returns a paginated catalog of all available ETF documents (KID/KIID) for a given language. Use the download_path to fetch each document via /v2/etfs/kid.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `language` | query | string | yes | ISO 639-1 language code (e.g. en, de, fr) Example `en`. |
| `isin` | query | string | no (at most one of isin, symbol) | Only this fund's documents (e.g., `IE00B4L5Y983`). Omit for the whole catalog. Provide at most one of isin or symbol. |
| `symbol` | query | string | no (at most one of isin, symbol) | Only the documents of this listing's fund, resolved to its ISIN (e.g., `IWDA.AS`). An unknown symbol is 404. Omit for the whole catalog. |
| `type` | query | string | no | Filter by document type. Omit to return both KID and KIID. One of `KID`, `KIID`. |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

Optional, at most one of `isin`, `symbol`.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of ETFDocumentCatalogItem | no |  |
| `data[].isin` | string \| null | yes | ETF ISIN code. Example: `IE00B4L5Y983`. |
| `data[].language` | string | yes | ISO 639-1 language code. Example: `en`. |
| `data[].type` | string | yes | Document type. One of `KID`, `KIID`. |
| `data[].download_path` | string | yes | API path to download the document via /v2/etfs/kid. Example: `/v2/etfs/kid?isin=IE00B4L5Y983&language=en`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/etfs/documents/catalog?language=en' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "isin": "ABA1285663C9",
      "language": "en",
      "type": "KID",
      "download_path": "/v2/etfs/kid?isin=ABA1285663C9&language=en&type=KID"
    },
    {
      "isin": "ADEB985A5832",
      "language": "en",
      "type": "KID",
      "download_path": "/v2/etfs/kid?isin=ADEB985A5832&language=en&type=KID"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 137,
    "totalCount": 13664,
    "parameters": {
      "language": "en",
      "limit": "100"
    },
    "time": 154
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_documents_catalog

---

# ETF Fees

> Returns ETF fee and expense information including management fee and expense ratios.

`GET https://api.bavest.co/v2/etfs/fees`

Group: ETFs. Route id: `v2_etfs_fees`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | ETFFees | no | ETF fee and expense information. |
| `data.managementFee` | number (double) \| null | no | Annual management fee as a decimal (e.g. 0.0045 = 0.45%) |
| `data.performanceFee` | number (double) \| null | no | Performance-based fee as a decimal, if applicable. |
| `data.netExpenseRatio` | number (double) | no | Net expense ratio after fee waivers, as a decimal (e.g. 0.002 = 0.2%) Example: `0.2`. |
| `data.totalExpenseRatio` | number (double) | no | Total (gross) expense ratio as a decimal. |
| `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/etfs/fees?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "managementFee": 0.2,
    "performanceFee": null,
    "netExpenseRatio": 0.2,
    "totalExpenseRatio": 0.2
  },
  "meta": {
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 33
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_fees

---

# ETF Holdings

> Returns all holdings with weights, values, and share counts.

`GET https://api.bavest.co/v2/etfs/holdings`

Group: ETFs. Route id: `v2_etfs_holdings`. Included in: Pro, Growth.

## Description

Returns all holdings with weights, values, and share counts. Swaps, futures, Treasury bills, money market funds and cash are rows of their own (`holdingType`); `view` picks market-value weights (`display`, default) or the issuer's exposure weights (`raw`).

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |
| `view` | query | string | no | Holdings view. `display` (default) weighs every row by market value, so a fund sums to ~100, with cash, Treasury bills and money market funds as their own rows; swaps and futures (no market value) and negative cash rows are left out. `raw` lists every row and keeps the issuer's exposure weights, so derivatives count at notional (a 3x fund ~300) and swaps list their counterparty. Plain ETFs are the same in both views. Unrecognized values fall back to `display`. One of `display`, `raw`. Default `display`. |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of HoldingRecord | no | Holdings for the requested page. |
| `data[].name` | string \| null | yes | Holding name. Null when the constituent has no resolved master-record name yet; the key is always present. Example: `Apple Inc.`. |
| `data[].symbol` | string \| null | no | Ticker symbol. Example: `AAPL`. |
| `data[].isin` | string \| null | no | ISIN identifier. |
| `data[].percent` | number (double) \| null | yes | Weight (%) of net assets. With `view=display` (default) the market-value weight, so a fund's rows sum to ~100; swaps and futures without a market value and negative cash rows are left out (they are in `raw`). With `view=raw` a derivative's exposure weight (a 3x fund sums to ~300, an inverse fund's swaps are negative). Plain ETFs carry the same rows and weights in both views. Null only when the issuer publishes neither weight. Example: `7.79`. |
| `data[].value` | number (double) \| null | no | Issuer-reported position value in the source currency, which is not normalized here. Null when not reported. Use calculatedValue for an explicitly labelled USD estimate. |
| `data[].share` | number (double) \| null | no | Shares held. |
| `data[].cusip` | string \| null | no | CUSIP identifier. |
| `data[].calculatedValue` | object \| null | no | Bavest-calculated USD estimate, separate from issuer-reported value. Only available for a currently matching equity position with no reported value. |
| `data[].calculatedValue.value` | number (double) | yes | Estimated position value in USD. |
| `data[].calculatedValue.currency` | string | yes | One of `USD`. |
| `data[].calculatedValue.method` | string | yes | Example: `equity_quantity_times_historical_close_v1`. |
| `data[].calculatedValue.priceDate` | string (date) | yes |  |
| `data[].calculatedValue.fxDate` | string (date) | yes |  |
| `data[].calculatedValue.calculatedAt` | string (date-time) | yes |  |
| `data[].holdingType` | string \| null | no | Position type. `equity` for a listed security; swaps, futures, Treasury bills, money market funds and cash / net other assets are kept as their own rows (no ISIN); `other` for an unlisted instrument such as a bond. Null on issuer top-10 lists that publish names only. One of `equity`, `swap`, `future`, `cash`, `money_market`, `treasury_bill`, `other`, `null`. Example: `equity`. |
| `data[].marketValue` | number (double) \| null | no | Issuer-reported market value in the source currency; the basis of `percent` in `view=display`. Null when the issuer publishes none (swaps, futures). |
| `data[].exposureValue` | number (double) \| null | no | Issuer-reported exposure (notional plus gain/loss) of a swap or future, in the source currency; the basis of `percent` in `view=raw`. Null for positions without one. Example: `9920928648.41`. |
| `data[].counterparty` | string \| null | no | Swap counterparty as the issuer names it. Null for every other position. Example: `BNP Paribas`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/etfs/holdings?isin=IE00B4L5Y983&view=display' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "name": "NVIDIA CORP",
      "percent": 5.7488,
      "value": 8712724624.12,
      "isin": "US67066G1040",
      "symbol": "NVDA",
      "cusip": null,
      "share": 38346572
    },
    {
      "name": "APPLE INC",
      "percent": 5.3245,
      "value": 8069636917.8,
      "isin": "US0378331005",
      "symbol": "AAPL",
      "cusip": null,
      "share": 24497987
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 13,
    "totalCount": 1265,
    "parameters": {
      "isin": "IE00B4L5Y983",
      "limit": "100"
    },
    "time": 48
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_holdings

---

# ETF Holdings Top

> Returns top 10 holdings by weight, in the chosen `view` (`display` by market value, default; `raw` by absolute exposure weight).

`GET https://api.bavest.co/v2/etfs/holdings/top`

Group: ETFs. Route id: `v2_etfs_holdings_top`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |
| `view` | query | string | no | Holdings view. `display` (default) weighs every row by market value, so a fund sums to ~100, with cash, Treasury bills and money market funds as their own rows; swaps and futures (no market value) and negative cash rows are left out. `raw` lists every row and keeps the issuer's exposure weights, so derivatives count at notional (a 3x fund ~300) and swaps list their counterparty. Plain ETFs are the same in both views. Unrecognized values fall back to `display`. One of `display`, `raw`. Default `display`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.symbol` | string \| null | no | Resolved ETF ticker, echoed from the lookup. |
| `data.atDate` | string (date) | no |  |
| `data.holdings` | array of HoldingRecord | no |  |
| `data.holdings[].name` | string \| null | yes | Holding name. Null when the constituent has no resolved master-record name yet; the key is always present. Example: `Apple Inc.`. |
| `data.holdings[].symbol` | string \| null | no | Ticker symbol. Example: `AAPL`. |
| `data.holdings[].isin` | string \| null | no | ISIN identifier. |
| `data.holdings[].percent` | number (double) \| null | yes | Weight (%) of net assets. With `view=display` (default) the market-value weight, so a fund's rows sum to ~100; swaps and futures without a market value and negative cash rows are left out (they are in `raw`). With `view=raw` a derivative's exposure weight (a 3x fund sums to ~300, an inverse fund's swaps are negative). Plain ETFs carry the same rows and weights in both views. Null only when the issuer publishes neither weight. Example: `7.79`. |
| `data.holdings[].value` | number (double) \| null | no | Issuer-reported position value in the source currency, which is not normalized here. Null when not reported. Use calculatedValue for an explicitly labelled USD estimate. |
| `data.holdings[].share` | number (double) \| null | no | Shares held. |
| `data.holdings[].cusip` | string \| null | no | CUSIP identifier. |
| `data.holdings[].calculatedValue` | object \| null | no | Bavest-calculated USD estimate, separate from issuer-reported value. Only available for a currently matching equity position with no reported value. |
| `data.holdings[].calculatedValue.value` | number (double) | yes | Estimated position value in USD. |
| `data.holdings[].calculatedValue.currency` | string | yes | One of `USD`. |
| `data.holdings[].calculatedValue.method` | string | yes | Example: `equity_quantity_times_historical_close_v1`. |
| `data.holdings[].calculatedValue.priceDate` | string (date) | yes |  |
| `data.holdings[].calculatedValue.fxDate` | string (date) | yes |  |
| `data.holdings[].calculatedValue.calculatedAt` | string (date-time) | yes |  |
| `data.holdings[].holdingType` | string \| null | no | Position type. `equity` for a listed security; swaps, futures, Treasury bills, money market funds and cash / net other assets are kept as their own rows (no ISIN); `other` for an unlisted instrument such as a bond. Null on issuer top-10 lists that publish names only. One of `equity`, `swap`, `future`, `cash`, `money_market`, `treasury_bill`, `other`, `null`. Example: `equity`. |
| `data.holdings[].marketValue` | number (double) \| null | no | Issuer-reported market value in the source currency; the basis of `percent` in `view=display`. Null when the issuer publishes none (swaps, futures). |
| `data.holdings[].exposureValue` | number (double) \| null | no | Issuer-reported exposure (notional plus gain/loss) of a swap or future, in the source currency; the basis of `percent` in `view=raw`. Null for positions without one. Example: `9920928648.41`. |
| `data.holdings[].counterparty` | string \| null | no | Swap counterparty as the issuer names it. Null for every other position. Example: `BNP Paribas`. |
| `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/etfs/holdings/top?isin=IE00B4L5Y983&view=display' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "holdings": [
      {
        "symbol": null,
        "cusip": null,
        "name": "NVIDIA",
        "share": null,
        "percent": 5.6408,
        "value": null,
        "isin": null
      },
      {
        "symbol": null,
        "cusip": null,
        "name": "APPLE",
        "share": null,
        "percent": 5.461,
        "value": null,
        "isin": null
      }
    ],
    "atDate": "2026-09-28",
    "symbol": null
  },
  "meta": {
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 125
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_holdings_top

---

# ETF KID Document

> Returns the Key Information Document (KID) as a PDF file.

`GET https://api.bavest.co/v2/etfs/kid`

Group: ETFs. Route id: `v2_etfs_kid`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `isin` | query | string | yes | ETF ISIN code (required for KID endpoints) Example `IE00B4L5Y983`. |
| `language` | query | string | no | Language code (ISO 639-1). `lang` is accepted as an alias. Example when explicitly filtering: `en`. Default `en`. |
| `type` | query | string | no | Which document to return. Omit it and the endpoint returns the PRIIPs KID, falling back to the UCITS KIID when no KID is held for that language. Set it to fetch one specific document -- in particular a KIID for an ISIN that also has a KID in the same language, which is otherwise unreachable even though /v2/etfs/documents/catalog lists it. Example when explicitly filtering: `KIID`. One of `KID`, `KIID`. |

## Response

200 KID document (application/pdf) (`application/pdf`).

## Example request

```bash
curl 'https://api.bavest.co/v2/etfs/kid?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'accept: application/pdf' \
  --output response.pdf
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_kid

---

# ETF KID Languages

> Returns available language codes for a specific ETF's KID document.

`GET https://api.bavest.co/v2/etfs/kid/languages`

Group: ETFs. Route id: `v2_etfs_kid_languages`. Free in every plan, including the trial.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `isin` | query | string | yes | ETF ISIN code (required for KID endpoints) Example `IE00B4L5Y983`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.languages` | array of string | no |  |
| `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/etfs/kid/languages?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "languages": [
      "de",
      "en"
    ]
  },
  "meta": {
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 3
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_kid_languages

---

# ETF List

> Returns a paginated list of all ETF, ETP, and ETN listings.

`GET https://api.bavest.co/v2/etfs/list`

Group: ETFs. Route id: `v2_etfs_list`. Free in every plan, including the trial.

## Description

Returns a paginated list of all ETF, ETP, and ETN listings. The list is listing-level: one row per exchange listing, so the same ISIN can appear multiple times. `isin` is guaranteed ISO-6166-shaped; `name` may be null when no name has been resolved yet.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |
| `exchangeCode` | query | string | no | Filter by exchange short code (e.g. NASDAQ, NYSE) Example when explicitly filtering: `NASDAQ`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of SecurityListItem | no |  |
| `data[].isin` | string | no | ISIN identifier. Guaranteed to be ISO-6166-shaped, uppercase and trimmed; rows without a structurally valid ISIN are excluded. Example: `IE00B4L5Y983`. |
| `data[].symbol` | string | no | Ticker symbol. Example: `SPY`. |
| `data[].name` | string \| null | yes | Security name. Null when no name has been resolved from any source yet; the key is always present. Example: `SPDR S&P 500 ETF Trust`. |
| `data[].country` | string \| null | no | Country of domicile (ISO 3166-1 alpha-2) Example: `US`. |
| `data[].exchange` | string \| null | no | Exchange name. Example: `NASDAQ Global Market`. |
| `data[].exchangeCode` | string \| null | no | Exchange short code. Example: `NASDAQ`. |
| `data[].sector` | string \| null | no | Industry sector. Example: `Technology`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/etfs/list' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "isin": "ZAE000273165",
      "symbol": "CSPROP.JO",
      "name": "10X South African Property Income ETF",
      "country": "ZA",
      "exchange": "Johannesburg Stock Exchange",
      "exchangeCode": "JNB",
      "sector": "Financial Services"
    },
    {
      "isin": "ZAE000268694",
      "symbol": "CSP500.JO",
      "name": "10X S&P 500 ETF",
      "country": "ZA",
      "exchange": "Johannesburg Stock Exchange",
      "exchangeCode": "JNB",
      "sector": "Financial Services"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 354,
    "totalCount": 35383,
    "parameters": {
      "limit": "100"
    },
    "time": 5
  }
}
```

## Errors

Also `400`, `401`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_list

---

# ETF Metrics

> Returns a paginated list of all ETF metrics — performance, risk, volatility, and fund characteristics — with full lineage/traceability.

`GET https://api.bavest.co/v2/etfs/metrics`

Group: ETFs. Route id: `v2_etfs_metrics`. Included in: Pro, Growth.

## Description

Returns a paginated list of all ETF metrics — performance, risk, volatility,
and fund characteristics — with full lineage/traceability.

**Metric groups:**
- **Returns:** 1M, 3M, YTD, 1Y, 3Y, 5Y, 10Y; annualized 5Y; since inception
  (cumulative and annualized). Returns are total returns: distributions are added back
  to the closes (an accumulating share class is used as quoted).
- **Risk (security & category):** beta, alpha, sharpe ratio, treynor ratio,
  R-squared, standard deviation, mean annual return (1Y/3Y/5Y/10Y)
- **Volatility:** YTD, 1Y, 3Y, 5Y, 10Y
- **Risk indicators:** SRI (price-based, 1-7), SRRI (document-based, 1-7)
- **Fund:** tracking error, net management fee
- **Dividends:** dividend_yield (trailing 12-month distributions / latest close,
  percent; 0.0 for accumulating share classes)

Pass `trace=true` to include computation lineage (formula, inputs, explanation)
for each metric.


Check each metric's `date` for freshness. `latestDate` is the newest date across metrics and does not mean every metric (including AUM) is current.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |
| `fields` | query | string | no | Comma-separated list of metric names to include in the response. Valid names are served by `/v2/etfs/metrics/names`. Example when explicitly filtering: `nav,aum,expense_ratio`. |
| `limit` | query | integer (int32) | no | Maximum number of metrics to return per page (default 50, max 200) Default `50`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |
| `trace` | query | boolean | no | Include computation lineage (formula, inputs, explanation) for each metric. Default `false`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.latestDate` | string (date) \| null | no | Most recent observation date across all metrics. Example: `2026-10-02`. |
| `data.metrics` | array of ETFMetricItem | no |  |
| `data.metrics[].metricId` | string | yes | Machine-readable metric identifier (lowercase, e.g. beta_3y, return_1y) Example: `beta_3y`. |
| `data.metrics[].metricName` | string | yes | Metric name as stored in the database (uppercase) Example: `BETA_3Y`. |
| `data.metrics[].date` | string (date) \| null | no | Observation date of this metric value. Example: `2026-03-31`. |
| `data.metrics[].value` | number (double) \| null | yes | Computed metric value. Null when computation failed. Example: `1.03`. |
| `data.metrics[].valid` | boolean | yes | Whether the metric was successfully computed. Example: `true`. |
| `data.metrics[].unit` | string \| null | no | Unit of measurement (MetricUnitModel value, uppercase) Example: `RATIO`. |
| `data.metrics[].currency` | string \| null | no | Currency code if the metric is currency-denominated (null for ratios/percentages) |
| `data.metrics[].trace` | object \| null | no | Computation lineage (only included when trace=true is passed) |
| `data.metrics[].trace.formula` | string \| null | no | Formula template used for computation. Example: `cov(R_etf, R_bench) / var(R_bench)`. |
| `data.metrics[].trace.formula_computed` | string \| null | no | Formula with actual computed values substituted. |
| `data.metrics[].trace.inputs` | object \| null | no | Input values used in the calculation. |
| `data.metrics[].trace.explanation` | string \| null | no | Natural language explanation of the computation result. Example: `Beta (3Y) = 1.03 for 3Y vs ^GSPC. Inputs: beta=1.0300`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/etfs/metrics?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "latestDate": "2026-10-02",
    "metrics": [
      {
        "metricId": "aum",
        "metricName": "aum",
        "value": 147022599924.06,
        "date": "2026-10-01",
        "valid": true,
        "unit": "CURRENCY",
        "currency": "USD"
      },
      {
        "metricId": "nav",
        "metricName": "nav",
        "value": 145.4398,
        "date": "2026-10-01",
        "valid": true,
        "unit": "CURRENCY",
        "currency": "USD"
      }
    ]
  },
  "meta": {
    "page": 1,
    "pageSize": 50,
    "totalPages": 3,
    "totalCount": 101,
    "parameters": {
      "isin": "IE00B4L5Y983",
      "limit": "50"
    },
    "time": 68
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_metrics

---

# ETF Profile

> Returns ETF identity and classification.

`GET https://api.bavest.co/v2/etfs/profile`

Group: ETFs. Route id: `v2_etfs_profile`. Included in: Pro, Growth.

## Description

Returns ETF identity and classification.

> Fees, risk metrics, structure and NAV live in dedicated resources: `/v2/etfs/fees`, `/v2/etfs/risk`, `/v2/etfs/structure`, `/v2/etfs/nav`, `/v2/etfs/metrics`. Holdings count is `meta.totalCount` on `/v2/etfs/holdings`.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | ETFProfile | no | Core ETF identity and classification. Every property is always present in the response; any value may be `null` where the issuer does not publish it. `cusip` and `website` may also be an empty string for non-US listings. |
| `data.symbol` | string \| null | no | ETF ticker symbol. Example: `ARKK`. |
| `data.isin` | string \| null | no | ETF ISIN code. Example: `IE00B4L5Y983`. |
| `data.name` | string \| null | yes | Official ETF name. Example: `ARK Innovation ETF`. |
| `data.description` | string \| null | no | Brief description of the ETF's investment objective. |
| `data.website` | string \| null | no | URL of the ETF issuer's product page, empty string if unknown. |
| `data.domicile` | string \| null | no | Country of domicile (ISO 3166-1 alpha-2 code) Example: `IE`. |
| `data.inceptionDate` | string (date) \| null | no | Date the ETF was launched. |
| `data.etfCompany` | string \| null | no | Name of the ETF issuer or management company. Example: `ARK Invest`. |
| `data.assetClass` | string \| null | no | Broad asset class (e.g. Equity, Fixed Income, Commodity) Example: `Equity`. |
| `data.cusip` | string \| null | no | CUSIP identifier for the ETF, empty string for non-US listings. Example: `78462F103`. |
| `data.distributionPolicy` | string \| null | no | Distribution policy (e.g. Accumulating, Distributing) |
| `data.etfCategory` | string \| null | no | Investment category within the asset class. Example: `U.S. Equity`. |
| `data.etfFocus` | string \| null | no | Investment focus or strategy. Example: `Broad Market`. |
| `data.etfNiche` | string \| null | no | Specific niche or investment approach. Example: `Index Tracking`. |
| `data.indice` | string \| null | no | Name of the tracked index as published by the issuer. Free text, not normalised: either the index family alone (`S&P 500®`, `MSCI World`) or the full index variant with return type, currency and hedging (`STOXX Europe 600 NR EUR`, `S&P 500® ESG Elite (EUR Hedged)`). Suffixes are part of the official index name: PR/NR/TR = price, net total return, gross total return; EUR/USD = index currency; `Hedged` = currency-hedged variant. Null for actively managed ETFs or when the index is not captured. Intended for display; do not join or filter on it. Example: `STOXX Europe 600 NR EUR`. |
| `data.replicationMethod` | string \| null | no | Index replication method (e.g. Full, Sampling, Synthetic) |
| `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/etfs/profile?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "symbol": "IWDA.L",
    "isin": "IE00B4L5Y983",
    "cusip": "",
    "name": "iShares Core MSCI World UCITS ETF USD (Acc)",
    "description": "With the iShares Core MSCI World UCITS ETF (Acc), investors can participate in the performance of currently over 1,500 large and medium-sized companies from 23 developed markets. The ETF thus enables access to an internationally diversified market segment.",
    "assetClass": "Equity",
    "domicile": "IE",
    "etfCompany": "iShares",
    "inceptionDate": "2009-09-25",
    "website": "",
    "etfCategory": "Global Equity",
    "etfFocus": "Broad Market",
    "etfNiche": "MSCI World Index Exposure",
    "indice": "MSCI World",
    "distributionPolicy": "Accumulating",
    "replicationMethod": "physical"
  },
  "meta": {
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 28
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_profile

---

# ETF Risk

> Returns risk metrics including beta, SRI/SRRI, tracking error, and volatility.

`GET https://api.bavest.co/v2/etfs/risk`

Group: ETFs. Route id: `v2_etfs_risk`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | ETFRisk | no | ETF risk metrics across time horizons. |
| `data.betaOneYear` | number (double) \| null | no | 1-year beta relative to the benchmark. |
| `data.betaThreeYears` | number (double) \| null | no | 3-year beta relative to the benchmark. |
| `data.betaFiveYears` | number (double) \| null | no | 5-year beta relative to the benchmark. |
| `data.sri` | integer \| null | no | Summary Risk Indicator (1-7) |
| `data.srri` | integer \| null | no | Synthetic Risk and Reward Indicator (1-7) |
| `data.trackingError` | number (double) \| null | no | Annualized tracking error versus the benchmark. |
| `data.volatility` | number (double) \| null | no | Annualized price volatility (standard deviation of returns) |
| `data.symbol` | string | yes | ETF ticker symbol. Example: `SPY`. |
| `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/etfs/risk?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "symbol": "IWDA.L",
    "betaOneYear": -0.0001,
    "betaThreeYears": 0.0007,
    "betaFiveYears": 0.0019,
    "sri": 4,
    "srri": 6,
    "trackingError": 0.0532,
    "volatility": 0.1101
  },
  "meta": {
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 35
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_risk

---

# ETF Sector Exposure

> Returns sector allocation percentages.

`GET https://api.bavest.co/v2/etfs/sectors`

Group: ETFs. Route id: `v2_etfs_sectors`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |
| `view` | query | string | no | Allocation view. `display` (default) hides rows with negative exposure and scales the remainder to 100. `raw` returns the stored rates, where swap/bond legs and short positions are legitimately negative. Unrecognized values fall back to `display`. One of `display`, `raw`. Default `display`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.atDate` | string (date) | no | Observation date for the exposure data. |
| `data.sectorExposure` | array of ETFSectorExposure | no |  |
| `data.sectorExposure[].sector` | string | yes | Sector name. Example: `Technology`. |
| `data.sectorExposure[].exposure` | number (double) | yes | Exposure percentage. Example: `35.62`. |
| `data.sectorExposure[].synthetic` | boolean | no | `true` when the row is Bavest-generated rather than scraped from an issuer breakdown. Applies to products with no published sector allocation to scrape — chiefly crypto and commodity funds. Example: `false`. |
| `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/etfs/sectors?isin=IE00B4L5Y983&view=display' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "sectorExposure": [
      {
        "sector": "Information Technology",
        "synthetic": false,
        "exposure": 31.39
      },
      {
        "sector": "Financials",
        "synthetic": false,
        "exposure": 15.81
      }
    ],
    "atDate": "2026-09-30"
  },
  "meta": {
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 679
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_sectors

---

# ETF Sectors Top

> Returns top sectors by allocation.

`GET https://api.bavest.co/v2/etfs/sectors/top`

Group: ETFs. Route id: `v2_etfs_sectors_top`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.atDate` | string (date) | no | Observation date for the exposure data. |
| `data.sectorExposure` | array of ETFSectorExposure | no |  |
| `data.sectorExposure[].sector` | string | yes | Sector name. Example: `Technology`. |
| `data.sectorExposure[].exposure` | number (double) | yes | Exposure percentage. Example: `35.62`. |
| `data.sectorExposure[].synthetic` | boolean | no | `true` when the row is Bavest-generated rather than scraped from an issuer breakdown. Applies to products with no published sector allocation to scrape — chiefly crypto and commodity funds. Example: `false`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/etfs/sectors/top?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "sectorExposure": [
      {
        "sector": "Information Technology",
        "synthetic": false,
        "exposure": 31.39
      },
      {
        "sector": "Financials",
        "synthetic": false,
        "exposure": 15.81
      }
    ],
    "atDate": "2026-09-30"
  },
  "meta": {
    "page": 1,
    "pageSize": 10,
    "totalPages": 2,
    "totalCount": 13,
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 385
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_sectors_top

---

# ETF Metric Names

> Returns every metric name available on `/v2/etfs/metrics`, with the unit and a description for each name.

`GET https://api.bavest.co/v2/etfs/metrics/names`

Group: ETFs. Route id: `v2_etfs_metrics_names`. Free in every plan, including the trial.

## Description

Returns every metric name available on `/v2/etfs/metrics`, with the unit
and a description for each name.

Use these names with the `fields` parameter of `/v2/etfs/metrics`. The
vocabulary is versioned with the API. New metric names may be added over
time and additions are backward compatible.

No ETF identifier is required.

## Parameters

None.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.count` | integer | no | Total number of registered metric names. Example: `92`. |
| `data.metrics` | array of object | no |  |
| `data.metrics[].name` | string | no | Canonical metric name (snake_case) Example: `beta_one_year_security`. |
| `data.metrics[].unit` | string | no | Unit of measurement (MetricUnitModel value) One of `CURRENCY`, `NUMERIC`, `PERCENTAGE`, `RATIO`, `DATE`, `BOOLEAN`, `YEARS`. Example: `RATIO`. |
| `data.metrics[].description` | string | no | Human-readable description of the metric. Example: `1-year beta of the fund versus S&P 500`. |
| `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/etfs/metrics/names' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "count": 104,
    "metrics": [
      {
        "name": "alpha_five_years_category",
        "unit": "RATIO",
        "description": "5-year Jensen's alpha of the fund's category"
      },
      {
        "name": "alpha_five_years_security",
        "unit": "RATIO",
        "description": "5-year Jensen's alpha of the fund"
      }
    ]
  },
  "meta": {
    "time": 57
  }
}
```

## Errors

Also `401`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_metrics_names

---

# ETF Countries Top

> Returns top countries by allocation.

`GET https://api.bavest.co/v2/etfs/countries/top`

Group: ETFs. Route id: `v2_etfs_top_countries`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.atDate` | string (date) | no | Observation date for the exposure data. |
| `data.countryExposure` | array of ETFCountryExposure | no |  |
| `data.countryExposure[].country` | string | yes | Country name. Example: `United States`. |
| `data.countryExposure[].exposure` | number (double) | yes | Exposure percentage. Example: `97.57`. |
| `data.countryExposure[].synthetic` | boolean | no | `true` when the row is Bavest-generated rather than scraped from an issuer breakdown. Applies to products with no published geographic allocation to scrape — chiefly crypto and commodity funds. Example: `false`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/etfs/countries/top?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "countryExposure": [
      {
        "country": "United States",
        "exposure": 72.68,
        "synthetic": false
      },
      {
        "country": "Japan",
        "exposure": 5.91,
        "synthetic": false
      }
    ],
    "atDate": "2026-10-02"
  },
  "meta": {
    "page": 1,
    "pageSize": 10,
    "totalPages": 2,
    "totalCount": 11,
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 3736
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_top_countries

---

# ETF Country List

> Returns the canonical set of values the `country` field of ETF geographic allocation (`/v2/etfs/countries`) can take.

`GET https://api.bavest.co/v2/etfs/countries/list`

Group: ETFs. Route id: `v2_etfs_countries_list`. Free in every plan, including the trial.

## Description

Returns the canonical set of values the `country` field of ETF geographic
allocation (`/v2/etfs/countries`) can take.

Every `country` value served by the API appears in this list. The list is
complete and authoritative. Each entry is tagged by `type`:

- `country`: ISO 3166 country or territory, including common aliases
- `region`: multi-country grouping such as "Europe" or "Emerging Markets"
- `supranational`: non-sovereign issuer bucket such as "Supranational" or
  "European Union", common in bond ETFs (World Bank, EIB, EU)
- `other`: non-geographic values such as "Cash", "Other", "Unknown", "N/A"

No ETF identifier is required.

## Parameters

None.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.count` | integer | no | Total number of country values in the catalog. Example: `293`. |
| `data.countries` | array of object | no |  |
| `data.countries[].name` | string | no | Country-allocation value. Example: `United States`. |
| `data.countries[].type` | string | no | Value category. One of `country`, `region`, `supranational`, `other`. Example: `country`. |
| `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/etfs/countries/list' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "count": 301,
    "countries": [
      {
        "name": "ASEAN",
        "type": "region"
      },
      {
        "name": "Afghanistan",
        "type": "country"
      }
    ]
  },
  "meta": {
    "time": 462
  }
}
```

## Errors

Also `401`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_countries_list

---

# ETF Structure

> Returns ETF structural classification including leverage, complexity, and benchmark status.

`GET https://api.bavest.co/v2/etfs/structure`

Group: ETFs. Route id: `v2_etfs_structure`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | ETFStructure | no | ETF structural classification. |
| `data.type` | string | yes | Product type (e.g. ETF, ETC, ETN) Example: `ETF`. |
| `data.isBenchmark` | boolean | no | Whether the ETF serves as a benchmark. |
| `data.isIndexTracked` | boolean | no | Whether the ETF tracks an index. |
| `data.isLeveraged` | boolean | no | Whether the ETF uses leverage. |
| `data.isComplex` | boolean | no | Whether the ETF is classified as a complex product. |
| `data.isStructured` | boolean | no | Whether the ETF is a structured product. |
| `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/etfs/structure?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "type": "ETF",
    "isBenchmark": false,
    "isIndexTracked": true,
    "isLeveraged": false,
    "isComplex": false,
    "isStructured": false
  },
  "meta": {
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 28
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_structure

---

# Submit ETF Data Export

> Submit an asynchronous export job for this account's ETF data.

`POST https://api.bavest.co/v2/etfs/exports`

Group: ETFs. Route id: `v2_etfs_export_submit`. Included in: Pro, Growth.

## Description

Submit an asynchronous export job for this account's ETF data. `dataset` selects the source: `metrics` (default), `countries`, `sectors`, or `holdings`. Choose symbols and/or isins (at least one, at most 100 together) and a from/to window (`metrics` also accepts a metric-name list); a batch worker materialises the Parquet export, then poll GET /etfs/exports/{exportId} for signed download links. symbols and isins union. A request with neither is a 400. Scoped to the caller's API key.

## Parameters

None.

## Request body

JSON, optional.

| Field | Type | Always present | Description |
|---|---|---|---|
| `dataset` | string | no | Which ETF dataset to export. One of `metrics`, `countries`, `sectors`, `holdings`. |
| `metrics` | array of string | no | Metric-name filter (dataset=metrics only). |
| `symbols` | array of string | no |  |
| `isins` | array of string | no |  |
| `from` | string (date) | no |  |
| `to` | string (date) | no |  |

## Response

200 Job accepted (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.exportId` | string | no |  |
| `data.assetClass` | string | no | Example: `etf`. |
| `data.status` | string | no | Example: `pending`. |
| `data.poll` | string | no | Poll this path for status and links. |
| `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 -X POST 'https://api.bavest.co/v2/etfs/exports' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"dataset":"metrics","metrics":["string"],"symbols":["string"],"isins":["string"],"from":"2026-01-02","to":"2026-01-02"}'
```

## Errors

Also `400`, `401`, `429` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_export_submit

---

# ETF Export Status

> Poll a submitted export job.

`GET https://api.bavest.co/v2/etfs/exports/{exportId}`

Group: ETFs. Route id: `v2_etfs_export_status`. Included in: Pro, Growth.

## Description

Poll a submitted export job. 'ready' returns presigned download links for each Parquet part plus the manifest; 'pending' is still materialising; 'failed' includes an error. Scoped to the caller's API key.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `exportId` | path | string | yes | The exportId returned by the submit call. |

## Response

200 Export status (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.exportId` | string | no |  |
| `data.status` | string | no | One of `ready`, `pending`, `failed`. |
| `data.rows` | integer | no |  |
| `data.requested` | integer | no | Count of explicitly-requested securities (absent for full-universe exports). |
| `data.returned` | integer | no | Requested securities that returned >=1 row. |
| `data.missing` | array of object | no | Requested securities that returned no rows. |
| `data.missing[].id` | string | no |  |
| `data.missing[].reason` | string | no | One of `NO_DATA`, `UNKNOWN_SECURITY`. |
| `data.schema` | array of string | no |  |
| `data.expiresInSeconds` | integer | no | Example: `3600`. |
| `data.manifestUrl` | string | no |  |
| `data.parts` | array of object | no |  |
| `data.parts[].metricName` | string | no |  |
| `data.parts[].url` | string | no |  |
| `data.error` | string | no | Present only when status=failed. |
| `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

`GET https://api.bavest.co/v2/etfs/exports/{exportId}` with the parameters above and the `x-api-key` header.

## Errors

Also `400`, `401`, `404`, `429` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_export_status

---

# ETF Asset Class Breakdown

> Returns asset-class allocation percentages based on holdings, including recursive look-through of underlying funds and ETFs.

`GET https://api.bavest.co/v2/etfs/asset-class-breakdown`

Group: ETFs. Route id: `v2_etfs_asset_class_breakdown`. Included in: Pro, Growth.

## Description

Returns asset-class allocation percentages based on holdings, including recursive look-through of underlying funds and ETFs. Preserves signed weights and reports missing or unclassified exposure as unknown.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | no (at most one of symbol, isin, cusip) | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | no (at most one of symbol, isin, cusip) | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |
| `cusip` | query | string | no (at most one of symbol, isin, cusip) | CUSIP code (e.g., `037833100`). Provide at most one of symbol, isin, or cusip. |

Optional, at most one of `symbol`, `isin`, `cusip`.

## Response

200 Holdings-based allocation including explicit unknown weight. (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.atDate` | string (date) \| null | no |  |
| `data.oldestHoldingsDate` | string (date) \| null | no |  |
| `data.assetClassBreakdown` | array of object | yes |  |
| `data.assetClassBreakdown[].assetClass` | string | yes | One of `equity`, `fixed_income`, `cash_money_market`, `commodities`, `crypto`, `other`, `unknown`. |
| `data.assetClassBreakdown[].percent` | number | yes |  |
| `data.assetClassBreakdown[].longPercent` | number | no |  |
| `data.assetClassBreakdown[].shortPercent` | number | no |  |
| `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/etfs/asset-class-breakdown?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "atDate": "2026-09-30",
    "oldestHoldingsDate": "2026-08-31",
    "assetClassBreakdown": [
      {
        "assetClass": "equity",
        "percent": 72,
        "longPercent": 72,
        "shortPercent": 0
      },
      {
        "assetClass": "fixed_income",
        "percent": 15,
        "longPercent": 15,
        "shortPercent": 0
      },
      {
        "assetClass": "cash_money_market",
        "percent": 0,
        "longPercent": 0,
        "shortPercent": 0
      },
      {
        "assetClass": "commodities",
        "percent": 0,
        "longPercent": 0,
        "shortPercent": 0
      },
      {
        "assetClass": "crypto",
        "percent": 0,
        "longPercent": 0,
        "shortPercent": 0
      },
      {
        "assetClass": "other",
        "percent": 0,
        "longPercent": 0,
        "shortPercent": 0
      },
      {
        "assetClass": "unknown",
        "percent": 13,
        "longPercent": 13,
        "shortPercent": 0
      }
    ]
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `503` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_etfs_asset_class_breakdown

---

# Earnings Release Filings

> Real-time feed of SEC 8-K earnings-release filings (item 2.02), source- agnostic and forward-compatible with future push delivery (websocket / webhook).

`GET https://api.bavest.co/v2/filings/earnings`

Group: Filings. Route id: `v2_filings_earnings`. Included in: Startup, Pro, Growth.

## Description

Real-time feed of SEC 8-K earnings-release filings (item 2.02), source-
agnostic and forward-compatible with future push delivery (websocket /
webhook). Each event is written twice: once at `stage=announced`
(lowest latency, minimal fields — typically seconds after the filing
hits EDGAR) and again at `stage=enriched` once the index page and
press-release exhibit have been hydrated.

Omit `symbol`/`isin`/`cusip` for the full firehose across all
companies. `from`/`to` filter on `filed_at`. For low-latency polling,
use `updated_since` instead of `from`/`to`: it switches the sort order
to `updated_at` ascending so a cursor never skips a row that was
updated between polls (e.g. an `announced` row that became
`enriched`). Ordered `filed_at DESC` by default, `updated_at ASC` when
`updated_since` is set.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | no (at most one of symbol, isin, cusip) | Optional ticker filter (e.g., `AAPL`). Omit for all securities. Provide at most one of symbol or isin. |
| `isin` | query | string | no (at most one of symbol, isin, cusip) | ISIN code (e.g., `US0378331005`). Provide exactly one of symbol or isin. Clear the symbol example before using an ISIN. |
| `cusip` | query | string | no (at most one of symbol, isin, cusip) | CUSIP code (e.g., `037833100`). Provide at most one of symbol, isin, or cusip. |
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `updated_since` | query | string (date-time) | no | Delta-polling cursor start. Accepts an ISO-8601 date or date-time. When set, results are sorted `updated_at` ascending instead of `filed_at` descending — the recommended low-latency polling pattern, since it guarantees a cursor never skips a row that was updated between polls. |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 50, max 500) Default `50`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

Optional, at most one of `symbol`, `isin`, `cusip`.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of EarningsRelease | no |  |
| `data[].event_type` | string | yes | Event type discriminator. Always `earnings_release` on this endpoint; other `/v2/filings/*` endpoints use other values. Example: `earnings_release`. |
| `data[].source` | string | yes | Filing source registry. Only `sec_edgar` in v1; EU regulator feeds (RNS, EQS) are a Phase 2 commercial/licensing item. One of `sec_edgar`. Example: `sec_edgar`. |
| `data[].form_type` | string | no | Regulator form type of the underlying filing (e.g. `8-K`). Kept as a free string so non-SEC form types fit without a schema change. Example: `8-K`. |
| `data[].is_amendment` | boolean | no | True when this filing amends a prior filing. Example: `false`. |
| `data[].amends_accession_number` | string \| null | no | Accession number of the filing this amends, or null when `is_amendment` is false. |
| `data[].items` | array of string \| null | no | SEC 8-K item codes that triggered this event, e.g. `2.02` (Results of Operations and Financial Condition) or `9.01` (Financial Statements and Exhibits). Null for future EU-source events, which carry no item codes. |
| `data[].identifiers` | FilingIdentifiers | no | All known identifier forms for the filer, so consumers can key on whichever one they use internally. |
| `data[].identifiers.symbol` | string \| null | no | Ticker symbol. Example: `AAPL`. |
| `data[].identifiers.isin` | string \| null | no | ISIN code. Example: `US0378331005`. |
| `data[].identifiers.cusip` | string \| null | no | CUSIP code. Example: `37833100`. |
| `data[].identifiers.cik` | string \| null | no | SEC Central Index Key (10-digit, zero-padded) Example: `320193`. |
| `data[].identifiers.lei` | string \| null | no | Legal Entity Identifier (GLEIF). Not yet populated for SEC-sourced filings — reserved for the EU/LEI backfill phase. |
| `data[].company_name` | string \| null | no | Filer's registered company name. Example: `Apple Inc.`. |
| `data[].accession_number` | string | yes | SEC accession number (unique per filing) Example: `0000320193-26-000018`. |
| `data[].filed_at` | string (date-time) | yes | Filing timestamp reported by SEC EDGAR (ISO-8601, UTC). Example: `2026-07-30T20:30:28+00:00`. |
| `data[].updated_at` | string (date-time) | yes | When this event row was last written (ISO-8601, UTC). Sort key for `updated_since` delta polling. Example: `2026-07-30T20:30:36+00:00`. |
| `data[].report_date` | string (date) \| null | no | Reporting date as stated by the filer, when different from `filed_at`'s calendar date. Example: `2026-07-30`. |
| `data[].headline` | string \| null | no | Short human-readable summary. Null until the filing is enriched. Example: `Apple reports third quarter results`. |
| `data[].documents` | FilingDocuments \| null | no | Links to the filing's documents. `exhibits` (and therefore `press_release`, which is derived from it) is null until enrichment completes. |
| `data[].documents.filing_index` | string (uri) | no | SEC EDGAR filing index page. Known as soon as the filing is detected, independent of enrichment stage. Example: `https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany`. |
| `data[].documents.press_release` | string (uri) \| null | no | URL of the press-release exhibit (EX-99.1), when one was identified during enrichment. Null until the filing is enriched. |
| `data[].documents.exhibits` | array of FilingExhibit \| null | no | Full exhibit list. Null until the filing is enriched. |
| `data[].documents.exhibits[].type` | string | no | Exhibit type code. Example: `EX-99.1`. |
| `data[].documents.exhibits[].url` | string (uri) | no | Exhibit document URL. Example: `https://www.sec.gov/Archives/edgar/data/320193/000032019326000018/ex99_1.htm`. |
| `data[].documents.exhibits[].description` | string \| null | no | Human-readable exhibit description. Example: `Press release`. |
| `data[].period` | FilingPeriod \| null | no | The fiscal period the filing reports on. Null until the filing is enriched. |
| `data[].period.fiscal_year` | integer \| null | no | Fiscal year. Currently always null in v1 — fiscal_year/ fiscal_quarter derivation from the earnings calendar is not yet implemented (later phase). Example: `2026`. |
| `data[].period.fiscal_quarter` | integer \| null | no | Fiscal quarter (1-4). Currently always null in v1 — fiscal_year/fiscal_quarter derivation from the earnings calendar is not yet implemented (later phase). Example: `3`. |
| `data[].period.period_end` | string (date) \| null | no | Period end date. Null when no matching earnings-calendar entry was found during enrichment. Example: `2026-06-27`. |
| `meta` | object | no | Cursor pagination metadata. No `totalCount` — computing an exact total across a firehose feed is not worth the query cost. |
| `meta.pageSize` | integer | no | Page size requested (echoes `limit`) |
| `meta.hasMore` | boolean | no | Whether another page is available. |
| `meta.nextCursor` | string \| null | no | Opaque cursor for the next page, or null when `hasMore` is false. |
| `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/filings/earnings' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "event_type": "earnings_release",
      "source": "sec_edgar",
      "form_type": "8-K",
      "is_amendment": false,
      "amends_accession_number": null,
      "items": [
        "2.02",
        "9.01"
      ],
      "identifiers": {
        "symbol": "TSLA",
        "isin": "US88160R1014",
        "cusip": null,
        "cik": 1318605,
        "lei": null
      },
      "company_name": "Tesla, Inc.",
      "accession_number": "0001628280-26-064366",
      "filed_at": "2026-10-02T13:04:26+00:00",
      "updated_at": "2026-10-02T14:00:58.860270+00:00",
      "report_date": "2026-10-02",
      "headline": "Document",
      "documents": {
        "filing_index": "https://www.sec.gov/Archives/edgar/data/1318605/000162828026064366/0001628280-26-064366-index.htm",
        "press_release": "https://www.sec.gov/Archives/edgar/data/1318605/000162828026064366/exhibit991111111.htm",
        "exhibits": [
          {
            "url": "https://www.sec.gov/ix?doc=/Archives/edgar/data/1318605/000162828026064366/tsla-20261002.htm",
            "type": "8-K",
            "description": "8-K"
          },
          {
            "url": "https://www.sec.gov/Archives/edgar/data/1318605/000162828026064366/exhibit991111111.htm",
            "type": "EX-99.1",
            "description": "EX-99.1"
          }
        ]
      },
      "period": {
        "fiscal_year": null,
        "fiscal_quarter": null,
        "period_end": null
      }
    },
    {
      "event_type": "earnings_release",
      "source": "sec_edgar",
      "form_type": "8-K",
      "is_amendment": false,
      "amends_accession_number": null,
      "items": [
        "2.02",
        "9.01"
      ],
      "identifiers": {
        "symbol": "TMQ",
        "isin": "CA89621C1059",
        "cusip": null,
        "cik": 1543418,
        "lei": null
      },
      "company_name": "Trilogy Metals Inc.",
      "accession_number": "0001279569-26-000946",
      "filed_at": "2026-10-02T12:39:09+00:00",
      "updated_at": "2026-10-02T13:00:50.371646+00:00",
      "report_date": "2026-10-02",
      "headline": "Exhibit 99.1",
      "documents": {
        "filing_index": "https://www.sec.gov/Archives/edgar/data/1543418/000127956926000946/0001279569-26-000946-index.htm",
        "press_release": "https://www.sec.gov/Archives/edgar/data/1543418/000127956926000946/ex991.htm",
        "exhibits": [
          {
            "url": "https://www.sec.gov/ix?doc=/Archives/edgar/data/1543418/000127956926000946/form8k.htm",
            "type": "8-K",
            "description": ""
          },
          {
            "url": "https://www.sec.gov/Archives/edgar/data/1543418/000127956926000946/ex991.htm",
            "type": "EX-99.1",
            "description": "NEWS RELEASE DATED OCTOBER 2, 2026"
          }
        ]
      },
      "period": {
        "fiscal_year": null,
        "fiscal_quarter": null,
        "period_end": "2026-08-31"
      }
    }
  ],
  "meta": {
    "pageSize": 50,
    "hasMore": true,
    "nextCursor": "eyJmaWxlZF9hdCI6ICIyMDI2LTA5LTI0VDIwOjA1OjI0KzAwOjAwIiwgImFjY2Vzc2lvbl9udW1iZXIiOiAiMDAwMTQ5MzE1Mi0yNi0wNDQxNDUifQ==",
    "parameters": {
      "limit": "50"
    },
    "time": 3627
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_filings_earnings

---

# Forex OHLCV Candles

> Returns OHLCV candlestick data for a currency pair.

`GET https://api.bavest.co/v2/forex/candles/{pair}`

Group: Forex. Route id: `v2_forex_candles_pair`. Included in: Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `pair` | path | string | yes | Currency pair (e.g., `EURUSD`, `GBPJPY`) Example `EURUSD`. |
| `resolution` | query | string | no | Candle resolution. One of `D`, `W`, `M`. Default `D`. |
| `from` | query | string (date) | yes | Start date (YYYY-MM-DD). Required for candle data. Example `2026-09-01`. |
| `to` | query | string (date) | yes | End date (YYYY-MM-DD). Required for candle data. Example `2026-09-30`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of ForexCandle | no |  |
| `data[].price` | number (double) | yes | Current price. Example: `1.1603`. |
| `data[].change` | number (double) \| null | no | Price change. Example: `-0.00054`. |
| `data[].changesPercentage` | number (double) \| null | no | Price change as a percentage. Example: `-0.04651804`. |
| `data[].dayHigh` | number (double) | no | Intraday high price. Example: `1.16456`. |
| `data[].dayLow` | number (double) | no | Intraday low price. Example: `1.15904`. |
| `data[].open` | number (double) | no | Opening price. Example: `1.16084`. |
| `data[].previousClose` | number (double) \| null | no | Previous session closing price. Example: `1.16084`. |
| `data[].timestamp` | string | yes | ISO 8601 timestamp. |
| `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/forex/candles/EURUSD?resolution=D&from=2026-09-01&to=2026-09-30' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "price": 1.16164,
      "change": -0.00061,
      "changesPercentage": -0.05248441,
      "timestamp": "2026-09-01T00:00:57",
      "dayLow": 1.16132,
      "dayHigh": 1.16225,
      "open": 1.16212,
      "previousClose": 1.16225
    },
    {
      "price": 1.16238,
      "change": 0.00013,
      "changesPercentage": 0.0111852,
      "timestamp": "2026-09-01T00:30:04",
      "dayLow": 1.16132,
      "dayHigh": 1.16279,
      "open": 1.16212,
      "previousClose": 1.16225
    }
  ],
  "meta": {
    "parameters": {
      "pair": "EURUSD",
      "from": "2026-09-01",
      "resolution": "D",
      "to": "2026-09-30"
    },
    "time": 3467
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_forex_candles_pair

---

# Forex Quote

> Returns real-time forex pair quote.

`GET https://api.bavest.co/v2/forex/quote/{pair}`

Group: Forex. Route id: `v2_forex_quote_pair`. Included in: Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `pair` | path | string | yes | Currency pair (e.g., `EURUSD`, `GBPJPY`) Example `EURUSD`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | ForexQuote | no | Real-time forex pair quote. |
| `data.symbol` | string | yes | Currency pair symbol. Example: `EURUSD`. |
| `data.price` | number (double) | yes | Current market price. Example: `1.15577`. |
| `data.change` | number (double) | no | Absolute price change from previous close. Example: `-0.00015`. |
| `data.changesPercentage` | number (double) | no | Percentage price change from previous close. Example: `-0.01297668`. |
| `data.dayHigh` | number (double) | no | Highest price during the trading day. Example: `1.15724`. |
| `data.dayLow` | number (double) | no | Lowest price during the trading day. Example: `1.15476`. |
| `data.open` | number (double) | no | Opening price for the trading day. Example: `1.1559`. |
| `data.previousClose` | number (double) | no | Previous trading day closing price. Example: `1.15592`. |
| `data.timestamp` | string (date-time) | no | Quote timestamp (ISO 8601) Example: `2026-03-30T11:59:59`. |
| `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/forex/quote/EURUSD' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "symbol": "EURUSD",
    "price": 1.1275,
    "change": 0.0030201,
    "changesPercentage": 0.26858,
    "open": 1.12435,
    "previousClose": 1.12448,
    "dayHigh": 1.12758,
    "dayLow": 1.12246,
    "timestamp": "2026-10-02T14:00:18"
  },
  "meta": {
    "parameters": {
      "pair": "EURUSD"
    },
    "time": 16
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_forex_quote_pair

---

# Fund Country Allocation

> Returns geographic exposure percentages.

`GET https://api.bavest.co/v2/funds/countries/{isin}`

Group: Funds. Route id: `v2_funds_countries_isin`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `isin` | path | string | yes | Fund ISIN code (e.g., `DE0009848119`) Example `DE0009848119`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.atDate` | string (date) | no | Observation date for the exposure data. |
| `data.countryExposure` | array of CountryExposure | no |  |
| `data.countryExposure[].country` | string | yes | Country name. Example: `United States`. |
| `data.countryExposure[].exposure` | number (double) | yes | Exposure percentage. Example: `97.57`. |
| `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/funds/countries/DE0009848119' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "countryExposure": [
      {
        "country": "Cash",
        "exposure": 0.5
      },
      {
        "country": "Netherlands",
        "exposure": 1.5
      }
    ],
    "atDate": "2026-08-31"
  },
  "meta": {
    "parameters": {
      "isin": "DE0009848119"
    },
    "time": 33
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_funds_countries_isin

---

# Fund Holdings

> Returns top holdings with exposure percentages.

`GET https://api.bavest.co/v2/funds/holdings/{isin}`

Group: Funds. Route id: `v2_funds_holdings_isin`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `isin` | path | string | yes | Fund ISIN code (e.g., `DE0009848119`) Example `DE0009848119`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.atDate` | string (date) | no | Observation date for the holdings data. |
| `data.holdings` | array of FundHolding | no |  |
| `data.holdings[].name` | string | no | Holding name. |
| `data.holdings[].exposure` | number | no | Allocation weight (percentage) |
| `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/funds/holdings/DE0009848119' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "holdings": [
      {
        "name": "Agnico Eagle Mines",
        "exposure": 3.7
      },
      {
        "name": "Taiwan Semiconduct. Manufact. Co",
        "exposure": 3.3
      }
    ],
    "atDate": "2026-08-31"
  },
  "meta": {
    "parameters": {
      "isin": "DE0009848119"
    },
    "time": 27
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_funds_holdings_isin

---

# Fund Metrics

> Returns all metrics for a fund in a single paginated response, with the latest observation per metric name.

`GET https://api.bavest.co/v2/funds/metrics`

Group: Funds. Route id: `v2_funds_metrics`. Included in: Pro, Growth.

## Description

Returns all metrics for a fund in a single paginated response, with the
latest observation per metric name.

Metric groups:
- NAV: latest net asset value per share in the quoted currency
- AUM: total fund assets under management, aggregated across all share
  classes of the fund
- Cumulative returns: YTD, 1M, 3M, 6M, 1Y, 3Y, 5Y, 10Y and since
  inception, in percent
- Annualized returns: 3Y, 5Y, 10Y and since inception, in percent
- Calendar year returns: `calendar_year_return_YYYY`, in percent
- Risk and cost metrics: volatility, Sharpe ratio, beta, alpha, information
  ratio, tracking error, max drawdown, TER, ongoing charges and SRI

Coverage varies by metric and fund. NAV and AUM cover most of the fund
universe. Performance returns are backfilled progressively and may be
unavailable for individual funds. The `date` field of each item states
the observation date of that value.

Use `fields` to select specific metrics by `metricId` or `metricName`.
The endpoint `/v2/funds/metrics/names` returns all valid metric names.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `isin` | query | string | yes | Fund ISIN code (e.g., `DE0009848119`) Example `DE0009848119`. |
| `fields` | query | string | no | Comma-separated list of metric names to include in the response. Valid names are served by `/v2/funds/metrics/names`. Example when explicitly filtering: `nav,aum,cumulative_return_5y,annualized_return_5y`. |
| `limit` | query | integer (int32) | no | Maximum number of metrics to return per page (default 50, max 200) Default `50`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.latestDate` | string (date) \| null | no | Most recent observation date across all metrics. Example: `2026-08-31`. |
| `data.metrics` | array of FundMetricItem | no |  |
| `data.metrics[].metricId` | string | yes | Machine-readable metric identifier (lowercase, e.g. nav, cumulative_return_1y) Example: `cumulative_return_1y`. |
| `data.metrics[].metricName` | string | yes | Metric name as stored in the database (lowercase, identical to metricId) Example: `cumulative_return_1y`. |
| `data.metrics[].date` | string (date) | no | Observation date of this metric value. Example: `2026-08-31`. |
| `data.metrics[].value` | number (double) \| null | yes | Metric value. Null when no value is available. Example: `12.4`. |
| `data.metrics[].valid` | boolean | yes | Whether the metric carries a value (false when value is null) Example: `true`. |
| `data.metrics[].unit` | string | no | Unit of measurement (MetricUnitModel value, uppercase) One of `CURRENCY`, `PERCENTAGE`, `RATIO`, `NUMERIC`. Example: `PERCENTAGE`. |
| `data.metrics[].currency` | string \| null | no | Currency code if the metric is currency-denominated (null for percentages) Example: `EUR`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/funds/metrics?isin=DE0009848119' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "latestDate": "2026-08-31",
    "metrics": [
      {
        "metricId": "aum",
        "metricName": "aum",
        "value": 24552928300,
        "date": "2026-07-31",
        "valid": true,
        "unit": "CURRENCY",
        "currency": "EUR"
      },
      {
        "metricId": "nav",
        "metricName": "nav",
        "value": 176.61,
        "date": "2026-08-31",
        "valid": true,
        "unit": "CURRENCY",
        "currency": "EUR"
      }
    ]
  },
  "meta": {
    "page": 1,
    "pageSize": 50,
    "totalPages": 1,
    "totalCount": 49,
    "parameters": {
      "isin": "DE0009848119",
      "limit": "50"
    },
    "time": 1177
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_funds_metrics

---

# Fund Metric Names

> Returns every metric name available on `/v2/funds/metrics`, with the unit and a description for each name.

`GET https://api.bavest.co/v2/funds/metrics/names`

Group: Funds. Route id: `v2_funds_metric_names`. Free in every plan, including the trial.

## Description

Returns every metric name available on `/v2/funds/metrics`, with the
unit and a description for each name. Metric families such as calendar
year returns are returned as name patterns. Any name that matches a
listed pattern is a valid metric name, for example
`calendar_year_return_2025`.

Use these names with the `fields` parameter of `/v2/funds/metrics`. The
vocabulary is versioned with the API. New metric names may be added over
time and additions are backward compatible.

No fund identifier is required.

## Parameters

None.

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.count` | integer | no | Number of exact metric names (name-pattern families are listed separately and not included in the count) Example: `51`. |
| `data.metrics` | array of object | no |  |
| `data.metrics[].name` | string | no | Canonical metric name (snake_case) Example: `cumulative_return_1y`. |
| `data.metrics[].unit` | string | no | Unit of measurement (MetricUnitModel value) One of `CURRENCY`, `PERCENTAGE`, `RATIO`, `NUMERIC`. Example: `PERCENTAGE`. |
| `data.metrics[].description` | string | no | Human-readable description of the metric. Example: `Total return over the trailing 1-year window`. |
| `data.patterns` | array of object | no | Metric-name families accepted in addition to the exact names. |
| `data.patterns[].pattern` | string | no | Regular expression the metric name must match. Example: `^calendar_year_return_(19|20)[0-9]{2}$`. |
| `data.patterns[].unit` | string | no | Unit of measurement (MetricUnitModel value) One of `CURRENCY`, `PERCENTAGE`, `RATIO`, `NUMERIC`. Example: `PERCENTAGE`. |
| `data.patterns[].description` | string | no | Human-readable description of the metric family. Example: `Calendar-year total return; the year is part of the metric name`. |
| `meta` | object | no | Response envelope metadata. |
| `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/funds/metrics/names' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "count": 52,
    "metrics": [
      {
        "name": "alpha_10y",
        "unit": "RATIO",
        "description": "Alpha vs. the peergroup benchmark, trailing 10 years (EUR basis)"
      },
      {
        "name": "alpha_1y",
        "unit": "RATIO",
        "description": "Alpha vs. the peergroup benchmark, trailing 1 year (EUR basis)"
      }
    ],
    "patterns": [
      {
        "pattern": "^calendar_year_return_(19|20)[0-9]{2}$",
        "unit": "PERCENTAGE",
        "description": "Calendar-year total return; the year is part of the metric name"
      }
    ]
  },
  "meta": {
    "time": 298
  }
}
```

## Errors

Also `401`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_funds_metric_names

---

# Fund Profile

> Returns mutual fund identity and classification.

`GET https://api.bavest.co/v2/funds/profile/{isin}`

Group: Funds. Route id: `v2_funds_profile_isin`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `isin` | path | string | yes | Fund ISIN code (e.g., `DE0009848119`) Example `DE0009848119`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.isin` | string | no | Fund ISIN code. Example: `DE0009848119`. |
| `data.name` | string | no | Fund name. |
| `data.fundCompany` | string | no | Fund management company. |
| `data.description` | string | no | Fund investment objective description. |
| `data.inceptionDate` | string (date) \| null | no | Fund inception date (yyyy-mm-dd) Example: `2003-04-28`. |
| `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/funds/profile/DE0009848119' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "isin": "DE0009848119",
    "name": "DWS Top Dividende LD",
    "description": "Der Fonds bietet eine Aktienanlage mit Chance auf laufenden Ertrag. Das Management investiert weltweit in Aktien, vorrangig hochkapitalisierte Werte, die eine höhere Dividendenrendite als der Marktdurchschnitt erwarten lassen. Seit Auflegung liegt die Dividendenrendite des Fondsportfolios bei durchschnittlich 4,0 bis 4,5 Prozent. Das bleibt auch in Zukunft Orientierungsgröße.",
    "fundCompany": "DWS Investment GmbH",
    "inceptionDate": "2003-04-28"
  },
  "meta": {
    "parameters": {
      "isin": "DE0009848119"
    },
    "time": 52
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_funds_profile_isin

---

# Fund Sector Allocation

> Returns sector exposure percentages.

`GET https://api.bavest.co/v2/funds/sectors/{isin}`

Group: Funds. Route id: `v2_funds_sectors_isin`. Included in: Pro, Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `isin` | path | string | yes | Fund ISIN code (e.g., `DE0009848119`) Example `DE0009848119`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.atDate` | string (date) | no | Observation date for the exposure data. |
| `data.sectorExposure` | array of SectorExposure | no |  |
| `data.sectorExposure[].sector` | string | yes | Sector name. Example: `Technology`. |
| `data.sectorExposure[].exposure` | number (double) | yes | Exposure percentage. Example: `35.62`. |
| `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/funds/sectors/DE0009848119' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "sectorExposure": [
      {
        "sector": "Communication Services",
        "exposure": 2.53
      },
      {
        "sector": "Financials",
        "exposure": 17.2
      }
    ],
    "atDate": "2026-10-01"
  },
  "meta": {
    "parameters": {
      "isin": "DE0009848119"
    },
    "time": 22
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `503`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_funds_sectors_isin

---

# Fund List

> Returns a paginated list of all mutual funds.

`GET https://api.bavest.co/v2/funds/list`

Group: Funds. Route id: `v2_funds_list`. Free in every plan, including the trial.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of FundListItem | no |  |
| `data[].isin` | string | yes | Fund ISIN. Example: `LU0342677829`. |
| `data[].name` | string | yes | Fund name. Example: `AGIF - Allianz Global Equity Unconstrained - A - EUR`. |
| `data[].fundCompany` | string \| null | no | Fund management company. Example: `Allianz Global Investors GmbH`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/funds/list' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "isin": "DE000DNA10Q7",
      "name": "10XDNA - Disruptive Technologies ex Crypto I-II",
      "fundCompany": "AXXION S.A."
    },
    {
      "isin": "DE000DNA10R5",
      "name": "10XDNA - Disruptive Technologies ex Crypto R",
      "fundCompany": "AXXION S.A."
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 333,
    "totalCount": 33262,
    "nextCursor": "eyJuYW1lIjogIkFCIEZDUCBJIC0gQW1lcmljYW4gSW5jb21lIFBvcnRmb2xpbyBBIiwgImlzaW4iOiAiTFUwMDQ0OTU3NzI3In0=",
    "parameters": {
      "limit": "100"
    },
    "time": 4
  }
}
```

## Errors

Also `400`, `401`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_funds_list

---

# Fund Asset Class Breakdown

> Returns asset-class allocation percentages based on holdings, including recursive look-through of underlying funds and ETFs.

`GET https://api.bavest.co/v2/funds/asset-class-breakdown/{isin}`

Group: Funds. Route id: `v2_funds_asset_class_breakdown`. Included in: Pro, Growth.

## Description

Returns asset-class allocation percentages based on holdings, including recursive look-through of underlying funds and ETFs. Preserves signed weights and reports missing or unclassified exposure as unknown.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `isin` | path | string | yes | Fund ISIN code (e.g., `DE0009848119`) Example `DE0009848119`. |

## Response

200 Holdings-based allocation including explicit unknown weight. (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.assetClassBreakdown` | array of object | yes |  |
| `data.assetClassBreakdown[].assetClass` | string | yes | One of `equity`, `fixed_income`, `cash_money_market`, `commodities`, `crypto`, `other`, `unknown`. |
| `data.assetClassBreakdown[].percent` | number | yes |  |
| `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/funds/asset-class-breakdown/DE0009848119' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "assetClassBreakdown": [
      {
        "assetClass": "equity",
        "percent": 80
      },
      {
        "assetClass": "fixed_income",
        "percent": 20
      }
    ]
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `503` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_funds_asset_class_breakdown

---

# Hot IPOs

> Returns the curated list of hot IPO offerings, each with an offering summary and a headline financials snapshot (latest full-year period).

`GET https://api.bavest.co/v2/ipo/hot`

Group: IPO. Route id: `v2_ipo_hot`. Included in: Growth.

## Description

Returns the curated list of hot IPO offerings, each with an offering
summary and a headline financials snapshot (latest full-year period).
Ordered by implied valuation descending, then public filing date
descending. Filter by `symbol`, `status`, or a `from`/`to` public-filing
date range. Supports offset and cursor pagination.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | no | Optional IPO ticker filter (e.g., `SPCX`). Omit for all offerings. |
| `status` | query | string | no | Filter by offering status (e.g. `Expected`, `Priced`, `Listed`). Example when explicitly filtering: `Expected`. |
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of HotIPORecord | no |  |
| `data[].symbol` | string | yes | Planned ticker symbol. Example: `SPCX`. |
| `data[].name` | string \| null | no | Company name. Example: `Space Exploration Technologies Corp.`. |
| `data[].exchange` | integer \| null | no | Target exchange identifier for the listing. |
| `data[].regulator` | string \| null | no | Filing regulator (e.g. `SEC`) Example: `SEC`. |
| `data[].filingType` | string \| null | no | Filing type (e.g. `S-1`) Example: `S-1`. |
| `data[].status` | string \| null | no | Offering status (e.g. `Expected`, `Priced`, `Listed`) Example: `Expected`. |
| `data[].priceType` | string \| null | no | Pricing mechanism (e.g. `fixed`, `range`) Example: `fixed`. |
| `data[].priceLow` | number (double) \| null | no | Lower bound of the expected price range. Example: `135`. |
| `data[].priceHigh` | number (double) \| null | no | Upper bound of the expected price range. Example: `135`. |
| `data[].currency` | string \| null | no | Offering currency (ISO 4217) Example: `USD`. |
| `data[].numberOfShares` | integer \| null | no | Number of shares offered. Example: `556600000`. |
| `data[].grossProceeds` | number (double) \| null | no | Expected gross proceeds. Example: `75141000000`. |
| `data[].impliedValuation` | number (double) \| null | no | Implied post-offering valuation. Example: `1750000000000`. |
| `data[].confidentialFilingDate` | string (date) \| null | no | Confidential filing date. Example: `2026-04-01`. |
| `data[].publicFilingDate` | string (date) \| null | no | Public filing date. Example: `2026-05-20`. |
| `data[].expectedListingDate` | string (date) \| null | no | Expected listing date, resolved from the listing milestone. Example: `2026-06-12`. |
| `data[].financialsSnapshot` | IPOFinancialsSnapshot \| null | no | Headline financials snapshot, or null when no financials exist. |
| `data[].financialsSnapshot.period` | string \| null | no | Reporting period label (e.g. `FY2025`) Example: `FY2025`. |
| `data[].financialsSnapshot.revenue` | number (double) \| null | no | Total revenue for the period. Example: `18674`. |
| `data[].financialsSnapshot.ebitdaAdjusted` | number (double) \| null | no | Adjusted EBITDA for the period. Example: `6584`. |
| `data[].financialsSnapshot.netIncome` | number (double) \| null | no | Net income for the period. Example: `-4940`. |
| `data[].financialsSnapshot.revenueYoY` | number (double) \| null | no | Year-over-year revenue growth (fraction, e.g. 0.3324 = 33.24%) Example: `0.3324`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/ipo/hot' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "symbol": "SPCX",
      "name": "Space Exploration Technologies Corp.",
      "exchange": null,
      "regulator": "SEC",
      "filingType": "S-1",
      "status": "Expected",
      "priceType": "fixed",
      "priceLow": 135,
      "priceHigh": 135,
      "currency": "USD",
      "numberOfShares": 556600000,
      "grossProceeds": 75141000000,
      "impliedValuation": 1750000000000,
      "confidentialFilingDate": "2026-04-01",
      "publicFilingDate": "2026-05-20",
      "expectedListingDate": "2026-06-12",
      "financialsSnapshot": {
        "period": "FY2025",
        "revenue": 18674,
        "ebitdaAdjusted": 6584,
        "netIncome": -4940,
        "revenueYoY": 0.3324
      }
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 1,
    "totalCount": 38,
    "parameters": {
      "limit": "100"
    },
    "time": 2437
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_ipo_hot

---

# IPO Documents

> Returns the document catalog for a single IPO (prospectus, SEC filings, multi-language prospectus summaries).

`GET https://api.bavest.co/v2/ipo/documents`

Group: IPO. Route id: `v2_ipo_documents`. Included in: Growth.

## Description

Returns the document catalog for a single IPO (prospectus, SEC filings,
multi-language prospectus summaries). The optional `language` parameter
filters documents to the requested language (only that language is
returned); the optional `type` parameter filters to a single document
type. Supports offset and cursor pagination.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | no | IPO ticker symbol (e.g., `SPCX` for SpaceX). Symbol only — ISIN is not supported for IPO endpoints. Example `SPCX`. |
| `language` | query | string | no | Filter documents to this language (ISO 639-1 / BCP-47). Only documents in the requested language are returned; omit for the full multi-language catalog. Example when explicitly filtering: `de`. |
| `type` | query | string | no | Filter to a single document type (e.g. `prospectus`, `sec_s1`, `prospectus_summary`). Example when explicitly filtering: `prospectus_summary`. |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of IPODocument | no |  |
| `data[].docType` | string | no | Document type key (e.g. `prospectus`, `sec_s1`, `prospectus_summary`) Example: `sec_s1`. |
| `data[].label` | string \| null | no | Localized document label. Example: `SEC S-1`. |
| `data[].language` | string \| null | no | Document language (ISO 639-1 / BCP-47) Example: `en`. |
| `data[].format` | string \| null | no | Document format. One of `pdf`, `html`. Example: `html`. |
| `data[].isPrimary` | boolean \| null | no | Whether this is the canonical language for its docType (used as fallback) Example: `true`. |
| `data[].url` | string \| null | no | Document URL, or null when not yet published. Example: `https://www.sec.gov/Archives/edgar/data/1181412/000162828026036936/spaceexplorationtechnologi.htm`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/ipo/documents?symbol=SPCX' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "docType": "prospectus",
      "label": "Prospectus",
      "language": "en",
      "format": "pdf",
      "isPrimary": true,
      "url": null
    },
    {
      "docType": "prospectus_summary",
      "label": "Prospectus Summary",
      "language": "en",
      "format": "pdf",
      "isPrimary": true,
      "url": null
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 1,
    "totalCount": 8,
    "parameters": {
      "limit": "100",
      "symbol": "SPCX"
    },
    "time": 2349
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_ipo_documents

---

# IPO Profile

> Returns the full profile for a single IPO: the offering summary plus nested milestones, statement-grouped financials (income statement, balance sheet, cash flow), and the document catalog.

`GET https://api.bavest.co/v2/ipo/profile`

Group: IPO. Route id: `v2_ipo_profile`. Included in: Growth.

## Description

Returns the full profile for a single IPO: the offering summary plus
nested milestones, statement-grouped financials (income statement,
balance sheet, cash flow), and the document catalog. Identify the IPO by
`symbol` or `isin`. Financials are sourced from the curated hot-IPO
financials and grouped per statement; each metric carries its fiscal
year/period, unit, currency, and a `valid` flag. Documents are served
separately by the /ipo/documents endpoint.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | no | IPO ticker symbol (e.g., `SPCX` for SpaceX). Symbol only — ISIN is not supported for IPO endpoints. Example `SPCX`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | IPOProfile | no | Full single-IPO detail — offering plus nested milestones and statement-grouped financials. Documents are served separately by the /ipo/documents endpoint. |
| `data.symbol` | string | yes | Example: `SPCX`. |
| `data.name` | string \| null | no | Example: `Space Exploration Technologies Corp.`. |
| `data.exchange` | integer \| null | no |  |
| `data.regulator` | string \| null | no | Example: `SEC`. |
| `data.filingType` | string \| null | no | Example: `S-1`. |
| `data.status` | string \| null | no | Example: `Expected`. |
| `data.priceType` | string \| null | no | Example: `fixed`. |
| `data.priceLow` | number (double) \| null | no | Example: `135`. |
| `data.priceHigh` | number (double) \| null | no | Example: `135`. |
| `data.currency` | string \| null | no | Example: `USD`. |
| `data.numberOfShares` | integer \| null | no | Example: `556600000`. |
| `data.grossProceeds` | number (double) \| null | no | Example: `75141000000`. |
| `data.impliedValuation` | number (double) \| null | no | Example: `1750000000000`. |
| `data.confidentialFilingDate` | string (date) \| null | no | Example: `2026-04-01`. |
| `data.publicFilingDate` | string (date) \| null | no | Example: `2026-05-20`. |
| `data.milestones` | array of IPOMilestone | no |  |
| `data.milestones[].stage` | string | no | Stage key. Example: `listing`. |
| `data.milestones[].label` | string \| null | no | Human-readable stage label. Example: `Day of IPO`. |
| `data.milestones[].startsAt` | string (date-time) \| null | no | Stage start timestamp (ISO-8601) |
| `data.milestones[].endsAt` | string (date-time) \| null | no | Stage end timestamp (ISO-8601) Example: `2026-06-10T19:00:00+02:00`. |
| `data.milestones[].expectedDate` | string (date) \| null | no | Expected date for the stage. Example: `2026-06-12`. |
| `data.milestones[].source` | string \| null | no | Provenance of the milestone. Example: `S-1`. |
| `data.financials` | IPOFinancials | no | Statement-grouped financials (income statement, balance sheet, cash flow) |
| `data.financials.incomeStatement` | array of IPOHotFinancialMetric | no | Income-statement metrics (revenue, costs, net income, EBITDA/EBIT, EPS, share counts) |
| `data.financials.incomeStatement[].metric_name` | string \| null | no | Metric identifier (e.g. `revenue`, `totalAssets`, `capex`, `eps`) Example: `revenue`. |
| `data.financials.incomeStatement[].value` | number (double) \| null | no | Metric value. Example: `18674000000`. |
| `data.financials.incomeStatement[].value_type` | string \| null | no | Value semantics. One of `currency`, `ratio`, `percentage`, `numeric`. Example: `currency`. |
| `data.financials.incomeStatement[].currency` | string \| null | no | ISO 4217 currency (null for non-currency metrics) Example: `USD`. |
| `data.financials.incomeStatement[].unit` | string \| null | no | Unit of the value (e.g. `USD`, `USD/share`, `shares`) Example: `USD`. |
| `data.financials.incomeStatement[].fiscal_year` | integer \| null | no | Fiscal year. Example: `2025`. |
| `data.financials.incomeStatement[].fiscal_period` | string \| null | no | Fiscal period. One of `FY`, `Q1`, `Q2`, `Q3`, `Q4`, `H1`, `H2`. Example: `FY`. |
| `data.financials.incomeStatement[].period_end_date` | string (date) \| null | no | Period end date. Example: `2025-12-31`. |
| `data.financials.incomeStatement[].source` | string \| null | no | Provenance of the figure. Example: `SpaceX EU retail prospectus summary, Bafin-approved 2026-06-05, section B.2`. |
| `data.financials.incomeStatement[].valid` | boolean | no | Whether the figure is considered valid (defaults to true) Example: `true`. |
| `data.financials.balanceSheet` | array of IPOHotFinancialMetric | no | Balance-sheet metrics (cash, total assets/liabilities, equity) |
| `data.financials.balanceSheet[].metric_name` | string \| null | no | Metric identifier (e.g. `revenue`, `totalAssets`, `capex`, `eps`) Example: `revenue`. |
| `data.financials.balanceSheet[].value` | number (double) \| null | no | Metric value. Example: `18674000000`. |
| `data.financials.balanceSheet[].value_type` | string \| null | no | Value semantics. One of `currency`, `ratio`, `percentage`, `numeric`. Example: `currency`. |
| `data.financials.balanceSheet[].currency` | string \| null | no | ISO 4217 currency (null for non-currency metrics) Example: `USD`. |
| `data.financials.balanceSheet[].unit` | string \| null | no | Unit of the value (e.g. `USD`, `USD/share`, `shares`) Example: `USD`. |
| `data.financials.balanceSheet[].fiscal_year` | integer \| null | no | Fiscal year. Example: `2025`. |
| `data.financials.balanceSheet[].fiscal_period` | string \| null | no | Fiscal period. One of `FY`, `Q1`, `Q2`, `Q3`, `Q4`, `H1`, `H2`. Example: `FY`. |
| `data.financials.balanceSheet[].period_end_date` | string (date) \| null | no | Period end date. Example: `2025-12-31`. |
| `data.financials.balanceSheet[].source` | string \| null | no | Provenance of the figure. Example: `SpaceX EU retail prospectus summary, Bafin-approved 2026-06-05, section B.2`. |
| `data.financials.balanceSheet[].valid` | boolean | no | Whether the figure is considered valid (defaults to true) Example: `true`. |
| `data.financials.cashFlow` | array of IPOHotFinancialMetric | no | Cash-flow metrics (capex, operating/investing/financing cash flow) |
| `data.financials.cashFlow[].metric_name` | string \| null | no | Metric identifier (e.g. `revenue`, `totalAssets`, `capex`, `eps`) Example: `revenue`. |
| `data.financials.cashFlow[].value` | number (double) \| null | no | Metric value. Example: `18674000000`. |
| `data.financials.cashFlow[].value_type` | string \| null | no | Value semantics. One of `currency`, `ratio`, `percentage`, `numeric`. Example: `currency`. |
| `data.financials.cashFlow[].currency` | string \| null | no | ISO 4217 currency (null for non-currency metrics) Example: `USD`. |
| `data.financials.cashFlow[].unit` | string \| null | no | Unit of the value (e.g. `USD`, `USD/share`, `shares`) Example: `USD`. |
| `data.financials.cashFlow[].fiscal_year` | integer \| null | no | Fiscal year. Example: `2025`. |
| `data.financials.cashFlow[].fiscal_period` | string \| null | no | Fiscal period. One of `FY`, `Q1`, `Q2`, `Q3`, `Q4`, `H1`, `H2`. Example: `FY`. |
| `data.financials.cashFlow[].period_end_date` | string (date) \| null | no | Period end date. Example: `2025-12-31`. |
| `data.financials.cashFlow[].source` | string \| null | no | Provenance of the figure. Example: `SpaceX EU retail prospectus summary, Bafin-approved 2026-06-05, section B.2`. |
| `data.financials.cashFlow[].valid` | boolean | no | Whether the figure is considered valid (defaults to true) Example: `true`. |
| `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/ipo/profile?symbol=SPCX' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "symbol": "SPCX",
    "name": "Space Exploration Technologies Corp.",
    "exchange": null,
    "regulator": "SEC",
    "filingType": "S-1",
    "status": "Expected",
    "priceType": "fixed",
    "priceLow": 135,
    "priceHigh": 135,
    "currency": "USD",
    "numberOfShares": 556600000,
    "grossProceeds": 75141000000,
    "impliedValuation": 1750000000000,
    "confidentialFilingDate": "2026-04-01",
    "publicFilingDate": "2026-05-20",
    "milestones": [
      {
        "stage": "subscription",
        "label": "Collecting subscriptions",
        "startsAt": null,
        "endsAt": "2026-06-10T17:00:00+00:00",
        "expectedDate": null,
        "source": "EU prospectus"
      },
      {
        "stage": "pricing",
        "label": "Setting price and allocation",
        "startsAt": null,
        "endsAt": null,
        "expectedDate": "2026-06-11",
        "source": "S-1"
      }
    ],
    "financials": {
      "incomeStatement": [
        {
          "metric_name": "accountsPayable",
          "value": 10002000000,
          "value_type": "currency",
          "currency": "USD",
          "unit": "USD",
          "fiscal_year": 2026,
          "fiscal_period": "Q1",
          "period_end_date": "2026-03-31",
          "source": "SpaceX prospectus (S-1) 2026-06-05, consolidated balance sheet",
          "valid": true
        },
        {
          "metric_name": "accountsPayable",
          "value": 11792000000,
          "value_type": "currency",
          "currency": "USD",
          "unit": "USD",
          "fiscal_year": 2025,
          "fiscal_period": "FY",
          "period_end_date": "2025-12-31",
          "source": "SpaceX prospectus (S-1) 2026-06-05, consolidated balance sheet",
          "valid": true
        }
      ],
      "balanceSheet": [
        {
          "metric_name": "cashAndCashEquivalents",
          "value": 15852000000,
          "value_type": "currency",
          "currency": "USD",
          "unit": "USD",
          "fiscal_year": 2026,
          "fiscal_period": "Q1",
          "period_end_date": "2026-03-31",
          "source": "SpaceX EU retail prospectus summary, Bafin-approved 2026-06-05, section B.2",
          "valid": true
        },
        {
          "metric_name": "cashAndCashEquivalents",
          "value": 24747000000,
          "value_type": "currency",
          "currency": "USD",
          "unit": "USD",
          "fiscal_year": 2025,
          "fiscal_period": "FY",
          "period_end_date": "2025-12-31",
          "source": "SpaceX EU retail prospectus summary, Bafin-approved 2026-06-05, section B.2",
          "valid": true
        }
      ],
      "cashFlow": [
        {
          "metric_name": "capex",
          "value": 10107000000,
          "value_type": "currency",
          "currency": "USD",
          "unit": "USD",
          "fiscal_year": 2026,
          "fiscal_period": "Q1",
          "period_end_date": "2026-03-31",
          "source": "SpaceX EU retail prospectus summary, Bafin-approved 2026-06-05, section B.2",
          "valid": true
        },
        {
          "metric_name": "capex",
          "value": 20737000000,
          "value_type": "currency",
          "currency": "USD",
          "unit": "USD",
          "fiscal_year": 2025,
          "fiscal_period": "FY",
          "period_end_date": "2025-12-31",
          "source": "SpaceX EU retail prospectus summary, Bafin-approved 2026-06-05, section B.2",
          "valid": true
        }
      ]
    }
  },
  "meta": {
    "parameters": {
      "symbol": "SPCX"
    },
    "time": 2314
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_ipo_profile

---

# Market News

> Returns market-wide financial news.

`GET https://api.bavest.co/v2/news/market`

Group: News. Route id: `v2_news_market`. Included in: Growth.

## Description

Returns market-wide financial news. Optionally filter by date range using `from` and `to` parameters.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `limit` | query | integer | no | Maximum number of articles to return (default 20, max 100) Default `20`. |
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of NewsArticle | no |  |
| `data[].symbol` | string \| null | no | Resolved ticker the article was matched to. Example: `AAPL`. |
| `data[].title` | string | no | Article headline. Example: `Apple Reports Record Q1 Revenue`. |
| `data[].text` | string | no | Article body or summary text. |
| `data[].site` | string | no | Publisher domain. Example: `benzinga.com`. |
| `data[].publishedDate` | string (date-time) | no | Publication date and time. |
| `data[].url` | string (uri) | no | Article URL. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/news/market' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "publishedDate": "2026-10-01T19:51:00",
      "title": "DOOR (OTC: LTCH) Resolves Final Legacy Matter, Completing Four-Year Turnaround of Its Financial Reporting and Legal Obligations",
      "site": "prnewswire.com",
      "text": "SEC settlement follows the filing of seven years of financial statements and resolution of four shareholder lawsuits; Company refocuses fully on profitability. ST. LOUIS, Oct. 1, 2026 /PRNewswire/ -- DOOR (OTC: LTCH), today announced that the Securities and Exchange Commission (the \"SEC\") has approved the Company's previously disclosed settlement, resolving the SEC's investigation.",
      "url": "https://www.prnewswire.com/news-releases/door-otc-ltch-resolves-final-legacy-matter-completing-four-year-turnaround-of-its-financial-reporting-and-legal-obligations-302896725.html"
    },
    {
      "publishedDate": "2026-10-01T19:43:15",
      "title": "Nike Q1: The Company Of The Past Is Gone",
      "site": "seekingalpha.com",
      "text": "Nike, Inc. remains unattractive despite a 76% five-year decline, still trading at 21x forward earnings. Q1 earnings revealed a 4% revenue decline, with significant weakness in Europe and Greater China; guidance was notably below consensus. Expense management improved margins, but increased 'demand creation' spending failed to stem revenue losses, highlighting execution and competitive challenges.",
      "url": "https://seekingalpha.com/article/4951482-nike-q1-the-company-of-the-past-is-gone"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 20,
    "totalPages": 2794,
    "totalCount": 55862,
    "parameters": {
      "limit": "20"
    },
    "time": 34
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_news_market

---

# Stock News

> Returns recent news articles for a specific stock.

`GET https://api.bavest.co/v2/news/stock`

Group: News. Route id: `v2_news_stock`. Included in: Growth.

## Description

Returns recent news articles for a specific stock. Optionally filter by date range using `from` and `to` parameters.

## 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. |
| `limit` | query | integer | no | Maximum number of articles to return (default 20, max 100) Default `20`. |
| `from` | query | string (date) | no | Start date (YYYY-MM-DD) |
| `to` | query | string (date) | no | End date (YYYY-MM-DD) |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of NewsArticle | no |  |
| `data[].symbol` | string \| null | no | Resolved ticker the article was matched to. Example: `AAPL`. |
| `data[].title` | string | no | Article headline. Example: `Apple Reports Record Q1 Revenue`. |
| `data[].text` | string | no | Article body or summary text. |
| `data[].site` | string | no | Publisher domain. Example: `benzinga.com`. |
| `data[].publishedDate` | string (date-time) | no | Publication date and time. |
| `data[].url` | string (uri) | no | Article URL. |
| `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/news/stock?symbol=AAPL' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "symbol": null,
      "publishedDate": "2026-09-27T15:45:00",
      "title": "Apple and Nvidia Are the Two Largest Companies in the World. Which is the Better Stock to Buy?",
      "site": "fool.com",
      "text": "Nvidia's growth rate will blow Apple away over the next year. Apple's stock is very pricey compared to Nvidia's.",
      "url": "https://www.fool.com/investing/2026/09/27/apple-nvidia-largest-companies-better-stock/"
    },
    {
      "symbol": null,
      "publishedDate": "2026-09-26T21:46:05",
      "title": "US jury says Apple owes record $5.7 billion in patent case against San Diego company",
      "site": "nypost.com",
      "text": "A US jury ruled that Apple owes Taction over $5.7 billion for infringing haptic technology patents in iPhones and Apple Watches.",
      "url": "https://nypost.com/2026/09/26/business/us-jury-says-apple-owes-record-5-7-billion-in-patent-case-against-san-diego-company/"
    }
  ],
  "meta": {
    "parameters": {
      "limit": "20",
      "symbol": "AAPL"
    },
    "time": 16
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_news_stock

---

# ADR List

> Returns a paginated list of all American Depositary Receipts (ADRs).

`GET https://api.bavest.co/v2/adrs/list`

Group: Reference. Route id: `v2_adrs_list`. Free in every plan, including the trial.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |
| `exchangeCode` | query | string | no | Filter by exchange short code (e.g. NASDAQ, NYSE) Example when explicitly filtering: `NASDAQ`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of SecurityListItem | no |  |
| `data[].isin` | string | no | ISIN identifier. Guaranteed to be ISO-6166-shaped, uppercase and trimmed; rows without a structurally valid ISIN are excluded. Example: `IE00B4L5Y983`. |
| `data[].symbol` | string | no | Ticker symbol. Example: `SPY`. |
| `data[].name` | string \| null | yes | Security name. Null when no name has been resolved from any source yet; the key is always present. Example: `SPDR S&P 500 ETF Trust`. |
| `data[].country` | string \| null | no | Country of domicile (ISO 3166-1 alpha-2) Example: `US`. |
| `data[].exchange` | string \| null | no | Exchange name. Example: `NASDAQ Global Market`. |
| `data[].exchangeCode` | string \| null | no | Exchange short code. Example: `NASDAQ`. |
| `data[].sector` | string \| null | no | Industry sector. Example: `Technology`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/adrs/list' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "isin": "US88025U1097",
      "symbol": "TXG",
      "name": "10x Genomics, Inc.",
      "country": "US",
      "exchange": "NASDAQ Global Select",
      "exchangeCode": "NASDAQ",
      "sector": "Healthcare"
    },
    {
      "isin": "US88025U1097",
      "symbol": "1KJ.TG",
      "name": "10x Genomics, Inc.",
      "country": null,
      "exchange": null,
      "exchangeCode": null,
      "sector": null
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 161,
    "totalCount": 16088,
    "nextCursor": "eyJuYW1lIjogIkFCIExhcmdlIENhcCBHcm93dGggRnVuZCBBZHZpc29yIENsYXNzIiwgImlzaW4iOiAiVVMwMTg3N0M0MDg3IiwgIl9pZCI6ICIwYzdiZjZjMS1mNzk3LTQ0MWItOTdkNS0zYTc4ZjE5ZTliMGIifQ==",
    "parameters": {
      "limit": "100"
    },
    "time": 5
  }
}
```

## Errors

Also `400`, `401`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_adrs_list

---

# Security List

> Returns a paginated list of all stock securities.

`GET https://api.bavest.co/v2/securities/list`

Group: Reference. Route id: `v2_securities_list`. Free in every plan, including the trial.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |
| `exchangeCode` | query | string | no | Filter by exchange short code (e.g. NASDAQ, NYSE) Example when explicitly filtering: `NASDAQ`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of SecurityListItem | no |  |
| `data[].isin` | string | no | ISIN identifier. Guaranteed to be ISO-6166-shaped, uppercase and trimmed; rows without a structurally valid ISIN are excluded. Example: `IE00B4L5Y983`. |
| `data[].symbol` | string | no | Ticker symbol. Example: `SPY`. |
| `data[].name` | string \| null | yes | Security name. Null when no name has been resolved from any source yet; the key is always present. Example: `SPDR S&P 500 ETF Trust`. |
| `data[].country` | string \| null | no | Country of domicile (ISO 3166-1 alpha-2) Example: `US`. |
| `data[].exchange` | string \| null | no | Exchange name. Example: `NASDAQ Global Market`. |
| `data[].exchangeCode` | string \| null | no | Exchange short code. Example: `NASDAQ`. |
| `data[].sector` | string \| null | no | Industry sector. Example: `Technology`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/securities/list' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "isin": "CA98955B1040",
      "symbol": "LNXGF",
      "name": "0187279 B.C. Ltd.",
      "country": "CA",
      "exchange": "Other OTC",
      "exchangeCode": "OTC",
      "sector": "Financial Services"
    },
    {
      "isin": "CA98956J1066",
      "symbol": "OONEF",
      "name": "01 Quantum Inc.",
      "country": "CA",
      "exchange": "Other OTC",
      "exchangeCode": "OTC",
      "sector": "Technology"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 777,
    "totalCount": 77641,
    "nextCursor": "eyJuYW1lIjogIjNEIEdsb2JhbCBCaW90ZWNoIEluYy4iLCAiaXNpbiI6ICJUVzAwMDY4MDgwMDkiLCAiX2lkIjogImQwMTAyNzFiLWU3NGQtNGMxZC1iNmM0LWI0NTEyMTMxYjJkNiJ9",
    "parameters": {
      "limit": "100"
    },
    "time": 5
  }
}
```

## Errors

Also `400`, `401`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_securities_list

---

# Delisted Securities List

> Returns a paginated list of delisted securities (lifecycle status 'delisted' — isActivelyTrading became false with no successor).

`GET https://api.bavest.co/v2/securities/delisted`

Group: Reference. Route id: `v2_securities_delisted`. Free in every plan, including the trial.

## Description

Returns a paginated list of delisted securities (lifecycle status 'delisted' — isActivelyTrading became false with no successor). Optionally filter by security type.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `type` | query | string | no | Filter by security type (e.g. EQUITY, ETF, ADR) Example when explicitly filtering: `EQUITY`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of DelistedSecurityListItem | no |  |
| `data[].isin` | string \| null | no | ISIN identifier. Example: `IE000TLLSP66`. |
| `data[].symbol` | string \| null | no | Ticker symbol. Example: `YI`. |
| `data[].name` | string | yes | Security name. Example: `111, Inc.`. |
| `data[].type` | string | no | Security type. Example: `EQUITY`. |
| `data[].exchange` | string \| null | no | Exchange the security traded on. Example: `NASDAQ`. |
| `data[].deprecatedAt` | string (date-time) \| null | no | When the security was marked delisted (ISO-8601, tz-aware) Example: `2026-05-21T12:16:43.824829+00:00`. |
| `data[].deprecationReason` | string \| null | no | Reason the row left active status. Example: `delisted`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/securities/delisted' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "isin": null,
      "symbol": "FBG",
      "name": "UBS AG FI Enhanced Big Cap Growth ETN",
      "type": "MUTUAL_FUND",
      "exchange": "NASDAQ",
      "deprecatedAt": "2026-09-22T07:02:08.021738+00:00",
      "deprecationReason": "delisted"
    },
    {
      "isin": "US4566771030",
      "symbol": "ZVAMIX",
      "name": "Infinity Core Alternative Fund",
      "type": "ADR",
      "exchange": "NASDAQ",
      "deprecatedAt": "2026-06-30T15:12:41.045839+00:00",
      "deprecationReason": "delisted"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 211,
    "totalCount": 21031,
    "parameters": {
      "limit": "100"
    },
    "time": 3343
  }
}
```

## Errors

Also `400`, `401`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_securities_delisted

---

# ISIN Change List

> Returns a paginated list of securities whose ISIN changed, with the old and new ISIN.

`GET https://api.bavest.co/v2/securities/isin-changed`

Group: Reference. Route id: `v2_securities_isin_changed`. Free in every plan, including the trial.

## Description

Returns a paginated list of securities whose ISIN changed, with the old and new ISIN. The old row was deprecated (deprecation_reason 'isin_changed') and superseded by a new active row for the same instrument. Optionally filter by security type.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `type` | query | string | no | Filter by security type (e.g. EQUITY, ETF, ADR) Example when explicitly filtering: `EQUITY`. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of IsinChangeListItem | no |  |
| `data[].oldIsin` | string \| null | no | Previous (deprecated) ISIN. Example: `US0079031078`. |
| `data[].newIsin` | string \| null | no | Current (successor) ISIN. Example: `US0079031115`. |
| `data[].symbol` | string \| null | no | Ticker symbol (the successor's, unchanged across an ISIN change) Example: `AMD`. |
| `data[].name` | string | yes | Security name. Example: `Advanced Micro Devices, Inc.`. |
| `data[].type` | string | no | Security type. Example: `EQUITY`. |
| `data[].exchange` | string \| null | no | Exchange the security trades on. Example: `NASDAQ`. |
| `data[].changedAt` | string (date-time) \| null | no | When the old row was deprecated / the ISIN change recorded (ISO-8601, tz-aware) Example: `2026-05-21T12:16:43.824829+00:00`. |
| `data[].deprecationReason` | string \| null | no | Reason the old row left active status. Example: `isin_changed`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/securities/isin-changed' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "oldIsin": "CA08662X4066",
      "newIsin": "CA08662X6046",
      "symbol": "SLVD.TO",
      "name": "BetaPro Silver -2x Daily Bear ETF",
      "type": "ETF",
      "exchange": "TSX",
      "changedAt": "2026-10-02T07:04:22.931218+00:00",
      "deprecationReason": "symbol_changed"
    },
    {
      "oldIsin": "TH0922B10Z07",
      "newIsin": "TH0922D10Z05",
      "symbol": "PSGC.BK",
      "name": "PSG Corporation Public Company Limited",
      "type": "EQUITY",
      "exchange": "SET",
      "changedAt": "2026-10-02T07:04:22.931218+00:00",
      "deprecationReason": "symbol_changed"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 32,
    "totalCount": 3127,
    "parameters": {
      "limit": "100"
    },
    "time": 6035
  }
}
```

## Errors

Also `400`, `401`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_securities_isin_changed

---

# Security Search

> Search across stocks, ETFs, funds, and crypto by name or ticker.

`GET https://api.bavest.co/v2/reference/search`

Group: Reference. Route id: `v2_reference_search`. Included in: Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `q` | query | string | yes | Search query (name, ticker, or ISIN) Example `Apple`. |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of SearchResult | no |  |
| `data[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `data[].type` | string | yes | Asset class of the security (e.g. EQUITY, ETF, ETP, MUTUAL_FUND, CLOSED_END_FUND, BOND, ADR, INDEX, CRYPTO_CURRENCY, CURRENCY, COMMODITY, CERTIFICATE). `EQUITY` und `STOCK` sind im Bestand beide vergeben und meinen dasselbe; die Suche vereinheitlicht sie zu `EQUITY` und stellt das urspruengliche `STOCK` in `subtype`. Example: `EQUITY`. |
| `data[].subtype` | string \| null | no | Feinere Klassifizierung, sofern vorhanden. Traegt unter anderem das urspruengliche `STOCK`, wenn `type` zu `EQUITY` vereinheitlicht wurde. `null`, wenn keine feinere Angabe vorliegt. Example: `STOCK`. |
| `data[].exchange` | string \| null | no | Primary listing exchange. `null`, wenn zu dem Papier keine Boerse gefuehrt wird, etwa bei OTC-Anleihen ohne Handelsplatz. Example: `NASDAQ`. |
| `data[].isin` | string \| null | no | ISIN code (if available) Example: `US0378331005`. |
| `data[].companyName` | string | no | Full company name. Example: `Leverage Shares 3x Apple ETC`. |
| `data[].isActivelyTrading` | boolean \| null | no | Whether the security is actively trading. `null`, wenn die Quelle dazu nichts sagt; das betrifft vor allem Publikumsfonds, fuer die kein Handelsstatus gefuehrt wird (z. B. LU0327386487). Example: `true`. |
| `data[].isAdr` | boolean | no | Whether the security is an American Depositary Receipt. Example: `false`. |
| `data[].isEtf` | boolean | no | Whether the security is an ETF. Example: `true`. |
| `data[].isFund` | boolean | no | Whether the security is a fund. Example: `false`. |
| `data[].isReit` | boolean \| null | no | Whether the company is a REIT (real estate investment trust): its industry starts with "REIT", e.g. Realty Income "REIT - Retail". Never true for ETFs or funds. `null` when no industry is known. Example: `false`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/reference/search?q=Apple' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": [
    {
      "symbol": "APC.DE",
      "companyName": "Apple Inc.",
      "isin": "US0378331005",
      "type": "ADR",
      "subtype": null,
      "isEtf": false,
      "isAdr": true,
      "isFund": false,
      "exchange": "XETRA",
      "isActivelyTrading": true
    },
    {
      "symbol": "AAPL",
      "companyName": "Apple Inc.",
      "isin": "US0378331005",
      "type": "EQUITY",
      "subtype": null,
      "isEtf": false,
      "isAdr": false,
      "isFund": false,
      "exchange": "NASDAQ",
      "isActivelyTrading": true
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 2,
    "totalCount": 104,
    "parameters": {
      "limit": "100",
      "q": "Apple"
    },
    "time": 4
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_reference_search

---

# Security Search Aggregated

> Returns aggregated search results grouped by security type.

`GET https://api.bavest.co/v2/reference/search/aggregated`

Group: Reference. Route id: `v2_reference_search_aggregated`. Included in: Growth.

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `q` | query | string | yes | Search query (name, ticker, or ISIN) Example `Tesla`. |
| `limit` | query | integer (int32) | no | Maximum number of results to return (default 100, max 1000) Default `100`. |
| `offset` | query | integer (int32) | no | Number of results to skip for pagination (default 0) Default `0`. |
| `cursor` | query | string | no | Opaque cursor for cursor-based pagination. When provided, returns results after the cursor position. Takes precedence over offset. |

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | object | no |  |
| `data.results` | array of object | no |  |
| `data.results[].name` | string | no | Security name. |
| `data.results[].listings` | array of SearchResult | no |  |
| `data.results[].listings[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `data.results[].listings[].type` | string | yes | Asset class of the security (e.g. EQUITY, ETF, ETP, MUTUAL_FUND, CLOSED_END_FUND, BOND, ADR, INDEX, CRYPTO_CURRENCY, CURRENCY, COMMODITY, CERTIFICATE). `EQUITY` und `STOCK` sind im Bestand beide vergeben und meinen dasselbe; die Suche vereinheitlicht sie zu `EQUITY` und stellt das urspruengliche `STOCK` in `subtype`. Example: `EQUITY`. |
| `data.results[].listings[].subtype` | string \| null | no | Feinere Klassifizierung, sofern vorhanden. Traegt unter anderem das urspruengliche `STOCK`, wenn `type` zu `EQUITY` vereinheitlicht wurde. `null`, wenn keine feinere Angabe vorliegt. Example: `STOCK`. |
| `data.results[].listings[].exchange` | string \| null | no | Primary listing exchange. `null`, wenn zu dem Papier keine Boerse gefuehrt wird, etwa bei OTC-Anleihen ohne Handelsplatz. Example: `NASDAQ`. |
| `data.results[].listings[].isin` | string \| null | no | ISIN code (if available) Example: `US0378331005`. |
| `data.results[].listings[].companyName` | string | no | Full company name. Example: `Leverage Shares 3x Apple ETC`. |
| `data.results[].listings[].isActivelyTrading` | boolean \| null | no | Whether the security is actively trading. `null`, wenn die Quelle dazu nichts sagt; das betrifft vor allem Publikumsfonds, fuer die kein Handelsstatus gefuehrt wird (z. B. LU0327386487). Example: `true`. |
| `data.results[].listings[].isAdr` | boolean | no | Whether the security is an American Depositary Receipt. Example: `false`. |
| `data.results[].listings[].isEtf` | boolean | no | Whether the security is an ETF. Example: `true`. |
| `data.results[].listings[].isFund` | boolean | no | Whether the security is a fund. Example: `false`. |
| `data.results[].listings[].isReit` | boolean \| null | no | Whether the company is a REIT (real estate investment trust): its industry starts with "REIT", e.g. Realty Income "REIT - Retail". Never true for ETFs or funds. `null` when no industry is known. Example: `false`. |
| `data.results[].root_ticker` | string | no | Primary ticker symbol. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl 'https://api.bavest.co/v2/reference/search/aggregated?q=Tesla' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "results": [
      {
        "name": "Tesla, Inc.",
        "listings": [
          {
            "symbol": "TL0.DE",
            "isin": "US88160R1014",
            "exchange": "XETRA",
            "type": "ADR",
            "isEtf": false,
            "isAdr": true,
            "isFund": false
          },
          {
            "symbol": "TSLA",
            "isin": "US88160R1014",
            "exchange": "NASDAQ",
            "type": "EQUITY",
            "isEtf": false,
            "isAdr": false,
            "isFund": false
          }
        ],
        "root_ticker": "TSLA"
      },
      {
        "name": "Tesla Exploration Ltd.",
        "listings": [
          {
            "symbol": "TXLZF",
            "isin": "CA8816011081",
            "exchange": "PNK",
            "type": "EQUITY",
            "isEtf": false,
            "isAdr": false,
            "isFund": false
          }
        ],
        "root_ticker": "TXLZF"
      }
    ]
  },
  "meta": {
    "page": 1,
    "pageSize": 100,
    "totalPages": 1,
    "totalCount": 45,
    "parameters": {
      "limit": "100",
      "q": "Tesla"
    },
    "time": 198
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_reference_search_aggregated

---

# Stock Screener

> Filter securities by financial metrics, profile attributes, valuation multiples, stability ratios, ESG scores, and more.

`POST https://api.bavest.co/v2/reference/screener`

Group: Reference. Route id: `v2_reference_screener_post`. Included in: Growth.

## Description

Filter securities by financial metrics, profile attributes, valuation multiples, stability ratios, ESG scores, and more. All query conditions are combined with AND. Results include the requested metric values alongside each security's symbol, name, and ISIN.

## Parameters

None.

## Request body

JSON, required.

| Field | Type | Always present | Description |
|---|---|---|---|
| `query` | array of ScreenerFilterItem | yes | List of filter conditions. All conditions are combined with AND logic. Each item specifies a metric, comparison operator, and threshold value. |
| `query[].metric` | string | yes | Short name for a screener metric. Resolved internally to an Elasticsearch field path. Alternatively, pass a raw dot-notation ES path directly (e.g., `profile.marketCapitalization`). Values: see `query[].metric` below. Example: `returnOnEquity`. |
| `query[].operator` | string | yes | Comparison operator. Use `eq` for exact string matches (e.g., sector, country). Numeric operators (`lt`, `gt`, `gte`, `lte`) for numeric fields. One of `lt`, `gt`, `gte`, `lte`, `eq`. Example: `gte`. |
| `query[].value` | number \| string \| boolean | yes | The value to compare against. Use a number for numeric metrics, a string for text fields (sector, country, industry, name, symbol) and a boolean for flags (`isReit`, with operator `eq`). Example: `10`. |
| `sort` | array of ScreenerSortItem | no | Optional list of sort criteria applied in order. When omitted results are returned in default Elasticsearch relevance order. |
| `sort[].metric` | string | yes | Short name for a screener metric. Resolved internally to an Elasticsearch field path. Alternatively, pass a raw dot-notation ES path directly (e.g., `profile.marketCapitalization`). Values: see `query[].metric` below. Example: `returnOnEquity`. |
| `sort[].order` | string | yes | Sort direction. One of `asc`, `desc`. Example: `desc`. |
| `offset` | integer | no | Pagination offset (number of results to skip). Example: `0`. |
| `limit` | integer | no | Maximum number of results to return. Example: `10`. |
| `currency` | string | no | Target currency for value conversion. When set, monetary metric values are converted to this currency. Example: `EUR`. |

### Values of `query[].metric`

- `name`: Company name (Category: Profile; ES Path: profile.name)
- `symbol`: Ticker symbol (Category: Profile; ES Path: profile.symbol)
- `isin`: ISIN identifier (Category: Profile; ES Path: profile.isin)
- `stockExchange`: Primary listing exchange (Category: Profile; ES Path: profile.exchangeShortName)
- `employeeTotal`: Total number of employees (Category: Profile; ES Path: profile.employeeTotal)
- `marketCapitalization`: Market cap (value x1 transform) (Category: Profile; ES Path: profile.marketCapitalization)
- `country`: Country of domicile (Category: Profile; ES Path: profile.country)
- `beta`: Beta coefficient (Category: Profile; ES Path: profile.beta)
- `industry`: Industry classification (Category: Profile; ES Path: profile.industry)
- `sector`: GICS sector (Category: Profile; ES Path: profile.sector)
- `price`: Current stock price (Category: Profile; ES Path: profile.price)
- `isReit`: REIT flag (boolean): FMP industry starts with "REIT", e.g. "REIT - Retail" (Category: Profile; ES Path: profile.isReit)
- `retainedEarnings`: Accumulated retained earnings (Category: Balance; ES Path: balance.retainedEarnings)
- `totalAssets`: Total assets (Category: Balance; ES Path: balance.totalAssets)
- `currentAssets`: Current assets (Category: Balance; ES Path: balance.currentAssets)
- `fixedAssets`: Fixed (non-current) assets (Category: Balance; ES Path: balance.fixedAssets)
- `totalCurrentLiabilities`: Total current liabilities (Category: Balance; ES Path: balance.totalCurrentLiabilities)
- `totalNonCurrentLiabilities`: Total non-current liabilities (Category: Balance; ES Path: balance.totalNonCurrentLiabilities)
- `longTermDebt`: Long-term debt (Category: Balance; ES Path: balance.longTermDebt)
- `totalLiabilities`: Total liabilities (Category: Balance; ES Path: balance.totalLiabilities)
- `totalEquity`: Total shareholders' equity (Category: Balance; ES Path: balance.totalEquity)
- `liabilitiesAndEquity`: Liabilities plus equity (Category: Balance; ES Path: balance.liabilitiesAndEquity)
- `operatingCashFlow`: Operating cash flow (Category: Cash flow; ES Path: cashflow.operatingCashFlow)
- `investingCashFlow`: Investing cash flow (Category: Cash flow; ES Path: cashflow.investingCashFlow)
- `financingCashFlow`: Financing cash flow (Category: Cash flow; ES Path: cashflow.financingCashFlow)
- `capitalExpenditure`: Capital expenditure (Category: Cash flow; ES Path: cashflow.capitalExpenditure)
- `freeCashFlow`: Free cash flow (Category: Cash flow; ES Path: cashflow.freeCashFlow)
- `netIncomeAfterTaxes`: Net income after taxes (Category: Income; ES Path: income.netIncomeAfterTaxes)
- `totalRevenue`: Total revenue (Category: Income; ES Path: income.totalRevenue)
- `grossIncome`: Gross income (Category: Income; ES Path: income.grossIncome)
- `ebit`: Earnings before interest and taxes (Category: Income; ES Path: income.ebit)
- `pretaxIncome`: Pre-tax income (Category: Income; ES Path: income.pretaxIncome)
- `ebitda`: EBITDA (Category: Income; ES Path: income.ebitda)
- `eps`: Earnings per share (Category: Income; ES Path: income.eps)
- `stockPrice`: Current stock price (quote) (Category: Quote; ES Path: quote.stockPrice)
- `shareOutstanding`: Shares outstanding (Category: Quote; ES Path: quote.shareOutstanding)
- `c`: Current price (Category: Quote; ES Path: quote.c)
- `dp`: Daily price change (%) (Category: Quote; ES Path: quote.dp)
- `environmentScore`: Environmental ESG score (Category: ESG; ES Path: esg.environmentScore)
- `governanceScore`: Governance ESG score (Category: ESG; ES Path: esg.governanceScore)
- `socialScore`: Social ESG score (Category: ESG; ES Path: esg.socialScore)
- `totalESGScore`: Combined ESG score (Category: ESG; ES Path: esg.totalESGScore)
- `dividendPerShare`: Dividend per share (Category: Metrics; ES Path: metric.dividendPerShare)
- `dividendPerShareAnnual`: Dividend per share (annual, alias) (Category: Metrics; ES Path: metric.dividendPerShare)
- `5DayPriceReturnDaily`: 5-day price return (Category: Metrics; ES Path: metric.5DayPriceReturnDaily)
- `13WeekPriceReturnDaily`: 13-week price return (Category: Metrics; ES Path: metric.13WeekPriceReturnDaily)
- `26WeekPriceReturnDaily`: 26-week price return (Category: Metrics; ES Path: metric.26WeekPriceReturnDaily)
- `52WeekPriceReturnDaily`: 52-week price return (Category: Metrics; ES Path: metric.1yearPriceReturnDaily)
- `roaRfy`: Return on assets (RFY) (Category: Metrics; ES Path: metric.roaRfy)
- `bookValuePerShareAnnual`: Book value per share (annual) (Category: Metrics; ES Path: metric.bookValuePerShareAnnual)
- `cashFlowPerShareAnnual`: Cash flow per share (annual) (Category: Metrics; ES Path: metric.cashFlowPerShareAnnual)
- `dividendYield5Y`: 5-year average dividend yield (Category: Metrics; ES Path: metric.dividendYield5Y)
- `dividendGrowthRate5Y`: 5-year dividend growth rate (Category: Metrics; ES Path: metric.dividendGrowthRate5Y)
- `epsGrowth3Y`: 3-year EPS growth (Category: Metrics; ES Path: metric.epsGrowth3Y)
- `epsGrowth5Y`: 5-year EPS growth (Category: Metrics; ES Path: metric.epsGrowth5Y)
- `capitalSpendingGrowth5Y`: 5-year capex growth (Category: Metrics; ES Path: metric.capitalSpendingGrowth5Y)
- `currentEv/freeCashFlowAnnual`: EV / FCF (annual) (Category: Metrics; ES Path: metric.currentEv/freeCashFlowAnnual)
- `currentEv/freeCashFlowTTM`: EV / FCF (TTM) (Category: Metrics; ES Path: metric.currentEv/freeCashFlowTTM)
- `revenueEmployeeAnnual`: Revenue per employee (annual) (Category: Metrics; ES Path: metric.revenueEmployeeAnnual)
- `revenueEmployeeTTM`: Revenue per employee (TTM) (Category: Metrics; ES Path: metric.revenueEmployeeTTM)
- `revenueGrowth3Y`: 3-year revenue growth (Category: Metrics; ES Path: metric.revenueGrowth3Y)
- `revenuePerShareAnnual`: Revenue per share (annual) (Category: Metrics; ES Path: metric.revenuePerShareAnnual)
- `revenuePerShareTTM`: Revenue per share (TTM) (Category: Metrics; ES Path: metric.revenuePerShareTTM)
- `revenueShareGrowth5Y`: 5-year revenue share growth (Category: Metrics; ES Path: metric.revenueShareGrowth5Y)
- `payoutRatioAnnual`: Payout ratio (annual) (Category: Metrics; ES Path: metric.payoutRatioAnnual)
- `payoutRatioTTM`: Payout ratio (TTM) (Category: Metrics; ES Path: metric.payoutRatioTTM)
- `performance`: Overall performance score (Category: Metrics; ES Path: metric.performance)
- `priceEarningsRatio`: P/E ratio (Category: Multiples; ES Path: fundamentals.multiples.priceEarningsRatio)
- `priceBookRatio`: P/B ratio (Category: Multiples; ES Path: fundamentals.multiples.priceBookRatio)
- `priceCashflowRatio`: P/CF ratio (Category: Multiples; ES Path: fundamentals.multiples.priceCashflowRatio)
- `priceSalesRatio`: P/S ratio (Category: Multiples; ES Path: fundamentals.multiples.priceSalesRatio)
- `ev/ebitda`: EV / EBITDA (Category: Multiples; ES Path: fundamentals.multiples.ev/ebitda)
- `ev/ebit`: EV / EBIT (Category: Multiples; ES Path: fundamentals.multiples.ev/ebit)
- `ev/fcf`: EV / Free Cash Flow (Category: Multiples; ES Path: fundamentals.multiples.ev/fcf)
- `ev`: Enterprise value (Category: Multiples; ES Path: fundamentals.multiples.ev)
- `ev/revenue`: EV / Revenue (Category: Multiples; ES Path: fundamentals.multiples.ev/revenue)
- `propertyPlantEquipment`: Fixed assets intensity (PP&E proxy) (Category: Multiples; ES Path: fundamentals.multiples.fixedAssetsIntensity)
- `ev/sales`: EV / Sales (Category: Multiples; ES Path: fundamentals.multiples.ev/sales)
- `equityRatio`: Equity ratio (Category: Stability; ES Path: fundamentals.stability.equityRatio)
- `debtRatio`: Total liabilities / total assets. Not total debt: `debt_to_assets` in financials.metrics is total debt / total assets (Category: Stability; ES Path: fundamentals.stability.debtRatio)
- `debtToEquityRatio`: Total liabilities / total equity. Not total debt: `debt_to_equity` in financials.metrics is total debt / total equity. Negative for negative equity, where `debt_to_equity` is null (Category: Stability; ES Path: fundamentals.stability.debtToEquityRatio)
- `dynamicLeverage`: Dynamic leverage ratio (Category: Stability; ES Path: fundamentals.stability.dynamicLeverage)
- `cataRatio`: Current assets to total assets (Category: Stability; ES Path: fundamentals.stability.cataRatio)
- `currentRatio`: Current ratio (Category: Stability; ES Path: fundamentals.stability.currentRatio)
- `fixedAssetIntensity`: Fixed asset intensity (Category: Stability; ES Path: fundamentals.stability.fixedAssetIntensity)
- `ppeRatio`: PP&E ratio (Category: Stability; ES Path: fundamentals.stability.ppeRatio)
- `assetCoverage1`: Asset coverage ratio (tier 1) (Category: Stability; ES Path: fundamentals.stability.assetCoverage1)
- `assetCoverage2`: Asset coverage ratio (tier 2) (Category: Stability; ES Path: fundamentals.stability.assetCoverage2)
- `cashRatio`: Cash ratio (Category: Stability; ES Path: fundamentals.stability.cashRatio)
- `quickRatio`: Quick ratio (Category: Stability; ES Path: fundamentals.stability.quickRatio)
- `returnOnEquity`: Return on equity (ROE) (Category: Profitability; ES Path: fundamentals.revenue.equityReturn)
- `salesReturn`: Return on sales (Category: Profitability; ES Path: fundamentals.revenue.salesReturn)
- `ebitMargin`: EBIT margin (Category: Profitability; ES Path: fundamentals.revenue.ebitMargin)
- `ebitdaMargin`: EBITDA margin (Category: Profitability; ES Path: fundamentals.revenue.ebitdaMargin)
- `capitalTurnover`: Capital turnover (Category: Profitability; ES Path: fundamentals.revenue.capitalTurnover)
- `assetsReturn`: Return on assets (Category: Profitability; ES Path: fundamentals.revenue.assetsReturn)
- `fundamentalScore`: Fundamental analysis score (Category: Scores; ES Path: score.fundamentalScore)
- `totalScore`: Composite total score (Category: Scores; ES Path: score.totalScore)
- `sentimentScore`: Market sentiment score (Category: Scores; ES Path: score.sentimentScore)

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | array of ScreenerResult | no |  |
| `data[].symbol` | string | yes | Ticker symbol. Example: `AAPL`. |
| `data[].name` | string | yes | Company name. Example: `Apple Inc`. |
| `data[].isin` | string | yes | ISIN identifier. Example: `US0378331005`. |
| `meta` | ResponseMeta | no | Response metadata for paginated endpoints. Offset pagination returns `page`/`pageSize`/`totalPages`/`totalCount`; cursor pagination returns `pageSize`/`hasMore`/`nextCursor` and `totalCount` only when known. |
| `meta.time` | integer | no | Server-side processing time in milliseconds. Example: `17`. |
| `meta.parameters` | object | no | Echo of the request parameters the endpoint resolved. |
| `meta.page` | integer | no | Current page number (offset pagination) Example: `1`. |
| `meta.pageSize` | integer | no | Number of results per page. Example: `50`. |
| `meta.totalPages` | integer | no | Total number of pages (offset pagination) Example: `2`. |
| `meta.totalCount` | integer | no | Total number of results across all pages. Example: `100`. |
| `meta.hasMore` | boolean | no | Whether more results follow (cursor pagination) |
| `meta.nextCursor` | string \| null | no | Cursor for the next page (cursor pagination), null on the last page. |

## Example request

```bash
curl -X POST 'https://api.bavest.co/v2/reference/screener' \
  -H "x-api-key: $BAVEST_API_KEY" \
  -H 'content-type: application/json' \
  --data '{"query":[{"metric":"returnOnEquity","operator":"gte","value":10},{"metric":"sector","operator":"eq","value":"Technology"},{"metric":"marketCapitalization","operator":"gte","value":1000000000}],"sort":[{"metric":"marketCapitalization","order":"desc"}],"offset":0,"limit":10}'
```

## Example response

```json
{
  "data": [
    {
      "symbol": "ASAN",
      "name": "Asana, Inc.",
      "isin": "US04342Y1047",
      "marketCapitalization": 2083961217,
      "returnOnEquity": 16.5541,
      "sector": "Technology"
    }
  ],
  "meta": {
    "page": 1,
    "pageSize": 10,
    "totalPages": 1,
    "totalCount": 1,
    "parameters": {
      "query": [
        {
          "metric": "returnOnEquity",
          "operator": "gte",
          "value": 10
        },
        {
          "metric": "sector",
          "operator": "eq",
          "value": "Technology"
        }
      ],
      "sort": [
        {
          "metric": "marketCapitalization",
          "order": "desc"
        }
      ],
      "offset": 0,
      "limit": 10
    },
    "time": 447
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_reference_screener_post

---

# Security NAV

> Returns the current Net Asset Value (NAV) for any security that has one.

`GET https://api.bavest.co/v2/securities/nav`

Group: Timeseries Data. Route id: `v2_securities_nav`. Included in: Growth.

## Description

Returns the current Net Asset Value (NAV) for any security that has one.

The endpoint looks up the security type from the Security table and routes
to the appropriate data source:
- **ETF / ETP / ETN** — ETF metrics table
- **MUTUAL_FUND** — Fund metrics table, else the ETF metrics table

Returns 404 for security types that do not carry a NAV (e.g. stocks).

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `symbol` | query | string | one of symbol, isin | ETF ticker symbol (e.g., `IWDA.AS`). Provide exactly one of symbol or isin; clear the ISIN example before using a symbol. |
| `isin` | query | string | one of symbol, isin | ETF ISIN code (e.g., `IE00B4L5Y983`, iShares Core MSCI World UCITS ETF). Provide exactly one of symbol or isin. Example `IE00B4L5Y983`. |

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

## Response

200 Successful response (`application/json`).

| Field | Type | Always present | Description |
|---|---|---|---|
| `data` | NavResponse | no | Net Asset Value for an ETF or mutual fund. |
| `data.nav` | number (double) | yes | Net Asset Value per share. Example: `664.88`. |
| `data.currency` | string | yes | NAV currency (ISO 4217) Example: `USD`. |
| `data.date` | string (date) | yes | NAV observation date. Example: `2025-10-17`. |
| `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/securities/nav?isin=IE00B4L5Y983' \
  -H "x-api-key: $BAVEST_API_KEY"
```

## Example response

```json
{
  "data": {
    "nav": 145.4398,
    "currency": "USD",
    "date": "2026-10-01"
  },
  "meta": {
    "parameters": {
      "isin": "IE00B4L5Y983"
    },
    "time": 12
  }
}
```

## Errors

Also `400`, `401`, `404`, `429`, `500`, `502`, `504`, `default` as listed under common errors at the top. Gateway `403` and `429` as described there.

HTML page: https://dashboard.bavest.co/docs/v2_securities_nav
