When a company is acquired, goes bankrupt, or is otherwise removed from an exchange, its ticker stops trading — but its price history, fundamentals, dividends and splits stay in EODHD. You can list every delisted symbol on an exchange and then query it with the same endpoints you use for active tickers. This is what makes survivorship-bias-free backtesting and long-horizon research possible.
Working with delisted data is a two-step job: find the ticker in the exchange symbol list, then query the regular data endpoints with it. The traps are all in step one — the ticker you remember may now belong to a different company.
Scope at a glance. Delisted symbols are listed per exchange with the delisted=1 flag, and every exchange we cover has them — 60,191 on US alone, 9,587 on Frankfurt, 4,077 on the LSE (September 2026). Once you have a code, the End-of-Day, Fundamentals, Dividends, Splits and Intraday endpoints behave exactly as they do for active tickers. Listing the symbols costs 1 API call.
Step 1 — List Delisted Tickers
Use the Exchange Symbol List endpoint with delisted=1. It returns only the inactive symbols for that exchange; without the flag, or with delisted=0, you get only the active ones. The exchange code goes in the path — US covers the combined US exchanges.
https://eodhd.com/api/exchange-symbol-list/{EXCHANGE}?delisted=1&api_token=YOUR_API_TOKEN
Method GET. Authentication by api_token. The default output is CSV; add fmt=json for a JSON array.
Parameters
api_token
string
required
delisted
enum
optional
type
enum
optional
fmt
enum
optional
Request Example
https://eodhd.com/api/exchange-symbol-list/US?delisted=1&type=common_stock&api_token=YOUR_API_TOKEN&fmt=json
curl --location "https://eodhd.com/api/exchange-symbol-list/US?delisted=1&type=common_stock&api_token=YOUR_API_TOKEN&fmt=json"
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://eodhd.com/api/exchange-symbol-list/US?delisted=1&type=common_stock&api_token=YOUR_API_TOKEN&fmt=json',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$data = curl_exec($curl);
curl_close($curl);
try {
$data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
var_dump($data);
} catch (Exception $e) {
echo 'Error. '.$e->getMessage();
}
import requests
url = f'https://eodhd.com/api/exchange-symbol-list/US?delisted=1&type=common_stock&api_token=YOUR_API_TOKEN&fmt=json'
data = requests.get(url).json()
print(data)
library(httr)
library(jsonlite)
url <- 'https://eodhd.com/api/exchange-symbol-list/US?delisted=1&type=common_stock&api_token=YOUR_API_TOKEN&fmt=json'
response <- GET(url)
if (http_type(response) == "application/json") {
content <- content(response, "text", encoding = "UTF-8")
cat(content)
} else {
cat("Error while receiving data\n")
}
Try it now (it's free)!
How to use it (YouTube)
Response Example
Two rows from the delisted common stocks on US — one from 2003, one from 2023:
[
{
"Code": "AAAB",
"Name": "Admiralty Bancorp Inc",
"Country": "USA",
"Exchange": "NASDAQ",
"Currency": "USD",
"Type": "Common Stock",
"Isin": null
},
{
"Code": "ATVI",
"Name": "Activision Blizzard Inc",
"Country": "USA",
"Exchange": "NASDAQ",
"Currency": "USD",
"Type": "Common Stock",
"Isin": "US00507V1098"
}
]
Response Fields
| Field | Type | Description |
|---|---|---|
| Code | string | Ticker symbol code, without the exchange suffix |
| Name | string | Company or instrument name |
| Country | string | Country of the exchange |
| Exchange | string | Exchange the ticker was listed on |
| Currency | string | Trading currency |
| Type | string | Instrument type, for example Common Stock, FUND, ETF or Preferred Stock |
| Isin | string or null | ISIN code, if available |
How the type Filter Groups Instruments
The five allowed values are groups, not literal Type strings. On the US delisted list they break down like this:
| type= | Type values it returns | Rows on US |
|---|---|---|
| common_stock | Common Stock | 33,051 |
| preferred_stock | Preferred Stock | 1,241 |
| stock | Common Stock and Preferred Stock | 34,292 |
| etf | ETF and ETC | 3,014 |
| fund | FUND and Mutual Fund | 22,484 |
| (omitted) | everything | 60,191 |
The groups do not cover the whole list. 401 US rows are typed Unit, Notes, Warrant, BOND or UNIT, and no value of the type parameter returns them. Omit the parameter and filter client-side if you need those.
Delisted Coverage by Exchange
Delisted symbols are not a US-only feature. A sample of exchange codes, measured in September 2026:
| Exchange code | Market | Delisted symbols |
|---|---|---|
| US | All US exchanges | 60,191 |
| F | Frankfurt | 9,587 |
| BE | Berlin | 8,077 |
| LSE | London | 4,077 |
| AU | Australia | 2,038 |
| V | TSX Venture | 2,022 |
| XETRA | Xetra | 1,768 |
| SW | SIX Swiss | 1,715 |
| TO | Toronto | 1,656 |
| PA | Euronext Paris | 1,362 |
| NSE | India NSE | 940 |
| HK | Hong Kong | 806 |
The full list of exchange codes is in the Exchanges API.
Reused Tickers and the _old Convention
This is the single biggest trap in delisted data, and it fails silently. When a ticker is freed up and later assigned to a different company, EODHD keeps the original company under the same code with an _old suffix. The bare code belongs to whoever holds it today.
| You ask for | You actually get | The company you meant is at |
|---|---|---|
| APC.US | ARKO Petroleum Corp — active, NASDAQ | APC_old.US — Anadarko Petroleum, delisted 2019-08-08 |
| STI.US | Solidion Technology Inc. — active, NASDAQ | STI_old.US — SunTrust Banks, delisted 2019-12-06 |
| PCLN.US | Pictet Cleaner Planet ETF — active, NYSE ARCA | PCLN_old.US — Booking Holdings, formerly Priceline |
| BITA.US | not the Chinese car portal | BITA_old.US — Bitauto Holdings |
Nothing about this is an error. A request for APC.US returns HTTP 200 and a clean price series — it just starts in 2026 and belongs to ARKO Petroleum, not Anadarko. If your backtest quietly loses a company’s history and gains a short, unrelated series, this is why.
1,778 codes on the US delisted list carry the _old suffix. A few use a trailing digit instead, such as TWX1 alongside TWX. The safe pattern is to resolve the company against the delisted symbol list rather than typing a remembered ticker: search the list by Name or Isin, and use the Code it gives you.
Step 2 — Get the Data for a Delisted Ticker
Once you have the code, query the regular endpoints. A delisted ticker keeps its full history up to the delisting date, and nothing about the request changes.
| Data | Endpoint | API calls |
|---|---|---|
| End-of-day prices | /api/eod/{TICKER} | 1 |
| Fundamentals | /api/fundamentals/{TICKER} | 10 |
| Dividends | /api/div/{TICKER} | 1 |
| Splits | /api/splits/{TICKER} | 1 |
| Intraday | /api/intraday/{TICKER} | 5 |
Request Example
End-of-day prices for ATVI.US — Activision Blizzard, delisted on 13 October 2023 after Microsoft completed the acquisition. The request returns 7,487 daily bars going back to 25 October 1993.
https://eodhd.com/api/eod/ATVI.US?api_token=YOUR_API_TOKEN&fmt=json
curl --location "https://eodhd.com/api/eod/ATVI.US?api_token=YOUR_API_TOKEN&fmt=json"
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://eodhd.com/api/eod/ATVI.US?api_token=YOUR_API_TOKEN&fmt=json',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$data = curl_exec($curl);
curl_close($curl);
try {
$data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
var_dump($data);
} catch (Exception $e) {
echo 'Error. '.$e->getMessage();
}
import requests
url = f'https://eodhd.com/api/eod/ATVI.US?api_token=YOUR_API_TOKEN&fmt=json'
data = requests.get(url).json()
print(data)
library(httr)
library(jsonlite)
url <- 'https://eodhd.com/api/eod/ATVI.US?api_token=YOUR_API_TOKEN&fmt=json'
response <- GET(url)
if (http_type(response) == "application/json") {
content <- content(response, "text", encoding = "UTF-8")
cat(content)
} else {
cat("Error while receiving data\n")
}
Try it now (it's free)!
How to use it (YouTube)
Response Example
The oldest bar and the final two:
[
{
"date": "1993-10-25",
"open": 1.25,
"high": 1.25,
"low": 0.9375,
"close": 0.9375,
"adjusted_close": 0.0686,
"volume": 18000
},
...
{
"date": "2023-10-12",
"open": 94.48,
"high": 94.54,
"low": 94.305,
"close": 94.42,
"adjusted_close": 94.42,
"volume": 7325799
},
{
"date": "2023-10-13",
"open": 94.42,
"high": 94.42,
"low": 94.42,
"close": 94.42,
"adjusted_close": 94.42,
"volume": 0
}
]
The last bar of a delisted series is usually a stub: open, high, low and close all equal the final settlement price and volume is 0. Treat it as the delisting marker, not as a trading day — a returns calculation that includes it will see a zero-volume bar, and a liquidity filter will drop it.
Intraday Needs an Explicit Date Range
The Intraday API defaults to a recent window. For a delisted ticker that window sits entirely after the last trade, so a request without from and to returns an empty array with HTTP 200 — which looks like missing data but is not. Pass Unix timestamps that cover the period you actually want.
https://eodhd.com/api/intraday/ATVI.US?interval=5m&from=1696118400&to=1697241600&api_token=YOUR_API_TOKEN&fmt=json
How far back intraday reaches depends on the interval, not on when the ticker was delisted. The 1-minute series goes back furthest; 5-minute and 1-hour start around October 2020. Measured on delisted tickers:
| Ticker | Last traded | 1m | 5m | 1h |
|---|---|---|---|---|
| MYL.US | 2020-11-18 | yes | yes | yes |
| WCG.US | 2020-01-23 | yes | no | no |
| RTN.US | 2020-04-02 | yes | no | no |
| RHT.US | 2019-07-08 | yes | no | no |
| ESRX.US | 2018-12-20 | no | no | no |
| LEH.US | 2008-09-17 | no | no | no |
Full parameters and interval rules are on the Intraday Historical Data API page.
Confirming a Ticker Is Delisted
The Fundamentals response carries the status in its General section.
| Field | Use it for |
|---|---|
| General.IsDelisted | Reliable true or false. This is the field to branch on |
| General.DelistedDate | Approximate. Exact for cleanly processed delistings, but see the warning below |
| General.UpdatedAt | When the record was last touched. Not the delisting date — ATVI shows 2023-12-10, two months after it stopped trading |
Do not trust DelistedDate on its own. For tickers that stop trading quietly rather than through a processed corporate action, the field is stamped with the date we flagged them, which can be today. SIVBQ.US reports a DelistedDate of 2026-09-17 but its last price bar is 2024-11-07; CITEW.US reports the same date against a last bar of 2025-01-10. The date of the final end-of-day bar is the authoritative last-traded date — take it from the EOD response and cross-check.
What Data Exists, by Era
How much you get depends on how long ago the company left the exchange. Fundamentals are the dividing line: for older delistings the endpoint still answers with HTTP 200, but returns a 2 KB stub with little more than the name and exchange, rather than the full 400 KB-plus record.
| Delisted | End-of-day | Fundamentals | Dividends and splits | Intraday |
|---|---|---|---|---|
| 2019 onwards | Full history | Full record | Yes | 1m; 5m and 1h from late 2020 |
| 2018 and earlier | Full history | Stub only | Rarely | No |
Worked examples, all verified against the live API:
| Ticker | Delisted | EOD bars | Fundamentals | Dividends | Splits |
|---|---|---|---|---|---|
| ATVI.US | 2023-10-13 | 7,487 | 726 KB | 14 | 8 |
| TWTR.US | 2022-10-28 | 2,259 | 284 KB | 0 | 0 |
| TIF.US | 2021-01-08 | 8,489 | 475 KB | 131 | 4 |
| RTN.US | 2020-04-03 | 5,600 | 449 KB | 87 | 3 |
| CELG.US | 2019-11-22 | 8,135 | 437 KB | 0 | 4 |
| LEH.US | 2008-09-17 | 2,695 | 2 KB stub | 0 | 0 |
| AAAB.US | 2003-01-29 | 1,023 | 2 KB stub | 0 | 0 |
A zero in the dividends column is not always a gap — CELG.US and TWTR.US never paid one. If you need to confirm coverage for a specific ticker before you build on it, ask support.
Renamed, Not Delisted
A ticker you cannot find is not always a delisting. After a merger or a rebrand the company keeps trading under a new code, and the old one disappears from the active symbol list without ever reaching the delisted one. Check the US Stock Symbol Rename History API before you conclude that a company is gone — it maps old symbols to new ones for US exchanges, and its page carries the full parameter reference.
The same endpoint also explains where a reused ticker came from. Solidion Technology took over the STI code in February 2024, which is why SunTrust’s history now lives at STI_old.US:
{
"exchange": "US",
"old_symbol": "NUBI",
"new_symbol": "STI",
"company_name": "Solidion Technology, Inc. Common Stock",
"effective": "2024-02-05"
}
Three practical notes when you query it alongside delisted data. Send from and to together or send neither — sending to on its own currently returns HTTP 500, while omitting both returns the trailing twelve months, which is the useful default. The ex parameter accepts US only; any other exchange returns an empty array rather than an error. And the endpoint answers in JSON whatever you pass in fmt.
Why Delisted Data Matters
A dataset that holds only currently listed companies suffers from survivorship bias. The failures, the bankruptcies and the takeovers are missing, so measured historical returns are too high and backtests are too kind. On US alone that is 60,191 symbols absent from an actives-only universe — including every bank that did not survive 2008 and every company acquired since.
Rebuilding a point-in-time universe means taking the delisted list for the exchange, keeping each symbol in the universe up to its last traded bar, and letting it drop out afterwards rather than deleting it from history. For whole-exchange daily snapshots rather than per-symbol requests, the Bulk API covers an entire exchange in one call.
Errors
| Code | Meaning | When it happens |
|---|---|---|
| 401 | Unauthenticated | The api_token is missing or invalid |
| 403 | Forbidden | The token is valid but not entitled to that data. The demo key returns this for every endpoint on this page |
| 404 | Exchange Not Found / Ticker Not Found | Unknown exchange code, or a symbol that exists on neither the active nor the delisted list |
| 422 | Validation error | An invalid type value or a malformed date. The body names the offending parameter and the allowed values |
| 500 | Server error | Currently returned by Symbol Change History when to is sent without from |
| 200 | Empty array | Not an error. Intraday without a date range, or Symbol Change History with a non-US exchange |
Plans and API Calls
There is no separate delisted-data subscription. Listing the symbols is part of the Exchanges API, and each data endpoint is billed and gated exactly as it is for active tickers — a delisted ticker costs the same as a live one. The full accounting of calls, requests and daily limits is on the API Limits page, and the live counter for your own account is on the dashboard.
| Step | Endpoint | API calls | Included in |
|---|---|---|---|
| List delisted symbols | Exchange Symbol List | 1 | All plans |
| Price history | End-of-Day | 1 | All-In-One, EOD Historical Data, EOD+Intraday, Free (1 year only) |
| Fundamentals | Fundamentals | 10 | All-In-One, Fundamentals Data Feed |
| Dividends, splits | Dividends, Splits | 1 each | All-In-One, EOD Historical Data, EOD+Intraday, Free (1 year only) |
| Intraday bars | Intraday | 5 | All-In-One, EOD+Intraday All World Extended |
| Renames | Symbol Change History | 1 | All plans |
The free plan is a poor fit for this particular job. It caps history at one year and allows 20 API calls a day, so you can list the delisted symbols but cannot pull the history of anything that stopped trading more than a year ago — which is most of the list. Full limits are on the API Limits page.
Related APIs
- Exchanges API — every exchange code, and the active symbol lists the delisted flag toggles away from.
- US Stock Symbol Rename History API — full reference for the rename feed, including its own parameters and response fields.
- End-of-Day Historical Data API — periods, date ranges and the adjustment rules behind the price series.
- Fundamental Data API — everything in the Fundamentals record beyond the General section.
- Splits and Dividends API — corporate actions in detail, with their exact dates and ratios.
- Intraday Historical Data API — intervals, history depth and the Unix timestamp format used above.
- Bulk API — whole-exchange daily snapshots when per-symbol requests are too slow.
- API Limits — the daily call budget and the per-minute request cap.