All exchanges API
The API and the dataset
Two ways to get this out of a browser. Both are free, need no key and no account, and carry the same disclaimer as everything else here.
Which one you want
If you need to know whether a market is open at this moment and you do not want to do the work, call the API. If you want the schedule so you can work it out yourself, whenever and as often as you like, take the dataset.
The dataset is the better answer for almost everybody. It is one static file on a CDN, it cannot rate-limit you, it works when this site is down, and it is the same calendar the API computes from. The arithmetic on top of it is about twenty lines.
One thing the dataset cannot tell you, and it is the thing it exists for. A market that has stopped unexpectedly, for a funeral or an outage or a storm, is suspended by hand and that suspension lives outside the calendar: the API merges it, the dataset does not carry it, and a rebuilt copy of the dataset will not have it either until the next nightly build. If you need to know about an unscheduled halt rather than a published schedule, that is the one case where the endpoint is the only answer.
The dataset
- URL
- /data/exchanges.v1.json
- Format
- JSON, one object
- Horizon
- per market, in horizon. Past it, unknown.
- Version
- 1.8.0
- Markets
- 33
- Odd weeks
- tadawul
- Licence
- CC BY 4.0
- Same, as text
- /llms-full.txt
Every market with its sessions, timezone, MIC code, currency, holidays and early closes. version follows semantic versioning against both the shape and the content: a patch means dates were corrected or the horizon moved out, a minor means a market or a field was added, a major means something a consumer depends on changed meaning. updated is the date the calendar itself last moved, which is deliberately not the date the site was last built. The site rebuilds every night; the calendar does not.
Poll it as often as you like. Once a day is plenty: the calendar changes a handful of times a year, and the version tells you when it did.
Working out a status yourself
Worth doing in your own code rather than calling the API, because then you are never waiting on this site to be up. The whole algorithm:
Start with kind. A market whose kind is always never shuts and none of the rest applies; one whose kind is continuous runs from weeklyClose.to until weeklyClose.from and is shut in between. Everything below is for the scheduled exchanges, which is what weekend and sessions are for: on the other two, weekend and horizon are null and sessions is an empty array.
Then the weekday, before anything else: if it is in weekend, the market is closed, however far out the date is. No calendar is needed to know it is Saturday, so that answer never expires.
Then the horizon: if the date is later than horizon, stop. That market's calendar does not reach it, and the honest answer is that you do not know rather than that it is open. The API returns unknown for exactly this. The order of these two matters and this page had it the other way round, which made the documented algorithm disagree with the engine on every weekend past a horizon.
Otherwise: take the date and time in the market's own tz. If that date is a key in holidays, the market is closed and the value is why. If it is in halfDays, it closes early at the time given. If its weekday is in weekend, it is closed. Otherwise compare the local clock against sessions, each a [from, to] pair in local time. If the clock is inside one, the market is open. If it is not, it is closed, and that includes the gap between two sessions: an exchange on its midday break is not matching orders, so you cannot trade, so the answer is no. reason says which kind of no it is.
Read that fourth step rather than assuming it. Not every market rests at the weekend you do: weekend is a list of weekday numbers counting from Sunday, usually [0, 6], and [5, 6] for the Gulf markets that trade Sunday to Thursday. Hardcoding Saturday and Sunday reports Tadawul shut on a Sunday it trades and open on a Friday it does not, which is two wrong answers a week on a market that keeps perfectly ordinary hours.
One rule matters more than the rest: use your platform's IANA timezone database for the conversion, never a fixed offset. Daylight saving is the entire difficulty. For three weeks each spring the US has switched and Europe has not, and a hardcoded offset is wrong on exactly the days somebody bothers to check. This site does the conversion in the visitor's browser for the same reason: browser vendors ship timezone patches faster than anybody else does.
The API
- Every market
- GET /api/status
- One market
- GET /api/status/<id>
- Auth
- None. No key, no account, no header.
- CORS
- access-control-allow-origin: *
- Cache
- public, max-age=30
- Errors
- 404 unknown id, 503 calendar unavailable
The id is either the short identifier or the MIC code, lowercased: /api/status/nyse and /api/status/xnys are the same request. An unknown one returns 404 with an error field rather than an empty object. If the calendar cannot be loaded the endpoint returns 503 rather than a stale guess.
Valid ids: asx, athex, b3, bet, bist, bme, borsa-italiana, bursa, crypto, euronext-paris, forex, gpw, hkex, jse, krx, lse, nasdaq, nse, nyse, nzx, omx-stockholm, oslo, pse, set, sgx, six, sse, tadawul, tse, tsx, twse, us-bonds, xetra
What comes back
The list endpoint returns asOf, calendarBuilt, disclaimer, terms and an exchanges array. The single-market endpoint returns one of those entries with the disclaimer beside it. Every entry has:
- id
- short identifier, the same one in the page URL
- mic
- ISO 10383 market identifier code
- name
- the market's full name
- city
- where it trades
- timezone
- IANA name, which the local fields below are in
- state
- open, closed or unknown
- isOpen
- true only when state is open
- suspended
- true when a manual override has shut the market outside its calendar
- label
- the state as a word, or Suspended
- reason
- why it is in that state: a holiday name, Weekend, Midday break, or that trading has finished for the day
- localTime
- HH:MM in the market's own timezone
- localDate
- YYYY-MM-DD in the market's own timezone
- nextChange
- ISO 8601 instant of the next open or close, or null
- nextChangeIn
- the same thing as a readable duration
- nextChangeIsOpen
- true when that next change opens the market
There are three states and no more. open means you can put an order in and it will match at a price the whole market made. Everything else is closed, and reason says why: a holiday, a weekend, the hour Tokyo takes for lunch, the auction at either end of the day, or simply that the session has not started. Sessions here are continuous trading and nothing else. Where an exchange runs an opening or closing call, a trade-at-last or an after-hours book, those are named on its own page and this site counts them as closed, because in every one of them either nothing matches or only a fraction of the market can be there.
unknown is the fourth state and the one worth handling before it surprises you. It means the date is past that market's horizon, so the calendar has no opinion. isOpen is false, which is not a claim that the market is shut, and nextChange is null, because a reopening cannot be computed from a calendar that has run out. Treat it as "ask the exchange", not as closed.
suspended is how an unscheduled stop shows up: a state funeral, an outage, a storm. It is set by hand when the canary catches a market that is shut when the calendar said it would trade, and it is the one field here that is not derived from the published schedule.
Fair use
There is no rate limit, no quota and nothing to sign. That is not generosity. A limit would need accounts, and accounts would need a privacy policy with something in it, and the best privacy policy is the one that has nothing to say.
Please do not make it necessary. Once a minute per market is far more than enough for a status that changes twice a day, and if you are going faster than that you want the dataset. Cache what you get, handle it being down, and do not put its output in front of your own users as authoritative. It is one person's hobby project on a free plan.
Where this comes from, and what it is not
This is a secondary source. It is not authority for any date. If you need to be certain, read the exchange's own published calendar.
That matters more than it sounds, because of how these things go wrong. Some of the dates here are refreshed from exchange_calendars, which is itself a compilation. If you build a calendar on this dataset, and a compilation later takes its dates from yours, the chain closes: every link is quoting a neighbour and none of them is quoting an exchange. Nobody has to be careless for that to happen. It happens because at each step there appeared to be a source.
So: use this to answer a question, ship it inside a product, put it on a page. Do not make it the upstream of another calendar. The upstream is the exchange, and it always was.
- Primary
- The exchanges' own published trading calendars
- Compilation
- exchange_calendars, by Gerry Manoim and contributors, Apache 2.0. Read as a diff and corrected by hand; never redistributed.
- Editorial
- Hand entry for markets the package does not carry, dates beyond its horizon, and corrections readers have sent in
- Verification
- A job every fifteen minutes comparing this calendar against a live source, which is what catches the closures nobody announces
Markets carrying verify in the data are the ones whose dates are not settled at any distance: mostly because their holidays follow lunar or annually announced calendars, and in the case of US Bonds because its hours are SIFMA recommendations rather than an exchange's rules. The flag is not a gap waiting to be filled, it is a standing property of those markets, and it means what it says: confirm before you rely on a specific date.
The dataset says all of this about itself, in a provenance object, so a copy that gets passed around carries the warning with it rather than leaving it behind on this page.
Licence and credit
The calendar, and everything computed from it, is CC BY 4.0. Use it for anything at all, commercial included. The conditions are that you say where it came from, and that you say so if you changed it. A link does the job:
Market calendar from <a href="https://isopennow.com/">isopennow.com</a> (CC BY 4.0)
The code that renders the site is MIT and asks for nothing.
Attribution is asked for one practical reason above the obvious one. A holiday calendar goes wrong eventually, and it only ever gets fixed by somebody who knows the market and can find their way back here to say so. If you spot a wrong date, tell me. That is worth more than the credit.
The small print
Offered free, unsupported, with no service level, and under everything on the legal page. It may change shape or disappear. Schedules are published here, never live prices. The disclaimer travels inside every response, not just on this page.