{
  "openapi": "3.1.0",
  "info": {
    "title": "VenturaCuida — Public Booking API",
    "summary": "Book massage and therapy services in Portugal via AI agents or applications.",
    "description": "VenturaCuida public API — REST CRUD.\n\n| Resource | Create | Read |\n|----------|--------|------|\n| services | — | GET /services, GET /services/{slug} |\n| sessions | POST /sessions | GET /sessions/{reference} |\n| partnerships | POST /partnerships | — |\n\nRate limits: GET 15/min; POST /sessions 3 per 10 minutes.",
    "version": "4.0.0",
    "contact": {
      "name": "VenturaCuida",
      "url": "https://www.venturacuida.com",
      "email": "venturacareportugal@gmail.com"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://ventura-cuida-backend.herokuapp.com",
      "description": "Production server"
    }
  ],
  "tags": [
    {
      "name": "Services",
      "description": "Discover available services (pricing from VenturaCuida) and locations."
    },
    {
      "name": "Booking",
      "description": "Submit session requests; evaluated by our team."
    },
    {
      "name": "Partnership",
      "description": "Submit partnership requests (hotels, Airbnbs)."
    }
  ],
  "paths": {
    "/api/public/v1/services": {
      "get": {
        "operationId": "listServices",
        "tags": ["Services"],
        "summary": "List all available massage and therapy services",
        "description": "Returns services as pricing records from VenturaCuida partnership (service + duration + price) and available locations. Each service item is a bookable product.\n\nNo authentication required.",
        "security": [],
        "responses": {
          "200": {
            "description": "List of services and locations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServicesResponse"
                },
                "examples": {
                  "success": {
                    "summary": "Successful response with services",
                    "value": {
                      "description": "VenturaCuida — On-demand massage and therapy services in Portugal.",
                      "website": "https://www.venturacuida.com",
                      "services": [
                        {
                          "id": "abc123",
                          "serviceSlug": "massage",
                          "serviceName": "Massage",
                          "duration": 60,
                          "totalPrice": 55,
                          "currency": "EUR",
                          "photo": null,
                          "therapistTypes": ["massage"]
                        }
                      ],
                      "locations": [
                        {
                          "name": "Example Hotel",
                          "slug": "example-hotel",
                          "workLocations": ["madeira-island"]
                        }
                      ],
                      "sessionRequirements": {
                        "create": "POST /api/public/v1/sessions",
                        "read": "GET /api/public/v1/sessions/{reference}",
                        "requiredFields": [
                          "serviceSlug",
                          "preferredDate",
                          "preferredTime",
                          "duration",
                          "clientName",
                          "clientPhone",
                          "clientEmail",
                          "address"
                        ],
                        "optionalFields": [
                          "notes",
                          "language",
                          "nationality"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/services/{serviceSlug}": {
      "get": {
        "operationId": "getService",
        "tags": ["Services"],
        "summary": "Read one service and its pricing options",
        "security": [],
        "parameters": [
          {
            "name": "serviceSlug",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "example": "relaxing-massage"
          }
        ],
        "responses": {
          "200": { "description": "Service pricing options" },
          "404": { "description": "Unknown service slug" }
        }
      }
    },
    "/api/public/v1/sessions": {
      "post": {
        "operationId": "createSession",
        "tags": ["Sessions"],
        "summary": "Create a session request",
        "description": "Submit a session request. VenturaCuida reviews and contacts the client. Rate limit: 3 per 10 minutes.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Session created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionResponse"
                }
              }
            }
          },
          "400": { "description": "Validation error" },
          "404": { "description": "Service or pricing not found" },
          "429": { "description": "Rate limit exceeded" }
        }
      }
    },
    "/api/public/v1/sessions/{reference}": {
      "get": {
        "operationId": "getSession",
        "tags": ["Sessions"],
        "summary": "Read session status",
        "security": [],
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "example": "VC-A1B2C3D4"
          },
          {
            "name": "clientPhone",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "example": "+351912345678"
          }
        ],
        "responses": {
          "200": {
            "description": "Session details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionResponse"
                }
              }
            }
          },
          "404": { "description": "Not found or phone mismatch" }
        }
      }
    },
    "/api/public/v1/partnerships": {
      "post": {
        "operationId": "createPartnership",
        "tags": ["Partnerships"],
        "summary": "Create a partnership request",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnershipCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Partnership request submitted" },
          "400": { "description": "Validation error" },
          "409": { "description": "Email already registered" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ServicesResponse": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "description": "Human-readable description of VenturaCuida services."
          },
          "website": {
            "type": "string",
            "format": "uri",
            "description": "VenturaCuida website URL."
          },
          "services": {
            "type": "array",
            "description": "List of available services (pricing from VenturaCuida). Each item = service + duration + price.",
            "items": {
              "$ref": "#/components/schemas/ServicePricingItem"
            }
          },
          "locations": {
            "type": "array",
            "description": "List of partner locations where services are available.",
            "items": {
              "$ref": "#/components/schemas/Location"
            }
          },
          "bookingInstructions": {
            "type": "object",
            "description": "Instructions for AI agents on how to create a booking.",
            "properties": {
              "summary": { "type": "string" },
              "endpoint": { "type": "string" },
              "requiredFields": {
                "type": "array",
                "items": { "type": "string" }
              },
              "optionalFields": {
                "type": "array",
                "items": { "type": "string" }
              }
            }
          }
        }
      },
      "PricingResponse": {
        "type": "object",
        "properties": {
          "services": {
            "type": "array",
            "description": "List of services with pricing information.",
            "items": {
              "$ref": "#/components/schemas/ServicePricing"
            }
          }
        }
      },
      "ServicePricingItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Pricing identifier."
          },
          "serviceSlug": {
            "type": "string",
            "description": "Service slug used in booking endpoint."
          },
          "serviceName": {
            "type": "string",
            "description": "Display name of the service."
          },
          "duration": {
            "type": "integer",
            "description": "Duration in minutes."
          },
          "totalPrice": {
            "type": "number",
            "description": "Total price in EUR."
          },
          "currency": {
            "type": "string",
            "const": "EUR"
          },
          "photo": {
            "type": ["string", "null"]
          },
          "therapistTypes": {
            "type": "array",
            "items": { "type": "string" }
          }
        }
      },
      "ServicePricing": {
        "type": "object",
        "properties": {
          "serviceSlug": {
            "type": "string",
            "description": "Service slug identifier."
          },
          "serviceName": {
            "type": "string",
            "description": "Display name of the service."
          },
          "pricing": {
            "type": "array",
            "description": "Available pricing options for this service.",
            "items": {
              "$ref": "#/components/schemas/PricingOption"
            }
          }
        }
      },
      "PricingOption": {
        "type": "object",
        "properties": {
          "duration": {
            "type": "integer",
            "description": "Duration in minutes."
          },
          "totalPrice": {
            "type": "number",
            "description": "Total price for the session."
          },
          "currency": {
            "type": "string",
            "description": "Currency code (always EUR).",
            "const": "EUR"
          },
          "numberOfSessions": {
            "type": "integer",
            "description": "Number of sessions included (1 for single bookings)."
          },
          "location": {
            "type": ["object", "null"],
            "description": "The location/partnership where this price applies.",
            "properties": {
              "name": { "type": "string" },
              "slug": { "type": "string" }
            }
          }
        }
      },
      "Location": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the partner location."
          },
          "slug": {
            "type": "string",
            "description": "URL-friendly identifier for this location."
          },
          "workLocations": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["lisbon", "madeira-island", "west-madeira-island"]
            },
            "description": "Geographic areas served by this partner."
          }
        }
      },
      "AvailabilityResponse": {
        "type": "object",
        "properties": {
          "location": {
            "type": "object",
            "properties": {
              "name": { "type": "string" },
              "slug": { "type": "string" }
            }
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "The requested date."
          },
          "timezone": {
            "type": "string",
            "description": "Timezone used for all times (always Europe/Lisbon).",
            "const": "Europe/Lisbon"
          },
          "slots": {
            "type": "array",
            "description": "Available time slots. Empty array means no therapist has declared availability yet, but a booking request can still be submitted.",
            "items": {
              "$ref": "#/components/schemas/TimeSlot"
            }
          },
          "note": {
            "type": "string",
            "description": "Additional context for the AI agent or user."
          }
        }
      },
      "TimeSlot": {
        "type": "object",
        "properties": {
          "dateTime": {
            "type": "string",
            "description": "Full date and time in YYYY-MM-DDTHH:mm format (Europe/Lisbon timezone)."
          },
          "time": {
            "type": "string",
            "description": "Time only in HH:mm format."
          },
          "available": {
            "type": "boolean",
            "description": "Whether this slot is available for booking."
          }
        }
      },
      "SessionCreateRequest": {
        "type": "object",
        "required": [
          "serviceSlug",
          "preferredDate",
          "preferredTime",
          "duration",
          "clientName",
          "clientPhone",
          "clientEmail",
          "address"
        ],
        "properties": {
          "serviceSlug": {
            "type": "string",
            "description": "From GET /api/public/v1/services (e.g. relaxing-massage).",
            "example": "relaxing-massage"
          },
          "preferredDate": {
            "type": "string",
            "format": "date",
            "description": "Preferred date in YYYY-MM-DD format (Europe/Lisbon)."
          },
          "preferredTime": {
            "type": "string",
            "description": "Preferred time in HH:mm 24-hour format (Europe/Lisbon).",
            "pattern": "^([01]\\d|2[0-3]):([0-5]\\d)$"
          },
          "duration": {
            "type": "integer",
            "enum": [30, 60, 90, 120]
          },
          "clientName": { "type": "string" },
          "clientPhone": {
            "type": "string",
            "description": "Mobile with + and country code (e.g. +351912345678)."
          },
          "clientEmail": { "type": "string", "format": "email" },
          "address": { "type": "string" },
          "notes": { "type": "string" },
          "language": { "type": "string", "enum": ["en", "pt"] },
          "nationality": { "type": "string" }
        }
      },
      "PartnershipCreateRequest": {
        "type": "object",
        "required": [
          "name",
          "contactPersonName",
          "email",
          "phone",
          "partnershipType"
        ],
        "properties": {
          "name": { "type": "string" },
          "contactPersonName": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "phone": { "type": "string" },
          "partnershipType": {
            "type": "string",
            "enum": ["hotel", "boutique_hotel", "airbnb_manager"]
          },
          "address": { "type": "string" },
          "roomsOrHouses": { "type": "integer" },
          "workLocations": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["lisbon", "madeira-island"]
            }
          },
          "language": { "type": "string", "enum": ["en", "pt"] },
          "notes": { "type": "string" }
        }
      },
      "SessionResponse": {
        "type": "object",
        "properties": {
          "message": { "type": "string" },
          "session": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "status": {
                "type": "string",
                "enum": [
                  "in_validation",
                  "awaiting_therapist_availability",
                  "session_scheduled",
                  "completed",
                  "cancelled"
                ]
              },
              "service": { "type": "string" },
              "location": { "type": "string" },
              "dateTime": { "type": "string" },
              "duration": { "type": "integer" },
              "totalPrice": { "type": "number" },
              "currency": { "type": "string", "const": "EUR" }
            }
          },
          "nextSteps": { "type": "string" }
        }
      },
      "BookingResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Confirmation message."
          },
          "booking": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "Unique booking identifier."
              },
              "status": {
                "type": "string",
                "description": "Current booking status.",
                "enum": [
                  "awaiting_therapist_availability",
                  "availability_provided",
                  "confirmed",
                  "session_scheduled",
                  "completed",
                  "cancelled"
                ]
              },
              "service": {
                "type": "string",
                "description": "Name of the booked service."
              },
              "location": {
                "type": "string",
                "description": "Name of the location."
              },
              "dateTime": {
                "type": "string",
                "description": "Booked date and time (YYYY-MM-DDTHH:mm, Europe/Lisbon)."
              },
              "duration": {
                "type": "integer",
                "description": "Session duration in minutes."
              },
              "totalPrice": {
                "type": "number",
                "description": "Total price for the session."
              },
              "currency": {
                "type": "string",
                "const": "EUR"
              }
            }
          },
          "nextSteps": {
            "type": "string",
            "description": "What happens next after booking."
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Human-readable error description."
          },
          "missingFields": {
            "type": "array",
            "items": { "type": "string" },
            "description": "List of missing required fields (for 400 errors)."
          },
          "error": {
            "type": "string",
            "description": "Machine-readable error code."
          },
          "example": {
            "type": "object",
            "description": "Example of a valid request (for 400 errors)."
          }
        }
      }
    }
  }
}
