GET /v1/stocks
GET /v1/stocks
Returns paged listings from the canonical instrument universe. Useful for seeding a local catalog, building a screener pre-filter, or auditing coverage in a region you care about.
Request
GET /v1/stocks?exchange=NASDAQ&type=Common%20Stock HTTP/1.1Host: api.oneapi.financeAuthorization: Bearer oa_live_<your_key>Query parameters
| Param | Type | Required | Notes |
|---|---|---|---|
exchange | string | no | Canonical exchange code. See exchanges. |
country | string | no | ISO 3166 alpha-2. |
type | string | no | Common Stock | ETF | Mutual Fund | Index | Crypto | FX | Bond. |
status | string | no | active (default) | delisted | unknown | all. |
outputsize | int | no | Default 100. Cap 1,000. |
cursor | string | no | Continuation cursor from a prior response. |
Response
{ "instruments": [ { "symbol": "AAPL", "name": "Apple Inc.", "exchange": "NASDAQ", "mic": "XNAS", "type": "Common Stock", "country": "US", "currency": "USD", "isin": "US0378331005", "figi": "BBG000B9XRY4", "cik": "0000320193", "status": "active" } ], "next_cursor": "eyJsYXN0X3N5bWJvbCI6IkFBUEwifQ=="}Field reference
Top level:
| Field | Type | Notes |
|---|---|---|
instruments | array | Page of instrument rows. Order is stable across paginated calls. |
next_cursor | string | null | Pass back as cursor= to retrieve the next page. null when exhausted. |
Each instrument row mirrors the columns of the instruments table in our
schema. See the migration file
for the authoritative shape.
Pagination
Unlike the time-series endpoints, /v1/stocks uses cursor pagination because
the underlying universe is large enough that windowed queries do not make sense.
The cursor is opaque (do not parse it). Loop until next_cursor is null:
def all_us_common_stock(api_key: str): cursor = None while True: params = {"exchange": "NASDAQ", "type": "Common Stock", "outputsize": 1000} if cursor: params["cursor"] = cursor r = httpx.get( "https://api.oneapi.finance/v1/stocks", params=params, headers={"Authorization": f"Bearer {api_key}"}, timeout=30.0, ) r.raise_for_status() body = r.json() yield from body["instruments"] cursor = body.get("next_cursor") if cursor is None: breakExamples
# First page of NASDAQ common stockcurl -H "Authorization: Bearer oa_live_..." \ "https://api.oneapi.finance/v1/stocks?exchange=NASDAQ&type=Common%20Stock&outputsize=1000"
# All German listingscurl -H "Authorization: Bearer oa_live_..." \ "https://api.oneapi.finance/v1/stocks?country=DE&outputsize=1000"
# Including delistedcurl -H "Authorization: Bearer oa_live_..." \ "https://api.oneapi.finance/v1/stocks?exchange=NASDAQ&status=all"import httpx, os
HEADERS = {"Authorization": f"Bearer {os.environ['ONEAPI_KEY']}"}
def list_etfs(country: str = "US"): r = httpx.get( "https://api.oneapi.finance/v1/stocks", params={"country": country, "type": "ETF", "outputsize": 1000}, headers=HEADERS, timeout=30.0, ) r.raise_for_status() return r.json()["instruments"]async function* listInstruments(filter = {}) { let cursor = null; while (true) { const params = new URLSearchParams({ outputsize: "1000", ...filter }); if (cursor) params.set("cursor", cursor); const r = await fetch( `https://api.oneapi.finance/v1/stocks?${params}`, { headers: { Authorization: `Bearer ${process.env.ONEAPI_KEY}` } }, ); const body = await r.json(); for (const inst of body.instruments) yield inst; if (!body.next_cursor) break; cursor = body.next_cursor; }}Errors
| Status | code | When |
|---|---|---|
| 400 | bad_request | Unknown type or status. |
| 401 | unauthenticated | Missing or invalid API key. |
| 429 | rate_limit | See rate limits. |
See also
GET /v1/symbol_search— fuzzy lookup, when you only know a name.- Exchanges — canonical exchange codes.
- Instruments — the identifier landscape.