{
  "openapi": "3.1.0",
  "paths": {
    "/me": {
      "get": {
        "description": "Returns the workspace, integration, scopes, property restriction and rate limits for the key you are calling with. Use it to verify a key and discover what it can reach.",
        "operationId": "getMe",
        "parameters": [
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The calling credential.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Retrieve the current credential",
        "tags": [
          "Account"
        ]
      }
    },
    "/properties": {
      "get": {
        "description": "Returns properties your integration may access, most recently modified first. Combine `updated_after` with the cursor for an incremental sync.",
        "operationId": "listProperties",
        "parameters": [
          {
            "name": "ids",
            "required": false,
            "in": "query",
            "description": "Comma-separated list of resource ids to fetch.",
            "schema": {
              "example": "0f8b1d2e-1c2a-4f3b-9a1e-7c2d3e4f5a6b,1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
              "type": "string"
            }
          },
          {
            "name": "created_after",
            "required": false,
            "in": "query",
            "description": "Only records created strictly after this instant (RFC 3339).",
            "schema": {
              "example": "2026-08-01T00:00:00Z",
              "type": "string"
            }
          },
          {
            "name": "created_before",
            "required": false,
            "in": "query",
            "description": "Only records created strictly before this instant (RFC 3339).",
            "schema": {
              "example": "2026-08-31T23:59:59Z",
              "type": "string"
            }
          },
          {
            "name": "updated_after",
            "required": false,
            "in": "query",
            "description": "Only records modified strictly after this instant (RFC 3339). Use this for delta syncs.",
            "schema": {
              "example": "2026-08-18T09:30:00Z",
              "type": "string"
            }
          },
          {
            "name": "updated_before",
            "required": false,
            "in": "query",
            "description": "Only records modified strictly before this instant (RFC 3339).",
            "schema": {
              "example": "2026-08-19T00:00:00Z",
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Page size, 1-200.",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "type": "number"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "Opaque cursor from a previous response. Pass `pagination.next_cursor` back verbatim.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "city",
            "required": false,
            "in": "query",
            "description": "Filter by city (case-insensitive exact match).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include_archived",
            "required": false,
            "in": "query",
            "description": "Include archived properties. Archived properties are excluded by default.",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          },
          {
            "name": "expand",
            "required": false,
            "in": "query",
            "description": "Comma-separated related objects to embed. Allowed: `photos`, `owner`.",
            "schema": {
              "example": "photos",
              "type": "string"
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A cursor-paginated page of properties.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PropertyList"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "List properties",
        "tags": [
          "Properties"
        ]
      }
    },
    "/properties/{id}": {
      "get": {
        "description": "Returns 404 both when the property does not exist and when it falls outside your grant.",
        "operationId": "getProperty",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Property id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand",
            "required": false,
            "in": "query",
            "description": "Comma-separated related objects to embed. Allowed: `photos`, `owner`.",
            "schema": {
              "example": "photos,owner",
              "type": "string"
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested property.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Property"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Retrieve a property",
        "tags": [
          "Properties"
        ]
      },
      "patch": {
        "description": "Updates listing details. Only the fields you send are changed. Address, geolocation, owner and access codes are not writable. Pricing is on `PUT /v1/properties/{id}/rates`.",
        "operationId": "updateProperty",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Property id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the original response instead of applying the change twice.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePropertyRequest"
              },
              "examples": {
                "default": {
                  "value": {
                    "name": "Chalet des Aravis",
                    "nickname": "Aravis",
                    "registration_number": "7401200012345",
                    "bedrooms": 0,
                    "bathrooms": 0,
                    "max_guests": 1,
                    "surface_sqm": 0,
                    "amenities": [
                      "wifi",
                      "parking"
                    ],
                    "bed_sizes": [
                      "160x200",
                      "90x190"
                    ],
                    "check_in_time": "16:00",
                    "check_out_time": "10:00",
                    "video_url": "https://vimeo.com/123456789",
                    "external_ref": "JAC-4471"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The property after the update.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Property"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Update a property",
        "tags": [
          "Properties"
        ]
      }
    },
    "/properties/{id}/rates": {
      "get": {
        "description": "The default nightly rate, its floor and ceiling, the property-level stay rules and the per-channel overlays. Per-date pricing is on `/v1/calendar`.",
        "operationId": "getRates",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Property id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "refresh",
            "required": false,
            "in": "query",
            "description": "Force a fresh read of the per-channel overlays instead of serving cached values. Slower; use it when you suspect the cache is stale.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The property's rates.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Rates"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Retrieve rates",
        "tags": [
          "Properties"
        ]
      },
      "put": {
        "description": "Sets the default rate, its bounds, the property-level stay rules and the per-channel markup in one call. Only the fields you send are changed. Re-read after writing, so the response reflects what was stored. See the [pricing guide](/pricing) for how the layers resolve.",
        "operationId": "updateRates",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Property id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the original response instead of applying the change twice.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRatesRequest"
              },
              "examples": {
                "default": {
                  "value": {
                    "base_price_cents": 12500,
                    "floor_price_cents": 8000,
                    "ceiling_price_cents": 40000,
                    "min_stay": 2,
                    "max_stay": 30,
                    "block_after_checkout_days": 0,
                    "channels": [
                      {
                        "channel": "airbnb",
                        "markup_multiplier": 1.1,
                        "guests_included": 2,
                        "extra_person_price": 15,
                        "last_minute_discount_percent": 10,
                        "last_minute_days_to_checkin": 7,
                        "fees": [
                          {
                            "code": "CLEANINGFEE",
                            "label": "Cleaning fee",
                            "amount": 60
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The rates after the update.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Rates"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Update rates",
        "tags": [
          "Properties"
        ]
      }
    },
    "/reservations": {
      "get": {
        "description": "Returns reservations, most recently modified first. `expand=guest` embeds guest identity and requires the `reservations:guest_read` scope; without it the `guest` field is omitted and the request still succeeds.",
        "operationId": "listReservations",
        "parameters": [
          {
            "name": "ids",
            "required": false,
            "in": "query",
            "description": "Comma-separated list of resource ids to fetch.",
            "schema": {
              "example": "0f8b1d2e-1c2a-4f3b-9a1e-7c2d3e4f5a6b,1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
              "type": "string"
            }
          },
          {
            "name": "created_after",
            "required": false,
            "in": "query",
            "description": "Only records created strictly after this instant (RFC 3339).",
            "schema": {
              "example": "2026-08-01T00:00:00Z",
              "type": "string"
            }
          },
          {
            "name": "created_before",
            "required": false,
            "in": "query",
            "description": "Only records created strictly before this instant (RFC 3339).",
            "schema": {
              "example": "2026-08-31T23:59:59Z",
              "type": "string"
            }
          },
          {
            "name": "updated_after",
            "required": false,
            "in": "query",
            "description": "Only records modified strictly after this instant (RFC 3339). Use this for delta syncs.",
            "schema": {
              "example": "2026-08-18T09:30:00Z",
              "type": "string"
            }
          },
          {
            "name": "updated_before",
            "required": false,
            "in": "query",
            "description": "Only records modified strictly before this instant (RFC 3339).",
            "schema": {
              "example": "2026-08-19T00:00:00Z",
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Page size, 1-200.",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "type": "number"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "Opaque cursor from a previous response. Pass `pagination.next_cursor` back verbatim.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "property_id",
            "required": false,
            "in": "query",
            "description": "Only reservations for this property.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by reservation status.",
            "schema": {
              "type": "string",
              "enum": [
                "confirmed",
                "pending",
                "cancelled",
                "completed"
              ]
            }
          },
          {
            "name": "channel",
            "required": false,
            "in": "query",
            "description": "Filter by booking channel.",
            "schema": {
              "type": "string",
              "enum": [
                "airbnb",
                "booking",
                "direct"
              ]
            }
          },
          {
            "name": "checkin_from",
            "required": false,
            "in": "query",
            "description": "Check-in on or after this date.",
            "schema": {
              "example": "2026-09-01",
              "type": "string"
            }
          },
          {
            "name": "checkin_to",
            "required": false,
            "in": "query",
            "description": "Check-in on or before this date.",
            "schema": {
              "example": "2026-09-30",
              "type": "string"
            }
          },
          {
            "name": "checkout_from",
            "required": false,
            "in": "query",
            "description": "Check-out on or after this date.",
            "schema": {
              "example": "2026-09-01",
              "type": "string"
            }
          },
          {
            "name": "checkout_to",
            "required": false,
            "in": "query",
            "description": "Check-out on or before this date.",
            "schema": {
              "example": "2026-09-30",
              "type": "string"
            }
          },
          {
            "name": "expand",
            "required": false,
            "in": "query",
            "description": "Comma-separated related objects to embed. Allowed: `guest`, `property`, `line_items`. Embedding `guest` requires the `reservations:guest_read` scope; without it the field is omitted and the request still succeeds.",
            "schema": {
              "example": "property",
              "type": "string"
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A cursor-paginated page of reservations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReservationList"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "List reservations",
        "tags": [
          "Reservations"
        ]
      }
    },
    "/reservations/{id}": {
      "get": {
        "description": "Returns a single reservation.",
        "operationId": "getReservation",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Reservation id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "expand",
            "required": false,
            "in": "query",
            "description": "Comma-separated related objects to embed. Allowed: `guest`, `property`, `line_items`.",
            "schema": {
              "example": "guest,property",
              "type": "string"
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested reservation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Reservation"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Retrieve a reservation",
        "tags": [
          "Reservations"
        ]
      }
    },
    "/blocks": {
      "get": {
        "description": "Returns owner and maintenance blocks. `from` and `to` match any block overlapping the window. Set `mine_only=true` for blocks your integration created.",
        "operationId": "listBlocks",
        "parameters": [
          {
            "name": "ids",
            "required": false,
            "in": "query",
            "description": "Comma-separated list of resource ids to fetch.",
            "schema": {
              "example": "0f8b1d2e-1c2a-4f3b-9a1e-7c2d3e4f5a6b,1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
              "type": "string"
            }
          },
          {
            "name": "created_after",
            "required": false,
            "in": "query",
            "description": "Only records created strictly after this instant (RFC 3339).",
            "schema": {
              "example": "2026-08-01T00:00:00Z",
              "type": "string"
            }
          },
          {
            "name": "created_before",
            "required": false,
            "in": "query",
            "description": "Only records created strictly before this instant (RFC 3339).",
            "schema": {
              "example": "2026-08-31T23:59:59Z",
              "type": "string"
            }
          },
          {
            "name": "updated_after",
            "required": false,
            "in": "query",
            "description": "Only records modified strictly after this instant (RFC 3339). Use this for delta syncs.",
            "schema": {
              "example": "2026-08-18T09:30:00Z",
              "type": "string"
            }
          },
          {
            "name": "updated_before",
            "required": false,
            "in": "query",
            "description": "Only records modified strictly before this instant (RFC 3339).",
            "schema": {
              "example": "2026-08-19T00:00:00Z",
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Page size, 1-200.",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "type": "number"
            }
          },
          {
            "name": "cursor",
            "required": false,
            "in": "query",
            "description": "Opaque cursor from a previous response. Pass `pagination.next_cursor` back verbatim.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "property_id",
            "required": false,
            "in": "query",
            "description": "Only blocks on this property.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Blocks overlapping on or after this date (YYYY-MM-DD).",
            "schema": {
              "example": "2026-09-01",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "Blocks overlapping on or before this date (YYYY-MM-DD).",
            "schema": {
              "example": "2026-09-30",
              "type": "string"
            }
          },
          {
            "name": "mine_only",
            "required": false,
            "in": "query",
            "description": "Return only the blocks created by your own integration.",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A cursor-paginated page of blocks.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlockList"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "List blocks",
        "tags": [
          "Blocks"
        ]
      },
      "post": {
        "description": "Blocks the given nights and closes them on the connected channels. Your integration owns the block, which is what allows you to update or delete it.",
        "operationId": "createBlock",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the original response instead of performing the write twice.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBlockRequest"
              },
              "examples": {
                "default": {
                  "value": {
                    "property_id": "0f8b1a2c-4d5e-4f60-9a71-2b3c4d5e6f70",
                    "start_date": "2026-09-10",
                    "end_date": "2026-09-14",
                    "last_day_is_checkout": false,
                    "reason_type": "maintenance",
                    "reason": "Boiler replacement"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created block.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Block"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Create a block",
        "tags": [
          "Blocks"
        ]
      }
    },
    "/blocks/{id}": {
      "get": {
        "description": "Returns a single block.",
        "operationId": "getBlock",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Block id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The requested block.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Block"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Retrieve a block",
        "tags": [
          "Blocks"
        ]
      },
      "patch": {
        "description": "Only blocks your integration created can be modified.",
        "operationId": "updateBlock",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Block id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the original response instead of performing the write twice.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBlockRequest"
              },
              "examples": {
                "default": {
                  "value": {
                    "start_date": "2026-09-11",
                    "end_date": "2026-09-15",
                    "last_day_is_checkout": false,
                    "reason_type": "maintenance",
                    "reason": "Boiler replacement"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated block.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Block"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Update a block",
        "tags": [
          "Blocks"
        ]
      },
      "delete": {
        "description": "Removes the block and reopens those nights. Only blocks your integration created can be deleted.",
        "operationId": "deleteBlock",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Block id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the original response instead of performing the write twice.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion acknowledgement.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Delete a block",
        "tags": [
          "Blocks"
        ]
      }
    },
    "/blocks/batch": {
      "post": {
        "description": "Accepts up to 100 blocks. Returns `207` with a per-item result, so an item that cannot be applied does not stop the rest. Every item must be schema-valid: one malformed item rejects the whole payload with `400`.",
        "operationId": "createBlocksBatch",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the original response instead of performing the write twice.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBlocksBatch"
              },
              "examples": {
                "default": {
                  "value": {
                    "items": [
                      {
                        "property_id": "0f8b1a2c-4d5e-4f60-9a71-2b3c4d5e6f70",
                        "start_date": "2026-09-10",
                        "end_date": "2026-09-14",
                        "last_day_is_checkout": false,
                        "reason_type": "maintenance",
                        "reason": "Boiler replacement"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "207": {
            "description": "Per-item results, in request order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResult"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Create blocks in bulk",
        "tags": [
          "Blocks"
        ]
      }
    },
    "/calendar": {
      "get": {
        "description": "One row per property per date: price, minimum and maximum stay, arrival and departure rules, and availability. `blocked_by` names what closed the night. Maximum 366 days per call.",
        "operationId": "getCalendar",
        "parameters": [
          {
            "name": "from",
            "required": true,
            "in": "query",
            "description": "First day of the range (YYYY-MM-DD).",
            "schema": {
              "example": "2026-09-01",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "description": "Last day of the range (YYYY-MM-DD). At most 366 days per call.",
            "schema": {
              "example": "2026-09-30",
              "type": "string"
            }
          },
          {
            "name": "property_ids",
            "required": false,
            "in": "query",
            "description": "Comma-separated property ids. Omit for every property you can access.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "channel",
            "required": false,
            "in": "query",
            "description": "Read the calendar as one channel sees it: any channel-specific price or restriction wins over the all-channel value. Omit for the all-channel baseline.",
            "schema": {
              "type": "string",
              "enum": [
                "airbnb",
                "booking",
                "direct"
              ]
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One calendar per requested property.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarList"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Retrieve the calendar",
        "tags": [
          "Calendar"
        ]
      },
      "put": {
        "description": "Sets per-date prices and stay restrictions across many properties and date ranges in one call. Returns `207` with a per-item result, so a range that cannot be applied does not stop the rest. Every item must be schema-valid: one malformed item rejects the whole payload with `400`.",
        "operationId": "updateCalendar",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the original response instead of applying the changes twice.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCalendar"
              },
              "examples": {
                "default": {
                  "value": {
                    "updates": [
                      {
                        "property_id": "0f8b1a2c-4d5e-4f60-9a71-2b3c4d5e6f70",
                        "from": "2026-09-01",
                        "to": "2026-09-15",
                        "price_cents": 12500,
                        "min_stay": 4,
                        "max_stay": 30,
                        "closed_to_arrival": false,
                        "closed_to_departure": false,
                        "stop_sell": false,
                        "channel": "airbnb"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "207": {
            "description": "Per-item results, in request order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResult"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Update the calendar",
        "tags": [
          "Calendar"
        ]
      }
    },
    "/webhooks": {
      "get": {
        "description": "Returns the endpoints registered for your integration.",
        "operationId": "listWebhooks",
        "parameters": [
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Your registered webhook endpoints.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookList"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "List webhook endpoints",
        "tags": [
          "Webhooks"
        ]
      },
      "post": {
        "description": "Registers an endpoint and returns its signing secret, once. Must be HTTPS and publicly resolvable; private and loopback addresses are rejected. Supported events: reservation.created, reservation.updated, reservation.cancelled, reservation.checkout, block.created, block.updated, block.deleted, calendar.updated, property.updated.",
        "operationId": "createWebhook",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the response.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              },
              "examples": {
                "default": {
                  "value": {
                    "url": "https://example.com/hooks/noe",
                    "events": [
                      "reservation.created",
                      "reservation.cancelled"
                    ],
                    "description": "Production sync"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created endpoint, including its signing secret. The secret is shown once.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookWithSecret"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Create a webhook endpoint",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/webhooks/{id}": {
      "patch": {
        "description": "Changes the URL, subscribed events or status.",
        "operationId": "updateWebhook",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook endpoint id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the response.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookRequest"
              },
              "examples": {
                "default": {
                  "value": {
                    "url": "https://example.com/hooks/noe-v2",
                    "events": [
                      "reservation.created"
                    ],
                    "description": "Production sync",
                    "status": "active"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Update a webhook endpoint",
        "tags": [
          "Webhooks"
        ]
      },
      "delete": {
        "description": "Stops delivery immediately. Pending attempts are dropped.",
        "operationId": "deleteWebhook",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook endpoint id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the response.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion acknowledgement.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Delete a webhook endpoint",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/webhooks/{id}/rotate-secret": {
      "post": {
        "description": "Returns a new secret. The previous one keeps working for a grace period so you can deploy without downtime.",
        "operationId": "rotateWebhookSecret",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook endpoint id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the response.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "The new secret and the grace-window expiry. The old secret verifies until it lapses.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSecret"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Rotate a signing secret",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/webhooks/{id}/deliveries": {
      "get": {
        "description": "Returns recent attempts for one endpoint, newest first, with the response status.",
        "operationId": "listWebhookDeliveries",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook endpoint id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Maximum attempts to return.",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "type": "number"
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recent delivery attempts, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryList"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "List delivery attempts",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/webhooks/{id}/deliveries/{deliveryId}/retry": {
      "post": {
        "description": "Queues the delivery for another attempt.",
        "operationId": "retryWebhookDelivery",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook endpoint id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deliveryId",
            "required": true,
            "in": "path",
            "description": "Delivery id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Any unique string (a UUID works). Retrying with the same key replays the response.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "examples": {
              "default": {
                "value": "7e1a4c2b-9d3f-4a60-8b71-5c2e9f0a3d84"
              }
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Retry acknowledgement.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "409": {
            "description": "The `Idempotency-Key` was already used for a different payload, or an identical request is still in flight.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Retry a delivery",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/events": {
      "get": {
        "description": "The durable event log, newest first. Use it to catch up after downtime instead of a full resync.",
        "operationId": "listEvents",
        "parameters": [
          {
            "name": "since",
            "required": false,
            "in": "query",
            "description": "Only events created strictly after this timestamp (ISO 8601).",
            "schema": {
              "example": "2026-08-19T00:00:00Z",
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Only events of this type.",
            "schema": {
              "example": "reservation.created",
              "type": "string",
              "enum": [
                "reservation.created",
                "reservation.updated",
                "reservation.cancelled",
                "reservation.checkout",
                "block.created",
                "block.updated",
                "block.deleted",
                "calendar.updated",
                "property.updated"
              ]
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Maximum events to return.",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "type": "number"
            }
          },
          {
            "name": "X-Noe-App",
            "in": "header",
            "required": false,
            "description": "Your integration key. Verified against the key you authenticated with; a mismatch is rejected.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Events, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "400": {
            "description": "The request was malformed or failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, malformed, revoked or expired.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "403": {
            "description": "The credential is valid but lacks the required scope, is calling from a disallowed IP or origin, or the workspace has revoked the integration.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or falls outside the properties your grant covers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See the `Retry-After` and `X-RateLimit-*` headers.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying. Present on 429 and 503.",
                "schema": {
                  "type": "integer",
                  "example": 37
                }
              }
            }
          },
          "500": {
            "description": "An unexpected error occurred. Quote `request_id` when contacting support.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Requests allowed in the current window, for whichever bucket is tightest.",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Requests left in that window. Back off as this approaches zero.",
                "schema": {
                  "type": "integer",
                  "example": 284
                }
              },
              "X-RateLimit-Reset": {
                "description": "Unix timestamp (seconds) at which the window resets.",
                "schema": {
                  "type": "integer",
                  "example": 1755500400
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "List events",
        "tags": [
          "Webhooks"
        ]
      }
    }
  },
  "info": {
    "title": "Noé Public API",
    "description": "The Noé Public API gives approved integrations programmatic access to a\nconciergerie workspace: properties, reservations, availability blocks and\nthe pricing calendar.\n\n## Authentication\n\nSend your key as `Authorization: Bearer noe_live_...`. Keys are issued by\nthe workspace owner from **Mon compte → API** and can be revoked at any\ntime. Include `X-Noe-App: <your-integration-key>` so a key used by the\nwrong system fails loudly rather than silently succeeding.\n\n## Scopes\n\nEvery endpoint declares the scope it needs. What a key can actually do is\nthe intersection of three layers, each of which can only narrow the last:\nwhat Noé approved for your integration, what the workspace consented to,\nand what the individual key was given. A grant may also be restricted to a\nsubset of the workspace’s properties.\n\n## Pagination\n\nList endpoints are cursor-paginated. Pass `pagination.next_cursor` back as\n`cursor` to get the next page. Combine `updated_after` with the cursor to\nrun an incremental sync rather than re-reading everything — that is the\nsingle most effective way to stay inside your rate limit.\n\n## Rate limits\n\nEvery response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and\n`X-RateLimit-Reset`. On `429` a `Retry-After` header tells you how long to\nwait. Writes have their own, tighter budget.\n\n## Idempotency\n\nEvery write requires an `Idempotency-Key` header. Retrying with the same\nkey replays the original response instead of performing the write twice,\nwhich makes a timeout safe to retry.\n\n## Errors\n\nErrors return `{ \"error\": { \"code\", \"message\", \"details\", \"request_id\" } }`.\nQuote the `request_id` when contacting support and we can find the exact\nrequest in our logs.",
    "version": "2026-08-01",
    "contact": {
      "name": "Noé Support",
      "url": "https://docs.wearenoe.fr",
      "email": "support@wearenoe.fr"
    }
  },
  "tags": [
    {
      "name": "Account",
      "description": "The credential you are calling with, and what it can reach."
    },
    {
      "name": "Properties",
      "description": "Properties in the workspace, and the default rates for each. Per-date pricing is under Calendar."
    },
    {
      "name": "Calendar",
      "description": "Daily price, stay restrictions and availability. A merged view of reservations, blocks and per-date overrides."
    },
    {
      "name": "Blocks",
      "description": "Owner stays, maintenance and other deliberate closures. A block has an id and an owner; only its creator may change it."
    },
    {
      "name": "Reservations",
      "description": "Bookings from every channel, and optionally guest identity. Read-only: the channel is the source of truth."
    },
    {
      "name": "Webhooks",
      "description": "Event subscriptions and the event log."
    }
  ],
  "servers": [
    {
      "url": "https://api.wearenoe.fr/v1",
      "description": "Production"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your API key, e.g. `noe_live_...`."
      }
    },
    "schemas": {
      "BatchItemError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "validation_failed"
          },
          "message": {
            "type": "string",
            "example": "end_date must not be before start_date."
          },
          "details": {
            "type": "object",
            "description": "Field-level detail, when available."
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "BatchItemResult": {
        "type": "object",
        "properties": {
          "index": {
            "type": "number",
            "description": "Position in the request array.",
            "example": 0
          },
          "status": {
            "type": "number",
            "description": "Per-item HTTP status.",
            "example": 200
          },
          "data": {
            "type": "object",
            "description": "The created or updated object, on success."
          },
          "error": {
            "description": "Present when the item failed.",
            "allOf": [
              {
                "$ref": "#/components/schemas/BatchItemError"
              }
            ]
          }
        },
        "required": [
          "index",
          "status"
        ]
      },
      "BatchResult": {
        "type": "object",
        "properties": {
          "results": {
            "description": "One entry per submitted item, in request order. An item that fails while being APPLIED does not stop the others, so inspect every entry. A payload that fails schema validation is rejected whole, with a single `400`.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchItemResult"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "Block": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "object": {
            "type": "string",
            "enum": [
              "block"
            ],
            "example": "block"
          },
          "property_id": {
            "type": "string",
            "format": "uuid"
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "description": "First blocked night.",
            "example": "2026-10-01"
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "description": "Last blocked night.",
            "example": "2026-10-05"
          },
          "last_day_is_checkout": {
            "type": "boolean",
            "description": "When true the final day is a check-out only, so that night stays bookable by an arriving guest.",
            "example": false
          },
          "reason_type": {
            "type": [
              "string",
              "null"
            ],
            "example": "maintenance"
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "example": "Boiler replacement"
          },
          "editable": {
            "type": "boolean",
            "description": "True when your integration created this block, which is also the only case in which you may modify or delete it.",
            "example": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-10T11:00:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-10T11:00:00Z"
          }
        },
        "required": [
          "id",
          "object",
          "property_id",
          "start_date",
          "end_date",
          "last_day_is_checkout",
          "reason_type",
          "reason",
          "editable",
          "created_at",
          "updated_at"
        ]
      },
      "BlockList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Block"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "CalendarDay": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "example": "2026-09-04"
          },
          "available": {
            "type": "boolean",
            "description": "Whether the night can be booked.",
            "example": false
          },
          "price_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "BASE nightly rate in cents: the price set for this date, else the property base price. Null when the workspace has set neither in Noé (the night then keeps the price already published on the channels). Channel markups configured by the workspace are applied on top before the OTA; this is the value to read and write back.",
            "example": 14500
          },
          "min_stay": {
            "type": [
              "number",
              "null"
            ],
            "description": "Minimum nights for an arrival on this date: the per-date value, else the property's default minimum stay.",
            "example": 2
          },
          "max_stay": {
            "type": [
              "number",
              "null"
            ],
            "description": "Maximum nights for an arrival on this date: the per-date value, else the property's default maximum stay.",
            "example": null
          },
          "closed_to_arrival": {
            "type": "boolean",
            "description": "Arrivals forbidden on this date.",
            "example": false
          },
          "closed_to_departure": {
            "type": "boolean",
            "description": "Departures forbidden on this date.",
            "example": false
          },
          "blocked_by": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "reservation",
              "block",
              "stop_sell",
              null
            ],
            "description": "Why the night is unavailable. Null when it is bookable.",
            "example": "reservation"
          }
        },
        "required": [
          "date",
          "available",
          "price_cents",
          "min_stay",
          "max_stay",
          "closed_to_arrival",
          "closed_to_departure",
          "blocked_by"
        ]
      },
      "CalendarList": {
        "type": "object",
        "properties": {
          "data": {
            "description": "One calendar per requested property.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PropertyCalendar"
            }
          }
        },
        "required": [
          "data"
        ]
      },
      "CalendarUpdate": {
        "type": "object",
        "properties": {
          "property_id": {
            "type": "string",
            "format": "uuid",
            "example": "0f8b1a2c-4d5e-4f60-9a71-2b3c4d5e6f70"
          },
          "from": {
            "type": "string",
            "example": "2026-09-01"
          },
          "to": {
            "type": "string",
            "example": "2026-09-15"
          },
          "price_cents": {
            "type": "number",
            "description": "Nightly price in cents, in the property currency. This is the BASE price: markup rules the workspace configured per channel still apply on top before it reaches the OTA. Below 100, or outside the property's floor/ceiling (`floor_price_cents` / `ceiling_price_cents`), the item is rejected with 422.",
            "example": 12500,
            "minimum": 0
          },
          "min_stay": {
            "type": "number",
            "description": "Minimum nights.",
            "minimum": 1,
            "maximum": 365,
            "example": 4
          },
          "max_stay": {
            "type": "number",
            "description": "Maximum nights.",
            "minimum": 1,
            "maximum": 365,
            "example": 30
          },
          "closed_to_arrival": {
            "type": "boolean",
            "description": "Forbid arrivals on these dates."
          },
          "closed_to_departure": {
            "type": "boolean",
            "description": "Forbid departures on these dates."
          },
          "stop_sell": {
            "type": "boolean",
            "description": "Close the dates for sale entirely."
          },
          "channel": {
            "type": "string",
            "enum": [
              "airbnb",
              "booking",
              "direct"
            ],
            "description": "Apply to ONE channel only, leaving the others on the all-channel value. Omit to set the value every channel inherits.\n\nA channel-specific value always wins over the all-channel one, so setting an Airbnb price does not disturb Booking.com. To remove a channel override, set it back to the all-channel value."
          }
        },
        "required": [
          "property_id",
          "from",
          "to"
        ]
      },
      "ChannelFeeInput": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Fee code, uppercase letters. Well-known codes include CLEANINGFEE.",
            "example": "CLEANINGFEE"
          },
          "label": {
            "type": "string",
            "description": "Display label. Informational only.",
            "example": "Cleaning fee"
          },
          "amount": {
            "type": "number",
            "description": "Amount in major currency units (euros, not cents).",
            "example": 60
          }
        },
        "required": [
          "code",
          "amount"
        ]
      },
      "ChannelFeeResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "example": "CLEANINGFEE"
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "example": "Ménage"
          },
          "amount": {
            "type": "number",
            "description": "Major currency units, not cents.",
            "example": 60
          }
        },
        "required": [
          "code",
          "label",
          "amount"
        ]
      },
      "ChannelOverlay": {
        "type": "object",
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "airbnb"
            ],
            "example": "airbnb"
          },
          "markup_multiplier": {
            "type": "number",
            "description": "Price multiplier for this channel: 1.1 adds 10% to every nightly rate published there. Send null to clear it. Note this is a MULTIPLIER, not a percentage — 10 would multiply your prices tenfold.",
            "example": 1.1,
            "minimum": 0,
            "maximum": 5
          },
          "guests_included": {
            "type": "number",
            "description": "Guests included before the extra-guest fee applies.",
            "example": 2
          },
          "extra_person_price": {
            "type": "number",
            "description": "Nightly fee per extra guest, in major units.",
            "example": 15
          },
          "last_minute_discount_percent": {
            "type": "number",
            "description": "Last-minute discount, 0-100 percent.",
            "example": 10
          },
          "last_minute_days_to_checkin": {
            "type": "number",
            "description": "How close to check-in the last-minute discount starts.",
            "example": 7
          },
          "fees": {
            "description": "Fee lines to upsert.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChannelFeeInput"
            }
          }
        },
        "required": [
          "channel"
        ]
      },
      "ChannelOverlayResponse": {
        "type": "object",
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "airbnb"
            ],
            "example": "airbnb"
          },
          "markup_multiplier": {
            "type": [
              "number",
              "null"
            ],
            "description": "Price multiplier for this channel: 1.1 publishes every rate 10% higher.",
            "example": 1.1
          },
          "guests_included": {
            "type": [
              "number",
              "null"
            ],
            "example": 2
          },
          "extra_person_price": {
            "type": [
              "number",
              "null"
            ],
            "example": 15
          },
          "last_minute_discount_percent": {
            "type": [
              "number",
              "null"
            ],
            "example": null
          },
          "last_minute_days_to_checkin": {
            "type": [
              "number",
              "null"
            ],
            "example": null
          },
          "fees": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChannelFeeResponse"
            }
          }
        },
        "required": [
          "channel",
          "markup_multiplier",
          "guests_included",
          "extra_person_price",
          "last_minute_discount_percent",
          "last_minute_days_to_checkin",
          "fees"
        ]
      },
      "CreateBlockRequest": {
        "type": "object",
        "properties": {
          "property_id": {
            "type": "string",
            "description": "Property to block.",
            "format": "uuid",
            "example": "0f8b1a2c-4d5e-4f60-9a71-2b3c4d5e6f70"
          },
          "start_date": {
            "type": "string",
            "description": "First blocked night (YYYY-MM-DD).",
            "example": "2026-09-10"
          },
          "end_date": {
            "type": "string",
            "description": "Last blocked night (YYYY-MM-DD), inclusive.",
            "example": "2026-09-14"
          },
          "last_day_is_checkout": {
            "type": "boolean",
            "description": "When true, `end_date` is a DEPARTURE day rather than a blocked night: the occupant leaves that morning and the date stays sellable as an arrival.",
            "default": false
          },
          "reason_type": {
            "type": "string",
            "description": "Free-form category, e.g. `owner` or `maintenance`.",
            "example": "maintenance"
          },
          "reason": {
            "type": "string",
            "description": "Human-readable note.",
            "example": "Boiler replacement"
          }
        },
        "required": [
          "property_id",
          "start_date",
          "end_date"
        ]
      },
      "CreateBlocksBatch": {
        "type": "object",
        "properties": {
          "items": {
            "maxItems": 100,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateBlockRequest"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "CreateWebhookRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "HTTPS endpoint to deliver to. Must be publicly resolvable.",
            "example": "https://example.com/hooks/noe"
          },
          "events": {
            "type": "array",
            "description": "Event types to subscribe to. At least one.",
            "example": [
              "reservation.created",
              "reservation.cancelled"
            ],
            "items": {
              "type": "string",
              "enum": [
                "reservation.created",
                "reservation.updated",
                "reservation.cancelled",
                "reservation.checkout",
                "block.created",
                "block.updated",
                "block.deleted",
                "calendar.updated",
                "property.updated"
              ]
            }
          },
          "description": {
            "type": "string",
            "description": "Your own label for this endpoint.",
            "maxLength": 200,
            "example": "Production sync"
          }
        },
        "required": [
          "url",
          "events"
        ]
      },
      "Deleted": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "object": {
            "type": "string",
            "example": "webhook_endpoint"
          },
          "deleted": {
            "type": "boolean",
            "enum": [
              true
            ],
            "example": true
          }
        },
        "required": [
          "id",
          "object",
          "deleted"
        ]
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Stable id — use it to deduplicate."
          },
          "object": {
            "type": "string",
            "enum": [
              "event"
            ],
            "example": "event"
          },
          "type": {
            "type": "string",
            "example": "reservation.created"
          },
          "api_version": {
            "type": "string",
            "description": "Payload version this event was shaped for.",
            "example": "2026-08-01"
          },
          "created": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-18T09:31:02Z"
          },
          "data": {
            "type": "object",
            "description": "Ids only, never a full object — fetch the resource for its current state.",
            "example": {
              "reservation_id": "9f2b7c1e-..."
            }
          }
        },
        "required": [
          "id",
          "object",
          "type",
          "api_version",
          "created",
          "data"
        ]
      },
      "EventList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Event"
            }
          }
        },
        "required": [
          "data"
        ]
      },
      "Me": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "credential"
            ],
            "example": "credential"
          },
          "api_version": {
            "type": "string",
            "description": "The API version your responses are shaped for.",
            "example": "2026-08-01"
          },
          "environment": {
            "type": "string",
            "enum": [
              "live",
              "test"
            ],
            "description": "Which environment this key belongs to.",
            "example": "live"
          },
          "workspace": {
            "description": "The workspace this key reads and writes.",
            "allOf": [
              {
                "$ref": "#/components/schemas/MeWorkspace"
              }
            ]
          },
          "integration": {
            "$ref": "#/components/schemas/MeIntegration"
          },
          "scopes": {
            "description": "What this key can actually do: the intersection of what Noé approved for the integration, what the workspace consented to, and what the key itself was given.",
            "example": [
              "properties:read",
              "calendar:read",
              "calendar:write"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "scope_details": {
            "description": "The same scopes, explained — handy for rendering a permissions screen.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScopeDescriptor"
            }
          },
          "property_scope": {
            "description": "Property ids you are restricted to. Null means the whole workspace, including properties added later.",
            "example": null,
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "rate_limits": {
            "$ref": "#/components/schemas/MeRateLimits"
          }
        },
        "required": [
          "object",
          "api_version",
          "environment",
          "workspace",
          "integration",
          "scopes",
          "scope_details",
          "property_scope",
          "rate_limits"
        ]
      },
      "MeIntegration": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "The value to send as `X-Noe-App`.",
            "example": "jaffichecomplet"
          },
          "name": {
            "type": "string",
            "example": "J'affiche Complet"
          }
        },
        "required": [
          "key",
          "name"
        ]
      },
      "MeRateLimits": {
        "type": "object",
        "properties": {
          "per_minute": {
            "type": "number",
            "example": 300
          },
          "per_day": {
            "type": "number",
            "example": 20000
          }
        },
        "required": [
          "per_minute",
          "per_day"
        ]
      },
      "MeWorkspace": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": "string",
            "example": "conciergerie-du-lac"
          }
        },
        "required": [
          "id",
          "slug"
        ]
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Pass back as `cursor` for the next page. Null on the last page.",
            "example": "MjAyNi0wOC0xOFQwOTozMDowMFo6YWJj"
          },
          "has_more": {
            "type": "boolean",
            "example": true
          }
        },
        "required": [
          "next_cursor",
          "has_more"
        ]
      },
      "PropertyAddress": {
        "type": "object",
        "properties": {
          "line1": {
            "type": "string",
            "example": "12 rue des Lilas"
          },
          "city": {
            "type": [
              "string",
              "null"
            ],
            "example": "Annecy"
          },
          "postal_code": {
            "type": [
              "string",
              "null"
            ],
            "example": "74000"
          },
          "region": {
            "type": [
              "string",
              "null"
            ],
            "example": "Auvergne-Rhône-Alpes"
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "example": "FR"
          },
          "latitude": {
            "type": [
              "number",
              "null"
            ],
            "example": 45.8992
          },
          "longitude": {
            "type": [
              "number",
              "null"
            ],
            "example": 6.1294
          },
          "floor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Floor or apartment indication, when the property has one.",
            "example": "3e étage"
          }
        },
        "required": [
          "line1",
          "city",
          "postal_code",
          "region",
          "country",
          "latitude",
          "longitude",
          "floor"
        ]
      },
      "PropertyCalendar": {
        "type": "object",
        "properties": {
          "property_id": {
            "type": "string",
            "format": "uuid"
          },
          "object": {
            "type": "string",
            "enum": [
              "calendar"
            ],
            "example": "calendar"
          },
          "from": {
            "type": "string",
            "format": "date",
            "example": "2026-09-01"
          },
          "to": {
            "type": "string",
            "format": "date",
            "example": "2026-09-30"
          },
          "currency": {
            "type": "string",
            "example": "EUR"
          },
          "days": {
            "description": "One entry per date in the range.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CalendarDay"
            }
          }
        },
        "required": [
          "property_id",
          "object",
          "from",
          "to",
          "currency",
          "days"
        ]
      },
      "PropertyCapacity": {
        "type": "object",
        "properties": {
          "bedrooms": {
            "type": "number",
            "example": 2
          },
          "bathrooms": {
            "type": "number",
            "example": 1
          },
          "max_guests": {
            "type": [
              "number",
              "null"
            ],
            "description": "Maximum guests.",
            "example": 4
          },
          "surface_sqm": {
            "type": [
              "number",
              "null"
            ],
            "example": 58
          },
          "bed_sizes": {
            "description": "Bed sizes, one entry per bed.",
            "example": [
              "160x200",
              "90x190"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "bedrooms",
          "bathrooms",
          "max_guests",
          "surface_sqm",
          "bed_sizes"
        ]
      },
      "Property": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "object": {
            "type": "string",
            "enum": [
              "property"
            ],
            "example": "property"
          },
          "reference": {
            "type": "string",
            "description": "Human reference used inside Noé.",
            "example": "A-102"
          },
          "name": {
            "type": "string",
            "example": "Chalet des Aravis"
          },
          "nickname": {
            "type": [
              "string",
              "null"
            ],
            "description": "Short internal label. Often the name staff actually use.",
            "example": "Aravis"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "archived"
            ],
            "example": "active"
          },
          "address": {
            "$ref": "#/components/schemas/PropertyAddress"
          },
          "classification": {
            "type": "string",
            "description": "Property type as classified in Noé.",
            "example": "apartment"
          },
          "residence_type": {
            "type": [
              "string",
              "null"
            ],
            "description": "Whether the home is a primary or secondary residence — drives local rental rules. Null when not declared in Noé (Airbnb does not supply this).",
            "example": "secondary"
          },
          "registration_number": {
            "type": [
              "string",
              "null"
            ],
            "description": "Official rental registration number, where the municipality requires one. Listing platforms are usually legally obliged to display it.",
            "example": "7401200012345"
          },
          "nights_limit": {
            "type": [
              "number",
              "null"
            ],
            "description": "Legal cap on nights rented per year, when one applies. Null means no cap.",
            "example": 120
          },
          "capacity": {
            "$ref": "#/components/schemas/PropertyCapacity"
          },
          "equipment": {
            "$ref": "#/components/schemas/PropertyEquipment"
          },
          "amenities": {
            "example": [
              "wifi",
              "parking",
              "balcony"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pricing": {
            "$ref": "#/components/schemas/PropertyPricing"
          },
          "stay_rules": {
            "$ref": "#/components/schemas/PropertyStayRules"
          },
          "video_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Video tour, when one exists.",
            "example": null
          },
          "external_ref": {
            "type": [
              "string",
              "null"
            ],
            "description": "Your own identifier for this property, if you set one.",
            "example": null
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-03-04T09:12:00Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-18T14:02:11Z"
          },
          "photos": {
            "description": "Only present with `expand=photos`.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PropertyPhoto"
            }
          },
          "owner": {
            "description": "Only present with `expand=owner`. Personal data — handle accordingly.",
            "allOf": [
              {
                "$ref": "#/components/schemas/PropertyOwner"
              }
            ]
          }
        },
        "required": [
          "id",
          "object",
          "reference",
          "name",
          "nickname",
          "status",
          "address",
          "classification",
          "residence_type",
          "registration_number",
          "nights_limit",
          "capacity",
          "equipment",
          "amenities",
          "pricing",
          "stay_rules",
          "video_url",
          "external_ref",
          "created_at",
          "updated_at"
        ]
      },
      "PropertyEquipment": {
        "type": "object",
        "properties": {
          "heating": {
            "type": [
              "string",
              "null"
            ],
            "example": "Pompe à chaleur"
          },
          "kitchen": {
            "example": [
              "Four",
              "Lave-vaisselle"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bathroom": {
            "example": [
              "Baignoire",
              "Sèche-cheveux"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "heating",
          "kitchen",
          "bathroom"
        ]
      },
      "PropertyList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Property"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "PropertyOwner": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "example": "Marie Dubois"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "example": "marie@example.fr"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ],
            "example": "+33 6 12 34 56 78"
          }
        },
        "required": [
          "name",
          "email",
          "phone"
        ]
      },
      "PropertyPhoto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "example": "https://cdn.wearenoe.fr/properties/abc/living-room.jpg"
          },
          "caption": {
            "type": [
              "string",
              "null"
            ],
            "example": "Salon"
          },
          "category": {
            "type": [
              "string",
              "null"
            ],
            "example": "living_room"
          },
          "position": {
            "type": "number",
            "description": "Display order, ascending.",
            "example": 0
          }
        },
        "required": [
          "id",
          "url",
          "caption",
          "category",
          "position"
        ]
      },
      "PropertyPricing": {
        "type": "object",
        "properties": {
          "base_price_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "Default nightly rate in cents, used for any date without an override.",
            "example": 12500
          },
          "floor_price_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "Lowest nightly rate an automated pricing tool may set, in cents.",
            "example": 8000
          },
          "ceiling_price_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "Highest nightly rate an automated pricing tool may set, in cents.",
            "example": 40000
          },
          "currency": {
            "type": "string",
            "description": "ISO 4217 currency for every amount on this property.",
            "example": "EUR"
          },
          "cleaning_fee_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "Cleaning fee charged to the guest, in cents. Null when none is charged.",
            "example": 6000
          }
        },
        "required": [
          "base_price_cents",
          "floor_price_cents",
          "ceiling_price_cents",
          "currency",
          "cleaning_fee_cents"
        ]
      },
      "PropertyStayRules": {
        "type": "object",
        "properties": {
          "min_stay": {
            "type": [
              "number",
              "null"
            ],
            "description": "Default minimum nights, applied to dates without a calendar override.",
            "example": 2
          },
          "max_stay": {
            "type": [
              "number",
              "null"
            ],
            "description": "Default maximum nights.",
            "example": 30
          },
          "max_occupancy": {
            "type": [
              "number",
              "null"
            ],
            "description": "Maximum occupancy published to channels.",
            "example": 4
          },
          "block_after_checkout_days": {
            "type": [
              "number",
              "null"
            ],
            "description": "Nights kept closed after each check-out, for turnover.",
            "example": 1
          },
          "check_in_time": {
            "type": [
              "string",
              "null"
            ],
            "description": "Local check-in time (HH:mm).",
            "example": "16:00"
          },
          "check_out_time": {
            "type": [
              "string",
              "null"
            ],
            "description": "Local check-out time (HH:mm).",
            "example": "10:00"
          }
        },
        "required": [
          "min_stay",
          "max_stay",
          "max_occupancy",
          "block_after_checkout_days",
          "check_in_time",
          "check_out_time"
        ]
      },
      "RatesDefaults": {
        "type": "object",
        "properties": {
          "base_price_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "Default nightly rate in cents, used for any date without an override.",
            "example": 12500
          },
          "floor_price_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "Lowest rate an automated pricing tool may set.",
            "example": 8000
          },
          "ceiling_price_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "Highest rate an automated pricing tool may set.",
            "example": 40000
          },
          "currency": {
            "type": "string",
            "description": "ISO 4217 currency for every amount here.",
            "example": "EUR"
          },
          "cleaning_fee_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "Cleaning fee charged to the guest, in cents.",
            "example": 6000
          },
          "reference_rate": {
            "type": [
              "number",
              "null"
            ],
            "description": "Reference nightly rate published to the channels, in major units.",
            "example": 125
          }
        },
        "required": [
          "base_price_cents",
          "floor_price_cents",
          "ceiling_price_cents",
          "currency",
          "cleaning_fee_cents",
          "reference_rate"
        ]
      },
      "Rates": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "rates"
            ],
            "example": "rates"
          },
          "property_id": {
            "type": "string",
            "format": "uuid"
          },
          "defaults": {
            "description": "What applies when no date overrides it.",
            "allOf": [
              {
                "$ref": "#/components/schemas/RatesDefaults"
              }
            ]
          },
          "stay_rules": {
            "$ref": "#/components/schemas/RatesStayRules"
          },
          "channels": {
            "description": "Per-channel overlays applied on top of whichever rate resolved.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChannelOverlayResponse"
            }
          },
          "channels_connected": {
            "type": "boolean",
            "description": "False when the property is not connected to any channel yet. The defaults still apply; the channel overlays are empty.",
            "example": true
          },
          "channels_synced_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the channel overlays were last reconciled.",
            "example": "2026-08-18T20:04:11Z"
          }
        },
        "required": [
          "object",
          "property_id",
          "defaults",
          "stay_rules",
          "channels",
          "channels_connected",
          "channels_synced_at"
        ]
      },
      "RatesStayRules": {
        "type": "object",
        "properties": {
          "min_stay": {
            "type": [
              "number",
              "null"
            ],
            "description": "Property-level floor for every per-date minimum stay.",
            "example": 2
          },
          "max_stay": {
            "type": [
              "number",
              "null"
            ],
            "example": 30
          },
          "max_occupancy": {
            "type": [
              "number",
              "null"
            ],
            "example": 4
          },
          "block_after_checkout_days": {
            "type": [
              "number",
              "null"
            ],
            "example": 0
          }
        },
        "required": [
          "min_stay",
          "max_stay",
          "max_occupancy",
          "block_after_checkout_days"
        ]
      },
      "ReservationAmounts": {
        "type": "object",
        "properties": {
          "total_cents": {
            "type": "number",
            "description": "What the guest pays in total, in cents.",
            "example": 48000
          },
          "accommodation_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "Accommodation portion.",
            "example": 40000
          },
          "cleaning_fee_cents": {
            "type": [
              "number",
              "null"
            ],
            "example": 6000
          },
          "tourist_tax_cents": {
            "type": [
              "number",
              "null"
            ],
            "example": 2000
          },
          "extra_fees_cents": {
            "type": [
              "number",
              "null"
            ],
            "example": 0
          },
          "channel_commission_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "Commission withheld by the channel (Airbnb host fee, Booking.com commission…), as reported by the channel. Not part of `total_cents`. Null when the channel did not report it.",
            "example": 7200
          },
          "host_payout_cents": {
            "type": "number",
            "description": "What the channel pays out to the host: accommodation + cleaning + extra fees − channel commission. Excludes tourist tax. Same figure as the « Versement » column of the Noé billing export.",
            "example": 38800
          },
          "management_fee_cents": {
            "type": "number",
            "description": "The workspace's management commission on this stay, computed with the property's commission rate and the workspace's commission basis — the same figure as the Noé billing export.",
            "example": 7760
          },
          "owner_net_cents": {
            "type": "number",
            "description": "What the property owner receives: `host_payout_cents` − `management_fee_cents`.",
            "example": 31040
          },
          "adjustments_cents": {
            "type": "number",
            "description": "After-the-fact changes on the channel invoice (refunds, resolution credits, price corrections), negative. 0 when none.",
            "example": 0
          },
          "vat_cents": {
            "type": [
              "number",
              "null"
            ],
            "description": "VAT contained in the invoice lines. Null when the channel does not send an itemised invoice (see `line_items`).",
            "example": 0
          },
          "currency": {
            "type": "string",
            "description": "ISO 4217 currency of every amount above.",
            "example": "EUR"
          }
        },
        "required": [
          "total_cents",
          "accommodation_cents",
          "cleaning_fee_cents",
          "tourist_tax_cents",
          "extra_fees_cents",
          "channel_commission_cents",
          "host_payout_cents",
          "management_fee_cents",
          "owner_net_cents",
          "adjustments_cents",
          "vat_cents",
          "currency"
        ]
      },
      "Reservation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "object": {
            "type": "string",
            "enum": [
              "reservation"
            ],
            "example": "reservation"
          },
          "property_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "confirmed",
              "pending",
              "cancelled",
              "completed"
            ],
            "example": "confirmed"
          },
          "channel": {
            "type": "string",
            "enum": [
              "airbnb",
              "booking",
              "direct"
            ],
            "description": "Where the booking came from.",
            "example": "airbnb"
          },
          "confirmation_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "The channel's own code.",
            "example": "HMKY3ZQ8XN"
          },
          "check_in": {
            "type": "string",
            "format": "date",
            "description": "Arrival date (YYYY-MM-DD).",
            "example": "2026-09-04"
          },
          "check_out": {
            "type": "string",
            "format": "date",
            "description": "Departure date.",
            "example": "2026-09-11"
          },
          "nights": {
            "type": "number",
            "example": 7
          },
          "guests_count": {
            "type": "number",
            "example": 4
          },
          "currency": {
            "type": "string",
            "example": "EUR"
          },
          "amounts": {
            "$ref": "#/components/schemas/ReservationAmounts"
          },
          "booked_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-06-02T18:22:41Z"
          },
          "cancelled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": null
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-06-02T18:22:41Z"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-01T07:15:03Z"
          },
          "guest": {
            "description": "Personal data. Present only when your key holds `reservations:guest_read`; otherwise the field is absent entirely rather than nulled. Every read is recorded in an audit trail.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ReservationGuest"
              }
            ]
          },
          "property": {
            "description": "Only present with `expand=property`.",
            "allOf": [
              {
                "$ref": "#/components/schemas/ReservationPropertyRef"
              }
            ]
          },
          "line_items": {
            "description": "Only present with `expand=line_items`. The channel invoice, line by line (discounts and adjustments included, payments excluded). Null when the channel does not send an itemised invoice — Airbnb sends a single net-payout line, so Airbnb stays are never itemised; use `amounts` for them.",
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/ReservationLineItem"
            }
          }
        },
        "required": [
          "id",
          "object",
          "property_id",
          "status",
          "channel",
          "confirmation_code",
          "check_in",
          "check_out",
          "nights",
          "guests_count",
          "currency",
          "amounts",
          "booked_at",
          "cancelled_at",
          "created_at",
          "updated_at"
        ]
      },
      "ReservationGuest": {
        "type": "object",
        "properties": {
          "first_name": {
            "type": [
              "string",
              "null"
            ],
            "example": "Camille"
          },
          "last_name": {
            "type": [
              "string",
              "null"
            ],
            "example": "Martin"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "example": "camille.martin@example.fr"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ],
            "example": "+33 6 98 76 54 32"
          }
        },
        "required": [
          "first_name",
          "last_name",
          "email",
          "phone"
        ]
      },
      "ReservationLineItem": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "accommodation",
              "cleaning",
              "tourist_tax",
              "extra_fee",
              "discount",
              "adjustment"
            ],
            "description": "`discount`: a negative line labelled as a discount/promotion. `adjustment`: any other negative line (refund, resolution credit, price correction).",
            "example": "accommodation"
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "description": "The channel's label.",
            "example": "Cleaning fee"
          },
          "quantity": {
            "type": "number",
            "example": 1
          },
          "amount_cents": {
            "type": "number",
            "description": "Signed, in cents: discounts and adjustments are negative.",
            "example": 4300
          },
          "vat_rate": {
            "type": "number",
            "description": "VAT rate in percent, as set on this invoice line.",
            "example": 0
          },
          "vat_cents": {
            "type": "number",
            "description": "VAT contained in `amount_cents` (amounts are VAT-inclusive).",
            "example": 0
          }
        },
        "required": [
          "kind",
          "label",
          "quantity",
          "amount_cents",
          "vat_rate",
          "vat_cents"
        ]
      },
      "ReservationList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Reservation"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        },
        "required": [
          "data",
          "pagination"
        ]
      },
      "ReservationPropertyRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": "string",
            "example": "A-102"
          },
          "name": {
            "type": "string",
            "example": "Chalet des Aravis"
          }
        },
        "required": [
          "id",
          "reference",
          "name"
        ]
      },
      "ScopeDescriptor": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "reservations:guest_read"
          },
          "label": {
            "type": "string",
            "example": "Guest identity"
          },
          "description": {
            "type": "string",
            "example": "Read the name, email and phone of the guest on a reservation."
          },
          "sensitive": {
            "type": "boolean",
            "description": "Personal data: every read is audited.",
            "example": true
          },
          "write": {
            "type": "boolean",
            "description": "Mutates data.",
            "example": false
          }
        },
        "required": [
          "key",
          "label",
          "description",
          "sensitive",
          "write"
        ]
      },
      "UpdateBlockRequest": {
        "type": "object",
        "properties": {
          "start_date": {
            "type": "string",
            "example": "2026-09-11"
          },
          "end_date": {
            "type": "string",
            "example": "2026-09-15"
          },
          "last_day_is_checkout": {
            "type": "boolean"
          },
          "reason_type": {
            "type": "string",
            "example": "maintenance"
          },
          "reason": {
            "type": "string",
            "example": "Boiler replacement"
          }
        }
      },
      "UpdateCalendar": {
        "type": "object",
        "properties": {
          "updates": {
            "maxItems": 1000,
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CalendarUpdate"
            }
          }
        },
        "required": [
          "updates"
        ]
      },
      "UpdatePropertyRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name.",
            "example": "Chalet des Aravis"
          },
          "nickname": {
            "type": "string",
            "description": "Short internal label.",
            "example": "Aravis"
          },
          "registration_number": {
            "type": "string",
            "description": "Official rental registration number. Listing platforms are usually legally required to display it.",
            "example": "7401200012345"
          },
          "bedrooms": {
            "type": "number",
            "description": "Number of bedrooms.",
            "minimum": 0,
            "maximum": 100
          },
          "bathrooms": {
            "type": "number",
            "description": "Number of bathrooms.",
            "minimum": 0,
            "maximum": 100
          },
          "max_guests": {
            "type": "number",
            "description": "Maximum guests.",
            "minimum": 1,
            "maximum": 100
          },
          "surface_sqm": {
            "type": "number",
            "description": "Floor area in m².",
            "minimum": 0
          },
          "amenities": {
            "description": "Replaces the amenity list entirely. Send the full set you want.",
            "example": [
              "wifi",
              "parking"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bed_sizes": {
            "description": "Replaces the bed-size list entirely.",
            "example": [
              "160x200",
              "90x190"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "check_in_time": {
            "type": "string",
            "description": "Local check-in time (HH:mm).",
            "example": "16:00"
          },
          "check_out_time": {
            "type": "string",
            "description": "Local check-out time (HH:mm).",
            "example": "10:00"
          },
          "video_url": {
            "type": "string",
            "description": "Video tour URL.",
            "example": "https://vimeo.com/123456789"
          },
          "external_ref": {
            "type": "string",
            "description": "Your own identifier for this property, echoed back on reads.",
            "example": "JAC-4471"
          }
        }
      },
      "UpdateRatesRequest": {
        "type": "object",
        "properties": {
          "base_price_cents": {
            "type": "number",
            "description": "Default nightly rate in cents, used for any date without an override.",
            "example": 12500,
            "minimum": 0
          },
          "floor_price_cents": {
            "type": "number",
            "description": "Lowest nightly rate an automated pricing tool may set, in cents.",
            "example": 8000,
            "minimum": 0
          },
          "ceiling_price_cents": {
            "type": "number",
            "description": "Highest nightly rate an automated pricing tool may set, in cents.",
            "example": 40000,
            "minimum": 0
          },
          "min_stay": {
            "type": "number",
            "description": "Property-level minimum stay. A FLOOR for every per-date minimum: a smaller value set through `PUT /v1/calendar` is capped by it.",
            "minimum": 1,
            "maximum": 365,
            "example": 2
          },
          "max_stay": {
            "type": "number",
            "description": "Property-level maximum stay.",
            "minimum": 1,
            "maximum": 365,
            "example": 30
          },
          "block_after_checkout_days": {
            "type": "number",
            "description": "Nights closed automatically after each check-out. 0 keeps the turnover day sellable; any higher value re-closes it, so reopening that date will not hold.",
            "minimum": 0,
            "maximum": 7,
            "example": 0
          },
          "channels": {
            "description": "Per-channel overlays: markup, occupancy pricing and fees. Only Airbnb supports them.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChannelOverlay"
            }
          }
        }
      },
      "UpdateWebhookRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "Replacement HTTPS endpoint.",
            "example": "https://example.com/hooks/noe-v2"
          },
          "events": {
            "type": "array",
            "description": "Replaces the subscription list entirely rather than adding to it.",
            "example": [
              "reservation.created"
            ],
            "items": {
              "type": "string",
              "enum": [
                "reservation.created",
                "reservation.updated",
                "reservation.cancelled",
                "reservation.checkout",
                "block.created",
                "block.updated",
                "block.deleted",
                "calendar.updated",
                "property.updated"
              ]
            }
          },
          "description": {
            "type": "string",
            "description": "Your own label for this endpoint.",
            "maxLength": 200,
            "example": "Production sync"
          },
          "status": {
            "type": "string",
            "description": "Set to `disabled` to stop delivery without deleting the endpoint.",
            "enum": [
              "active",
              "disabled"
            ]
          }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "object": {
            "type": "string",
            "enum": [
              "webhook_delivery"
            ],
            "example": "webhook_delivery"
          },
          "event_id": {
            "type": "string",
            "format": "uuid",
            "description": "The event this attempt delivered. Correlate it with `GET /v1/events`."
          },
          "event_type": {
            "type": "string",
            "example": "reservation.created"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "succeeded",
              "failed",
              "exhausted"
            ],
            "example": "succeeded"
          },
          "attempt": {
            "type": "number",
            "description": "Attempt number, starting at 0.",
            "example": 1
          },
          "response_status": {
            "type": [
              "number",
              "null"
            ],
            "description": "HTTP status your endpoint returned.",
            "example": 200
          },
          "response_body": {
            "type": [
              "string",
              "null"
            ],
            "description": "Truncated response body.",
            "example": "ok"
          },
          "error": {
            "type": [
              "string",
              "null"
            ],
            "description": "Transport-level failure, when the attempt never got a response.",
            "example": null
          },
          "next_attempt_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": null
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-08-18T09:31:05Z"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-08-18T09:31:04Z"
          }
        },
        "required": [
          "id",
          "object",
          "event_id",
          "event_type",
          "status",
          "attempt",
          "response_status",
          "response_body",
          "error",
          "next_attempt_at",
          "delivered_at",
          "created_at"
        ]
      },
      "WebhookDeliveryList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookDelivery"
            }
          }
        },
        "required": [
          "data"
        ]
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "object": {
            "type": "string",
            "enum": [
              "webhook_endpoint"
            ],
            "example": "webhook_endpoint"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "example": "https://example.com/hooks/noe"
          },
          "events": {
            "example": [
              "reservation.created",
              "reservation.cancelled"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "disabled",
              "auto_disabled"
            ],
            "example": "active"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "example": "Production listener"
          },
          "api_version": {
            "type": "string",
            "description": "Payload version deliveries to this endpoint are shaped for.",
            "example": "2026-08-01"
          },
          "consecutive_failures": {
            "type": "number",
            "description": "Consecutive delivery failures. Reset by the first success.",
            "example": 0
          },
          "last_success_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-08-18T09:31:04Z"
          },
          "last_failure_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": null
          },
          "disabled_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why Noé disabled the endpoint, when `status` is `auto_disabled`.",
            "example": null
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-07-01T10:00:00Z"
          }
        },
        "required": [
          "id",
          "object",
          "url",
          "events",
          "status",
          "description",
          "api_version",
          "consecutive_failures",
          "last_success_at",
          "last_failure_at",
          "disabled_reason",
          "created_at"
        ]
      },
      "WebhookList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Webhook"
            }
          }
        },
        "required": [
          "data"
        ]
      },
      "WebhookSecret": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "secret": {
            "type": "string",
            "description": "The new signing secret. Shown once.",
            "example": "whsec_9f2b7c..."
          },
          "previous_secret_valid_until": {
            "type": "string",
            "format": "date-time",
            "description": "Until when the PREVIOUS secret still verifies, so you can deploy without gaps.",
            "example": "2026-08-20T09:31:04Z"
          }
        },
        "required": [
          "id",
          "secret",
          "previous_secret_valid_until"
        ]
      },
      "WebhookWithSecret": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "object": {
            "type": "string",
            "enum": [
              "webhook_endpoint"
            ],
            "example": "webhook_endpoint"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "example": "https://example.com/hooks/noe"
          },
          "events": {
            "example": [
              "reservation.created",
              "reservation.cancelled"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "disabled",
              "auto_disabled"
            ],
            "example": "active"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "example": "Production listener"
          },
          "api_version": {
            "type": "string",
            "description": "Payload version deliveries to this endpoint are shaped for.",
            "example": "2026-08-01"
          },
          "consecutive_failures": {
            "type": "number",
            "description": "Consecutive delivery failures. Reset by the first success.",
            "example": 0
          },
          "last_success_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": "2026-08-18T09:31:04Z"
          },
          "last_failure_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "example": null
          },
          "disabled_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why Noé disabled the endpoint, when `status` is `auto_disabled`.",
            "example": null
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-07-01T10:00:00Z"
          },
          "secret": {
            "type": "string",
            "description": "Signing secret, returned ONCE at creation and never again. Store it now; verify every delivery with it.",
            "example": "whsec_9f2b7c..."
          }
        },
        "required": [
          "id",
          "object",
          "url",
          "events",
          "status",
          "description",
          "api_version",
          "consecutive_failures",
          "last_success_at",
          "last_failure_at",
          "disabled_reason",
          "created_at",
          "secret"
        ]
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "example": "insufficient_scope"
              },
              "message": {
                "type": "string",
                "example": "Missing required scope(s): calendar:write."
              },
              "details": {
                "type": "object",
                "additionalProperties": true
              },
              "request_id": {
                "type": [
                  "string",
                  "null"
                ],
                "example": "3f2b1c9e-..."
              }
            }
          }
        }
      }
    }
  },
  "x-noe-scopes": [
    {
      "key": "properties:read",
      "description": "Read properties, including amenities, photos metadata and base pricing.",
      "write": false,
      "sensitive": false,
      "since": "2026-08-01"
    },
    {
      "key": "properties:write",
      "description": "Create, update and archive properties. Hard deletion is never exposed.",
      "write": true,
      "sensitive": false,
      "since": "2026-08-01"
    },
    {
      "key": "reservations:read",
      "description": "Read reservations: dates, status, channel and amounts. Excludes guest identity.",
      "write": false,
      "sensitive": false,
      "since": "2026-08-01"
    },
    {
      "key": "reservations:guest_read",
      "description": "Read guest identity (name, email, phone). Every access is audited.",
      "write": false,
      "sensitive": true,
      "since": "2026-08-01"
    },
    {
      "key": "blocks:read",
      "description": "Read availability blocks (owner stays, maintenance).",
      "write": false,
      "sensitive": false,
      "since": "2026-08-01"
    },
    {
      "key": "blocks:write",
      "description": "Create blocks, and update or delete only the blocks this integration created itself.",
      "write": true,
      "sensitive": false,
      "since": "2026-08-01"
    },
    {
      "key": "calendar:read",
      "description": "Read the daily calendar: price, minimum stay, CTA/CTD rules and availability.",
      "write": false,
      "sensitive": false,
      "since": "2026-08-01"
    },
    {
      "key": "calendar:write",
      "description": "Update nightly prices and stay restrictions. Changes propagate to the connected OTAs.",
      "write": true,
      "sensitive": false,
      "since": "2026-08-01"
    },
    {
      "key": "webhooks:manage",
      "description": "Manage this integration’s own webhook endpoints. Grants no additional data access.",
      "write": true,
      "sensitive": false,
      "since": "2026-08-01"
    }
  ]
}
