‹ API Foundations Lesson 8 of 16
Contents Lesson 8 of 16

4 min read · practitioner

Why is FOREX in the exchange list when it isn't an exchange?

Pull /exchanges-list and most rows look exactly as you would expect: a real venue with a real ISO MIC. LSE with XLON, XETRA with XETR, TO with XTSE.

Then you reach these, returned live on 2026-07-28:

{"Name": "Money Market Virtual Exchange", "Code": "MONEY", "OperatingMIC": null,
 "Country": "Unknown", "Currency": "Unknown"}
{"Name": "Europe Fund Virtual Exchange", "Code": "EUFUND", "OperatingMIC": null,
 "Country": "Unknown", "Currency": "EUR"}
{"Name": "Government Bonds", "Code": "GBOND", "OperatingMIC": null,
 "Country": "Unknown", "Currency": "Unknown"}
{"Name": "Cryptocurrencies", "Code": "CC", "OperatingMIC": "CRYP", "Country": "Unknown"}
{"Name": "FOREX", "Code": "FOREX", "OperatingMIC": "CDSL", "Country": "Unknown"}

Two of them say "Virtual Exchange" in the name. All five say Country: "Unknown". Three have no MIC at all.

Resolve two of them through /exchange-details/{EXCHANGE_CODE} and every field a real venue would answer comes back, mostly saying nothing:

Live API response: forex exchange details
Live API response: gbond exchange details

They are namespaces, not venues

The API addresses everything through one grammar: SYMBOL.EXCHANGE. But plenty of financial series do not trade on an exchange. A currency pair trades over the counter across a decentralised network. A benchmark rate is published, not traded. A government bond yield is a computed number, not a transaction.

Rather than invent a second addressing scheme for those, the API gives them a fictional venue so the existing grammar keeps working. FOREX is not a place. It is a namespace that lets EURUSD.FOREX be a valid address.

Real examples, all of which go to the ordinary /eod/{ticker} endpoint:

  • EURUSD.FOREX, EUR.FOREX — currency pairs
  • BTC-USD.CC — crypto
  • US10Y.GBOND — the 10-year US Treasury yield
  • EURIBOR3M.MONEY, SOFR.MONEY, ECBRATES.MONEY — reference and policy rates. Pull the exchange's symbol list before you guess a code here: the plausible-looking ones are often not there, and a wrong code on a virtual exchange returns 404 Ticker Not Found rather than an empty series.
  • GSPC.INDX — the S&P 500 index

What comes back is still shaped like a stock

Call /eod/US10Y.GBOND for 20 to 24 July 2026 and you get this (live, 2026-07-28):

{"date": "2026-07-24", "open": 4.7, "high": 4.716, "low": 4.655,
 "close": 4.687, "adjusted_close": 4.687, "volume": 0}

The seven OHLCV fields are all there. But close here is 4.687 percent, not 4.687 dollars — it is a yield wearing a price schema. volume is 0 for every row, because a computed yield has no shares changing hands. And adjusted_close equals close exactly, because there are no splits or dividends to adjust for.

Code that assumes every /eod response is a tradable price in currency units will happily compute a nonsense market value from that. The schema is generic; the meaning is not.

The gap in the list

Now the trap. INDX is a working exchange code — GSPC.INDX resolves, and /exchange-symbol-list/INDX returns the index universe, roughly 1,668 symbols. But INDX does not appear in the 70 rows that /exchanges-list returns.

If your code builds its universe by iterating /exchanges-list, it will never see a single index and will never tell you why. The general form of this is worth carrying: a list endpoint returns what that endpoint lists, which is not the same as everything that exists. Verify the codes you depend on by calling them, not by assuming they were enumerated.

Try it now

  1. /exchanges-list returned 70 rows on 28 September 2026. Its last seven are below, and no row above them has Country set to "Unknown". Count the rows where Country is "Unknown", then use the JSON block at the top of this lesson to count those where OperatingMIC is null. Say what your parser currently does with each of the two fields.
Live API response: mda1 exchanges list tail
  1. Here are /eod/US10Y.GBOND and /eod/AAPL.US for the same week, the one ending Friday 25 September 2026. Same seven columns; write down what close and volume mean in each.
Live API response: mda1 us10y week bar
Live API response: mda1 apple suffixed week
  1. Below is the head of /exchange-symbol-list/INDX: a working exchange code, 1,674 symbols long on 28 September 2026. Now look back at the 70-row list: no row has Code INDX. That gap is the lesson.
Live API response: mda1 indx symbol list head