Browse all documentation

Exchange closures API reference

The days an exchange is closed, closes early or opens late, and its normal trading sessions, in the exchange's own time.

Request

GET /v1/calendars/exchanges/{mic}/closures returns the days one exchange does not trade a full normal day, and the trading windows of a normal day. Use your Narwhal bearer key. Times are local exchange time, not UTC.

Closures of the New York Stock Exchange in 2026
curl --request GET \
  --url "https://api.narwhalapi.com/v1/calendars/exchanges/XNYS/closures?year=2026" \
  --header "Authorization: Bearer $NARWHAL_API_KEY"

Parameters

NameTypeRule
micstringRequired path value. The exchange's Market Identifier Code: four uppercase letters or digits, such as XNYS. A lowercase or longer code returns 400.
yearintegerOptional query value, 2000 to 2100. Returns that calendar year only. Left out, the answer holds every closure from 1 January of the current year on, however far ahead the calendar goes.

There is no pagination, and no other query parameter. An unknown query parameter is ignored.

Response

A 200 answer holds the exchange, its closures in date order and its sessions. This answer is trimmed to three of the twelve closures of 2026. Thanksgiving Day is a full closure and the day after is an early close.

200 OK
{
  "mic": "XNYS",
  "name": "New York Stock Exchange",
  "timezone": "America/New_York",
  "closures": [
    {
      "date": "2026-11-26",
      "name": "Thanksgiving Day",
      "holiday_key": "thanksgiving_day",
      "type": "exchange",
      "mic": "XNYS",
      "day_type": "full",
      "status": "confirmed"
    },
    {
      "date": "2026-11-27",
      "name": "Day after Thanksgiving",
      "holiday_key": "day_after_thanksgiving",
      "type": "exchange",
      "mic": "XNYS",
      "day_type": "early_close",
      "closes_at": "13:00",
      "status": "confirmed"
    },
    {
      "date": "2026-12-25",
      "name": "Christmas Day",
      "holiday_key": "christmas_day",
      "type": "exchange",
      "mic": "XNYS",
      "day_type": "full",
      "status": "confirmed"
    }
  ],
  "sessions": [
    {
      "name": "Pre-market",
      "opens_at": "04:00",
      "closes_at": "09:30",
      "valid_from": "2026-01-01"
    },
    {
      "name": "Regular",
      "opens_at": "09:30",
      "closes_at": "16:00",
      "valid_from": "2026-01-01"
    },
    {
      "name": "After-hours",
      "opens_at": "16:00",
      "closes_at": "20:00",
      "valid_from": "2026-01-01"
    }
  ]
}

B3 opens late on Ash Wednesday and gives the local name of each day. This answer shows two of the fifteen closures of 2026.

Late open
curl --request GET \
  --url "https://api.narwhalapi.com/v1/calendars/exchanges/BVMF/closures?year=2026" \
  --header "Authorization: Bearer $NARWHAL_API_KEY"
200 OK
{
  "mic": "BVMF",
  "name": "B3",
  "timezone": "America/Sao_Paulo",
  "closures": [
    {
      "date": "2026-02-17",
      "name": "Carnival",
      "holiday_key": "carnival",
      "local_name": "Carnaval",
      "type": "exchange",
      "mic": "BVMF",
      "day_type": "full",
      "status": "confirmed"
    },
    {
      "date": "2026-02-18",
      "name": "Ash Wednesday",
      "holiday_key": "ash_wednesday",
      "local_name": "Quarta-feira de Cinzas",
      "type": "exchange",
      "mic": "BVMF",
      "day_type": "late_open",
      "opens_at": "13:00",
      "status": "confirmed"
    }
  ],
  "sessions": [
    {
      "name": "Regular",
      "opens_at": "10:00",
      "closes_at": "17:55",
      "valid_from": "2026-01-01"
    }
  ]
}

A provisional day comes from a government list or a moon-dependent date and can still move. This answer shows the first of the Xetra closures of 2028.

Provisional day
curl --request GET \
  --url "https://api.narwhalapi.com/v1/calendars/exchanges/XETR/closures?year=2028" \
  --header "Authorization: Bearer $NARWHAL_API_KEY"
