{
  "openapi": "3.0.3",
  "info": {
    "title": "SPRAWNO Booking API (for AI agents)",
    "description": "Public interface for AI assistants to check availability, prices and working hours at SPRAWNO — a car service & detailing shop in Bogucin near Poznań, Poland — and to create a booking REQUEST. Booking is a request model: the shop phones the customer to confirm; it is not an instantly confirmed appointment. All times are Europe/Warsaw. Currently bookable services: oil change and tyre service; more from the ~2026-09-01 opening.",
    "version": "1.0.0",
    "contact": {
      "name": "SPRAWNO",
      "url": "https://sprawno.pl",
      "email": "kontakt@sprawno.pl"
    }
  },
  "servers": [{ "url": "https://sprawno.pl" }],
  "paths": {
    "/api/agent/services": {
      "get": {
        "operationId": "listServices",
        "summary": "List bookable services",
        "description": "Returns the currently bookable services with their stable ids (use the id in bookAppointment) and 'from' prices.",
        "responses": {
          "200": {
            "description": "Bookable services",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "timezone": { "type": "string" },
                    "booking_model": { "type": "string" },
                    "currency": { "type": "string" },
                    "services": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "string" },
                          "name": { "type": "string" },
                          "name_en": { "type": "string" },
                          "silo": { "type": "string" },
                          "price_from": { "type": "number", "nullable": true }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/hours": {
      "get": {
        "operationId": "getWorkingHours",
        "summary": "Working hours & timezone",
        "responses": { "200": { "description": "Working hours" } }
      }
    },
    "/api/agent/slots": {
      "get": {
        "operationId": "listAvailableSlots",
        "summary": "Free 45-minute slots for a service in a date range",
        "description": "Returns free slots (Europe/Warsaw). Resolve relative dates (e.g. 'next week') to explicit from/to before calling.",
        "parameters": [
          {
            "name": "service",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Service id from listServices"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "Start date YYYY-MM-DD (default: today or opening date)"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "End date YYYY-MM-DD (max 21 days from 'from')"
          }
        ],
        "responses": {
          "200": {
            "description": "Free slots",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "timezone": { "type": "string" },
                    "service": { "type": "string" },
                    "slots": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": { "type": "string", "format": "date" },
                          "time": { "type": "string" },
                          "end": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "Unknown or unavailable service" }
        }
      }
    },
    "/api/agent/book": {
      "post": {
        "operationId": "bookAppointment",
        "summary": "Create a booking request",
        "description": "Creates a booking REQUEST (the shop phones the customer to confirm). Always confirm the chosen slot and collect the customer's name and phone from the user first. Tell the user this is a request, not a confirmed appointment.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "service_id",
                  "date",
                  "time",
                  "customer_name",
                  "phone"
                ],
                "properties": {
                  "service_id": {
                    "type": "string",
                    "description": "id from listServices"
                  },
                  "date": {
                    "type": "string",
                    "format": "date",
                    "description": "YYYY-MM-DD"
                  },
                  "time": {
                    "type": "string",
                    "description": "Slot start HH:MM (from listAvailableSlots)"
                  },
                  "customer_name": { "type": "string" },
                  "phone": {
                    "type": "string",
                    "description": "Polish 9-digit or international +… number"
                  },
                  "car": {
                    "type": "string",
                    "description": "make/model, optional"
                  },
                  "email": { "type": "string", "description": "optional" },
                  "note": { "type": "string", "description": "optional" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Booking request created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": { "type": "string" },
                    "status": { "type": "string" },
                    "service": { "type": "string" },
                    "date": { "type": "string" },
                    "time": { "type": "string" },
                    "message": { "type": "string" }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Slot no longer available — fetch slots again and propose another"
          },
          "422": { "description": "Missing/invalid name or phone" },
          "429": { "description": "Rate limited" }
        }
      }
    }
  }
}
