{
  "openapi": "3.0.3",
  "info": {
    "title": "Rinsepay Owner API",
    "version": "1.0.0",
    "description": "Read access to everything in your Rinsepay account. Authenticate with an API key from Settings → API Access as a Bearer token. Lists return { data, next_cursor }; pass next_cursor back as ?cursor= until it is null. Limits: 30 calls/min and 2,000/day per key (heavy exports count 5); see the X-RateLimit-* headers."
  },
  "servers": [
    {
      "url": "https://api.rinsepay.app",
      "description": "Production"
    },
    {
      "url": "https://api.rinsepay.design",
      "description": "Sandbox (test-mode keys)"
    }
  ],
  "security": [
    {
      "ApiKey": []
    }
  ],
  "tags": [
    {
      "name": "Meta"
    },
    {
      "name": "Locations"
    },
    {
      "name": "Bays"
    },
    {
      "name": "Controllers"
    },
    {
      "name": "Sessions"
    },
    {
      "name": "Money"
    },
    {
      "name": "Customers"
    },
    {
      "name": "Memberships"
    },
    {
      "name": "Bundles"
    },
    {
      "name": "Fleet"
    },
    {
      "name": "Rewards"
    },
    {
      "name": "Analytics"
    },
    {
      "name": "Staff"
    },
    {
      "name": "Support"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "rp_live_… / rp_test_…",
        "description": "Owner API key created on Settings → API Access."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "Me": {
        "type": "object",
        "properties": {
          "owner_id": {
            "type": "string",
            "format": "uuid"
          },
          "business_name": {
            "type": "string"
          },
          "account_number": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "test_mode": {
            "type": "boolean"
          },
          "key": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "prefix": {
                "type": "string"
              },
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "id",
              "prefix",
              "scopes"
            ]
          }
        },
        "required": [
          "owner_id",
          "business_name",
          "account_number",
          "timezone",
          "test_mode",
          "key"
        ]
      },
      "MeResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Me"
          }
        },
        "required": [
          "data"
        ]
      },
      "Location": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "company_name": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "zip": {
            "type": "string"
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "support_email": {
            "type": "string",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "location_tz": {
            "type": "string"
          },
          "latitude": {
            "type": "number",
            "nullable": true
          },
          "longitude": {
            "type": "number",
            "nullable": true
          },
          "out_of_service_message": {
            "type": "string",
            "nullable": true
          },
          "state_tax_rate": {
            "type": "number"
          },
          "local_tax_rate": {
            "type": "number"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "company_name",
          "address",
          "city",
          "state",
          "zip",
          "phone",
          "support_email",
          "is_active",
          "location_tz",
          "latitude",
          "longitude",
          "out_of_service_message",
          "state_tax_rate",
          "local_tax_rate",
          "created_at",
          "updated_at"
        ]
      },
      "LocationList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Location"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "LocationResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Location"
          }
        },
        "required": [
          "data"
        ]
      },
      "BayTier": {
        "type": "object",
        "properties": {
          "tier_id": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string"
          },
          "price_cents": {
            "type": "integer"
          },
          "enabled": {
            "type": "boolean"
          }
        },
        "required": [
          "tier_id",
          "name",
          "price_cents",
          "enabled"
        ]
      },
      "BayAction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "price_cents": {
            "type": "integer",
            "nullable": true
          },
          "enabled": {
            "type": "boolean"
          },
          "steps": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "kind",
          "name",
          "price_cents",
          "enabled",
          "steps"
        ]
      },
      "Bay": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "location_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "is_active": {
            "type": "boolean"
          },
          "config_mode": {
            "type": "string"
          },
          "price_per_minute": {
            "type": "number",
            "nullable": true
          },
          "minimum_charge_cents": {
            "type": "integer",
            "nullable": true
          },
          "maximum_charge_cents": {
            "type": "integer",
            "nullable": true
          },
          "tiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BayTier"
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BayAction"
            }
          },
          "live_state": {
            "type": "object",
            "properties": {
              "in_use": {
                "type": "boolean"
              },
              "out_of_service": {
                "type": "boolean"
              },
              "testing": {
                "type": "boolean"
              }
            },
            "required": [
              "in_use",
              "out_of_service",
              "testing"
            ]
          },
          "controllers": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "deep_link": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "location_id",
          "name",
          "type",
          "is_active",
          "config_mode",
          "price_per_minute",
          "minimum_charge_cents",
          "maximum_charge_cents",
          "tiers",
          "actions",
          "live_state",
          "controllers",
          "deep_link",
          "created_at",
          "updated_at"
        ]
      },
      "BayList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Bay"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "BayResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Bay"
          }
        },
        "required": [
          "data"
        ]
      },
      "VendingMachine": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "location_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "machine_type": {
            "type": "string",
            "nullable": true
          },
          "controller_id": {
            "type": "string",
            "nullable": true
          },
          "relay_index": {
            "type": "integer",
            "nullable": true
          },
          "credit_step_cents": {
            "type": "integer",
            "nullable": true
          },
          "max_credit_cents": {
            "type": "integer",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "location_id",
          "name",
          "machine_type",
          "controller_id",
          "relay_index",
          "credit_step_cents",
          "max_credit_cents",
          "is_active",
          "created_at",
          "updated_at"
        ]
      },
      "VendingMachineList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VendingMachine"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "Controller": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "model": {
            "type": "string"
          },
          "model_label": {
            "type": "string"
          },
          "firmware_version": {
            "type": "string",
            "nullable": true
          },
          "firmware_family": {
            "type": "string",
            "nullable": true
          },
          "relay_count": {
            "type": "integer"
          },
          "input_count": {
            "type": "integer"
          },
          "is_online": {
            "type": "boolean"
          },
          "last_seen": {
            "type": "string",
            "nullable": true
          },
          "ip_address": {
            "type": "string",
            "nullable": true
          },
          "wifi_rssi": {
            "type": "number",
            "nullable": true
          },
          "uptime_seconds": {
            "type": "number",
            "nullable": true
          },
          "free_heap": {
            "type": "number",
            "nullable": true
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "relay_states": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "number"
            }
          },
          "inputs_state": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "ota_status": {
            "type": "string",
            "nullable": true
          },
          "ota_version": {
            "type": "string",
            "nullable": true
          },
          "serves": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "type": "string"
                },
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              },
              "required": [
                "kind",
                "id",
                "name"
              ]
            }
          },
          "claimed_at": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "model",
          "model_label",
          "firmware_version",
          "firmware_family",
          "relay_count",
          "input_count",
          "is_online",
          "last_seen",
          "ip_address",
          "wifi_rssi",
          "uptime_seconds",
          "free_heap",
          "capabilities",
          "relay_states",
          "inputs_state",
          "ota_status",
          "ota_version",
          "serves",
          "claimed_at",
          "created_at"
        ]
      },
      "ControllerList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Controller"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "ControllerResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Controller"
          }
        },
        "required": [
          "data"
        ]
      },
      "WashSession": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "location_id": {
            "type": "string",
            "format": "uuid"
          },
          "bay_id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "bay_type": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "funding": {
            "type": "string"
          },
          "started_at": {
            "type": "string"
          },
          "ended_at": {
            "type": "string",
            "nullable": true
          },
          "duration_minutes": {
            "type": "number",
            "nullable": true
          },
          "price_per_minute": {
            "type": "number",
            "nullable": true
          },
          "gross_cents": {
            "type": "integer"
          },
          "platform_fee_cents": {
            "type": "integer"
          },
          "owner_payout_cents": {
            "type": "integer"
          },
          "refunded_cents": {
            "type": "integer"
          },
          "payment_brand": {
            "type": "string",
            "nullable": true
          },
          "fleet_account_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "attendant_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "owner_initiated": {
            "type": "boolean"
          },
          "location_tz": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "location_id",
          "bay_id",
          "user_id",
          "bay_type",
          "status",
          "funding",
          "started_at",
          "ended_at",
          "duration_minutes",
          "price_per_minute",
          "gross_cents",
          "platform_fee_cents",
          "owner_payout_cents",
          "refunded_cents",
          "payment_brand",
          "fleet_account_id",
          "attendant_id",
          "owner_initiated",
          "location_tz",
          "created_at"
        ]
      },
      "WashSessionList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WashSession"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "WashSessionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/WashSession"
          }
        },
        "required": [
          "data"
        ]
      },
      "LineItem": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "amount_cents": {
            "type": "integer"
          },
          "funded_by": {
            "type": "string"
          }
        },
        "required": [
          "kind",
          "name",
          "amount_cents",
          "funded_by"
        ]
      },
      "Transaction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "location_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "bay_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "vending_machine_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string"
          },
          "tier_name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "amount_cents": {
            "type": "integer"
          },
          "platform_fee_cents": {
            "type": "integer"
          },
          "owner_payout_cents": {
            "type": "integer"
          },
          "stripe_fee_cents": {
            "type": "integer",
            "nullable": true
          },
          "refunded_cents": {
            "type": "integer"
          },
          "payment_brand": {
            "type": "string",
            "nullable": true
          },
          "stripe_payment_intent_id": {
            "type": "string",
            "nullable": true
          },
          "line_items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LineItem"
            }
          },
          "location_tz": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "location_id",
          "bay_id",
          "vending_machine_id",
          "user_id",
          "type",
          "tier_name",
          "status",
          "amount_cents",
          "platform_fee_cents",
          "owner_payout_cents",
          "stripe_fee_cents",
          "refunded_cents",
          "payment_brand",
          "stripe_payment_intent_id",
          "line_items",
          "location_tz",
          "created_at"
        ]
      },
      "TransactionList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Transaction"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "TransactionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Transaction"
          }
        },
        "required": [
          "data"
        ]
      },
      "Refund": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "transaction_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "wash_session_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "amount_cents": {
            "type": "integer"
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "stripe_refund_id": {
            "type": "string",
            "nullable": true
          },
          "issued_by_role": {
            "type": "string",
            "nullable": true
          },
          "restored_quantity": {
            "type": "integer",
            "nullable": true
          },
          "restored_unit": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "transaction_id",
          "wash_session_id",
          "amount_cents",
          "kind",
          "status",
          "reason",
          "stripe_refund_id",
          "issued_by_role",
          "restored_quantity",
          "restored_unit",
          "created_at"
        ]
      },
      "RefundList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Refund"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "Customer": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "account_number": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string"
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          },
          "membership": {
            "type": "object",
            "nullable": true,
            "properties": {
              "plan_id": {
                "type": "string",
                "format": "uuid"
              },
              "plan_name": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "setup_state": {
                "type": "string"
              }
            },
            "required": [
              "plan_id",
              "plan_name",
              "status",
              "setup_state"
            ]
          },
          "bundles_remaining": {
            "type": "integer"
          },
          "points_balance": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "account_number",
          "name",
          "email",
          "phone",
          "created_at",
          "membership",
          "bundles_remaining",
          "points_balance"
        ],
        "description": "Without the read:pii scope, name is the first name + initial, email is masked (j***@gmail.com) and phone is null."
      },
      "CustomerList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Customer"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "CustomerResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Customer"
          }
        },
        "required": [
          "data"
        ]
      },
      "SubscriptionPlan": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "plan_type": {
            "type": "string"
          },
          "tier_name": {
            "type": "string",
            "nullable": true
          },
          "price_monthly_cents": {
            "type": "integer"
          },
          "max_washes_per_day": {
            "type": "number",
            "nullable": true
          },
          "max_washes_per_month": {
            "type": "number",
            "nullable": true
          },
          "max_minutes_per_day": {
            "type": "number",
            "nullable": true
          },
          "max_minutes_per_month": {
            "type": "number",
            "nullable": true
          },
          "location_scope": {
            "type": "string",
            "nullable": true
          },
          "location_ids": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            }
          },
          "included_upsell_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "is_active": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "plan_type",
          "tier_name",
          "price_monthly_cents",
          "max_washes_per_day",
          "max_washes_per_month",
          "max_minutes_per_day",
          "max_minutes_per_month",
          "location_scope",
          "location_ids",
          "included_upsell_ids",
          "is_active",
          "created_at"
        ]
      },
      "SubscriptionPlanList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SubscriptionPlan"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "Subscription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "customer_id": {
            "type": "string",
            "format": "uuid"
          },
          "plan_id": {
            "type": "string",
            "format": "uuid"
          },
          "plan_name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "setup_state": {
            "type": "string"
          },
          "billing": {
            "type": "string",
            "enum": [
              "stripe",
              "none"
            ]
          },
          "current_period_start": {
            "type": "string",
            "nullable": true
          },
          "current_period_end": {
            "type": "string",
            "nullable": true
          },
          "next_bill_date": {
            "type": "string",
            "nullable": true
          },
          "cancel_at_period_end": {
            "type": "boolean"
          },
          "canceled_at": {
            "type": "string",
            "nullable": true
          },
          "suspended_at": {
            "type": "string",
            "nullable": true
          },
          "washes_used_today": {
            "type": "integer"
          },
          "washes_used_this_month": {
            "type": "integer"
          },
          "minutes_used_this_month": {
            "type": "number"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "customer_id",
          "plan_id",
          "plan_name",
          "status",
          "setup_state",
          "billing",
          "current_period_start",
          "current_period_end",
          "next_bill_date",
          "cancel_at_period_end",
          "canceled_at",
          "suspended_at",
          "washes_used_today",
          "washes_used_this_month",
          "minutes_used_this_month",
          "created_at"
        ]
      },
      "SubscriptionList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Subscription"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "SubscriptionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Subscription"
          }
        },
        "required": [
          "data"
        ]
      },
      "BundlePlan": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "tier_name": {
            "type": "string",
            "nullable": true
          },
          "wash_count": {
            "type": "integer"
          },
          "price_cents": {
            "type": "integer"
          },
          "location_scope": {
            "type": "string",
            "nullable": true
          },
          "expiration_days": {
            "type": "number",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "tier_name",
          "wash_count",
          "price_cents",
          "location_scope",
          "expiration_days",
          "is_active",
          "created_at"
        ]
      },
      "BundlePlanList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BundlePlan"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "Bundle": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "customer_id": {
            "type": "string",
            "format": "uuid"
          },
          "bundle_plan_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "washes_total": {
            "type": "integer"
          },
          "washes_used": {
            "type": "integer"
          },
          "washes_remaining": {
            "type": "integer"
          },
          "amount_paid_cents": {
            "type": "integer"
          },
          "refunded_cents": {
            "type": "integer"
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "type": "string"
                },
                "tier_name": {
                  "type": "string",
                  "nullable": true
                },
                "total_quantity": {
                  "type": "number",
                  "nullable": true
                },
                "used_quantity": {
                  "type": "number",
                  "nullable": true
                },
                "total_minutes": {
                  "type": "number",
                  "nullable": true
                },
                "used_minutes": {
                  "type": "number",
                  "nullable": true
                }
              },
              "required": [
                "kind",
                "tier_name",
                "total_quantity",
                "used_quantity",
                "total_minutes",
                "used_minutes"
              ]
            }
          },
          "expires_at": {
            "type": "string",
            "nullable": true
          },
          "purchased_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "customer_id",
          "bundle_plan_id",
          "status",
          "washes_total",
          "washes_used",
          "washes_remaining",
          "amount_paid_cents",
          "refunded_cents",
          "items",
          "expires_at",
          "purchased_at"
        ]
      },
      "BundleList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Bundle"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "FleetAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "company_name": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "pricing_tier_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "billing_email": {
            "type": "string",
            "nullable": true
          },
          "payment_terms_days": {
            "type": "number",
            "nullable": true
          },
          "monthly_spending_limit_cents": {
            "type": "number",
            "nullable": true
          },
          "autopay_enabled": {
            "type": "boolean"
          },
          "primary_contact": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "nullable": true
              },
              "email": {
                "type": "string",
                "nullable": true
              },
              "phone": {
                "type": "string",
                "nullable": true
              }
            },
            "required": [
              "name",
              "email",
              "phone"
            ]
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "company_name",
          "status",
          "pricing_tier_id",
          "billing_email",
          "payment_terms_days",
          "monthly_spending_limit_cents",
          "autopay_enabled",
          "primary_contact",
          "created_at"
        ]
      },
      "FleetAccountList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FleetAccount"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "FleetAccountResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/FleetAccount"
          }
        },
        "required": [
          "data"
        ]
      },
      "FleetVehicle": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fleet_account_id": {
            "type": "string",
            "format": "uuid"
          },
          "license_plate": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "nullable": true
          },
          "make": {
            "type": "string",
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true
          },
          "year": {
            "type": "number",
            "nullable": true
          },
          "color": {
            "type": "string",
            "nullable": true
          },
          "nickname": {
            "type": "string",
            "nullable": true
          },
          "department": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "fleet_account_id",
          "license_plate",
          "state",
          "make",
          "model",
          "year",
          "color",
          "nickname",
          "department",
          "status",
          "created_at"
        ]
      },
      "FleetVehicleList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FleetVehicle"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "FleetInvoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fleet_account_id": {
            "type": "string",
            "format": "uuid"
          },
          "invoice_number": {
            "type": "string"
          },
          "billing_period_start": {
            "type": "string",
            "nullable": true
          },
          "billing_period_end": {
            "type": "string",
            "nullable": true
          },
          "subtotal_cents": {
            "type": "integer"
          },
          "discount_percentage": {
            "type": "number",
            "nullable": true
          },
          "discount_cents": {
            "type": "integer"
          },
          "tax_cents": {
            "type": "integer"
          },
          "total_cents": {
            "type": "integer"
          },
          "status": {
            "type": "string"
          },
          "due_date": {
            "type": "string",
            "nullable": true
          },
          "sent_at": {
            "type": "string",
            "nullable": true
          },
          "paid_at": {
            "type": "string",
            "nullable": true
          },
          "payment_method": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "fleet_account_id",
          "invoice_number",
          "billing_period_start",
          "billing_period_end",
          "subtotal_cents",
          "discount_percentage",
          "discount_cents",
          "tax_cents",
          "total_cents",
          "status",
          "due_date",
          "sent_at",
          "paid_at",
          "payment_method",
          "created_at"
        ]
      },
      "FleetInvoiceList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FleetInvoice"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "FleetInvoiceDetail": {
        "type": "object",
        "properties": {
          "data": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FleetInvoice"
              },
              {
                "type": "object",
                "properties": {
                  "washes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "bay_id": {
                          "type": "string",
                          "nullable": true
                        },
                        "wash_type": {
                          "type": "string",
                          "nullable": true
                        },
                        "retail_price_cents": {
                          "type": "integer"
                        },
                        "status": {
                          "type": "string"
                        },
                        "created_at": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "bay_id",
                        "wash_type",
                        "retail_price_cents",
                        "status",
                        "created_at"
                      ]
                    }
                  }
                },
                "required": [
                  "washes"
                ]
              }
            ]
          }
        },
        "required": [
          "data"
        ]
      },
      "Voucher": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "discount_kind": {
            "type": "string",
            "nullable": true
          },
          "percent_off": {
            "type": "number",
            "nullable": true
          },
          "free_minutes": {
            "type": "number",
            "nullable": true
          },
          "credit_cents": {
            "type": "number",
            "nullable": true
          },
          "tier_name": {
            "type": "string",
            "nullable": true
          },
          "bay_type": {
            "type": "string",
            "nullable": true
          },
          "location_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "redemption_limit": {
            "type": "number",
            "nullable": true
          },
          "redemptions_used": {
            "type": "integer"
          },
          "per_customer_limit": {
            "type": "number",
            "nullable": true
          },
          "expires_at": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "code",
          "kind",
          "discount_kind",
          "percent_off",
          "free_minutes",
          "credit_cents",
          "tier_name",
          "bay_type",
          "location_id",
          "status",
          "redemption_limit",
          "redemptions_used",
          "per_customer_limit",
          "expires_at",
          "source",
          "created_at"
        ]
      },
      "VoucherList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Voucher"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "VoucherRedemption": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "voucher_id": {
            "type": "string",
            "format": "uuid"
          },
          "customer_id": {
            "type": "string",
            "format": "uuid"
          },
          "transaction_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "wash_session_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "bay_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "discount_cents": {
            "type": "integer"
          },
          "redeemed_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "voucher_id",
          "customer_id",
          "transaction_id",
          "wash_session_id",
          "bay_id",
          "discount_cents",
          "redeemed_at"
        ]
      },
      "VoucherRedemptionList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VoucherRedemption"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "PointsSummary": {
        "type": "object",
        "properties": {
          "customers_with_points": {
            "type": "integer"
          },
          "outstanding_balance": {
            "type": "integer"
          },
          "lifetime_earned": {
            "type": "integer"
          },
          "earned_last_30_days": {
            "type": "integer"
          },
          "redeemed_last_30_days": {
            "type": "integer"
          }
        },
        "required": [
          "customers_with_points",
          "outstanding_balance",
          "lifetime_earned",
          "earned_last_30_days",
          "redeemed_last_30_days"
        ]
      },
      "PointsSummaryResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PointsSummary"
          }
        },
        "required": [
          "data"
        ]
      },
      "Report": {
        "type": "object",
        "properties": {},
        "description": "Same payload as the owner panel endpoint, keys in snake_case."
      },
      "AnalyticsSummary": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Report"
          }
        },
        "required": [
          "data"
        ]
      },
      "AnalyticsRevenue": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Report"
          }
        },
        "required": [
          "data"
        ]
      },
      "AnalyticsPnl": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Report"
          }
        },
        "required": [
          "data"
        ]
      },
      "AnalyticsSalesTax": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Report"
          }
        },
        "required": [
          "data"
        ]
      },
      "AnalyticsHeatmap": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Report"
          }
        },
        "required": [
          "data"
        ]
      },
      "Attendant": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "hire_date": {
            "type": "string",
            "nullable": true
          },
          "hourly_rate_cents": {
            "type": "number",
            "nullable": true
          },
          "overtime_rule": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "user_id",
          "name",
          "email",
          "is_active",
          "hire_date",
          "hourly_rate_cents",
          "overtime_rule",
          "created_at"
        ]
      },
      "AttendantList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Attendant"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "Shift": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "attendant_id": {
            "type": "string",
            "format": "uuid"
          },
          "location_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "clock_in_time": {
            "type": "string"
          },
          "clock_out_time": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "locked_at": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "attendant_id",
          "location_id",
          "clock_in_time",
          "clock_out_time",
          "status",
          "notes",
          "locked_at",
          "created_at"
        ]
      },
      "ShiftList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Shift"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "PayrollReport": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Report"
          }
        },
        "required": [
          "data"
        ]
      },
      "Expense": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "location_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "category": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "amount_cents": {
            "type": "integer"
          },
          "incurred_on": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "location_id",
          "category",
          "description",
          "amount_cents",
          "incurred_on",
          "created_at"
        ]
      },
      "ExpenseList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Expense"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "ProblemReport": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "transaction_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "location_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "bay_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "category": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "tx_amount_cents": {
            "type": "number",
            "nullable": true
          },
          "refunded_cents": {
            "type": "number",
            "nullable": true
          },
          "reporter": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "nullable": true
              },
              "email": {
                "type": "string",
                "nullable": true
              },
              "phone": {
                "type": "string",
                "nullable": true
              }
            },
            "required": [
              "name",
              "email",
              "phone"
            ]
          },
          "resolved_at": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "transaction_id",
          "location_id",
          "bay_id",
          "category",
          "description",
          "status",
          "tx_amount_cents",
          "refunded_cents",
          "reporter",
          "resolved_at",
          "created_at"
        ],
        "description": "reporter contact details need read:pii; otherwise they are null."
      },
      "ProblemReportList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProblemReport"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      },
      "Rating": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "customer_id": {
            "type": "string",
            "format": "uuid"
          },
          "location_id": {
            "type": "string",
            "nullable": true,
            "format": "uuid"
          },
          "wash_type": {
            "type": "string"
          },
          "wash_id": {
            "type": "string",
            "nullable": true
          },
          "rating": {
            "type": "integer"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "customer_id",
          "location_id",
          "wash_type",
          "wash_id",
          "rating",
          "created_at"
        ]
      },
      "RatingList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Rating"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "data",
          "next_cursor"
        ]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/api/v1/me": {
      "get": {
        "tags": [
          "Meta"
        ],
        "summary": "The owner and key behind this request",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Owner + key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/locations": {
      "get": {
        "tags": [
          "Locations"
        ],
        "summary": "List locations",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Locations, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/locations/{id}": {
      "get": {
        "tags": [
          "Locations"
        ],
        "summary": "Get a location",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Location",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/locations/{id}/bays": {
      "get": {
        "tags": [
          "Bays"
        ],
        "summary": "List bays at a location",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Bays (all, no paging)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BayList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/bays/{id}": {
      "get": {
        "tags": [
          "Bays"
        ],
        "summary": "Get a bay with live state and actions",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Bay",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BayResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vending-machines": {
      "get": {
        "tags": [
          "Bays"
        ],
        "summary": "List vending machines",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Vending machines",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VendingMachineList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/controllers": {
      "get": {
        "tags": [
          "Controllers"
        ],
        "summary": "List controllers",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Controllers, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ControllerList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/controllers/{id}": {
      "get": {
        "tags": [
          "Controllers"
        ],
        "summary": "Get a controller",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Controller",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ControllerResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/wash-sessions": {
      "get": {
        "tags": [
          "Sessions"
        ],
        "summary": "List wash sessions (metered bays, vacuums, comps)",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "location_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "bay_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "funding",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Sessions, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WashSessionList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/wash-sessions/{id}": {
      "get": {
        "tags": [
          "Sessions"
        ],
        "summary": "Get a wash session",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WashSessionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/transactions": {
      "get": {
        "tags": [
          "Money"
        ],
        "summary": "List transactions (card washes, memberships, bundles, add-ons, vending…) with line items",
        "description": "Pages larger than 50 count as a heavy call (5 units).",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "location_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "bay_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "type",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "status",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/transactions/{id}": {
      "get": {
        "tags": [
          "Money"
        ],
        "summary": "Get a transaction",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Transaction",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/refunds": {
      "get": {
        "tags": [
          "Money"
        ],
        "summary": "List refunds and credit restores",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Refunds, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/customers": {
      "get": {
        "tags": [
          "Customers"
        ],
        "summary": "List customers (people who paid, hold a membership or bundle, or have points)",
        "description": "Page-based. Exports above 50 rows count as heavy.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "required": false,
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "required": false,
            "name": "search",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List customers (people who paid, hold a membership or bundle, or have points)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/customers/{id}": {
      "get": {
        "tags": [
          "Customers"
        ],
        "summary": "Get a customer",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Get a customer",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/subscription-plans": {
      "get": {
        "tags": [
          "Memberships"
        ],
        "summary": "List membership plans",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List membership plans",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionPlanList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/subscriptions": {
      "get": {
        "tags": [
          "Memberships"
        ],
        "summary": "List memberships",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "plan_id",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List memberships",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/subscriptions/{id}": {
      "get": {
        "tags": [
          "Memberships"
        ],
        "summary": "Get a membership",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Get a membership",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/bundle-plans": {
      "get": {
        "tags": [
          "Bundles"
        ],
        "summary": "List bundle plans",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List bundle plans",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BundlePlanList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/bundles": {
      "get": {
        "tags": [
          "Bundles"
        ],
        "summary": "List purchased bundles",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "status",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List purchased bundles",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BundleList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/accounts": {
      "get": {
        "tags": [
          "Fleet"
        ],
        "summary": "List fleet accounts",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List fleet accounts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FleetAccountList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/accounts/{id}": {
      "get": {
        "tags": [
          "Fleet"
        ],
        "summary": "Get a fleet account",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Get a fleet account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FleetAccountResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/vehicles": {
      "get": {
        "tags": [
          "Fleet"
        ],
        "summary": "List fleet vehicles",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "fleet_account_id",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List fleet vehicles",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FleetVehicleList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/invoices": {
      "get": {
        "tags": [
          "Fleet"
        ],
        "summary": "List fleet invoices",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "fleet_account_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "status",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List fleet invoices",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FleetInvoiceList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/fleet/invoices/{id}": {
      "get": {
        "tags": [
          "Fleet"
        ],
        "summary": "Get a fleet invoice with its washes (heavy: 5 units)",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Get a fleet invoice with its washes (heavy: 5 units)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FleetInvoiceDetail"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vouchers": {
      "get": {
        "tags": [
          "Rewards"
        ],
        "summary": "List vouchers / gifts / promos",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "kind",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List vouchers / gifts / promos",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoucherList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/vouchers/{id}/redemptions": {
      "get": {
        "tags": [
          "Rewards"
        ],
        "summary": "List redemptions of a voucher",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List redemptions of a voucher",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoucherRedemptionList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/points/summary": {
      "get": {
        "tags": [
          "Rewards"
        ],
        "summary": "Loyalty points summary",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Loyalty points summary",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PointsSummaryResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/summary": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Dashboard summary (today, range, active, ratings)",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "YYYY-MM-DD (owner-local day)"
            },
            "required": false,
            "name": "from",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "to",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "location_id",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Dashboard summary (today, range, active, ratings)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsSummary"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/revenue": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Revenue over a range, grouped",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "YYYY-MM-DD (owner-local day)"
            },
            "required": false,
            "name": "from",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "to",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "location_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "day",
                "bay",
                "payment",
                "package",
                "upsell"
              ],
              "default": "day"
            },
            "required": false,
            "name": "group_by",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Revenue over a range, grouped",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsRevenue"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/pnl": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Profit & loss (heavy: 5 units)",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "start",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "end",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "current_month",
                "previous_month",
                "ytd"
              ]
            },
            "required": false,
            "name": "period",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "month",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Profit & loss (heavy: 5 units)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsPnl"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/sales-tax": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Sales tax report (heavy: 5 units)",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "start",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "end",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "current_month",
                "previous_month",
                "ytd"
              ]
            },
            "required": false,
            "name": "period",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "month",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Sales tax report (heavy: 5 units)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsSalesTax"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/heatmap": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Hour × weekday wash heatmap",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "YYYY-MM-DD (owner-local day)"
            },
            "required": false,
            "name": "from",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "to",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "location_id",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Hour × weekday wash heatmap",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnalyticsHeatmap"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/attendants": {
      "get": {
        "tags": [
          "Staff"
        ],
        "summary": "List attendants",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List attendants",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttendantList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/shifts": {
      "get": {
        "tags": [
          "Staff"
        ],
        "summary": "List shifts",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "attendant_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "status",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List shifts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShiftList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/payroll/report": {
      "get": {
        "tags": [
          "Staff"
        ],
        "summary": "Payroll report for a period",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "start",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "end",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Payroll report for a period",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayrollReport"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/expenses": {
      "get": {
        "tags": [
          "Money"
        ],
        "summary": "List expenses",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "location_id",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List expenses",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/problem-reports": {
      "get": {
        "tags": [
          "Support"
        ],
        "summary": "List customer problem reports",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "status",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List customer problem reports",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemReportList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ratings": {
      "get": {
        "tags": [
          "Support"
        ],
        "summary": "List wash ratings",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size, 1–200 (default 50)."
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 400,
              "description": "Opaque cursor from the previous page's next_cursor."
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created at or after this ISO timestamp."
            },
            "required": false,
            "name": "since",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only items created before this ISO timestamp."
            },
            "required": false,
            "name": "until",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "location_id",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "List wash ratings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RatingList"
                }
              }
            }
          },
          "401": {
            "description": "Missing / invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (see X-RateLimit-* and Retry-After headers)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  }
}
