{"info":{"contact":{"email":"reservations@mascotcarrental.com"},"description":"Public API for Mascot Car Rental (Kos island, Greece). All prices come from the live tariff. AI bookings are requests only -- they require email verification and staff review before confirmation. No deposit is ever taken; payment is always at pickup.","title":"Mascot Car Rental -- Public API","version":"1.0.0"},"openapi":"3.0.3","paths":{"/api/public/ai/ask":{"post":{"description":"Ask a question about car availability in plain text. Parses dates and vehicle preferences from natural language and returns matching vehicles with pricing.","operationId":"askNaturalLanguage","requestBody":{"content":{"application/json":{"schema":{"properties":{"question":{"description":"e.g. \"Do you have a small car for July 10-15?\"","type":"string"}},"required":["question"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Parsed query with matching vehicles and pricing"},"400":{"description":"Missing question"}},"summary":"Natural language availability query"}},"/api/public/ai/booking":{"post":{"description":"Submit a car rental booking request on behalf of a customer. The customer MUST verify their email before the request reaches staff. Payment is always at pickup -- no deposit or card pre-authorisation is ever taken. Card details are explicitly rejected. Rate limited to 5 requests per IP per 24 hours. Set \"test\": true for a dry-run that exercises the full flow without creating a real booking. This operator may require 1-2 additional consent confirmations before booking -- call GET /api/public/site/settings and check site.consents for which are currently required and their exact text, then include matching consent_N_agreed: true fields below for each one present.","operationId":"submitAIBooking","requestBody":{"content":{"application/json":{"schema":{"properties":{"comments":{"description":"Optional customer comments","maxLength":500,"type":"string"},"consent_1_agreed":{"description":"Required only if site.consents from GET /api/public/site/settings includes slot 1. Confirms the customer agreed to that consent text.","type":"boolean"},"consent_2_agreed":{"description":"Required only if site.consents from GET /api/public/site/settings includes slot 2. Confirms the customer agreed to that consent text.","type":"boolean"},"customer_email":{"format":"email","type":"string"},"customer_name":{"type":"string"},"customer_phone":{"type":"string"},"end_date":{"description":"YYYY-MM-DD","format":"date","type":"string"},"extras":{"items":{"properties":{"extra_id":{"type":"integer"},"quantity":{"default":1,"type":"integer"}},"type":"object"},"type":"array"},"group_code":{"description":"Vehicle group code (e.g. A, B, C)","type":"string"},"insurance_tier_id":{"type":"integer"},"pickup_location_id":{"type":"integer"},"pickup_time":{"description":"HH:MM (default 09:00)","type":"string"},"return_location_id":{"type":"integer"},"return_time":{"description":"HH:MM (default 09:00)","type":"string"},"start_date":{"description":"YYYY-MM-DD","format":"date","type":"string"},"test":{"default":false,"description":"Set true for a test/demo run -- no real booking created","type":"boolean"}},"required":["group_code","start_date","end_date","customer_name","customer_email","customer_phone"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Test booking created (when test=true)"},"201":{"description":"Booking request submitted; verification email sent"},"400":{"description":"Validation error or card details rejected"},"404":{"description":"Vehicle group not found"},"409":{"description":"Group unavailable or bookings paused"},"429":{"description":"Rate limit exceeded"},"503":{"description":"AI bookings disabled by admin"}},"summary":"Submit a booking request via AI agent"}},"/api/public/ai/booking/{reference}/cancel":{"post":{"description":"Cancel a booking that was submitted via the AI booking API. Requires email match. Staff are notified via Telegram.","operationId":"cancelAIBooking","parameters":[{"in":"path","name":"reference","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"format":"email","type":"string"},"reason":{"description":"Optional cancellation reason","type":"string"}},"required":["email"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Booking cancelled successfully"},"400":{"description":"Missing email"},"404":{"description":"Booking not found or email mismatch"},"409":{"description":"Already cancelled or cannot be cancelled"}},"summary":"Cancel an AI booking"}},"/api/public/ai/booking/{reference}/modify":{"post":{"description":"Modify dates or vehicle group on an AI booking. Availability is checked before any modification is applied. If the requested group/dates are unavailable, returns alternative available groups. Requires email match.","operationId":"modifyAIBooking","parameters":[{"in":"path","name":"reference","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"changes":{"properties":{"pickup_date":{"format":"date","type":"string"},"pickup_time":{"type":"string"},"return_date":{"format":"date","type":"string"},"return_time":{"type":"string"},"vehicle_group":{"type":"string"}},"type":"object"},"email":{"format":"email","type":"string"}},"required":["email","changes"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Booking modified with new pricing"},"400":{"description":"Missing email or invalid data"},"404":{"description":"Booking not found or email mismatch"},"409":{"description":"Vehicle group unavailable (alternatives provided) or booking cannot be modified"}},"summary":"Modify an AI booking"}},"/api/public/ai/booking/{reference}/status":{"get":{"description":"Look up the status of an AI-submitted booking by reference number. Email is required to prevent enumeration.","operationId":"getAIBookingStatus","parameters":[{"description":"Booking reference (e.g. MAS-2026-0042)","in":"path","name":"reference","required":true,"schema":{"type":"string"}},{"description":"Customer email (must match booking)","in":"query","name":"email","required":true,"schema":{"format":"email","type":"string"}}],"responses":{"200":{"description":"Booking status with pricing and details"},"400":{"description":"Missing email parameter"},"404":{"description":"Booking not found or email mismatch"}},"summary":"Check AI booking status"}},"/api/public/availability/grouped":{"get":{"description":"Returns which vehicle groups have cars available for the given date range, along with live pricing.","operationId":"getGroupedAvailability","parameters":[{"in":"query","name":"start_date","required":true,"schema":{"format":"date","type":"string"}},{"in":"query","name":"end_date","required":true,"schema":{"format":"date","type":"string"}}],"responses":{"200":{"description":"Grouped availability with pricing"}},"summary":"Check availability by vehicle group for a date range"}},"/api/public/check-hours":{"get":{"description":"Returns whether the requested pickup/return times incur an out-of-hours surcharge and the fee amount.","operationId":"checkOutOfHoursFee","parameters":[{"in":"query","name":"start_date","required":true,"schema":{"format":"date","type":"string"}},{"in":"query","name":"end_date","required":true,"schema":{"format":"date","type":"string"}},{"description":"HH:MM","in":"query","name":"pickup_time","schema":{"type":"string"}},{"description":"HH:MM","in":"query","name":"return_time","schema":{"type":"string"}}],"responses":{"200":{"description":"OOH fee details"}},"summary":"Check out-of-hours fee for given times"}},"/api/public/extras":{"get":{"description":"Returns available extras (baby seat, GPS, etc.) with pricing. Some extras are per-day, some are flat-fee. Prices come from the live tariff.","operationId":"getExtras","responses":{"200":{"description":"Array of extras with pricing"}},"summary":"List available rental extras"}},"/api/public/fleet-status":{"get":{"description":"Returns total fleet size, available cars today, most popular vehicle group this month, and busiest upcoming days.","operationId":"getFleetStatus","responses":{"200":{"description":"Fleet status snapshot"}},"summary":"Real-time fleet snapshot"}},"/api/public/insurance":{"get":{"description":"Returns available insurance tiers and their daily rates per vehicle group. Basic CDW is included in all rentals; upgrades (e.g. FDW) reduce the excess.","operationId":"getInsuranceOptions","parameters":[{"description":"Filter by vehicle group code","in":"query","name":"group_code","schema":{"type":"string"}}],"responses":{"200":{"description":"Insurance tier list with pricing"}},"summary":"List insurance tiers with daily rates"}},"/api/public/pricing":{"post":{"description":"Server-side pricing calculation. Accepts group, dates, insurance, extras, locations and returns a complete price breakdown from the live tariff. No booking is created.","operationId":"calculatePricing","requestBody":{"content":{"application/json":{"schema":{"properties":{"end_date":{"format":"date","type":"string"},"extras":{"items":{"properties":{"extra_id":{"type":"integer"},"quantity":{"type":"integer"}},"type":"object"},"type":"array"},"group_code":{"description":"Vehicle group code (e.g. A, B, C, D)","type":"string"},"insurance_tier_id":{"type":"integer"},"pickup_location_id":{"type":"integer"},"pickup_time":{"description":"HH:MM","type":"string"},"return_location_id":{"type":"integer"},"return_time":{"description":"HH:MM","type":"string"},"start_date":{"format":"date","type":"string"}},"required":["group_code","start_date","end_date"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Full price breakdown"}},"summary":"Calculate full pricing for a rental configuration"}},"/api/public/site/locations":{"get":{"description":"Returns active pickup/return locations (airport, port, marina, office, hotels) with any delivery fees.","operationId":"getLocations","responses":{"200":{"description":"Array of locations"}},"summary":"List pickup and return locations"}},"/api/public/status":{"get":{"description":"Returns API version, operational status, AI booking count, rate limit info, and links to all discovery endpoints.","operationId":"getApiStatus","responses":{"200":{"description":"API status and capabilities"}},"summary":"API health and capabilities"}},"/api/public/terms":{"get":{"description":"Returns full terms and conditions in HTML and plain text, plus cancellation and fuel policies. Use the summary field for a quick overview of key policies.","operationId":"getTerms","parameters":[{"description":"Language (default: en)","in":"query","name":"lang","schema":{"enum":["en","el","de","it"],"type":"string"}}],"responses":{"200":{"description":"Terms and conditions with policies"}},"summary":"Terms and conditions"}},"/api/public/vehicle-groups":{"get":{"description":"Returns all active vehicle groups (categories) with their daily rates from the live WEB tariff. Prices reflect current seasonal and duration multipliers. Optionally pass start_date and end_date to get date-specific pricing.","operationId":"getVehicleGroups","parameters":[{"description":"YYYY-MM-DD","in":"query","name":"start_date","schema":{"format":"date","type":"string"}},{"description":"YYYY-MM-DD","in":"query","name":"end_date","schema":{"format":"date","type":"string"}}],"responses":{"200":{"description":"Array of vehicle groups with pricing"}},"summary":"List vehicle groups with live pricing"}},"/api/public/webhooks/subscribe":{"post":{"description":"Register a callback URL to receive notifications when booking events occur (accepted, rejected, cancelled, modified). Requires HTTPS URL and a secret for HMAC-SHA256 signing.","operationId":"subscribeWebhook","requestBody":{"content":{"application/json":{"schema":{"properties":{"events":{"items":{"enum":["booking.accepted","booking.rejected","booking.cancelled","booking.modified"],"type":"string"},"type":"array"},"secret":{"description":"Shared secret for HMAC signing (min 16 chars)","type":"string"},"url":{"description":"HTTPS callback URL","type":"string"}},"required":["url","events","secret"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Webhook registered"},"400":{"description":"Invalid URL, events, or weak secret"}},"summary":"Register a webhook for booking events"}}},"servers":[{"url":"https://mascotcarrental.com"}]}
