openapi: 3.1.0
info:
  title: MeterMaid — Business Days & Holidays API
  version: 1.0.0
  description: >
    Business-day calculator and public-holiday data for 49 countries
    (coverage 2024–2030). Weekends default to Saturday/Sunday; Egypt,
    Israel and Saudi Arabia use Friday/Saturday; the UAE uses
    Saturday/Sunday. Holiday data: date-holidays dataset (ISC + CC-BY-3.0).
servers:
  - url: https://metermaid.square-firefly-0154.workers.dev
security:
  - ApiKey: []
paths:
  /v1/businessdays/countries:
    get:
      summary: List supported countries and covered years
      operationId: listCountries
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  count: { type: integer, example: 49 }
                  years_covered: { type: array, items: { type: integer } }
                  countries:
                    type: array
                    items:
                      type: object
                      properties:
                        code: { type: string, example: US }
                        name: { type: string, example: United States of America }
        '401': { $ref: '#/components/responses/Unauthorized' }
        '429': { $ref: '#/components/responses/QuotaExceeded' }
  /v1/businessdays/holidays:
    get:
      summary: Public holidays for a country and year
      operationId: getHolidays
      parameters:
        - { name: country, in: query, required: true, schema: { type: string, example: US } }
        - { name: year, in: query, required: true, schema: { type: integer, example: 2026 } }
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  country: { type: string }
                  year: { type: integer }
                  count: { type: integer }
                  holidays:
                    type: array
                    items:
                      type: object
                      properties:
                        date: { type: string, format: date }
                        name: { type: string }
        '404': { $ref: '#/components/responses/UnsupportedCountry' }
        '422': { $ref: '#/components/responses/OutOfCoverage' }
  /v1/businessdays/is-business-day:
    get:
      summary: Is a date a business day?
      operationId: isBusinessDay
      parameters:
        - { name: country, in: query, required: true, schema: { type: string, example: US } }
        - { name: date, in: query, required: true, schema: { type: string, format: date, example: '2026-07-03' } }
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  country: { type: string }
                  date: { type: string, format: date }
                  weekday: { type: string, example: Friday }
                  is_weekend: { type: boolean }
                  is_holiday: { type: boolean }
                  holiday_name: { type: string, nullable: true, example: Independence Day (substitute day) }
                  is_business_day: { type: boolean }
  /v1/businessdays/add:
    get:
      summary: Add N business days to a date (negative N moves backwards)
      operationId: addBusinessDays
      parameters:
        - { name: country, in: query, required: true, schema: { type: string } }
        - { name: date, in: query, required: true, schema: { type: string, format: date } }
        - { name: days, in: query, required: true, schema: { type: integer, minimum: -3660, maximum: 3660 } }
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  country: { type: string }
                  start_date: { type: string, format: date }
                  days: { type: integer }
                  result_date: { type: string, format: date }
  /v1/businessdays/count:
    get:
      summary: Count business days between two dates
      operationId: countBusinessDays
      parameters:
        - { name: country, in: query, required: true, schema: { type: string } }
        - { name: from, in: query, required: true, schema: { type: string, format: date } }
        - { name: to, in: query, required: true, schema: { type: string, format: date } }
        - { name: inclusive, in: query, required: false, schema: { type: boolean, default: true }, description: 'false = end-exclusive count' }
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  country: { type: string }
                  from: { type: string, format: date }
                  to: { type: string, format: date }
                  inclusive: { type: boolean }
                  business_days: { type: integer }
  /v1/businessdays/next:
    get:
      summary: Next (or previous) business day after a date
      operationId: nextBusinessDay
      parameters:
        - { name: country, in: query, required: true, schema: { type: string } }
        - { name: date, in: query, required: true, schema: { type: string, format: date } }
        - { name: direction, in: query, required: false, schema: { type: integer, enum: [1, -1], default: 1 } }
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  country: { type: string }
                  date: { type: string, format: date }
                  direction: { type: integer }
                  result_date: { type: string, format: date }
components:
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-Api-Key
      description: Your MeterMaid key (direct) — or call via RapidAPI with your RapidAPI key.
  responses:
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
    QuotaExceeded:
      description: Plan quota exceeded
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
    UnsupportedCountry:
      description: Country code not supported
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
    OutOfCoverage:
      description: Date/year outside the 2024–2030 holiday-data coverage
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Error' }
  schemas:
    Error:
      type: object
      properties:
        error: { type: string, example: quota_exceeded }
        message: { type: string }
