{"components":{"parameters":{"folioId":{"in":"path","name":"id","required":true,"schema":{"type":"integer"}},"idempotencyKey":{"description":"Repeat a write safely (see Idempotency).","in":"header","name":"Idempotency-Key","required":false,"schema":{"maxLength":200,"type":"string"}},"page":{"in":"query","name":"page","schema":{"default":1,"minimum":1,"type":"integer"}},"page_size":{"in":"query","name":"page_size","schema":{"default":50,"maximum":200,"minimum":1,"type":"integer"}},"reservationId":{"in":"path","name":"id","required":true,"schema":{"type":"integer"}},"roomOfReservationId":{"description":"The id of the room entry of the reservation (`rooms[].id`), not the physical room.","in":"path","name":"rid","required":true,"schema":{"type":"integer"}},"webhookId":{"in":"path","name":"id","required":true,"schema":{"type":"integer"}}},"responses":{"BadRequest":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"A parameter is missing or malformed."},"Conflict":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"A conflict with the current state (duplicate reference, room taken, open folios)."},"Forbidden":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The key lacks the scope, or the API is off for the property."},"NotFound":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The record does not exist or belongs to another property."},"ReadOnly":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The property is in its seasonal pause."},"ReservationDetail":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reservation"}}},"description":"The reservation after the operation."},"ReservationOperation":{"content":{"application/json":{"schema":{"properties":{"done":{"description":"The ids of the rooms the operation was applied to.","items":{"type":"integer"},"type":"array"},"reservation":{"$ref":"#/components/schemas/Reservation"},"skipped":{"items":{"properties":{"reason":{"type":"string"},"room":{"type":"string"},"room_id":{"type":"integer"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"The reservation after the operation, with the rooms done and the ones skipped."},"RuleViolation":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"A business rule of the PMS refused the change; the message says which."},"StayGuests":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/StayGuest"},"type":"array"}},"type":"object"}}},"description":"The guests of the room."},"Unauthorized":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"No key, unknown key or revoked key."}},"schemas":{"AgeBracket":{"properties":{"age_from":{"type":["integer","null"]},"age_to":{"type":["integer","null"]},"code":{"type":"string"},"counts_as_person":{"type":"boolean"},"id":{"type":"integer"},"name":{"type":"string"}},"type":"object"},"ChargeInput":{"properties":{"description":{"description":"Replaces the name of the item on the line.","type":"string"},"discount_pct":{"type":"number"},"item_id":{"description":"An item of GET /items.","type":"integer"},"posted_on":{"description":"Default the business date.","format":"date","type":"string"},"quantity":{"default":1,"type":"number"},"reservation_room_id":{"description":"The room of the reservation the charge belongs to.","type":"integer"},"unit_price":{"description":"List price when omitted.","type":"number"}},"required":["item_id"],"type":"object"},"CheckOutOptions":{"properties":{"charge_full_period":{"description":"With early_departure, still charge the remaining nights.","type":"boolean"},"charge_remaining":{"description":"The answer to 409 `nights_to_charge`: true charges the remaining nights (they go on a new folio to invoice), false checks out without charging them because the document issued already includes them. Omitted, the call asks.","type":"boolean"},"early_departure":{"description":"Departure after today: move it to today.","type":"boolean"}},"type":"object"},"Error":{"properties":{"error":{"additionalProperties":true,"properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"type":"object"}},"type":"object"},"Event":{"properties":{"created_at":{"format":"date-time","type":"string"},"data":{"additionalProperties":true,"description":"A few facts of the moment (status, dates, room); read the reservation for the whole picture.","type":"object"},"entity":{"enum":["reservation","stay"],"type":"string"},"entity_id":{"description":"The reservation, or the room of the reservation (`rooms[].id`).","type":"integer"},"id":{"type":"integer"},"type":{"enum":["reservation.created","reservation.updated","stay.confirmed","stay.room_assigned","stay.updated","stay.checked_in","stay.checked_out","stay.cancelled"],"type":"string"}},"type":"object"},"Folio":{"properties":{"balance":{"type":"number"},"charges":{"type":"number"},"description":{"type":"string"},"document":{"description":"The number of the document issued, once closed.","type":["string","null"]},"guest_id":{"description":"The holder of the folio.","type":["integer","null"]},"guest_name":{"type":"string"},"id":{"type":"integer"},"issue_date":{"format":"date","type":["string","null"]},"lines":{"items":{"$ref":"#/components/schemas/FolioLine"},"type":"array"},"payments":{"type":"number"},"prices_include_vat":{"type":"boolean"},"reservation_id":{"type":["integer","null"]},"status":{"enum":["open","suspended","closed"],"type":"string"}},"type":"object"},"FolioLine":{"properties":{"description":{"type":"string"},"discount":{"type":"number"},"id":{"type":"integer"},"posted_on":{"format":"date","type":"string"},"quantity":{"type":"number"},"reversal_of":{"type":["integer","null"]},"room":{"type":"string"},"service_item_id":{"type":["integer","null"]},"tax_pct":{"type":"number"},"total":{"type":"number"},"type":{"description":"charge, payment, …","type":"string"},"unit_price":{"type":"number"}},"type":"object"},"FolioRef":{"properties":{"balance":{"type":"number"},"charges":{"type":"number"},"description":{"type":"string"},"id":{"type":"integer"},"payments":{"type":"number"},"status":{"enum":["open","suspended","closed"],"type":"string"}},"type":"object"},"Guest":{"additionalProperties":true,"description":"A guest of the archive with every field of the card.","properties":{"address":{"type":["string","null"]},"birth_country":{"type":["string","null"]},"birth_date":{"format":"date","type":["string","null"]},"birth_place":{"type":["string","null"]},"city":{"type":["string","null"]},"company_name":{"type":["string","null"]},"country_code":{"type":["string","null"]},"display_name":{"type":"string"},"doc_expires_on":{"format":"date","type":["string","null"]},"doc_issued_by":{"type":["string","null"]},"doc_issued_on":{"format":"date","type":["string","null"]},"doc_number":{"type":["string","null"]},"doc_type":{"type":["string","null"]},"email":{"type":["string","null"]},"first_name":{"type":["string","null"]},"gender":{"type":["string","null"]},"id":{"type":"integer"},"kind":{"enum":["private","company","agency"],"type":"string"},"language":{"type":["string","null"]},"last_name":{"type":["string","null"]},"mobile":{"type":["string","null"]},"nationality":{"type":["string","null"]},"notes":{"type":["string","null"]},"phone":{"type":["string","null"]},"province":{"type":["string","null"]},"tax_code":{"type":["string","null"]},"vat_number":{"type":["string","null"]},"zip":{"type":["string","null"]}},"type":"object"},"GuestInput":{"additionalProperties":true,"description":"The fields of a guest; every one is optional and only the ones sent change.","properties":{"address":{"type":"string"},"birth_country":{"description":"ISO 3166-1 alpha-2.","type":"string"},"birth_date":{"format":"date","type":"string"},"birth_place":{"type":"string"},"city":{"type":"string"},"company_name":{"type":"string"},"country_code":{"description":"ISO 3166-1 alpha-2.","type":"string"},"doc_expires_on":{"format":"date","type":"string"},"doc_issue_country":{"type":"string"},"doc_issued_by":{"type":"string"},"doc_issued_on":{"format":"date","type":"string"},"doc_number":{"type":"string"},"doc_type":{"description":"The document code of the police tables of the country.","type":"string"},"email":{"type":"string"},"first_name":{"type":"string"},"gender":{"enum":["M","F"],"type":"string"},"kind":{"enum":["private","company","agency"],"type":"string"},"language":{"type":"string"},"last_name":{"type":"string"},"mobile":{"type":"string"},"nationality":{"description":"ISO 3166-1 alpha-2.","type":"string"},"notes":{"type":"string"},"pec":{"type":"string"},"phone":{"type":"string"},"province":{"type":"string"},"sdi_code":{"type":"string"},"tax_code":{"type":"string"},"title":{"type":"string"},"vat_chargeability":{"description":"Italian e-invoice VAT chargeability: I immediate, D deferred, S split payment (public bodies).","enum":["I","D","S"],"type":"string"},"vat_number":{"type":"string"},"zip":{"type":"string"}},"type":"object"},"Item":{"properties":{"code":{"type":"string"},"department":{"type":"string"},"id":{"type":"integer"},"kind":{"type":"string"},"name":{"type":"string"},"price":{"type":"number"},"tax_pct":{"type":"number"}},"type":"object"},"NewParty":{"description":"A booker created with the reservation.","properties":{"city":{"type":"string"},"company_name":{"type":"string"},"country_code":{"description":"ISO 3166-1 alpha-2.","type":"string"},"email":{"type":"string"},"first_name":{"type":"string"},"kind":{"default":"private","enum":["private","company","agency"],"type":"string"},"last_name":{"type":"string"},"phone":{"type":"string"}},"type":"object"},"Page":{"properties":{"page":{"type":"integer"},"page_size":{"type":"integer"},"pages":{"type":"integer"},"total":{"type":"integer"}},"type":"object"},"Party":{"description":"A guest, company or agency in short.","properties":{"email":{"type":"string"},"id":{"type":"integer"},"kind":{"enum":["private","company","agency"],"type":"string"},"name":{"type":"string"},"phone":{"type":"string"}},"type":"object"},"Property":{"properties":{"activity":{"description":"hotel, b\u0026b, apartments…","type":"string"},"address":{"type":"string"},"business_date":{"description":"The working date of the front desk (the day after the last night audit).","format":"date","type":"string"},"check_in_time":{"example":"15:00","type":"string"},"check_out_time":{"example":"11:00","type":"string"},"city":{"type":"string"},"code":{"type":"string"},"country":{"description":"ISO 3166-1 alpha-2.","type":"string"},"currency":{"example":"EUR","type":"string"},"email":{"type":"string"},"id":{"type":"integer"},"latitude":{"type":["number","null"]},"legal_name":{"type":"string"},"longitude":{"type":["number","null"]},"name":{"type":"string"},"phone":{"type":"string"},"province":{"type":"string"},"star_rating":{"type":"string"},"timezone":{"example":"Europe/Rome","type":"string"},"website":{"type":"string"},"zip":{"type":"string"}},"type":"object"},"Quote":{"additionalProperties":true,"description":"The total and the price of each night as the rate engine computed it.","properties":{"nights":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"total":{"type":"number"}},"type":"object"},"QuoteRequest":{"properties":{"adults":{"default":2,"type":"integer"},"arrival":{"format":"date","type":"string"},"brackets":{"additionalProperties":{"type":"integer"},"description":"Children by age bracket id.","type":"object"},"departure":{"format":"date","type":"string"},"discount_pct":{"type":"number"},"offer_id":{"type":"integer"},"price_override":{"description":"A fixed nightly price instead of the grid.","type":"number"},"rate_plan_id":{"description":"Default plan when omitted.","type":"integer"},"room_type_id":{"type":"integer"}},"required":["room_type_id","arrival","departure"],"type":"object"},"RatePlan":{"properties":{"cadence":{"description":"How the room charge is posted.","enum":["daily","weekly","monthly","month_start"],"type":"string"},"code":{"type":"string"},"discount_pct":{"type":"number"},"id":{"type":"integer"},"is_default":{"type":"boolean"},"name":{"type":"string"},"per_person":{"type":"boolean"}},"type":"object"},"RatePlanRef":{"properties":{"code":{"type":"string"},"id":{"type":"integer"},"name":{"type":"string"}},"type":"object"},"Reservation":{"properties":{"arrival":{"format":"date","type":"string"},"billing_party":{"oneOf":[{"$ref":"#/components/schemas/Party"},{"type":"null"}]},"booker":{"oneOf":[{"$ref":"#/components/schemas/Party"},{"type":"null"}]},"booker_reference":{"type":"string"},"booking_code":{"description":"The code of the booking on the channel.","type":"string"},"channel":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"departure":{"format":"date","type":"string"},"external_ref":{"description":"Your own id of the booking, unique for the property.","type":"string"},"folios":{"description":"Only in the detail.","items":{"$ref":"#/components/schemas/FolioRef"},"type":"array"},"group_name":{"type":"string"},"id":{"type":"integer"},"market":{"type":"string"},"nights":{"type":"integer"},"notes":{"type":"string"},"option_expires_on":{"format":"date","type":["string","null"]},"rooms":{"items":{"$ref":"#/components/schemas/ReservationRoom"},"type":"array"},"source":{"type":"string"},"status":{"description":"The least advanced status among the rooms not cancelled.","enum":["option","confirmed","checked_in","checked_out","cancelled"],"type":"string"},"total":{"type":"number"},"type":{"enum":["individual","group","allotment"],"type":"string"},"updated_at":{"description":"The latest change of the head or of a room.","format":"date-time","type":"string"},"voucher":{"type":"string"}},"type":"object"},"ReservationCreate":{"properties":{"billing_party_id":{"type":"integer"},"booker_is_guest":{"description":"Whether the booker sleeps in the (first) room; default the rule of the property.","type":"boolean"},"booker_reference":{"type":"string"},"booking_code":{"type":"string"},"channel":{"type":"string"},"external_ref":{"description":"Your own id of the booking, unique for the property.","type":"string"},"force":{"description":"Accept an overbooking of the type.","type":"boolean"},"group_name":{"type":"string"},"market":{"type":"string"},"new_party":{"$ref":"#/components/schemas/NewParty"},"notes":{"type":"string"},"option_expires_on":{"format":"date","type":"string"},"party_id":{"description":"An existing guest, company or agency as booker.","type":"integer"},"rooms":{"items":{"$ref":"#/components/schemas/RoomRequest"},"minItems":1,"type":"array"},"source":{"type":"string"},"status":{"default":"confirmed","enum":["confirmed","option"],"type":"string"},"voucher":{"type":"string"}},"required":["rooms"],"type":"object"},"ReservationPatch":{"properties":{"billing_party_id":{"type":"integer"},"booker_id":{"type":"integer"},"booker_reference":{"type":"string"},"booking_code":{"type":"string"},"channel":{"type":"string"},"external_ref":{"type":"string"},"group_name":{"type":"string"},"market":{"type":"string"},"notes":{"type":"string"},"option_expires_on":{"description":"Empty string clears it.","format":"date","type":"string"},"source":{"type":"string"},"voucher":{"type":"string"}},"type":"object"},"ReservationRoom":{"description":"One accommodation of a reservation (a stay).","properties":{"adults":{"type":"integer"},"arrival":{"format":"date","type":"string"},"arrival_time":{"example":"18:30","type":"string"},"brackets":{"additionalProperties":{"type":"integer"},"type":"object"},"cancelled_by":{"enum":["guest","hotel"],"type":"string"},"checked_in_at":{"format":"date-time","type":["string","null"]},"checked_out_at":{"format":"date-time","type":["string","null"]},"departure":{"format":"date","type":"string"},"discount_pct":{"type":"number"},"guests":{"description":"Only in the detail.","items":{"$ref":"#/components/schemas/StayGuest"},"type":"array"},"id":{"type":"integer"},"nights":{"type":"integer"},"notes":{"type":"string"},"offer_id":{"type":["integer","null"]},"option_expires_on":{"format":"date","type":["string","null"]},"price_override":{"type":["number","null"]},"rate_plan":{"oneOf":[{"$ref":"#/components/schemas/RatePlanRef"},{"type":"null"}]},"room":{"oneOf":[{"$ref":"#/components/schemas/RoomRef"},{"type":"null"}]},"room_type":{"$ref":"#/components/schemas/RoomRef"},"status":{"enum":["option","confirmed","checked_in","checked_out","cancelled"],"type":"string"},"total":{"type":"number"},"updated_at":{"format":"date-time","type":"string"}},"type":"object"},"Room":{"properties":{"code":{"description":"The number of the room.","type":"string"},"extra_beds":{"type":"integer"},"floor":{"type":["string","null"]},"housekeeping":{"enum":["clean","dirty","inspected"],"type":"string"},"id":{"type":"integer"},"name":{"type":"string"},"room_type_id":{"type":"integer"},"sellable":{"description":"False when the room is kept out of the availability.","type":"boolean"}},"type":"object"},"RoomRef":{"properties":{"code":{"type":"string"},"id":{"type":"integer"}},"type":"object"},"RoomRequest":{"properties":{"adults":{"default":1,"type":"integer"},"arrival":{"format":"date","type":"string"},"arrival_time":{"example":"18:30","type":"string"},"brackets":{"additionalProperties":{"type":"integer"},"description":"Children by age bracket id.","type":"object"},"departure":{"format":"date","type":"string"},"discount_pct":{"type":"number"},"notes":{"type":"string"},"offer_id":{"type":"integer"},"price_override":{"description":"A fixed nightly price.","type":"number"},"quantity":{"default":1,"description":"Identical rooms to book.","type":"integer"},"rate_plan_id":{"type":"integer"},"room_id":{"description":"A specific room (must be free).","type":"integer"},"room_type_id":{"type":"integer"},"units":{"description":"For each room booked, the physical room and the guests who sleep in it.","items":{"properties":{"guests":{"items":{"properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"party_id":{"type":"integer"}},"type":"object"},"type":"array"},"room_id":{"type":"integer"}},"type":"object"},"type":"array"}},"required":["room_type_id","arrival","departure"],"type":"object"},"RoomType":{"properties":{"channel_code":{"description":"The code the hotel uses for this type on the channels.","type":"string"},"code":{"type":"string"},"id":{"type":"integer"},"max_pax":{"type":"integer"},"name":{"type":"string"},"rooms":{"description":"Rooms of the type on sale.","type":"integer"}},"type":"object"},"StayGuest":{"properties":{"birth_date":{"format":"date","type":["string","null"]},"email":{"type":["string","null"]},"first_name":{"type":["string","null"]},"guest_id":{"description":"The guest in the archive.","type":"integer"},"id":{"description":"The placement of the guest in the room (use it to remove the guest).","type":"integer"},"is_main":{"type":"boolean"},"last_name":{"type":["string","null"]},"name":{"type":"string"},"nationality":{"type":["string","null"]}},"type":"object"},"StayPatch":{"properties":{"adults":{"type":"integer"},"arrival":{"format":"date","type":"string"},"arrival_time":{"type":"string"},"brackets":{"additionalProperties":{"type":"integer"},"description":"Full replacement of the children.","type":"object"},"clear_offer":{"type":"boolean"},"clear_price_override":{"type":"boolean"},"clear_room":{"description":"Take the room away.","type":"boolean"},"departure":{"format":"date","type":"string"},"discount_pct":{"type":"number"},"notes":{"type":"string"},"offer_id":{"type":"integer"},"price_override":{"type":"number"},"rate_plan_id":{"type":"integer"},"room_id":{"description":"Move to this room.","type":"integer"},"room_type_id":{"type":"integer"}},"type":"object"},"TypeAvailability":{"properties":{"code":{"type":"string"},"days":{"items":{"properties":{"available":{"type":"integer"},"date":{"format":"date","type":"string"},"occupied":{"type":"integer"},"out_of_order":{"type":"integer"},"total":{"type":"integer"}},"type":"object"},"type":"array"},"name":{"type":"string"},"room_type_id":{"type":"integer"}},"type":"object"},"Webhook":{"properties":{"active":{"type":"boolean"},"api_key_id":{"description":"The key that created it; a revoked key stops the webhook.","type":["integer","null"]},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"disabled_reason":{"type":["string","null"]},"events":{"items":{"type":"string"},"type":"array"},"failures":{"description":"Failed attempts in a row.","type":"integer"},"id":{"type":"integer"},"last_delivered_at":{"format":"date-time","type":["string","null"]},"last_error":{"type":["string","null"]},"last_event_id":{"description":"The last event delivered.","type":"integer"},"last_status":{"type":["integer","null"]},"next_attempt_at":{"format":"date-time","type":["string","null"]},"property_id":{"type":"integer"},"updated_at":{"format":"date-time","type":"string"},"url":{"type":"string"}},"type":"object"},"WebhookDelivery":{"properties":{"attempt":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"duration_ms":{"type":"integer"},"error":{"type":["string","null"]},"event_id":{"description":"0 for a test ping.","type":"integer"},"event_type":{"type":"string"},"id":{"type":"integer"},"status":{"type":["integer","null"]}},"type":"object"},"WebhookInput":{"properties":{"active":{"type":"boolean"},"description":{"type":"string"},"events":{"description":"The event types wanted; empty or omitted = all.","items":{"type":"string"},"type":"array"},"url":{"description":"An https address (required on creation).","format":"uri","type":"string"}},"type":"object"},"WebhookPayload":{"description":"The body of a delivery.","properties":{"attempt":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"data":{"additionalProperties":true,"type":"object"},"entity":{"type":"string"},"entity_id":{"type":"integer"},"id":{"description":"The event id (0 for a ping). Keep it to ignore repeats.","type":"integer"},"property_id":{"type":"integer"},"subscription_id":{"type":"integer"},"type":{"type":"string"}},"type":"object"}},"securitySchemes":{"apiKey":{"description":"The API key of the property (`gh_live_…`). `X-API-Key` is accepted too.","scheme":"bearer","type":"http"}}},"info":{"contact":{"email":"support@galaxy-hotel.net","name":"Galaxy Hotel Cloud support","url":"https://galaxy-hotel.net/developers/"},"description":"The public API lets booking engines, channel managers, point-of-sale systems, door locks and\nother tools work with a property managed in Galaxy Hotel Cloud: read availability and rates,\ncreate and change reservations, place guests in rooms, charge items on a folio, follow what\nhappens through the event log.\n\n## Authentication\n\nEvery call carries an API key created by the hotel in **Settings → Marketplace → Public API\nand webhooks**. Send it as a bearer token:\n\n```\nAuthorization: Bearer gh_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n```\n\nA key belongs to **one property** and carries **scopes** (`reservations:read`, `folios:write`, …):\nevery operation names the scope it needs. Start with `GET /v1/me` to see what a key can do.\n\n## Conventions\n\n* JSON everywhere, `snake_case` field names, UTF-8.\n* Dates are `YYYY-MM-DD`; the **departure date is exclusive** (a stay 2026-10-01 → 2026-10-04 is three nights).\n* Timestamps are RFC 3339 in UTC (`2026-09-25T10:00:00Z`).\n* Amounts are decimal numbers in the currency of the property (EUR), VAT included unless the folio says otherwise.\n* Lists answer `{ \"data\": [...] }`; paged lists add `page`, `page_size`, `total`, `pages`.\n* Ids are integers, stable for the life of the record.\n\n## Errors\n\nAn error answers a status code and a body `{ \"error\": { \"code\": \"...\", \"message\": \"...\" } }`.\nRely on `code`: it is stable. The message is for humans and may be localised.\n\n| status | code | meaning |\n|---|---|---|\n| 400 | `invalid_request` | a parameter is missing or malformed |\n| 401 | `unauthenticated`, `invalid_key`, `key_revoked` | no key, an unknown key, a revoked key |\n| 402 | `subscription_expired` | the subscription of the account has run out |\n| 403 | `api_disabled`, `insufficient_scope`, `account_suspended` | the API is off for the property, the key lacks the scope |\n| 404 | `not_found` | the record does not exist or belongs to another property |\n| 409 | `duplicate_external_ref`, `room_unavailable`, `open_folios`, `nights_to_charge` | a conflict with the current state |\n| 422 | `rule_violation`, `idempotency_mismatch` | a business rule of the PMS refused the change |\n| 423 | `read_only` | the property is in its seasonal pause |\n| 429 | `rate_limited` | too many calls: wait and retry |\n| 503 | — | maintenance |\n\n## Rate limits\n\n600 calls a minute for each key, with a burst of 120. The headers `X-RateLimit-Limit` and\n`X-RateLimit-Remaining` say where you stand; a 429 carries `Retry-After`.\n\n## Idempotency\n\nA write (`POST`, `PATCH`, `DELETE`) may carry an `Idempotency-Key` header (any string up to 200\ncharacters, unique for the call). If the connection drops after the request, repeat it with the\nsame key: the answer already given comes back with the header `Idempotent-Replayed: true`\ninstead of the operation running twice. Keys are kept for 24 hours. The same key with a\ndifferent body answers 422 `idempotency_mismatch`.\n\nReservations offer a second guard: an `external_ref` (your own id of the booking) is unique\nfor the property, so a retry of a creation answers 409 `duplicate_external_ref` with the id\nof the reservation already made.\n\n## Webhooks\n\nInstead of polling `GET /events`, subscribe an https address with `POST /webhooks` (scope\n`webhooks:manage`): every event of the property is posted to it in order, as JSON, with the\nheaders `X-Galaxy-Event` (the type), `X-Galaxy-Delivery` (event id and attempt) and\n`X-Galaxy-Signature`. Answer 2xx within 10 seconds; anything else is retried with a growing\nwait (1 min, 5, 15, 1 h, 3 h, 6 h) and the subscription is switched off after three days of\nfailures. Deliveries are at least once: keep the event `id` to ignore a repeat.\n\nThe signature is `t=\u003cunix timestamp\u003e,v1=\u003chex\u003e` where `\u003chex\u003e` is HMAC-SHA256 of\n`\"\u003ctimestamp\u003e.\u003craw body\u003e\"` with the secret answered when the subscription was created. Verify\nit before trusting a delivery and refuse timestamps older than a few minutes:\n\n```js\nconst [t, v1] = header.split(\",\").map((p) =\u003e p.split(\"=\")[1]);\nconst expected = crypto.createHmac(\"sha256\", secret).update(t + \".\" + rawBody).digest(\"hex\");\nconst ok = crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected)) \u0026\u0026 Math.abs(Date.now() / 1000 - t) \u003c 300;\n```\n\n`POST /webhooks/{id}/test` sends a `ping` event right away; `GET /webhooks/{id}/deliveries`\nshows the latest attempts with the status received.\n\n## Versioning\n\nThe version is in the path (`/v1`). Fields and endpoints are only ever added; nothing is\nremoved or renamed within a version. Ignore fields you do not know.\n","summary":"The public API of the Galaxy Hotel Cloud property management system.","title":"Galaxy Hotel Cloud API","version":"1.0"},"openapi":"3.1.0","paths":{"/age-brackets":{"get":{"description":"The children brackets of the property (infant, child…). The occupancy of a room is\n`adults` plus `brackets`, a map from bracket id to count. Scope: `property:read`.\n","operationId":"listAgeBrackets","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/AgeBracket"},"type":"array"}},"type":"object"}}},"description":"The brackets."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"Age brackets","tags":["Property"]}},"/availability":{"get":{"description":"For every accommodation type, the rooms free on each night of the period: the rooms of the\ntype on sale, minus the stays (counted on the type of the room assigned, or on the type\nrequested when no room is assigned yet), minus the rooms out of order. Scope: `availability:read`.\n","operationId":"getAvailability","parameters":[{"description":"First night (default the business date of the property).","in":"query","name":"from","schema":{"format":"date","type":"string"}},{"description":"Exclusive end (default 14 nights after `from`; 62 nights at most).","in":"query","name":"to","schema":{"format":"date","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/TypeAvailability"},"type":"array"},"from":{"format":"date","type":"string"},"to":{"format":"date","type":"string"}},"type":"object"}}},"description":"The availability."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"Availability by type and night","tags":["Availability"]}},"/classifications":{"get":{"description":"The values a reservation may carry as `source`, `channel` and `market`: the archives of\nthe property (Settings → Reservation). A value outside them is refused with 422; `required`\nsays which of the three the property makes mandatory. Scope: `property:read`.\n","operationId":"getClassifications","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"channels":{"items":{"type":"string"},"type":"array"},"markets":{"items":{"type":"string"},"type":"array"},"required":{"properties":{"channel":{"type":"boolean"},"market":{"type":"boolean"},"source":{"type":"boolean"}},"type":"object"},"sources":{"items":{"type":"string"},"type":"array"}},"type":"object"}}},"description":"The archives."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"Sources, channels and markets","tags":["Property"]}},"/events":{"get":{"description":"What happened in the property, oldest first: `reservation.created`, `reservation.updated`,\n`stay.confirmed`, `stay.room_assigned`, `stay.updated`, `stay.checked_in`, `stay.checked_out`,\n`stay.cancelled`. Keep the last `id` you handled and ask again with `after`; the log holds\n30 days. Webhooks push the same events. Scope: `events:read`.\n","operationId":"listEvents","parameters":[{"description":"Only events with an id greater than this.","in":"query","name":"after","schema":{"default":0,"type":"integer"}},{"description":"Comma-separated event types.","in":"query","name":"types","schema":{"type":"string"}},{"in":"query","name":"limit","schema":{"default":100,"maximum":500,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/Event"},"type":"array"},"has_more":{"type":"boolean"},"next_after":{"description":"The value to send as `after` next time.","type":"integer"}},"type":"object"}}},"description":"A batch of events."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"The event log","tags":["Events"]}},"/folios/{id}":{"get":{"description":"Scope: `folios:read`.","operationId":"getFolio","parameters":[{"$ref":"#/components/parameters/folioId"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Folio"}}},"description":"The folio."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Folio detail","tags":["Folios"]}},"/folios/{id}/charges":{"post":{"description":"Posts an article (GET /items) on an open folio: what a point of sale does when a guest signs\nthe bill to the room. The price is the list price unless `unit_price` is given. Scope: `folios:write`.\n","operationId":"createFolioCharge","parameters":[{"$ref":"#/components/parameters/folioId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChargeInput"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Folio"}}},"description":"The folio after the charge."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Charge an item on a folio","tags":["Folios"]}},"/guests":{"get":{"description":"People, companies and agencies of the account (a group of hotels shares one archive).\nUp to 200 results: refine `q` (name, e-mail, phone or document number). Scope: `guests:read`.\n","operationId":"listGuests","parameters":[{"in":"query","name":"q","schema":{"type":"string"}},{"in":"query","name":"kind","schema":{"enum":["private","company","agency"],"type":"string"}},{"in":"query","name":"limit","schema":{"default":50,"maximum":200,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/Guest"},"type":"array"}},"type":"object"}}},"description":"The guests found."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"Search the guest archive","tags":["Guests"]},"post":{"description":"Scope: `guests:write`.","operationId":"createGuest","parameters":[{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestInput"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Guest"}}},"description":"The guest."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Create a guest","tags":["Guests"]}},"/guests/{id}":{"get":{"description":"Scope: `guests:read`.","operationId":"getGuest","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Guest"}}},"description":"The guest."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Guest detail","tags":["Guests"]},"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"integer"}}],"patch":{"description":"Only the fields sent change. Scope: `guests:write`.","operationId":"updateGuest","parameters":[{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestInput"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Guest"}}},"description":"The guest after the change."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Update a guest","tags":["Guests"]}},"/items":{"get":{"description":"The articles that can be charged on a folio (extras, bar, restaurant…). Scope: `property:read`.","operationId":"listItems","parameters":[{"description":"A part of the code or of the name.","in":"query","name":"q","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/Item"},"type":"array"}},"type":"object"}}},"description":"The items."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"Chargeable items","tags":["Property"]}},"/me":{"get":{"description":"No scope needed. Use it to check a key after creating it.","operationId":"getMe","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"account":{"properties":{"name":{"type":"string"},"plan":{"type":"string"},"sandbox":{"description":"True on the shared test environment.","type":"boolean"}},"type":"object"},"key":{"properties":{"created_at":{"format":"date-time","type":"string"},"id":{"type":"integer"},"name":{"type":"string"},"prefix":{"description":"The visible start of the key.","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"}},"type":"object"},"property":{"properties":{"code":{"type":"string"},"id":{"type":"integer"},"name":{"type":"string"}},"type":"object"}},"type":"object"}}},"description":"The key, its property and account."},"401":{"$ref":"#/components/responses/Unauthorized"}},"summary":"The key and its property","tags":["Account"]}},"/property":{"get":{"description":"Scope: `property:read`.","operationId":"getProperty","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Property"}}},"description":"The property of the key."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"The property","tags":["Property"]}},"/quotes":{"post":{"description":"The price of a stay night by night, computed by the rate engine of the PMS without booking anything. Scope: `availability:read`.","operationId":"createQuote","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}},"description":"The quote."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"}},"summary":"Price a stay","tags":["Availability"]}},"/rate-plans":{"get":{"description":"The active rate plans of the property (the negotiated plans of a contract stay out). Scope: `property:read`.","operationId":"listRatePlans","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/RatePlan"},"type":"array"}},"type":"object"}}},"description":"The plans."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"Rate plans","tags":["Property"]}},"/reservations":{"get":{"description":"The reservations of the property, paged, with their rooms (guests and folios come with the\ndetail). Filters on the rooms match a reservation when at least one of its rooms matches.\nScope: `reservations:read`.\n","operationId":"listReservations","parameters":[{"in":"query","name":"arrival_from","schema":{"format":"date","type":"string"}},{"in":"query","name":"arrival_to","schema":{"format":"date","type":"string"}},{"in":"query","name":"departure_from","schema":{"format":"date","type":"string"}},{"in":"query","name":"departure_to","schema":{"format":"date","type":"string"}},{"description":"A night within the stay.","in":"query","name":"stay_on","schema":{"format":"date","type":"string"}},{"in":"query","name":"status","schema":{"enum":["option","confirmed","checked_in","checked_out","cancelled"],"type":"string"}},{"in":"query","name":"room_id","schema":{"type":"integer"}},{"description":"Your own reference of the booking (exact match).","in":"query","name":"external_ref","schema":{"type":"string"}},{"in":"query","name":"booking_code","schema":{"type":"string"}},{"in":"query","name":"voucher","schema":{"type":"string"}},{"in":"query","name":"created_since","schema":{"format":"date-time","type":"string"}},{"description":"Reservations changed (head or rooms) since this instant. Poll it to keep in sync.","in":"query","name":"updated_since","schema":{"format":"date-time","type":"string"}},{"description":"A part of the name of the booker, of a guest or of the group.","in":"query","name":"q","schema":{"type":"string"}},{"in":"query","name":"sort","schema":{"default":"arrival","enum":["arrival","arrival_desc","created_desc","updated_desc"],"type":"string"}},{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/page_size"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"data":{"items":{"$ref":"#/components/schemas/Reservation"},"type":"array"}},"type":"object"}]}}},"description":"One page of reservations."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"List reservations","tags":["Reservations"]},"post":{"description":"Books one or more rooms for a booker: an existing guest (`party_id`) or a new one\n(`new_party`). Each entry of `rooms` is a request of one accommodation type for a period;\n`quantity` books that many identical rooms. The price comes from the rate engine\n(`rate_plan_id`, default plan when omitted). `source`, `channel` and `market` must be values\nof GET /classifications. When the type has no room left the call answers\n422 unless `force` is true (overbooking). Give your own id in `external_ref`: a second call\nwith the same value answers 409 instead of booking twice. Scope: `reservations:write`.\n","operationId":"createReservation","parameters":[{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"examples":{"simple":{"summary":"One double room, new guest","value":{"external_ref":"BE-2026-000123","new_party":{"country_code":"IT","email":"maria.rossi@example.com","first_name":"Maria","kind":"private","last_name":"Rossi","phone":"+39 333 1234567"},"rooms":[{"adults":2,"arrival":"2026-10-01","departure":"2026-10-04","room_type_id":2}],"source":"Booking engine","status":"confirmed"}}},"schema":{"$ref":"#/components/schemas/ReservationCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"reservation":{"$ref":"#/components/schemas/Reservation"},"warnings":{"items":{"type":"string"},"type":"array"}},"type":"object"}}},"description":"The reservation made."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Create a reservation","tags":["Reservations"]}},"/reservations/{id}":{"get":{"description":"The reservation with its rooms, the guests of each room and its folios. Scope: `reservations:read`.","operationId":"getReservation","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reservation"}}},"description":"The reservation."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Reservation detail","tags":["Reservations"]},"parameters":[{"$ref":"#/components/parameters/reservationId"}],"patch":{"description":"Booker, references, source, notes, option expiry. Only the fields sent change. Scope: `reservations:write`.","operationId":"updateReservation","parameters":[{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationPatch"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reservation"}}},"description":"The reservation after the change."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Change the head of a reservation","tags":["Reservations"]}},"/reservations/{id}/assign-rooms":{"post":{"description":"Scope: `reservations:write`.","operationId":"assignRoomsReservation","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"allow_other_type":{"description":"Also rooms of another type when the requested one is full.","type":"boolean"}},"type":"object"}}}},"responses":{"200":{"$ref":"#/components/responses/ReservationOperation"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Give a free room to every room without one","tags":["Reservations"]}},"/reservations/{id}/cancel":{"post":{"description":"A room already checked in is skipped. Scope: `reservations:write`.","operationId":"cancelReservation","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"by":{"default":"guest","description":"Who cancels.","enum":["guest","hotel"],"type":"string"}},"type":"object"}}}},"responses":{"200":{"$ref":"#/components/responses/ReservationOperation"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Cancel every room","tags":["Reservations"]}},"/reservations/{id}/check-in":{"post":{"description":"Each room needs a room assigned and the arrival date of today. Scope: `reservations:write`.","operationId":"checkInReservation","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"charge_no_show":{"description":"Arrival in the past: charge the missed nights instead of moving the arrival to today.","type":"boolean"}},"type":"object"}}}},"responses":{"200":{"$ref":"#/components/responses/ReservationOperation"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Check in every room arriving today","tags":["Reservations"]}},"/reservations/{id}/check-out":{"post":{"description":"A room with an open balance answers 409 `open_folios`. With `charge_full_period`, when a fiscal document of the reservation is already issued and nights are still to charge, the call answers 409 `nights_to_charge` (rooms, nights, dates, amount) and changes nothing: repeat it with `charge_remaining`. Scope: `reservations:write`.","operationId":"checkOutReservation","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckOutOptions"}}}},"responses":{"200":{"$ref":"#/components/responses/ReservationOperation"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Check out every room in house","tags":["Reservations"]}},"/reservations/{id}/confirm":{"post":{"description":"Scope: `reservations:write`.","operationId":"confirmReservation","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"responses":{"200":{"$ref":"#/components/responses/ReservationOperation"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Confirm every room in option","tags":["Reservations"]}},"/reservations/{id}/folios":{"get":{"description":"Scope: `folios:read`.","operationId":"listReservationFolios","parameters":[{"$ref":"#/components/parameters/reservationId"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/Folio"},"type":"array"}},"type":"object"}}},"description":"The folios with their lines."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"The folios of a reservation","tags":["Folios"]}},"/reservations/{id}/rooms/{rid}":{"patch":{"description":"Dates, occupancy, type, rate plan, discount, fixed price, notes, the room assigned. The\nprice is computed again. A room already checked out cannot change. Scope: `reservations:write`.\n","operationId":"updateReservationRoom","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/roomOfReservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StayPatch"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reservation"}}},"description":"The reservation after the change."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Change one room of a reservation","tags":["Reservations"]}},"/reservations/{id}/rooms/{rid}/assign-room":{"post":{"description":"The room given (`room_id`), or the first free room of the type when the body is empty. Scope: `reservations:write`.","operationId":"assignReservationRoom","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/roomOfReservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"room_id":{"description":"A room of the property (GET /rooms).","type":"integer"}},"type":"object"}}}},"responses":{"200":{"$ref":"#/components/responses/ReservationDetail"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Assign a room","tags":["Reservations"]}},"/reservations/{id}/rooms/{rid}/cancel":{"post":{"description":"Scope: `reservations:write`.","operationId":"cancelReservationRoom","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/roomOfReservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"by":{"default":"guest","enum":["guest","hotel"],"type":"string"}},"type":"object"}}}},"responses":{"200":{"$ref":"#/components/responses/ReservationDetail"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Cancel one room","tags":["Reservations"]}},"/reservations/{id}/rooms/{rid}/check-in":{"post":{"description":"Scope: `reservations:write`.","operationId":"checkInReservationRoom","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/roomOfReservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"charge_no_show":{"type":"boolean"}},"type":"object"}}}},"responses":{"200":{"$ref":"#/components/responses/ReservationDetail"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Check in one room","tags":["Reservations"]}},"/reservations/{id}/rooms/{rid}/check-out":{"post":{"description":"A room with an open balance answers 409 `open_folios`. With `charge_full_period`, when a fiscal document of the reservation is already issued and nights are still to charge, the call answers 409 `nights_to_charge` and changes nothing: repeat it with `charge_remaining`. Scope: `reservations:write`.","operationId":"checkOutReservationRoom","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/roomOfReservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckOutOptions"}}}},"responses":{"200":{"$ref":"#/components/responses/ReservationDetail"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Check out one room","tags":["Reservations"]}},"/reservations/{id}/rooms/{rid}/confirm":{"post":{"description":"Scope: `reservations:write`.","operationId":"confirmReservationRoom","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/roomOfReservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"responses":{"200":{"$ref":"#/components/responses/ReservationDetail"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Confirm one room in option","tags":["Reservations"]}},"/reservations/{id}/rooms/{rid}/guests":{"get":{"description":"Scope: `reservations:read`.","operationId":"listReservationRoomGuests","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/roomOfReservationId"}],"responses":{"200":{"$ref":"#/components/responses/StayGuests"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"The guests of a room","tags":["Reservations"]},"post":{"description":"An existing guest of the archive (`guest_id`) or a new one (`guest`, with at least\n`last_name` and `first_name`: the rest can be completed later, at check-in). Scope: `guests:write`.\n","operationId":"addReservationRoomGuest","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/roomOfReservationId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"guest":{"$ref":"#/components/schemas/GuestInput"},"guest_id":{"type":"integer"},"is_main":{"description":"The main guest of the room.","type":"boolean"}},"type":"object"}}},"required":true},"responses":{"201":{"$ref":"#/components/responses/StayGuests"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Put a guest in a room","tags":["Reservations"]}},"/reservations/{id}/rooms/{rid}/guests/{gid}":{"delete":{"description":"`gid` is the id of the placement (the `id` of the guest entry of the room, not the guest). Scope: `guests:write`.","operationId":"removeReservationRoomGuest","parameters":[{"$ref":"#/components/parameters/reservationId"},{"$ref":"#/components/parameters/roomOfReservationId"},{"in":"path","name":"gid","required":true,"schema":{"type":"integer"}},{"$ref":"#/components/parameters/idempotencyKey"}],"responses":{"200":{"$ref":"#/components/responses/StayGuests"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Take a guest out of a room","tags":["Reservations"]}},"/room-types":{"get":{"description":"The types of accommodation sold (virtual types excluded). Scope: `property:read`.","operationId":"listRoomTypes","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/RoomType"},"type":"array"}},"type":"object"}}},"description":"The types."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"Accommodation types","tags":["Property"]}},"/rooms":{"get":{"description":"Every room of the property with its type and housekeeping state. Scope: `property:read`.","operationId":"listRooms","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/Room"},"type":"array"}},"type":"object"}}},"description":"The rooms."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"Rooms","tags":["Property"]}},"/webhooks":{"get":{"description":"The subscriptions of the property with their state. Scope: `webhooks:manage`.","operationId":"listWebhooks","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/Webhook"},"type":"array"},"event_types":{"items":{"type":"string"},"type":"array"}},"type":"object"}}},"description":"The subscriptions and the event types."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}},"summary":"List the webhooks","tags":["Webhooks"]},"post":{"description":"Creates a subscription: an https address, the event types wanted (all when omitted) and a\ndescription. The answer carries the signing `secret`, this once. Delivery starts from the\nevents after the subscription; the past is read with GET /events. Ten subscriptions per\nproperty at most. Scope: `webhooks:manage`.\n","operationId":"createWebhook","parameters":[{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookInput"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"secret":{"description":"The signing secret, shown only now.","type":"string"},"webhook":{"$ref":"#/components/schemas/Webhook"}},"type":"object"}}},"description":"The subscription and its secret."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Subscribe an address","tags":["Webhooks"]}},"/webhooks/{id}":{"delete":{"description":"Scope: `webhooks:manage`.","operationId":"deleteWebhook","parameters":[{"$ref":"#/components/parameters/idempotencyKey"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"deleted":{"type":"boolean"},"id":{"type":"integer"}},"type":"object"}}},"description":"Deleted."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Delete a webhook","tags":["Webhooks"]},"get":{"description":"Scope: `webhooks:manage`.","operationId":"getWebhook","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}},"description":"The subscription."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"Webhook detail","tags":["Webhooks"]},"parameters":[{"$ref":"#/components/parameters/webhookId"}],"patch":{"description":"Address, events, description or active. Setting active to true after a failure clears the failures and resumes. Scope: `webhooks:manage`.","operationId":"updateWebhook","parameters":[{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookInput"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}},"description":"The subscription after the change."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/RuleViolation"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Change a webhook","tags":["Webhooks"]}},"/webhooks/{id}/deliveries":{"get":{"description":"The latest attempts of the subscription, newest first (200 kept). Scope: `webhooks:manage`.","operationId":"listWebhookDeliveries","parameters":[{"$ref":"#/components/parameters/webhookId"},{"in":"query","name":"limit","schema":{"default":50,"maximum":200,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/WebhookDelivery"},"type":"array"}},"type":"object"}}},"description":"The deliveries."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"summary":"The latest deliveries","tags":["Webhooks"]}},"/webhooks/{id}/test":{"post":{"description":"Posts a `ping` event to the address now, signed like any delivery, and answers what the endpoint said. Scope: `webhooks:manage`.","operationId":"testWebhook","parameters":[{"$ref":"#/components/parameters/webhookId"}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"ok":{"type":"boolean"},"status":{"description":"The HTTP status received (0 when the call did not go through).","type":"integer"}},"type":"object"}}},"description":"The outcome of the test."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"423":{"$ref":"#/components/responses/ReadOnly"}},"summary":"Send a test event","tags":["Webhooks"]}}},"security":[{"apiKey":[]}],"servers":[{"description":"Production","url":"https://api.galaxy-hotel.net/v1"}],"tags":[{"description":"Who you are.","name":"Account"},{"description":"The property and its master data.","name":"Property"},{"description":"Free rooms and prices.","name":"Availability"},{"description":"Reservations with their rooms and guests.","name":"Reservations"},{"description":"The guest archive (people, companies, agencies).","name":"Guests"},{"description":"Accounts of a reservation and charges.","name":"Folios"},{"description":"What happened in the property, in order.","name":"Events"},{"description":"Push the events to your address.","name":"Webhooks"}]}