200 OK
{
  "mic": "XETR",
  "name": "Xetra",
  "timezone": "Europe/Berlin",
  "closures": [
    {
      "date": "2028-04-14",
      "name": "Good Friday",
      "holiday_key": "good_friday",
      "type": "exchange",
      "mic": "XETR",
      "day_type": "full",
      "status": "provisional"
    }
  ],
  "sessions": [
    {
      "name": "Regular",
      "opens_at": "09:00",
      "closes_at": "17:30",
      "valid_from": "2026-01-01"
    }
  ]
}

Fields

FieldTypeMeaning
micstringThe code you asked for, on the answer and on every closure.
namestringThe exchange's English name on the answer. On a closure it is the English name of the day.
timezonestringIANA time zone of the exchange, such as America/New_York. Every time in the answer is in this zone.
closuresarrayOne entry for each day, or each segment of a day, that is not a full normal day. Never empty on a 200 answer.
datedate stringLocal date of the closure, YYYY-MM-DD.
holiday_keystringA stable key for the kind of day, such as christmas_day.
local_namestringName in the local language. Left out when not available.
typestringAlways exchange.
segmentstringThe part of the exchange the day affects, when it is not the whole exchange. Left out when the whole exchange is affected.
day_typestringfull: the exchange is closed all day. early_close: it closes at closes_at. late_open: it opens at opens_at.
opens_at / closes_atstringLocal time as HH:MM. opens_at is set on a late_open day and closes_at on an early_close day. Both are left out on a full day.
statusstringconfirmed: the exchange's own notice or a published rule. provisional: from a government list or a moon-dependent date. A provisional day can still move.
sessionsarrayThe trading windows of a normal day. Each has a name, opens_at and closes_at in local time, and valid_from, the date the window starts to apply. A lunch break shows as two windows. Not limited by year. Can be empty.

Public holidays do not prove that an exchange is closed. Use this route for the days an exchange itself does not trade a full day. Public holidays reference

Exchanges

These 19 exchanges have a published calendar. Any other code returns 404. Years are the years that hold closures. An exchange marked with another code uses that exchange's list, so the closures match.

MICExchangeYearsUses the list of
ARCXNYSE Arca2026, 2027XNYS
BATSCboe BZX2026, 2027XNYS
BVMFB32026
OTCMOTC Markets2026, 2027XNYS
XASENYSE American2026, 2027XNYS
XASXASX2026, 2027
XETRXetra2026 to 2032
XHKGHong Kong Exchanges and Clearing2025, 2026, 2027
XKARPakistan Stock Exchange2026
XKOSKOSDAQ2026, 2027XKRX
XKRXKorea Exchange2026, 2027
XLONLondon2026, 2027
XNASNasdaq2026, 2027XNYS
XNYSNew York Stock Exchange2026, 2027
XSHGShanghai Stock Exchange2026
XTAITaiwan Stock Exchange2026, 2027
XTKSTokyo Stock Exchange2026, 2027
XTSEToronto Stock Exchange2026, 2027
XTSXTSXV, Toronto2026, 2027

Matching MCP call

Send an authenticated POST /mcp with Accept: application/json, text/event-stream. The tool is calendars_get_exchange_closures.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "calendars_get_exchange_closures",
    "arguments": {
      "mic": "BVMF",
      "year": 2026
    }
  }
}

Successful results have isError: false, the same response in structuredContent, and serialized JSON in content[0].text. Domain errors have isError: true.

Errors and credits

StatusCodeWhen
400invalid_queryThe MIC is not four uppercase letters or digits, or year is not an integer from 2000 to 2100.
401invalid_api_keyThe key is missing or invalid.
402insufficient_creditsThe balance cannot pay for the call. The answer carries top_up_url.
404not_foundNo calendar is published for the MIC, or the exchange holds no closure for the year you asked for. The detail text reads the same in both cases.
429rate_limit_exceededThe per-minute limit is reached.
503database_unavailableThe data store is temporarily unavailable. Retry shortly.

A successful request costs one call on the Calendars API code, $2 per 1,000 calls, however many closures it returns. Errors cost nothing. Shared error details

Public holidays reference ยท Economic release calendars

Was this page helpful?