{
  "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)."
    },
    {
      "name": "ACP",
      "description": "Agentic Commerce Protocol checkout endpoints."
    }
  ],
  "paths": {
    "/api/public/v1/booking-partnerships": {
      "get": {
        "operationId": "listBookingPartnerships",
        "tags": ["Services"],
        "summary": "List bookable partner venues by region",
        "description": "Hotels, gyms, pharmacies, and other partners that accept external client bookings. Grouped by madeira-island and lisbon. Use partnershipSlug on GET /services and POST /sessions.",
        "security": [],
        "responses": {
          "200": {
            "description": "Partnerships per region"
          }
        }
      }
    },
    "/api/public/v1/services": {
      "get": {
        "operationId": "listServices",
        "tags": ["Services"],
        "summary": "List services and prices for a partnership",
        "description": "Requires partnershipSlug query from GET /booking-partnerships. Returns pricing rows for that venue.",
        "security": [],
        "parameters": [
          {
            "name": "partnershipSlug",
            "in": "query",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "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/availability": {
      "get": {
        "operationId": "listAvailability",
        "tags": ["Services"],
        "summary": "List open time slots for a venue on a date (privacy-safe)",
        "description": "Returns Lisbon HH:mm times that currently look open for the partnership, reusing the same anonymized engine as the internal availability insights. Never returns therapist names, ids, photos, or capacity counts. Advisory only — submitting still creates a request (not an instant booking). Best for today + 3 days; later dates return withinSchedulingHorizon=false.",
        "security": [],
        "parameters": [
          {
            "name": "partnershipSlug",
            "in": "query",
            "required": true,
            "description": "Venue slug from GET /booking-partnerships.",
            "schema": { "type": "string" }
          },
          {
            "name": "date",
            "in": "query",
            "required": true,
            "description": "Calendar date YYYY-MM-DD (Europe/Lisbon).",
            "schema": { "type": "string", "format": "date" },
            "example": "2026-06-15"
          },
          {
            "name": "serviceSlug",
            "in": "query",
            "required": false,
            "description": "Optional — narrows to therapists who perform this service.",
            "schema": { "type": "string" }
          },
          {
            "name": "duration",
            "in": "query",
            "required": false,
            "description": "Optional session length in minutes for overlap checks.",
            "schema": { "type": "integer", "minimum": 1 }
          }
        ],
        "responses": {
          "200": {
            "description": "Open time slots for the date (privacy-safe)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailabilityResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing/invalid partnershipSlug or date",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Partnership not bookable or not found",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/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" }
        }
      }
    },
    "/api/public/v1/acp/checkout_sessions": {
      "post": {
        "operationId": "acpCreateCheckoutSession",
        "tags": ["ACP"],
        "summary": "Create ACP checkout session",
        "description": "Creates an ACP checkout session. Requires Authorization, API-Version, and Idempotency-Key headers.",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": { "type": "string" },
            "example": "Bearer merchant_api_key"
          },
          {
            "name": "API-Version",
            "in": "header",
            "required": true,
            "schema": { "type": "string" },
            "example": "2026-04-17"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcpCheckoutSessionCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Checkout session created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcpCheckoutSession"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/acp/checkout_sessions/{checkout_session_id}": {
      "get": {
        "operationId": "acpGetCheckoutSession",
        "tags": ["ACP"],
        "summary": "Retrieve ACP checkout session",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "API-Version",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "checkout_session_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Checkout session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcpCheckoutSession"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "acpUpdateCheckoutSession",
        "tags": ["ACP"],
        "summary": "Update ACP checkout session",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "API-Version",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "checkout_session_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcpCheckoutSessionUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout session updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcpCheckoutSession"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/acp/checkout_sessions/{checkout_session_id}/complete": {
      "post": {
        "operationId": "acpCompleteCheckoutSession",
        "tags": ["ACP"],
        "summary": "Complete ACP checkout session",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "API-Version",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "checkout_session_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcpCheckoutSessionCompleteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout completed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcpCheckoutSessionWithOrder"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/acp/checkout_sessions/{checkout_session_id}/cancel": {
      "post": {
        "operationId": "acpCancelCheckoutSession",
        "tags": ["ACP"],
        "summary": "Cancel ACP checkout session",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "API-Version",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": { "type": "string" }
          },
          {
            "name": "checkout_session_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Checkout canceled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcpCheckoutSession"
                }
              }
            }
          }
        }
      }
    }
  },
  "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",
        "description": "Privacy-safe open time slots for a venue on a date. Never includes therapist identity or how many therapists are free — only whether a time looks open. Availability is advisory: submitting still creates a request, not an instant booking.",
        "properties": {
          "partnershipSlug": {
            "type": "string",
            "description": "Venue these slots belong to."
          },
          "partnershipName": { "type": "string" },
          "date": {
            "type": "string",
            "format": "date",
            "description": "The requested date (Europe/Lisbon calendar)."
          },
          "timezone": {
            "type": "string",
            "description": "Timezone used for all times (always Europe/Lisbon).",
            "const": "Europe/Lisbon"
          },
          "hasAvailability": {
            "type": "boolean",
            "description": "True when at least one open slot was found for this date."
          },
          "slots": {
            "type": "array",
            "description": "Open time slots. Empty array does not mean unavailable — a booking request can still be submitted.",
            "items": {
              "$ref": "#/components/schemas/TimeSlot"
            }
          },
          "withinSchedulingHorizon": {
            "type": "boolean",
            "description": "True when the date is inside the rolling window (today + 3 days) where open slots are pre-computed. When false, an empty slots array is expected and the guest should just submit a request."
          },
          "note": {
            "type": "string",
            "description": "Plain-language guidance for the AI agent or guest."
          },
          "confirmationNotice": { "type": "object" },
          "support": { "type": "object" }
        }
      },
      "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": "Always true for returned slots — the response only lists open times (no capacity counts)."
          }
        }
      },
      "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",
            "minimum": 1,
            "description":
              "Session length in minutes — must match a catalog row from GET /services."
          },
          "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."
          }
        }
      },
      "AcpCheckoutSessionCreateRequest": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AcpCheckoutItemInput" },
            "description":
              "Item IDs must use partnershipSlug:serviceSlug:durationMinutes (example: local-pharma:relaxing-massage:60)."
          },
          "buyer": { "$ref": "#/components/schemas/AcpBuyer" },
          "fulfillment_details": {
            "$ref": "#/components/schemas/AcpFulfillmentDetails"
          },
          "capabilities": { "$ref": "#/components/schemas/AcpCapabilities" }
        }
      },
      "AcpCheckoutSessionUpdateRequest": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AcpCheckoutItemInput" }
          },
          "buyer": { "$ref": "#/components/schemas/AcpBuyer" },
          "fulfillment_details": {
            "$ref": "#/components/schemas/AcpFulfillmentDetails"
          },
          "selected_fulfillment_options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AcpSelectedFulfillmentOption"
            }
          }
        }
      },
      "AcpCheckoutSessionCompleteRequest": {
        "type": "object",
        "required": ["payment_data"],
        "properties": {
          "buyer": { "$ref": "#/components/schemas/AcpBuyer" },
          "payment_data": { "$ref": "#/components/schemas/AcpPaymentData" }
        }
      },
      "AcpCheckoutSession": {
        "type": "object",
        "required": [
          "id",
          "status",
          "currency",
          "line_items",
          "totals",
          "capabilities"
        ],
        "properties": {
          "id": { "type": "string" },
          "status": {
            "type": "string",
            "enum": [
              "not_ready_for_payment",
              "ready_for_payment",
              "completed",
              "canceled"
            ]
          },
          "currency": { "type": "string", "const": "eur" },
          "line_items": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AcpLineItem" }
          },
          "totals": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AcpTotal" }
          },
          "messages": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AcpMessage" }
          },
          "buyer": { "$ref": "#/components/schemas/AcpBuyer" },
          "fulfillment_details": {
            "$ref": "#/components/schemas/AcpFulfillmentDetails"
          },
          "selected_fulfillment_options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AcpSelectedFulfillmentOption"
            }
          },
          "capabilities": { "$ref": "#/components/schemas/AcpCapabilities" },
          "support": { "$ref": "#/components/schemas/AcpSupportInfo" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" },
          "expires_at": { "type": "string", "format": "date-time" }
        }
      },
      "AcpCheckoutSessionWithOrder": {
        "allOf": [
          { "$ref": "#/components/schemas/AcpCheckoutSession" },
          {
            "type": "object",
            "required": ["order"],
            "properties": {
              "order": { "$ref": "#/components/schemas/AcpOrder" }
            }
          }
        ]
      },
      "AcpCheckoutItemInput": {
        "type": "object",
        "required": ["id", "quantity"],
        "properties": {
          "id": { "type": "string" },
          "quantity": { "type": "integer", "minimum": 1 }
        }
      },
      "AcpLineItem": {
        "type": "object",
        "required": ["id", "item", "quantity", "totals"],
        "properties": {
          "id": { "type": "string" },
          "item": {
            "type": "object",
            "required": ["id", "name", "unit_amount"],
            "properties": {
              "id": { "type": "string" },
              "name": { "type": "string" },
              "unit_amount": { "type": "integer" }
            }
          },
          "quantity": { "type": "integer", "minimum": 1 },
          "name": { "type": "string" },
          "unit_amount": { "type": "integer" },
          "product_id": { "type": "string" },
          "sku": { "type": "string" },
          "totals": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AcpTotal" }
          }
        }
      },
      "AcpTotal": {
        "type": "object",
        "required": ["type", "display_text", "amount"],
        "properties": {
          "type": { "type": "string" },
          "display_text": { "type": "string" },
          "amount": { "type": "integer" }
        }
      },
      "AcpMessage": {
        "type": "object",
        "required": ["type", "code", "content_type", "content"],
        "properties": {
          "type": { "type": "string", "enum": ["error", "warning", "info"] },
          "code": { "type": "string" },
          "resolution": { "type": "string" },
          "param": { "type": "string" },
          "content_type": { "type": "string", "enum": ["plain", "markdown"] },
          "content": { "type": "string" }
        }
      },
      "AcpBuyer": {
        "type": "object",
        "properties": {
          "first_name": { "type": "string" },
          "last_name": { "type": "string" },
          "full_name": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "phone_number": { "type": "string" }
        }
      },
      "AcpAddress": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "line_one": { "type": "string" },
          "line_two": { "type": "string" },
          "city": { "type": "string" },
          "state": { "type": "string" },
          "country": { "type": "string" },
          "postal_code": { "type": "string" }
        }
      },
      "AcpFulfillmentDetails": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "phone_number": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "address": { "$ref": "#/components/schemas/AcpAddress" }
        }
      },
      "AcpSelectedFulfillmentOption": {
        "type": "object",
        "properties": {
          "type": { "type": "string" },
          "option_id": { "type": "string" },
          "item_ids": { "type": "array", "items": { "type": "string" } }
        }
      },
      "AcpPaymentData": {
        "type": "object",
        "required": ["handler_id", "instrument"],
        "properties": {
          "handler_id": { "type": "string" },
          "instrument": {
            "type": "object",
            "required": ["type", "credential"],
            "properties": {
              "type": { "type": "string" },
              "credential": {
                "type": "object",
                "required": ["type", "token"],
                "properties": {
                  "type": { "type": "string" },
                  "token": { "type": "string" }
                }
              }
            }
          }
        }
      },
      "AcpPaymentHandler": {
        "type": "object",
        "required": [
          "id",
          "name",
          "version",
          "spec",
          "requires_delegate_payment",
          "requires_pci_compliance",
          "psp",
          "config_schema",
          "instrument_schemas",
          "config"
        ],
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "display_name": { "type": "string" },
          "version": { "type": "string" },
          "spec": { "type": "string", "format": "uri" },
          "requires_delegate_payment": { "type": "boolean" },
          "requires_pci_compliance": { "type": "boolean" },
          "psp": { "type": "string" },
          "config_schema": { "type": "string", "format": "uri" },
          "instrument_schemas": {
            "type": "array",
            "items": { "type": "string", "format": "uri" }
          },
          "config": { "type": "object" }
        }
      },
      "AcpCapabilities": {
        "type": "object",
        "properties": {
          "payment": {
            "type": "object",
            "properties": {
              "handlers": {
                "type": "array",
                "items": { "$ref": "#/components/schemas/AcpPaymentHandler" }
              }
            }
          },
          "interventions": {
            "type": "object",
            "properties": {
              "supported": {
                "type": "array",
                "items": { "type": "string" }
              }
            }
          },
          "extensions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": { "type": "string" },
                "extends": {
                  "type": "array",
                  "items": { "type": "string" }
                },
                "spec": { "type": "string", "format": "uri" }
              }
            }
          }
        }
      },
      "AcpSupportInfo": {
        "type": "object",
        "properties": {
          "email": { "type": "string", "format": "email" },
          "help_center_url": { "type": "string", "format": "uri" }
        }
      },
      "AcpOrder": {
        "type": "object",
        "required": ["type", "id", "checkout_session_id", "permalink_url"],
        "properties": {
          "type": { "type": "string", "const": "order" },
          "id": { "type": "string" },
          "checkout_session_id": { "type": "string" },
          "order_number": { "type": "string" },
          "permalink_url": { "type": "string", "format": "uri" },
          "status": { "type": "string" },
          "support": { "$ref": "#/components/schemas/AcpSupportInfo" },
          "line_items": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AcpOrderLineItem" }
          },
          "totals": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AcpTotal" }
          }
        }
      },
      "AcpOrderLineItem": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "title": { "type": "string" },
          "product_id": { "type": "string" },
          "quantity": {
            "type": "object",
            "properties": {
              "ordered": { "type": "integer" },
              "current": { "type": "integer" },
              "fulfilled": { "type": "integer" }
            }
          },
          "unit_price": { "type": "integer" },
          "subtotal": { "type": "integer" },
          "status": { "type": "string" },
          "totals": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AcpTotal" }
          }
        }
      },
      "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)."
          }
        }
      }
    }
  }
}
