GET /v1/symbol_search
GET /v1/symbol_search
Resolves a free-text query to a ranked list of instruments. Useful for autocomplete, ticker disambiguation, and importing from a CSV that names companies inconsistently.
Request
GET /v1/symbol_search?query=apple HTTP/1.1Host: api.oneapi.financeAuthorization: Bearer oa_live_<your_key>Query parameters
| Param | Type | Required | Notes |
|---|---|---|---|
query | string | yes | Free text. Matches ticker, name, ISIN, FIGI, CIK. |
limit | int | no | Max results. Default 10, cap 50. |
country | string | no | ISO 3166 alpha-2 to restrict results. |
type | string | no | Restrict by instrument type (Common Stock, ETF, Index). |
Response
{ "symbols": [ { "symbol": "AAPL", "name": "Apple Inc.", "exchange": "NASDAQ", "type": "Common Stock", "country": "US", "currency": "USD", "isin": "US0378331005", "figi": "BBG000B9XRY4", "score": 0.98 }, { "symbol": "APC.DE", "name": "Apple Inc.", "exchange": "XETR", "type": "Common Stock", "country": "DE", "currency": "EUR", "isin": "US0378331005", "figi": "BBG000B9XQB4", "score": 0.85 } ]}Field reference
| Field | Type | Notes |
|---|---|---|
symbols | array | Ranked descending by score. |
symbols[].symbol | string | Ticker, with Yahoo suffix where applicable. |
symbols[].name | string | null | Display name. |
symbols[].exchange | string | null | Canonical exchange code. |
symbols[].type | string | null | Common Stock | ETF | Mutual Fund | Index | Crypto | FX | Bond. |
symbols[].country | string | null | ISO 3166 alpha-2. |
symbols[].currency | string | null | ISO 4217. |
symbols[].isin | string | null | |
symbols[].figi | string | null | |
symbols[].score | number | null | Relevance, 0..1. Higher is better. Useful as a confidence threshold. |
The wire-format models are
SymbolSearchResult, SymbolSearchResponse.
How matching works
The endpoint runs a hybrid search:
- Exact match on
symbol,isin,figi, orcikalways wins. - Trigram match on
symbolandnameprovides fuzzy results for typos and partial names. - Vector similarity (sentence-transformers MiniLM-L6-v2 embeddings stored in pgvector) catches semantic matches like “the iPhone company” → AAPL.
The score column reflects the combined ranking. For autocomplete UIs, treat
results below score = 0.5 with skepticism.
Examples
# Free textcurl -H "Authorization: Bearer oa_live_..." \ "https://api.oneapi.finance/v1/symbol_search?query=apple"
# By ISINcurl -H "Authorization: Bearer oa_live_..." \ "https://api.oneapi.finance/v1/symbol_search?query=US0378331005"
# Restrict to German listingscurl -H "Authorization: Bearer oa_live_..." \ "https://api.oneapi.finance/v1/symbol_search?query=BMW&country=DE"import httpx, os
def find(query: str, limit: int = 5): r = httpx.get( "https://api.oneapi.finance/v1/symbol_search", params={"query": query, "limit": limit}, headers={"Authorization": f"Bearer {os.environ['ONEAPI_KEY']}"}, timeout=10.0, ) r.raise_for_status() return r.json()["symbols"]
for hit in find("the iPhone company"): print(f"{hit['symbol']:<10} {hit['name']:<30} score={hit['score']:.2f}")async function searchSymbols(query, limit = 5) { const r = await fetch( `https://api.oneapi.finance/v1/symbol_search?query=${encodeURIComponent(query)}&limit=${limit}`, { headers: { Authorization: `Bearer ${process.env.ONEAPI_KEY}` } }, ); if (!r.ok) throw new Error(`HTTP ${r.status}`); return (await r.json()).symbols;}Errors
| Status | code | When |
|---|---|---|
| 400 | bad_request | Empty query, or limit > 50. |
| 401 | unauthenticated | Missing or invalid API key. |
| 429 | rate_limit | See rate limits. |
/v1/symbol_search does not return 404. An empty match list is a valid
response: {"symbols": []}.
See also
- Instruments — what the identifiers mean.
GET /v1/profile— once you have a symbol, get the full profile.