{
  "openapi": "3.0.2",
  "info": {
    "title": "Echo API",
    "description": "Last update: 30/06/2026\n - Geolocation on `GET /allExperiences`: rank by distance / filter by radius (opt-in per API key)\n - Set video cover as optional in VideoUpdateRequest (put, patch)\n\nThe Echo API is a public API that has been defined and developed to give external partners the possibility to create and manage their experiences progamatically.\n-\nThe API is composed of various endpoints to manage and retrieve information from Echo\n- All Experiences\n- Experiences\n- Venues\n- Audiences\n- Categories\n- Communes\n- Environments\n- Formats\n\n## Authentication\nIn order to use this API, a **api-key** needs to be issued through **Echo's website**. All API requests require this API key to be provided in the `api-key` header. API keys are tied to a specific organization.\n\n## Rate Limiting\nThe API implements rate limiting to prevent abuse. By default, rate limiting is not enabled, but it might be for some API keys.\n\nWhen rate limiting is enabled for an API key, the API returns the following headers to help you track your rate limit usage:\n- `X-RateLimit-Limit-Minute`: The rate limit ceiling for requests per minute\n- `X-RateLimit-Remaining-Minute`: The number of requests left for the current minute\n- `X-RateLimit-Reset-Minute`: The time at which the current rate limit window resets in Unix time\n- `X-RateLimit-Limit-Hour`: The rate limit ceiling for requests per hour\n- `X-RateLimit-Remaining-Hour`: The number of requests left for the current hour\n- `X-RateLimit-Reset-Hour`: The time at which the current rate limit window resets in Unix time\n- `X-RateLimit-Limit-Day`: The rate limit ceiling for requests per day\n- `X-RateLimit-Remaining-Day`: The number of requests left for the current day\n- `X-RateLimit-Reset-Day`: The time at which the current rate limit window resets in Unix time\n\nIf you exceed the rate limit, you will receive a 429 Too Many Requests response.\n\n## Geolocation\n`GET /allExperiences` can rank experiences by distance and optionally filter them by radius. Pass\ncoordinates via the `geo` query parameter: `geo[lat]` and `geo[lng]` (required together, WGS84) and\nan optional `geo[radius]` in meters (max 100000). Omit the radius to rank by distance without\nfiltering. When geo is requested, each returned experience includes a `distanceMeters` field, and\ngeo combines with all the existing filters (categories, audiences, communes, dates, etc.) and with\npagination.\n\nGeolocation is **opt-in per API key**. A key that is not enabled for geo and sends `geo[...]`\nreceives a `403`. Contact support to have it enabled. Requests without geo params are unaffected.\n\n## General Information\nAPI calls need to be made to: https://api.echo.lu/v1/\n\n**Warning**: Data models still subject to change! In case of questions or proposals, go to\nhttps://newaccount1615557201808.freshdesk.com/\n\n**Important**: Only small amount of events from Events in Luxembourg were imported and attached to an organisation.\n\n**Dates**: the date-time for dates has to be a date as an ISO string, as defined here: https://tools.ietf.org/html/rfc3339#section-5.6\n\nThe API expects the dates in ISO string, and on **ECHO** it will be displayed in 'Europe/Luxembourg' timezone.\n\nIf the date is in UTC form (preferrable):\n- like _2022-04-23T18:00:00Z_ on **ECHO** it will be _23/04/2022, 20:00_,\n- or for winter _2022-01-23T19:00:00Z_ on **ECHO** it will be _23/01/2022, 20:00_,\n\nIf the date is in GMT, have to specify the offset according to when the experience is planned:\n- like _2022-04-23T18:00:00+02:00_ on **ECHO** it will be _23/04/2022, 20:00_,\n- or for winter _2022-01-23T19:00:00+01:00_ on **ECHO** it will be _23/01/2022, 20:00_,\n\n[Publication Flow on ECHO](https://storage.googleapis.com/lu-echo-prod-experiences/api-doc/echo-api-status-flow.pdf)",
    "version": "1.1.0"
  },
  "paths": {
    "/experiences/{id}/cancel": {
      "patch": {
        "tags": [
          "Experiences"
        ],
        "description": "Display as Cancelled an already published experience, by setting its status to cancelled",
        "operationId": "CancelExperience",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Experience ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/experiences/{id}/complete": {
      "patch": {
        "tags": [
          "Experiences"
        ],
        "description": "Display as Complete an already published experience, by setting its status to complete",
        "operationId": "CompleteExperience",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Experience ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "https://api.echo.lu/v1/experiences": {
      "post": {
        "tags": [
          "Experiences"
        ],
        "description": "Create a new experience",
        "operationId": "CreateExperience",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateExperienceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "201 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateExperienceResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateExperienceErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/venues": {
      "post": {
        "tags": [
          "Venues"
        ],
        "description": "Create a new venue",
        "operationId": "CreateVenue",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVenueRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "201 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateVenueResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateVenueErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Venues"
        ],
        "description": "Get all venues from the database with applied filters",
        "operationId": "ListVenues",
        "parameters": [
          {
            "name": "categories",
            "in": "query",
            "description": "Category IDs",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "communes",
            "in": "query",
            "description": "Commune IDs",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "pagination",
            "in": "query",
            "style": "deepObject",
            "explode": true,
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/PaginationRequest"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListVenuesResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListVenuesErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListVenuesNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/experiences/{id}": {
      "delete": {
        "tags": [
          "Experiences"
        ],
        "description": "Delete an existing experience",
        "operationId": "DeleteExperience",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Experience ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteExperienceSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteExperienceNotFoundResponse"
                }
              }
            }
          },
          "409": {
            "description": "409 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteExperienceConflictResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Experiences"
        ],
        "description": "Get an existing experience",
        "operationId": "GetExperience",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Experience ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetExperienceResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Experiences"
        ],
        "description": "Update an existing experience",
        "operationId": "PatchExperience",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Experience ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateExperienceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateExperienceResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Experiences"
        ],
        "description": "Update an existing experience",
        "operationId": "PutExperience",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Experience ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateExperienceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateExperienceResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/allExperiences/{id}": {
      "get": {
        "tags": [
          "Published Experiences"
        ],
        "description": "Get published existing experience",
        "operationId": "GetPublishedExperience",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Experience ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetExperienceResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/venues/{id}": {
      "get": {
        "tags": [
          "Venues"
        ],
        "description": "Get a venue",
        "operationId": "GetVenue",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Venue ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetVenueResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetVenueErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetVenueNotFoundResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Venues"
        ],
        "description": "Update a venue",
        "operationId": "PatchVenue",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Venue ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchVenueRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateVenueResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateVenueErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateVenueNotFoundResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Venues"
        ],
        "description": "Update a venue",
        "operationId": "PutVenue",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Venue ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PutVenueRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateVenueResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateVenueErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateVenueNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/audiences": {
      "get": {
        "tags": [
          "Audiences"
        ],
        "description": "Get all available audience types",
        "operationId": "ListAudiences",
        "parameters": [],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListAudiencesResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListAudiencesErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListAudiencesNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/categories": {
      "get": {
        "tags": [
          "Categories"
        ],
        "description": "Get all available categories",
        "operationId": "ListCategories",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "description": "Category type ('experience', 'venue')",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListCategoriesResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListCategoriesErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListCategoriesNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/communes": {
      "get": {
        "tags": [
          "Communes"
        ],
        "description": "Get all available communes (municipalities)",
        "operationId": "ListCommunes",
        "parameters": [],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListCommunesResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListCommunesErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListCommunesNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/environments": {
      "get": {
        "tags": [
          "Environments"
        ],
        "description": "Get all available environment types",
        "operationId": "ListEnvironments",
        "parameters": [],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvironmentsResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvironmentsErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEnvironmentsNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/experiences": {
      "get": {
        "tags": [
          "Experiences"
        ],
        "description": "Get all experience from the database with applied filters",
        "operationId": "ListExperience",
        "parameters": [
          {
            "name": "audiences",
            "in": "query",
            "description": "Audience IDs",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "categories",
            "in": "query",
            "description": "Category IDs",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "communes",
            "in": "query",
            "description": "Commune IDs of the venues where the experiences are taking place",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "date",
            "in": "query",
            "style": "deepObject",
            "explode": true,
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateRequest"
            }
          },
          {
            "name": "pagination",
            "in": "query",
            "description": "Pagination if it's needed. All experiences by default",
            "style": "deepObject",
            "explode": true,
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/PaginationRequest"
            }
          },
          {
            "name": "venues",
            "in": "query",
            "description": "Venue IDs",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListExperienceResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/formats": {
      "get": {
        "tags": [
          "Formats"
        ],
        "description": "Get all available format types",
        "operationId": "ListFormats",
        "parameters": [],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListFormatsResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListFormatsErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListFormatsNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/allExperiences/highlight": {
      "get": {
        "tags": [
          "Published Experiences"
        ],
        "description": "Get highlighted experiences from the Echo.lu homepage slider.\n\nReturns the exact same experiences displayed in the highlight slider at the top of echo.lu.\nExperiences are selected by the Echo team and sorted by their configured position.\nIf some promoted experiences are no longer available, they are automatically replaced\nwith popular experiences.",
        "operationId": "ListHighlightedExperiences",
        "parameters": [],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListExperienceResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/allExperiences": {
      "get": {
        "tags": [
          "Published Experiences"
        ],
        "description": "Get all published experiences from the database with applied filters",
        "operationId": "ListPublishedExperiences",
        "parameters": [
          {
            "name": "audiences",
            "in": "query",
            "description": "Audience IDs",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "categories",
            "in": "query",
            "description": "Category IDs",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "communes",
            "in": "query",
            "description": "Commune IDs of the venues where the experiences are taking place",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "date",
            "in": "query",
            "style": "deepObject",
            "explode": true,
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateRequest"
            }
          },
          {
            "name": "geo",
            "in": "query",
            "description": "Geolocation: rank experiences by distance and optionally filter by radius. When set, each record includes `distanceMeters`. Not enabled by default — contact Echo to request access (otherwise HTTP 403 `geo/not-enabled`); enabled keys will be rate limited.",
            "style": "deepObject",
            "explode": true,
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/GeoRequest"
            }
          },
          {
            "name": "organisations",
            "in": "query",
            "description": "Organisations",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "pagination",
            "in": "query",
            "description": "For published experiences pagination is required. Max 100 items per page",
            "style": "deepObject",
            "explode": true,
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/PaginationRequest"
            }
          },
          {
            "name": "tags",
            "in": "query",
            "description": "Tags",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "venues",
            "in": "query",
            "description": "Venue IDs",
            "style": "form",
            "explode": true,
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListExperienceResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/experiences/{id}/postpone": {
      "patch": {
        "tags": [
          "Experiences"
        ],
        "description": "Display as Postponed an already published experience, by setting its status to postponed",
        "operationId": "PostponeExperience",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Experience ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      }
    },
    "/experiences/{id}/unpublish": {
      "patch": {
        "tags": [
          "Experiences"
        ],
        "description": "Unpublish an experience, and set its status to draft",
        "operationId": "UnpublishExperience",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Experience ID",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceSuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "400 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "404 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelPostponeCompleteExperienceNotFoundResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Address": {
        "type": "object",
        "properties": {
          "street": {
            "type": "string"
          },
          "number": {
            "type": "string"
          },
          "postcode": {
            "type": "string"
          },
          "town": {
            "type": "string"
          },
          "commune": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "longitude": {
            "type": "string"
          },
          "latitude": {
            "type": "string"
          },
          "gid": {
            "type": "string"
          },
          "mapUrl": {
            "type": "string"
          }
        },
        "required": [
          "street",
          "postcode",
          "town",
          "commune",
          "country",
          "longitude",
          "latitude"
        ]
      },
      "Audience": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "titles": {
            "$ref": "#/components/schemas/Content"
          }
        },
        "required": [
          "id",
          "titles"
        ]
      },
      "CancelPostponeCompleteExperienceErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "CancelPostponeCompleteExperienceNotFoundResponse": {
        "type": "object",
        "description": "REQUEST FAILED - no published experience found"
      },
      "CancelPostponeCompleteExperienceSuccessResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "result": {
            "type": "boolean"
          }
        },
        "required": [
          "stats",
          "result"
        ]
      },
      "Category": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "parent": {
            "type": "string"
          },
          "order": {
            "type": "number",
            "format": "float"
          },
          "titles": {
            "$ref": "#/components/schemas/Content"
          },
          "type": {
            "type": "string",
            "enum": [
              "experience",
              "venue"
            ]
          }
        },
        "required": [
          "id",
          "titles",
          "type"
        ]
      },
      "Commune": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "titles": {
            "$ref": "#/components/schemas/Content"
          },
          "parent": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "titles"
        ]
      },
      "Contact": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "website": {
            "type": "string"
          },
          "company": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "email",
          "phone",
          "company"
        ]
      },
      "Content": {
        "oneOf": [
          {
            "type": "string"
          },
          {
            "type": "object",
            "properties": {
              "en": {
                "type": "string"
              },
              "fr": {
                "type": "string"
              },
              "de": {
                "type": "string"
              }
            }
          }
        ]
      },
      "CreateExperienceErrorResponse": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "description": "Error message"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "field",
          "message"
        ]
      },
      "CreateExperienceRequest": {
        "type": "object",
        "properties": {
          "title": {
            "$ref": "#/components/schemas/Content"
          },
          "subtitle": {
            "$ref": "#/components/schemas/Content"
          },
          "pictures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PictureCreateRequest"
            },
            "description": "List of pictures to add to the experience.\nFirst picture will be used as a main image.\nImportant: file names should be unique, and file size should be less than 2MB!\nAllowed file types: jpeg, png"
          },
          "videos": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VideoCreateRequest"
            }
          },
          "dates": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ExperienceDateSingle"
                },
                {
                  "$ref": "#/components/schemas/ExperienceDateRecurring"
                },
                {
                  "$ref": "#/components/schemas/ExperienceDatePermanent"
                }
              ]
            }
          },
          "venues": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "description": {
            "$ref": "#/components/schemas/Content"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Categories: id from the /categories endpoint"
          },
          "audiences": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of languages the experience is in: lb, fr, de, en, etc."
          },
          "environments": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Experience environments: indoor, outdoor, online, etc."
          },
          "onlineLink": {
            "type": "string",
            "description": "Online link: url to attend the experience remotely, usually set when `environments` contains \"online\""
          },
          "formats": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Formats: workshop, concert, lecture, etc."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          },
          "tickets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Ticket"
            },
            "description": "Tickets"
          },
          "purchaseLink": {
            "type": "string",
            "description": "Purchase link: url of the ticketing page if not present in the Tickets"
          },
          "luxembourgTickets": {
            "$ref": "#/components/schemas/LuxTicketSettings"
          },
          "salesContact": {
            "$ref": "#/components/schemas/Contact"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "pending"
            ],
            "description": "Status:\n- draft: add a new experience to the organisation's repository as a draft.\n- pending: save and ask for validation of the experience in one request.\n(in case of PUT: the validation is triggered only if the previous status was draft)\n\n[![flow](https://storage.googleapis.com/lu-echo-prod-experiences/api-doc/echo-api-status-flow-post-img.jpg)](https://storage.googleapis.com/lu-echo-prod-experiences/api-doc/echo-api-status-flow.pdf)"
          }
        },
        "required": [
          "title",
          "pictures",
          "dates",
          "venues",
          "description",
          "categories",
          "audiences",
          "languages",
          "environments",
          "formats",
          "tags"
        ],
        "description": "Dates: the date-time for dates has to be a date as an ISO string, as defined here: https://tools.ietf.org/html/rfc3339#section-5.6\n\nThe API expects the dates in ISO string, and on **ECHO** it will be displayed in 'Europe/Luxembourg' timezone.\n\nIf the date is in UTC form (preferrable):\n- like _2022-04-23T18:00:00Z_ on **ECHO** it will be _23/04/2022, 20:00_,\n- or for winter _2022-01-23T19:00:00Z_ on **ECHO** it will be _23/01/2022, 20:00_,\n\nIf the date is in GMT, have to specify the offset according to when the experience is planned:\n- like _2022-04-23T18:00:00+02:00_ on **ECHO** it will be _23/04/2022, 20:00_,\n- or for winter _2022-01-23T19:00:00+01:00_ on **ECHO** it will be _23/01/2022, 20:00_,\n\nPrices:\nThe experience is displayed as free until the first ticket is added."
      },
      "CreateExperienceResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "record": {
            "$ref": "#/components/schemas/Experience"
          }
        },
        "required": [
          "stats",
          "record"
        ]
      },
      "CreateVenueErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "CreateVenueRequest": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Title"
          },
          "pictures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PictureCreateRequest"
            },
            "description": "List of pictures to import/add to the venue. First picture will be used as a main image. Important: file names should be unique!"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "description": {
            "$ref": "#/components/schemas/Content"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Category IDs"
          },
          "website": {
            "type": "string",
            "description": "Website URL"
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          }
        },
        "required": [
          "title",
          "location",
          "description",
          "categories",
          "website",
          "contact"
        ]
      },
      "CreateVenueResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "record": {
            "$ref": "#/components/schemas/Venue"
          }
        },
        "required": [
          "stats",
          "record"
        ]
      },
      "DateRequest": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "from"
        ],
        "description": "A `date-time` as defined by https://tools.ietf.org/html/rfc3339#section-5.6"
      },
      "DeleteExperienceConflictResponse": {
        "type": "object",
        "description": "REQUEST FAILED - Published experience found, unpublish it first."
      },
      "DeleteExperienceErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "DeleteExperienceNotFoundResponse": {
        "type": "object"
      },
      "DeleteExperienceSuccessResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "result": {
            "type": "boolean"
          }
        },
        "required": [
          "stats",
          "result"
        ]
      },
      "Experience": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Experience ID"
          },
          "title": {
            "$ref": "#/components/schemas/Content"
          },
          "subtitle": {
            "$ref": "#/components/schemas/Content"
          },
          "pictures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Picture"
            },
            "description": "List of pictures: { size, url, isPlaceholder }"
          },
          "videos": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Video"
            },
            "description": "Videos: { id, type, url }"
          },
          "dates": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ExperienceDateSingle"
                },
                {
                  "$ref": "#/components/schemas/ExperienceDateRecurring"
                },
                {
                  "$ref": "#/components/schemas/ExperienceDatePermanent"
                }
              ]
            },
            "description": "Dates for Single, Recurring, or Permanent experiences"
          },
          "endDate": {
            "type": "string",
            "format": "date-time",
            "description": "Date of last appearence on the events list (generated from dates array)"
          },
          "venues": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Venue"
            },
            "description": "List of venues"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "distanceMeters": {
            "type": "number",
            "format": "float",
            "description": "Distance in meters from the requested `geo[lat]`/`geo[lng]`. Present only when geolocation is requested."
          },
          "description": {
            "$ref": "#/components/schemas/Content"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of category IDs"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of tags"
          },
          "audiences": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Audiences: { id, titles }"
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of languages the experience is in: lb, fr, de, en, etc."
          },
          "environments": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Experience environments: indoor, outdoor, online, etc."
          },
          "onlineLink": {
            "type": "string",
            "description": "Online link: url to attend the experience remotely, usually set when `environments` contains \"online\""
          },
          "formats": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Formats: workshop, concert, lecture, etc."
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          },
          "tickets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Ticket"
            },
            "description": "List of tickets: title, currency, value, etc."
          },
          "purchaseLink": {
            "type": "string",
            "description": "Purchase Link: in case if any of tickets don't have link to the purchase page, this will be used"
          },
          "luxembourgTickets": {
            "$ref": "#/components/schemas/LuxTicketSettings"
          },
          "salesContact": {
            "$ref": "#/components/schemas/Contact"
          },
          "status": {
            "$ref": "#/components/schemas/ExperienceStatus"
          },
          "organisationId": {
            "type": "string",
            "description": "Organisation ID"
          },
          "timestamps": {
            "$ref": "#/components/schemas/Timestamps"
          }
        },
        "required": [
          "id",
          "title",
          "pictures",
          "dates",
          "endDate",
          "venues",
          "description",
          "categories",
          "tags",
          "audiences",
          "languages",
          "environments",
          "formats",
          "organisationId",
          "timestamps"
        ],
        "description": "Description for Experience Model"
      },
      "ExperienceDatePermanent": {
        "type": "object",
        "properties": {
          "openingHours": {
            "$ref": "#/components/schemas/OpeningHours"
          },
          "closingTimes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExperienceDateSingle"
            }
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "purchaseLink": {
            "type": "string"
          }
        },
        "required": [
          "openingHours",
          "from",
          "to"
        ]
      },
      "ExperienceDateRecurring": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time",
            "description": "Start date and time of the occurences in the rrule (overwrite the date in the rrule if tin the rrule date is earlier)"
          },
          "to": {
            "type": "string",
            "format": "date-time",
            "description": "End date and time of the occurences in the rrule (overwrite the date in the rrule if the rrule have a later date)"
          },
          "duration": {
            "type": "number",
            "format": "float",
            "description": "The length of the show in minutes"
          },
          "rrule": {
            "type": "string",
            "description": "Recurrence Rule from the iCal RFC (https://datatracker.ietf.org/doc/html/rfc5545)"
          },
          "purchaseLink": {
            "type": "string",
            "description": "Purchase Link: in case if there is a direct link to the repeating events from the rrule"
          }
        },
        "required": [
          "from",
          "to",
          "rrule"
        ]
      },
      "ExperienceDateSingle": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time",
            "description": "Start date and time of the experience"
          },
          "to": {
            "type": "string",
            "format": "date-time",
            "description": "End date and time of the experience"
          },
          "duration": {
            "type": "number",
            "format": "float",
            "description": "The length of the show in minutes"
          },
          "purchaseLink": {
            "type": "string",
            "description": "Purchase Link: in case if there is a direct link to the specific date"
          }
        },
        "required": [
          "from",
          "to"
        ]
      },
      "ExperienceStatus": {
        "type": "object",
        "properties": {
          "current": {
            "type": "string",
            "description": "Current status of the experience: draft, pending, rejected or published. Only the first two can be set by API"
          },
          "startDate": {
            "type": "string",
            "format": "date-time",
            "description": "Date and time when the status was set"
          }
        },
        "required": [
          "current",
          "startDate"
        ]
      },
      "Format": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "titles": {
            "$ref": "#/components/schemas/Content"
          }
        },
        "required": [
          "id",
          "titles"
        ]
      },
      "GeoRequest": {
        "type": "object",
        "properties": {
          "lat": {
            "type": "number",
            "format": "float"
          },
          "lng": {
            "type": "number",
            "format": "float"
          },
          "radius": {
            "type": "number",
            "format": "float"
          }
        },
        "required": [
          "lat",
          "lng"
        ],
        "description": "Geolocation input for proximity ranking and radius filtering.\n\n**Access:** Geolocation is not enabled by default. It must be activated per API key —\ncontact Echo to request access. A key without geo access that sends `geo[...]` parameters\nreceives **HTTP 403 (`geo/not-enabled`)**. Enabled keys will be rate limited.\n\nExample (rank by distance, no filter):\n\n**?geo[lat]=49.6116&geo[lng]=6.1319**\n\nExample (only experiences within 2 km):\n\n**?geo[lat]=49.6116&geo[lng]=6.1319&geo[radius]=2000**\n\n- `lat` and `lng` are required together (WGS84). Coordinates are rounded to ~111 m.\n- `radius` is optional, in meters (max 100000). Omit it to rank by distance without filtering.\n- When geo is provided, each returned experience includes a `distanceMeters` field."
      },
      "GetExperienceErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "GetExperienceNotFoundResponse": {
        "type": "object"
      },
      "GetExperienceResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "record": {
            "$ref": "#/components/schemas/Experience"
          }
        },
        "required": [
          "stats",
          "record"
        ]
      },
      "GetVenueErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "GetVenueNotFoundResponse": {
        "type": "object"
      },
      "GetVenueResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "record": {
            "$ref": "#/components/schemas/Venue"
          }
        },
        "required": [
          "stats",
          "record"
        ]
      },
      "ListAudiencesErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "ListAudiencesNotFoundResponse": {
        "type": "object"
      },
      "ListAudiencesResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Audience"
            }
          }
        },
        "required": [
          "stats",
          "records"
        ]
      },
      "ListCategoriesErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "ListCategoriesNotFoundResponse": {
        "type": "object"
      },
      "ListCategoriesResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Category"
            }
          }
        },
        "required": [
          "stats",
          "records"
        ]
      },
      "ListCommunesErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "ListCommunesNotFoundResponse": {
        "type": "object"
      },
      "ListCommunesResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Commune"
            }
          }
        },
        "required": [
          "stats",
          "records"
        ]
      },
      "ListEnvironmentsErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "ListEnvironmentsNotFoundResponse": {
        "type": "object"
      },
      "ListEnvironmentsResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Audience"
            }
          }
        },
        "required": [
          "stats",
          "records"
        ]
      },
      "ListExperienceErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "ListExperienceNotFoundResponse": {
        "type": "object"
      },
      "ListExperienceResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Experience"
            }
          }
        },
        "required": [
          "stats",
          "records"
        ]
      },
      "ListFormatsErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "ListFormatsNotFoundResponse": {
        "type": "object"
      },
      "ListFormatsResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Format"
            }
          }
        },
        "required": [
          "stats",
          "records"
        ]
      },
      "ListVenuesErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "ListVenuesNotFoundResponse": {
        "type": "object"
      },
      "ListVenuesResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Venue"
            }
          }
        },
        "required": [
          "stats",
          "records"
        ]
      },
      "Location": {
        "type": "object",
        "properties": {
          "address": {
            "$ref": "#/components/schemas/Address"
          }
        },
        "required": [
          "address"
        ]
      },
      "LuxTicketSettings": {
        "type": "object",
        "properties": {
          "publishOnEventim": {
            "type": "boolean",
            "description": "Eventim listing: if true, this tickets will be available on eventim.de"
          },
          "includeSalesFee": {
            "type": "boolean",
            "description": "Include the sales fee in the price or add it to the original price"
          },
          "delivery": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "self-print",
                "post"
              ]
            },
            "description": "Delivery type options: self-print and post"
          },
          "saleLimit": {
            "type": "integer",
            "format": "int32",
            "description": "Sale limit: sell no more than n-tickets via luxembourg-ticket.lu (common number across the all ticket types)"
          },
          "excludedTickets": {
            "type": "integer",
            "format": "int32",
            "description": "Number of tickets excluded from sale"
          },
          "kulturpassTickets": {
            "type": "integer",
            "format": "int32",
            "description": "Number of tickets on sale with Kulturpass discount"
          },
          "requiresSeatingPlan": {
            "type": "boolean",
            "description": "Experience requires a seating plan (added manually later)"
          },
          "seatingReservation": {
            "type": "boolean",
            "description": "Seating reservation"
          }
        },
        "required": [
          "publishOnEventim",
          "includeSalesFee",
          "delivery",
          "requiresSeatingPlan",
          "seatingReservation"
        ],
        "description": "Luxembourg Ticket Settings\n\nin case if the tickets for the experience should be available via luxembourg-ticket.lu\nthere are additional settings to fine tune the user experience"
      },
      "OpeningHours": {
        "type": "object",
        "properties": {
          "monday": {
            "$ref": "#/components/schemas/OpeningHoursSetting"
          },
          "tuesday": {
            "$ref": "#/components/schemas/OpeningHoursSetting"
          },
          "wednesday": {
            "$ref": "#/components/schemas/OpeningHoursSetting"
          },
          "thursday": {
            "$ref": "#/components/schemas/OpeningHoursSetting"
          },
          "friday": {
            "$ref": "#/components/schemas/OpeningHoursSetting"
          },
          "saturday": {
            "$ref": "#/components/schemas/OpeningHoursSetting"
          },
          "sunday": {
            "$ref": "#/components/schemas/OpeningHoursSetting"
          }
        }
      },
      "OpeningHoursSetting": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "Time in format HH:mm"
          },
          "to": {
            "type": "string",
            "description": "Time in format HH:mm"
          },
          "breakTime": {
            "type": "boolean",
            "description": "Flag to indicate if there is a 2nd time slot"
          },
          "secondFrom": {
            "type": "string",
            "description": "Time in format HH:mm\nOnly take into account **if breakTime is true**"
          },
          "secondTo": {
            "type": "string",
            "description": "Time in format HH:mm\nOnly take into account **if breakTime is true**"
          }
        },
        "required": [
          "from",
          "to"
        ],
        "description": "If ommited, the day is considered closed\n\nIf only **from** and **to** are provided,\nthe day is considered open from **from - 12:00** and **12:00 - to**\n\nIf **breakTime** is true,\nthe day is considered open from **from - to** and **secondFrom - secondTo**"
      },
      "PaginationRequest": {
        "type": "object",
        "properties": {
          "page": {
            "type": "number",
            "format": "float"
          },
          "perPage": {
            "type": "number",
            "format": "float"
          }
        },
        "required": [
          "page",
          "perPage"
        ],
        "description": "Example:\n\n**?pagination[page]=0&pagination[perPage]=10**\n\nThe request returns nothing if the requested page exceeds records/perPage"
      },
      "PatchVenueRequest": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Title"
          },
          "pictures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PictureUpdateRequest"
            },
            "description": "List of pictures to be updated. Important: all pictures will be replaced. File names should be unique!"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "description": {
            "$ref": "#/components/schemas/Content"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Category IDs"
          },
          "website": {
            "type": "string",
            "description": "Website URL"
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          }
        }
      },
      "Picture": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "copy": {
            "type": "string"
          },
          "alt": {
            "type": "string"
          },
          "originalUrl": {
            "type": "string"
          },
          "fileName": {
            "type": "string"
          },
          "previews": {
            "type": "object",
            "properties": {
              "card": {
                "$ref": "#/components/schemas/PicturePreview"
              },
              "dashboard": {
                "$ref": "#/components/schemas/PicturePreview"
              },
              "detail": {
                "$ref": "#/components/schemas/PicturePreview"
              },
              "featured": {
                "$ref": "#/components/schemas/PicturePreview"
              },
              "share": {
                "$ref": "#/components/schemas/PicturePreview"
              }
            }
          }
        },
        "required": [
          "url",
          "originalUrl",
          "fileName"
        ],
        "description": "Description for Picture Model"
      },
      "PictureCreateRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "URL pointing to an endpoint serving the image (jpeg, png) to import.\nOr a base64 string representing the image data in jpeg/png.\nFile size limit: 2mb."
          },
          "copy": {
            "type": "string",
            "description": "Copyright information of the image"
          },
          "alt": {
            "type": "string",
            "description": "Text for screen readers"
          }
        },
        "required": [
          "url"
        ]
      },
      "PicturePreview": {
        "type": "object",
        "properties": {
          "size": {
            "type": "string"
          },
          "fileName": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "size",
          "fileName",
          "url"
        ],
        "description": "Picture preview\n\nThat is an image that is created automatically when a new image for an experience or a venue is uploaded.\nPreviews are lower quality than the original, they differ in size and ratio, and are used on the website\ninstead of the original one.\n\nSome of the basic preview sizes:\ncard: 355x200\ndashboard: 156x88\ndetail: 1600x900\nfeatured: 896x504\nshare: 1200x630"
      },
      "PictureUpdateRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "URL pointing to the image to import, or a base64 string representing the image data"
          },
          "copy": {
            "type": "string",
            "description": "Copyright information of the image"
          },
          "alt": {
            "type": "string",
            "description": "Text for screen readers"
          }
        },
        "required": [
          "url"
        ]
      },
      "PutVenueRequest": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Title"
          },
          "pictures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PictureUpdateRequest"
            },
            "description": "Pictures"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "description": {
            "$ref": "#/components/schemas/Content"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Category IDs"
          },
          "website": {
            "type": "string",
            "description": "Website URL"
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          }
        },
        "required": [
          "title",
          "pictures",
          "location",
          "description",
          "categories",
          "website",
          "contact"
        ]
      },
      "StatsResponse": {
        "type": "object",
        "properties": {
          "start": {
            "type": "integer",
            "format": "int32"
          },
          "end": {
            "type": "integer",
            "format": "int32"
          },
          "duration": {
            "type": "integer",
            "format": "int32"
          }
        },
        "required": [
          "start",
          "end",
          "duration"
        ]
      },
      "Ticket": {
        "type": "object",
        "properties": {
          "title": {
            "$ref": "#/components/schemas/Content"
          },
          "price": {
            "type": "number",
            "format": "float",
            "description": "Price: the price of the ticket. Should be 0 if the entrance is free"
          },
          "currency": {
            "type": "string",
            "enum": [
              "EUR"
            ]
          },
          "quantity": {
            "type": "integer",
            "format": "int32",
            "description": "Number: quantity of tickets available"
          },
          "salesStart": {
            "oneOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "string",
                "format": "date-time"
              }
            ],
            "description": "Date (and time, optionally) when the ticket should be available for sell, if omitted ticket is available when the experience is published"
          },
          "salesEnd": {
            "oneOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "string",
                "format": "date-time"
              }
            ],
            "description": "Date (and time, optionally) when the ticket is not available, if omitted, the experience start date and time is used (you cannot buy a ticket after the start of the event)"
          }
        },
        "required": [
          "title",
          "price"
        ]
      },
      "Timestamps": {
        "type": "object",
        "properties": {
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdBy": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedBy": {
            "type": "string"
          },
          "deletedAt": {
            "type": "string",
            "format": "date-time"
          },
          "deletedBy": {
            "type": "string"
          }
        }
      },
      "UpdateExperienceErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "UpdateExperienceNotFoundResponse": {
        "type": "object"
      },
      "UpdateExperienceRequest": {
        "type": "object",
        "properties": {
          "title": {
            "$ref": "#/components/schemas/Content"
          },
          "subtitle": {
            "$ref": "#/components/schemas/Content"
          },
          "pictures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PictureUpdateRequest"
            },
            "description": "List of pictures to be updated. Important: all pictures will be replaced. File names should be unique, and file size should be less than 2MB!"
          },
          "videos": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VideoUpdateRequest"
            },
            "description": "List of videos to add to the experience"
          },
          "dates": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ExperienceDateSingle"
                },
                {
                  "$ref": "#/components/schemas/ExperienceDateRecurring"
                },
                {
                  "$ref": "#/components/schemas/ExperienceDatePermanent"
                }
              ]
            }
          },
          "venues": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "description": {
            "$ref": "#/components/schemas/Content"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "audiences": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of languages the experience is in: lb, fr, de, en, etc."
          },
          "environments": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Experience environments: indoor, outdoor, online, etc."
          },
          "onlineLink": {
            "type": "string",
            "description": "Online link: url to attend the experience remotely, usually set when `environments` contains \"online\""
          },
          "formats": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Formats: workshop, concert, lecture, etc."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          },
          "tickets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Ticket"
            },
            "description": "Tickets"
          },
          "purchaseLink": {
            "type": "string",
            "description": "Purchase link"
          },
          "luxembourgTickets": {
            "$ref": "#/components/schemas/LuxTicketSettings"
          },
          "salesContact": {
            "$ref": "#/components/schemas/Contact"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "pending"
            ],
            "description": "Status:\n- draft: mark that the experience was updated via API.\n- pending: send the experience to validation, works only if the previeus status was draft.\n\n[![flow](https://storage.googleapis.com/lu-echo-prod-experiences/api-doc/echo-api-status-flow-patch-img.jpg)](https://storage.googleapis.com/lu-echo-prod-experiences/api-doc/echo-api-status-flow.pdf)"
          }
        },
        "description": "Update Experience Request\n\nThe `date-time` for dates should set as defined by https://tools.ietf.org/html/rfc3339#section-5.6"
      },
      "UpdateExperienceResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "record": {
            "$ref": "#/components/schemas/Experience"
          }
        },
        "required": [
          "stats",
          "record"
        ]
      },
      "UpdateVenueErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": [
          "error"
        ]
      },
      "UpdateVenueNotFoundResponse": {
        "type": "object"
      },
      "UpdateVenueResponse": {
        "type": "object",
        "properties": {
          "stats": {
            "$ref": "#/components/schemas/StatsResponse"
          },
          "record": {
            "$ref": "#/components/schemas/Venue"
          }
        },
        "required": [
          "stats",
          "record"
        ]
      },
      "Venue": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Venue ID"
          },
          "title": {
            "type": "string",
            "description": "Title"
          },
          "pictures": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Picture"
            },
            "description": "Pictures"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "description": {
            "$ref": "#/components/schemas/Content"
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Categories"
          },
          "website": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ],
            "description": "Venue website"
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          },
          "timestamps": {
            "$ref": "#/components/schemas/Timestamps"
          },
          "creationSource": {
            "type": "string",
            "enum": [
              "api",
              "admin_ui",
              "experience_publish",
              "imported",
              "unidentified"
            ],
            "description": "Identifies how the venue was originally created. Read-only — set server-side."
          }
        },
        "required": [
          "id",
          "title",
          "pictures",
          "location",
          "description",
          "categories",
          "website",
          "contact",
          "timestamps"
        ],
        "description": "Venue Model"
      },
      "Video": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/VideoTypes"
          },
          "url": {
            "type": "string",
            "description": "Address of the embedded video"
          },
          "cover": {
            "$ref": "#/components/schemas/Picture"
          },
          "description": {
            "$ref": "#/components/schemas/Content"
          }
        },
        "required": [
          "type",
          "url"
        ],
        "description": "Description for Video Model"
      },
      "VideoCreateRequest": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/VideoTypes"
          },
          "url": {
            "type": "string",
            "description": "Address of the embedded video"
          },
          "cover": {
            "type": "string",
            "description": "URL pointing to the image to import, or a base64 string representing the image data"
          },
          "description": {
            "$ref": "#/components/schemas/Content"
          }
        },
        "required": [
          "type",
          "url"
        ]
      },
      "VideoTypes": {
        "type": "string",
        "enum": [
          "youtube",
          "vimeo",
          "other"
        ]
      },
      "VideoUpdateRequest": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/VideoTypes"
          },
          "url": {
            "type": "string",
            "description": "Address of the embedded video"
          },
          "cover": {
            "type": "string",
            "description": "URL pointing to the image to import, or a base64 string representing the image data"
          },
          "description": {
            "$ref": "#/components/schemas/Content"
          }
        },
        "required": [
          "type",
          "url"
        ]
      }
    },
    "securitySchemes": {
      "SecurityHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "api-key",
        "description": "API key issued through **Echo's website"
      }
    }
  },
  "security": [
    {
      "SecurityHeader": []
    }
  ]
}