{
  "openapi": "3.0.3",
  "info": {
    "title": "TotemClock Time Tools API",
    "version": "1.0.0",
    "description": "Free, keyless calculations for worked hours and decimal hours. Calculations are mathematical utilities, not payroll or legal advice.",
    "contact": {
      "name": "TotemClock AI",
      "url": "https://totemclock.com/developers/",
      "email": "support@totemclock.com"
    },
    "license": {
      "name": "Public use",
      "url": "https://totemclock.com/en/privacy-cookies/"
    }
  },
  "servers": [{ "url": "https://totemclock.com" }],
  "tags": [{ "name": "Time tools", "description": "Stateless time calculations with no authentication." }],
  "paths": {
    "/api/tools/decimal-hours": {
      "get": {
        "operationId": "convertDecimalHours",
        "summary": "Convert between HH:MM and decimal hours",
        "tags": ["Time tools"],
        "parameters": [
          { "name": "time", "in": "query", "description": "Time duration in HH:MM. Use either time or decimal.", "schema": { "type": "string", "pattern": "^[0-9]{1,2}:[0-9]{2}$" }, "example": "07:30" },
          { "name": "decimal", "in": "query", "description": "Decimal hours. Use either decimal or time.", "schema": { "type": "number", "minimum": 0, "maximum": 10000 }, "example": 7.5 }
        ],
        "responses": {
          "200": { "description": "Converted duration", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TimeResult" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/api/tools/worked-hours": {
      "get": {
        "operationId": "calculateWorkedHours",
        "summary": "Calculate worked hours for a shift",
        "description": "Subtracts an unpaid break and recognizes an end time on the next day when end is earlier than or equal to start.",
        "tags": ["Time tools"],
        "parameters": [
          { "name": "start", "in": "query", "required": true, "schema": { "type": "string", "pattern": "^[0-9]{1,2}:[0-9]{2}$" }, "example": "08:30" },
          { "name": "end", "in": "query", "required": true, "schema": { "type": "string", "pattern": "^[0-9]{1,2}:[0-9]{2}$" }, "example": "17:30" },
          { "name": "breakMinutes", "in": "query", "schema": { "type": "integer", "minimum": 0, "maximum": 1440, "default": 0 }, "example": 60 }
        ],
        "responses": {
          "200": { "description": "Calculated shift", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WorkedHoursResult" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "TimeResult": {
        "type": "object",
        "properties": {
          "minutes": { "type": "integer" },
          "decimalHours": { "type": "number" },
          "formatted": { "type": "string" },
          "learnMore": { "type": "string", "format": "uri" }
        }
      },
      "WorkedHoursResult": {
        "allOf": [
          { "$ref": "#/components/schemas/TimeResult" },
          { "type": "object", "properties": { "overnight": { "type": "boolean" }, "elapsedMinutes": { "type": "integer" }, "workedMinutes": { "type": "integer" } } }
        ]
      }
    },
    "responses": {
      "BadRequest": { "description": "Invalid or missing query parameter" }
    }
  }
}
