{
  "openapi": "3.1.0",
  "info": {
    "title": "Valpas Public API",
    "description": "Hotel data for external developers",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://connect.valpashotels.com",
      "description": "Production"
    }
  ],
  "security": [{ "ApiKeyAuth": [] }],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    },
    "schemas": {
      "Hotel": {
        "type": "object",
        "required": ["id", "name", "description", "postal_code", "city", "country_code", "language", "star_rating", "website_url", "email", "images", "certified", "certified_from", "certified_until", "certification_url", "netstorming_id", "giata_id"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique hotel identifier",
            "example": "00391351-e308-4aae-8b66-d868ebb37ff3"
          },
          "name": {
            "type": "string",
            "description": "Hotel name",
            "example": "Grand Helsinki Hotel"
          },
          "description": {
            "type": ["string", "null"],
            "description": "Marketing description of the hotel (null if not available)",
            "example": "A refined stay in the heart of Helsinki, steps from the central railway station."
          },
          "address": {
            "type": ["string", "null"],
            "description": "Street address of the hotel",
            "example": "Mannerheimintie 1, 00100 Helsinki"
          },
          "postal_code": {
            "type": ["string", "null"],
            "description": "Postal code (null if not available)",
            "example": "00100"
          },
          "city": {
            "type": ["string", "null"],
            "description": "City name (null if not available)",
            "example": "Helsinki"
          },
          "country_code": {
            "type": ["string", "null"],
            "description": "Country code (ISO 3166-1 alpha-2, null if not available)",
            "example": "FI"
          },
          "latitude": {
            "type": ["number", "null"],
            "description": "Geographic latitude in decimal degrees",
            "example": 60.1699
          },
          "longitude": {
            "type": ["number", "null"],
            "description": "Geographic longitude in decimal degrees",
            "example": 24.9384
          },
          "language": {
            "type": ["string", "null"],
            "description": "Primary language at the hotel (ISO 639-1 code)",
            "example": "fi"
          },
          "star_rating": {
            "type": ["number", "null"],
            "description": "Official hotel star rating, e.g. 4 or 4.5 (null if not available)",
            "example": 4.5
          },
          "room_count": {
            "type": ["integer", "null"],
            "description": "Total number of rooms (null if not configured)",
            "example": 85
          },
          "website_url": {
            "type": ["string", "null"],
            "format": "uri",
            "description": "Hotel website URL (null if not available)",
            "example": "https://www.grandhelsinkihotel.com"
          },
          "email": {
            "type": ["string", "null"],
            "format": "email",
            "description": "Hotel reception email address (null if not available)",
            "example": "reception@grandhelsinkihotel.com"
          },
          "images": {
            "type": "array",
            "description": "Hotel photos (up to 3), served from the Valpas CDN. Empty array if no photos are available.",
            "items": {
              "type": "object",
              "required": ["url", "caption"],
              "properties": {
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Publicly accessible image URL"
                },
                "caption": {
                  "type": ["string", "null"],
                  "description": "Short image caption (null if not available)"
                }
              }
            },
            "example": [
              {
                "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/1.jpg",
                "caption": "Great Room Lobby"
              }
            ]
          },
          "certified": {
            "type": "boolean",
            "description": "Whether the hotel holds a current Valpas certification",
            "example": true
          },
          "certified_from": {
            "type": ["string", "null"],
            "format": "date",
            "description": "Date when the hotel's Valpas certification becomes valid (YYYY-MM-DD)",
            "example": "2026-01-15"
          },
          "certified_until": {
            "type": ["string", "null"],
            "format": "date",
            "description": "Date when the hotel's Valpas certification expires (YYYY-MM-DD)",
            "example": "2026-03-30"
          },
          "certification_url": {
            "type": ["string", "null"],
            "format": "uri",
            "description": "Link target for the Valpas certification badge (null when the hotel is not certified)",
            "example": "https://valpashotels.com"
          },
          "netstorming_id": {
            "type": ["string", "null"],
            "description": "Netstorming integration identifier",
            "example": "45373"
          },
          "giata_id": {
            "type": ["integer", "null"],
            "description": "GIATA MultiCodes property identifier (null if the hotel is not mapped to a GIATA code, or if your API key lacks the `giata` scope)",
            "example": 99999999
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable error message",
            "example": "Unauthorized"
          }
        }
      }
    }
  },
  "paths": {
    "/hotels": {
      "get": {
        "operationId": "listHotels",
        "summary": "List hotels",
        "description": "Returns a paginated list of hotels accessible with your API key.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of hotels to return (default: 20, max: 100)",
            "required": false,
            "schema": { "type": "integer", "default": 20, "minimum": 1, "maximum": 100 }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Number of hotels to skip for pagination (default: 0)",
            "required": false,
            "schema": { "type": "integer", "default": 0, "minimum": 0 }
          },
          {
            "name": "giata_id",
            "in": "query",
            "description": "Filter to the hotel with this GIATA MultiCodes identifier. GIATA IDs are unique, so at most one hotel is returned. Requires the `giata` scope.",
            "required": false,
            "schema": { "type": "integer", "example": 99999999 }
          }
        ],
        "responses": {
          "200": {
            "description": "A list of hotels",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Hotel" }
                },
                "example": [
                  {
                    "id": "00391351-e308-4aae-8b66-d868ebb37ff3",
                    "name": "Paris Marriott Rive Gauche Hotel & Conference Center",
                    "description": "Surrounded by diverse attractions, Paris Marriott Rive Gauche Hotel is a stylish haven in an iconic travel destination.",
                    "address": "17 Boulevard Saint Jacques, 75014 Paris France",
                    "postal_code": "75014",
                    "city": "Paris",
                    "country_code": "FR",
                    "latitude": 48.831917,
                    "longitude": 2.340172,
                    "language": null,
                    "star_rating": null,
                    "room_count": null,
                    "website_url": "https://www.marriott.com/en-us/hotels/parst-paris-marriott-rive-gauche-hotel-and-conference-center/overview/",
                    "email": null,
                    "images": [
                      {
                        "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/1.jpg",
                        "caption": "Great Room Lobby"
                      },
                      {
                        "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/2.jpg",
                        "caption": "Palyma Bar"
                      },
                      {
                        "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/3.jpg",
                        "caption": "Brasserie Restaurant"
                      }
                    ],
                    "certified": true,
                    "certified_from": null,
                    "certified_until": null,
                    "certification_url": "https://valpashotels.com",
                    "netstorming_id": "45373",
                    "giata_id": 99999999
                  }
                ]
              }
            }
          },
          "400": {
            "description": "The supplied giata_id is not an integer",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "giata_id must be an integer" }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Unauthorized" }
              }
            }
          },
          "403": {
            "description": "The giata_id filter was used with an API key that lacks the `giata` scope",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Forbidden" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Internal server error" }
              }
            }
          }
        }
      }
    },
    "/hotels/{id}": {
      "get": {
        "operationId": "getHotel",
        "summary": "Get hotel by ID",
        "description": "Returns a single hotel by its unique identifier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Unique hotel identifier",
            "schema": { "type": "string", "example": "00391351-e308-4aae-8b66-d868ebb37ff3" }
          }
        ],
        "responses": {
          "200": {
            "description": "Hotel found",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Hotel" },
                "example": {
                  "id": "00391351-e308-4aae-8b66-d868ebb37ff3",
                  "name": "Paris Marriott Rive Gauche Hotel & Conference Center",
                  "description": "Surrounded by diverse attractions, Paris Marriott Rive Gauche Hotel is a stylish haven in an iconic travel destination.",
                  "address": "17 Boulevard Saint Jacques, 75014 Paris France",
                  "postal_code": "75014",
                  "city": "Paris",
                  "country_code": "FR",
                  "latitude": 48.831917,
                  "longitude": 2.340172,
                  "language": null,
                  "star_rating": null,
                  "room_count": null,
                  "website_url": "https://www.marriott.com/en-us/hotels/parst-paris-marriott-rive-gauche-hotel-and-conference-center/overview/",
                  "email": null,
                  "images": [
                    {
                      "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/1.jpg",
                      "caption": "Great Room Lobby"
                    },
                    {
                      "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/2.jpg",
                      "caption": "Palyma Bar"
                    },
                    {
                      "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/3.jpg",
                      "caption": "Brasserie Restaurant"
                    }
                  ],
                  "certified": true,
                  "certified_from": null,
                  "certified_until": null,
                  "certification_url": "https://valpashotels.com",
                  "netstorming_id": "45373",
                  "giata_id": 99999999
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Unauthorized" }
              }
            }
          },
          "404": {
            "description": "Hotel not found",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Hotel not found" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Internal server error" }
              }
            }
          }
        }
      }
    },
    "/hotels/netstorming/{netstormingId}": {
      "get": {
        "operationId": "getHotelByNetstormingId",
        "summary": "Get hotel by Netstorming ID",
        "description": "Returns a single hotel by its Netstorming integration identifier.",
        "parameters": [
          {
            "name": "netstormingId",
            "in": "path",
            "required": true,
            "description": "Netstorming integration identifier",
            "schema": { "type": "string", "example": "45373" }
          }
        ],
        "responses": {
          "200": {
            "description": "Hotel found",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Hotel" },
                "example": {
                  "id": "00391351-e308-4aae-8b66-d868ebb37ff3",
                  "name": "Paris Marriott Rive Gauche Hotel & Conference Center",
                  "description": "Surrounded by diverse attractions, Paris Marriott Rive Gauche Hotel is a stylish haven in an iconic travel destination.",
                  "address": "17 Boulevard Saint Jacques, 75014 Paris France",
                  "postal_code": "75014",
                  "city": "Paris",
                  "country_code": "FR",
                  "latitude": 48.831917,
                  "longitude": 2.340172,
                  "language": null,
                  "star_rating": null,
                  "room_count": null,
                  "website_url": "https://www.marriott.com/en-us/hotels/parst-paris-marriott-rive-gauche-hotel-and-conference-center/overview/",
                  "email": null,
                  "images": [
                    {
                      "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/1.jpg",
                      "caption": "Great Room Lobby"
                    },
                    {
                      "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/2.jpg",
                      "caption": "Palyma Bar"
                    },
                    {
                      "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/3.jpg",
                      "caption": "Brasserie Restaurant"
                    }
                  ],
                  "certified": true,
                  "certified_from": null,
                  "certified_until": null,
                  "certification_url": "https://valpashotels.com",
                  "netstorming_id": "45373",
                  "giata_id": 99999999
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Unauthorized" }
              }
            }
          },
          "404": {
            "description": "Hotel not found for the given Netstorming ID",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Hotel not found" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Internal server error" }
              }
            }
          }
        }
      }
    },
    "/hotels/giata/{giataId}": {
      "get": {
        "operationId": "getHotelByGiataId",
        "summary": "Get hotel by GIATA ID",
        "description": "Returns a single hotel by its GIATA MultiCodes property identifier. Requires the `giata` scope.",
        "parameters": [
          {
            "name": "giataId",
            "in": "path",
            "required": true,
            "description": "GIATA MultiCodes property identifier",
            "schema": { "type": "integer", "example": 99999999 }
          }
        ],
        "responses": {
          "200": {
            "description": "Hotel found",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Hotel" },
                "example": {
                  "id": "00391351-e308-4aae-8b66-d868ebb37ff3",
                  "name": "Paris Marriott Rive Gauche Hotel & Conference Center",
                  "description": "Surrounded by diverse attractions, Paris Marriott Rive Gauche Hotel is a stylish haven in an iconic travel destination.",
                  "address": "17 Boulevard Saint Jacques, 75014 Paris France",
                  "postal_code": "75014",
                  "city": "Paris",
                  "country_code": "FR",
                  "latitude": 48.831917,
                  "longitude": 2.340172,
                  "language": null,
                  "star_rating": null,
                  "room_count": null,
                  "website_url": "https://www.marriott.com/en-us/hotels/parst-paris-marriott-rive-gauche-hotel-and-conference-center/overview/",
                  "email": null,
                  "images": [
                    {
                      "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/1.jpg",
                      "caption": "Great Room Lobby"
                    },
                    {
                      "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/2.jpg",
                      "caption": "Palyma Bar"
                    },
                    {
                      "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/3.jpg",
                      "caption": "Brasserie Restaurant"
                    }
                  ],
                  "certified": true,
                  "certified_from": null,
                  "certified_until": null,
                  "certification_url": "https://valpashotels.com",
                  "netstorming_id": "45373",
                  "giata_id": 99999999
                }
              }
            }
          },
          "400": {
            "description": "The supplied GIATA ID is not an integer",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "giata_id must be an integer" }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Unauthorized" }
              }
            }
          },
          "403": {
            "description": "API key lacks the `giata` scope",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Forbidden" }
              }
            }
          },
          "404": {
            "description": "Hotel not found for the given GIATA ID",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Hotel not found" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Internal server error" }
              }
            }
          }
        }
      }
    },
    "/hotels/netstorming/batch": {
      "post": {
        "operationId": "batchGetHotelsByNetstormingIds",
        "summary": "Batch fetch hotels by Netstorming IDs",
        "description": "Returns multiple hotels matching the provided Netstorming IDs. Maximum 1000 IDs per request. Hotels without a matching Netstorming ID are omitted from the response.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["netstorming_ids"],
                "properties": {
                  "netstorming_ids": {
                    "type": "array",
                    "items": { "type": "string" },
                    "description": "Array of Netstorming IDs to look up (max 1000)",
                    "example": ["45373", "63148"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "List of matching hotels",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Hotel" }
                },
                "example": [
                  {
                    "id": "00391351-e308-4aae-8b66-d868ebb37ff3",
                    "name": "Paris Marriott Rive Gauche Hotel & Conference Center",
                    "description": "Surrounded by diverse attractions, Paris Marriott Rive Gauche Hotel is a stylish haven in an iconic travel destination.",
                    "address": "17 Boulevard Saint Jacques, 75014 Paris France",
                    "postal_code": "75014",
                    "city": "Paris",
                    "country_code": "FR",
                    "latitude": 48.831917,
                    "longitude": 2.340172,
                    "language": null,
                    "star_rating": null,
                    "room_count": null,
                    "website_url": "https://www.marriott.com/en-us/hotels/parst-paris-marriott-rive-gauche-hotel-and-conference-center/overview/",
                    "email": null,
                    "images": [
                      {
                        "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/1.jpg",
                        "caption": "Great Room Lobby"
                      },
                      {
                        "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/2.jpg",
                        "caption": "Palyma Bar"
                      },
                      {
                        "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/3.jpg",
                        "caption": "Brasserie Restaurant"
                      }
                    ],
                    "certified": true,
                    "certified_from": null,
                    "certified_until": null,
                    "certification_url": "https://valpashotels.com",
                    "netstorming_id": "45373",
                    "giata_id": 99999999
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Invalid request body",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Request body must include a `netstorming_ids` array" }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Unauthorized" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Internal server error" }
              }
            }
          }
        }
      }
    },
    "/hotels/giata/batch": {
      "post": {
        "operationId": "batchGetHotelsByGiataIds",
        "summary": "Batch fetch hotels by GIATA IDs",
        "description": "Returns multiple hotels matching the provided GIATA MultiCodes identifiers. Maximum 1000 IDs per request. IDs with no matching hotel are omitted from the response. Requires the `giata` scope.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["giata_ids"],
                "properties": {
                  "giata_ids": {
                    "type": "array",
                    "items": { "type": "integer" },
                    "description": "Array of GIATA IDs to look up (max 1000). Integer-valued strings are also accepted.",
                    "example": [99999999, 99999998]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "List of matching hotels",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Hotel" }
                },
                "example": [
                  {
                    "id": "00391351-e308-4aae-8b66-d868ebb37ff3",
                    "name": "Paris Marriott Rive Gauche Hotel & Conference Center",
                    "description": "Surrounded by diverse attractions, Paris Marriott Rive Gauche Hotel is a stylish haven in an iconic travel destination.",
                    "address": "17 Boulevard Saint Jacques, 75014 Paris France",
                    "postal_code": "75014",
                    "city": "Paris",
                    "country_code": "FR",
                    "latitude": 48.831917,
                    "longitude": 2.340172,
                    "language": null,
                    "star_rating": null,
                    "room_count": null,
                    "website_url": "https://www.marriott.com/en-us/hotels/parst-paris-marriott-rive-gauche-hotel-and-conference-center/overview/",
                    "email": null,
                    "images": [
                      {
                        "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/1.jpg",
                        "caption": "Great Room Lobby"
                      },
                      {
                        "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/2.jpg",
                        "caption": "Palyma Bar"
                      },
                      {
                        "url": "https://misxceaqoppcaiaitpkj.supabase.co/storage/v1/object/public/hotel-images/00391351-e308-4aae-8b66-d868ebb37ff3/3.jpg",
                        "caption": "Brasserie Restaurant"
                      }
                    ],
                    "certified": true,
                    "certified_from": null,
                    "certified_until": null,
                    "certification_url": "https://valpashotels.com",
                    "netstorming_id": "45373",
                    "giata_id": 99999999
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Invalid request body",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Request body must include a `giata_ids` array" }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Unauthorized" }
              }
            }
          },
          "403": {
            "description": "API key lacks the `giata` scope",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Forbidden" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": { "error": "Internal server error" }
              }
            }
          }
        }
      }
    }
  }
}
