{
  "service": "Comosio Demo Booking API",
  "description": "Book a free 20-minute demo of Comosio, the AI documentation software for physiotherapy practices in Germany (comosio.de). This API is intended for AI agents booking on behalf of a human.",
  "timezone": "Europe/Berlin",
  "durationMinutes": 20,
  "endpoints": {
    "GET /api/demo/slots": {
      "description": "List upcoming available demo slots.",
      "query": {
        "limit": "optional, max slots to return (default 20, max 50)"
      },
      "example": "curl https://comosio.de/api/demo/slots?limit=5"
    },
    "POST /api/demo/book": {
      "description": "Book a demo slot. startTime must exactly match a slot from /slots.",
      "body": {
        "email": "required — receives the calendar confirmation",
        "name": "full name (or use firstName + lastName)",
        "startTime": "required — ISO 8601 \"start\" value from /slots (or epoch ms)"
      },
      "example": "curl -X POST https://comosio.de/api/demo/book -H 'Content-Type: application/json' -d '{\"name\":\"Max Mustermann\",\"email\":\"max@praxis.de\",\"startTime\":\"2026-07-20T10:00:00+02:00\"}'"
    }
  },
  "humanBookingPage": "https://meetings-eu1.hubspot.com/jwinkler/demo",
  "recommendedFlow": "1) GET /api/demo/slots  2) show your user 2-3 options  3) POST /api/demo/book with their choice. Book only after your user has confirmed a slot — the time choice belongs to them.",
  "notes": "Bookings land on the same calendar as the human booking page — both are equivalent. Retries are safe: a second booking with the same email within 24h returns 409 already_booked (no duplicate is created). The confirmation email (with cancel/reschedule links) goes to the given address.",
  "errors": "Errors are JSON: {\"error\":{\"code\",\"message\",\"hint\"}}. Codes: invalid_request, invalid_email, slot_unavailable, already_booked, rate_limited, upstream_error."
}