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

## Authentication

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

## Parameters

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

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

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

## Links

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