{
  "openapi": "3.1.0",
  "info": {
    "title": "SettleDate API",
    "version": "1.0.0",
    "summary": "Exchange holidays, trading sessions, business-day math and T+1/T+2 settlement dates.",
    "description": "Market holiday and settlement calendar API for 29 exchanges, 3 payment-rail calendars and 52 countries (2020-2030). Data is derived from exchange_calendars (Apache-2.0), python-holidays (MIT) and official exchange notices; provenance per calendar is at /sources. Keyless calls are allowed for free calendars (60/hour per IP). Send an API key in X-API-Key (or Authorization: Bearer) for higher limits and all calendars.",
    "contact": {
      "name": "Elco Dev",
      "email": "support@elcodev.com",
      "url": "https://www.elcodev.com/apps/settledate"
    },
    "termsOfService": "https://www.elcodev.com/apps/settledate/terms"
  },
  "servers": [
    {
      "url": "https://www.elcodev.com/apps/settledate"
    }
  ],
  "security": [
    {
      "ApiKey": []
    },
    {}
  ],
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      },
      "Bearer": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "responses": {
      "Error": {
        "description": "Error",
        "content": {
          "application/json": {
            "example": {
              "error": {
                "code": "out_of_range",
                "message": "'date' 2031-01-02 is outside the published range for XNYS (2020-01-01 to 2030-12-31)."
              }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/v1/calendars": {
      "get": {
        "operationId": "listCalendars",
        "summary": "List calendars",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "exchange",
                "rail",
                "country"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Calendars",
            "content": {
              "application/json": {
                "example": {
                  "calendars": [
                    {
                      "id": "XNYS",
                      "kind": "exchange",
                      "name": "New York Stock Exchange",
                      "country": "US",
                      "currency": "USD",
                      "timezone": "America/New_York",
                      "data_through": "2030-12-31",
                      "verification": {
                        "level": "checked-against-official",
                        "checked_against_official": [
                          2026,
                          2027
                        ]
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/calendars/{id}": {
      "get": {
        "operationId": "getCalendar",
        "summary": "Calendar metadata (hours, weekend, source, verification, settlement cycles)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Calendar id: a MIC (XNYS), a rail (us-fed, eu-target2, gb-bacs-chaps) or an ISO country/subdivision (US, GB-ENG). Join several with commas for a joint calendar (open only when all are open), e.g. XNYS,XLON.",
            "schema": {
              "type": "string",
              "example": "XNYS"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Calendar",
            "content": {
              "application/json": {
                "example": {
                  "id": "XNYS",
                  "regular_hours": [
                    {
                      "open": "09:30",
                      "close": "16:00",
                      "from": "2020-01-01",
                      "to": "2030-12-31"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/calendars/{id}/is-trading-day": {
      "get": {
        "operationId": "isTradingDay",
        "summary": "Is a date a trading/business day? (alias: is-business-day)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Calendar id: a MIC (XNYS), a rail (us-fed, eu-target2, gb-bacs-chaps) or an ISO country/subdivision (US, GB-ENG). Join several with commas for a joint calendar (open only when all are open), e.g. XNYS,XLON.",
            "schema": {
              "type": "string",
              "example": "XNYS"
            }
          },
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Date (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-11-27"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "example": {
                  "calendar": "XNYS",
                  "date": "2026-12-25",
                  "weekday": "Fri",
                  "is_business_day": false,
                  "closed_reasons": [
                    {
                      "calendar": "XNYS",
                      "type": "holiday",
                      "name": "Christmas"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/calendars/{id}/next-trading-day": {
      "get": {
        "operationId": "nextTradingDay",
        "summary": "Next trading day after a date (alias: next-business-day)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Calendar id: a MIC (XNYS), a rail (us-fed, eu-target2, gb-bacs-chaps) or an ISO country/subdivision (US, GB-ENG). Join several with commas for a joint calendar (open only when all are open), e.g. XNYS,XLON.",
            "schema": {
              "type": "string",
              "example": "XNYS"
            }
          },
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Start date",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-11-27"
            }
          },
          {
            "name": "inclusive",
            "in": "query",
            "required": false,
            "description": "true returns `date` itself when it is open",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "example": {
                  "calendar": "XNYS",
                  "date": "2026-12-24",
                  "next_business_day": "2026-12-28",
                  "inclusive": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/calendars/{id}/previous-trading-day": {
      "get": {
        "operationId": "previousTradingDay",
        "summary": "Previous trading day before a date (alias: previous-business-day)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Calendar id: a MIC (XNYS), a rail (us-fed, eu-target2, gb-bacs-chaps) or an ISO country/subdivision (US, GB-ENG). Join several with commas for a joint calendar (open only when all are open), e.g. XNYS,XLON.",
            "schema": {
              "type": "string",
              "example": "XNYS"
            }
          },
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Start date",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-11-27"
            }
          },
          {
            "name": "inclusive",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "example": {
                  "calendar": "XLON",
                  "date": "2026-12-28",
                  "previous_business_day": "2026-12-24",
                  "inclusive": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/calendars/{id}/add-trading-days": {
      "get": {
        "operationId": "addTradingDays",
        "summary": "Shift a date by N trading days (negative N goes back; alias: add-business-days)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Calendar id: a MIC (XNYS), a rail (us-fed, eu-target2, gb-bacs-chaps) or an ISO country/subdivision (US, GB-ENG). Join several with commas for a joint calendar (open only when all are open), e.g. XNYS,XLON.",
            "schema": {
              "type": "string",
              "example": "XNYS"
            }
          },
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Start date",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-11-27"
            }
          },
          {
            "name": "n",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": -2000,
              "maximum": 2000,
              "example": 2
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "example": {
                  "calendar": "XETR",
                  "date": "2026-04-02",
                  "n": 2,
                  "result": "2026-04-08"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/calendars/{id}/trading-days-between": {
      "get": {
        "operationId": "tradingDaysBetween",
        "summary": "Count trading days in [from, to) (alias: business-days-between)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Calendar id: a MIC (XNYS), a rail (us-fed, eu-target2, gb-bacs-chaps) or an ISO country/subdivision (US, GB-ENG). Join several with commas for a joint calendar (open only when all are open), e.g. XNYS,XLON.",
            "schema": {
              "type": "string",
              "example": "XNYS"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "Start (inclusive)",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-11-27"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "End (exclusive unless inclusive_end=true)",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-11-27"
            }
          },
          {
            "name": "inclusive_end",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "example": {
                  "calendar": "XNYS",
                  "from": "2026-01-01",
                  "to": "2027-01-01",
                  "inclusive_end": false,
                  "business_days": 251
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/calendars/{id}/holidays": {
      "get": {
        "operationId": "holidays",
        "summary": "Holidays in a year (exchanges also list early closes and late opens)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Calendar id: a MIC (XNYS), a rail (us-fed, eu-target2, gb-bacs-chaps) or an ISO country/subdivision (US, GB-ENG). Join several with commas for a joint calendar (open only when all are open), e.g. XNYS,XLON.",
            "schema": {
              "type": "string",
              "example": "XNYS"
            }
          },
          {
            "name": "year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 2026
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Holidays",
            "content": {
              "application/json": {
                "example": {
                  "calendar": "XNYS",
                  "year": 2026,
                  "holidays": [
                    {
                      "date": "2026-01-01",
                      "name": "New Year's Day",
                      "weekday": "Thu"
                    }
                  ],
                  "early_closes": [
                    {
                      "date": "2026-11-27",
                      "close_local": "13:00",
                      "weekday": "Fri"
                    }
                  ],
                  "late_opens": []
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/markets/{mic}/session": {
      "get": {
        "operationId": "session",
        "summary": "Session hours on a date, in local time and UTC",
        "parameters": [
          {
            "name": "mic",
            "in": "path",
            "required": true,
            "description": "Exchange MIC, e.g. XNYS, XLON, XTKS.",
            "schema": {
              "type": "string",
              "example": "XNYS"
            }
          },
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Date",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-11-27"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session",
            "content": {
              "application/json": {
                "example": {
                  "market": "XNYS",
                  "date": "2026-11-27",
                  "open": true,
                  "session_type": "early_close",
                  "timezone": "America/New_York",
                  "local": {
                    "open": "09:30",
                    "close": "13:00"
                  },
                  "utc": {
                    "open": "2026-11-27T14:30:00Z",
                    "close": "2026-11-27T18:00:00Z"
                  },
                  "regular_close_local": "16:00",
                  "utc_offset": "-05:00"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/markets/{mic}/sessions": {
      "get": {
        "operationId": "sessions",
        "summary": "All sessions in a date range (max 400 days)",
        "parameters": [
          {
            "name": "mic",
            "in": "path",
            "required": true,
            "description": "Exchange MIC, e.g. XNYS, XLON, XTKS.",
            "schema": {
              "type": "string",
              "example": "XNYS"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "Start",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-11-27"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "End (inclusive)",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-11-27"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sessions",
            "content": {
              "application/json": {
                "example": {
                  "market": "XTKS",
                  "from": "2026-03-02",
                  "to": "2026-03-02",
                  "sessions": [
                    {
                      "local": {
                        "open": "09:00",
                        "close": "15:30",
                        "break_start": "11:30",
                        "break_end": "12:30"
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/markets/{mic}/status": {
      "get": {
        "operationId": "status",
        "summary": "Open / closed / lunch break at an instant, with next open and close",
        "parameters": [
          {
            "name": "mic",
            "in": "path",
            "required": true,
            "description": "Exchange MIC, e.g. XNYS, XLON, XTKS.",
            "schema": {
              "type": "string",
              "example": "XNYS"
            }
          },
          {
            "name": "at",
            "in": "query",
            "required": false,
            "description": "ISO-8601 instant; default now",
            "schema": {
              "type": "string",
              "format": "date-time",
              "example": "2026-11-27T15:00:00Z"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status",
            "content": {
              "application/json": {
                "example": {
                  "market": "XNYS",
                  "status": "open",
                  "is_open": true,
                  "next_close": "2026-11-27T18:00:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/settlement-date": {
      "get": {
        "operationId": "settlementDate",
        "summary": "Settlement date for a trade (T+1/T+2/T+3), using the market calendar joined with the settlement-currency calendar",
        "parameters": [
          {
            "name": "market",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "example": "XETR"
            }
          },
          {
            "name": "trade_date",
            "in": "query",
            "required": true,
            "description": "Trade date",
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-11-27"
            }
          },
          {
            "name": "cycle",
            "in": "query",
            "required": false,
            "description": "Override the market's standard cycle, e.g. T+1",
            "schema": {
              "type": "string",
              "example": "T+1"
            }
          },
          {
            "name": "calendars",
            "in": "query",
            "required": false,
            "description": "Extra calendars to join (comma-separated), e.g. XNYS for a cross-listed trade",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "currency_calendar",
            "in": "query",
            "required": false,
            "description": "Override the cash-leg calendar (us-fed, eu-target2, gb-bacs-chaps) or `none`",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Settlement",
            "content": {
              "application/json": {
                "example": {
                  "market": "XETR",
                  "trade_date": "2027-10-08",
                  "settlement_date": "2027-10-12",
                  "cycle": "T+2",
                  "basis": "market_rule",
                  "status": "in_effect",
                  "calendars_used": [
                    "XETR",
                    "eu-target2"
                  ],
                  "skipped_days": [],
                  "upcoming_change": {
                    "cycle": "T+1",
                    "effective_from": "2027-10-11",
                    "status": "confirmed"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/settlement-cycles": {
      "get": {
        "operationId": "settlementCycles",
        "summary": "Standard settlement cycle rules by market, with status (in_effect / confirmed / announced_not_final) and sources",
        "parameters": [
          {
            "name": "market",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rules",
            "content": {
              "application/json": {
                "example": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/changes": {
      "get": {
        "operationId": "changes",
        "summary": "Corrections log: hand overrides applied on top of library data, each with an official source",
        "responses": {
          "200": {
            "description": "Changes",
            "content": {
              "application/json": {
                "example": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "usage",
        "summary": "Your plan and calls used this month (requires a key)",
        "responses": {
          "200": {
            "description": "Usage",
            "content": {
              "application/json": {
                "example": {
                  "plan": "free",
                  "month": "202610",
                  "calls_used": 42,
                  "monthly_limit": 5000
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "422": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  }
}