repull 0.2.18 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/openapi/v1.json CHANGED
@@ -6943,6 +6943,97 @@
6943
6943
  }
6944
6944
  }
6945
6945
  },
6946
+ "rooms": {
6947
+ "type": "array",
6948
+ "nullable": true,
6949
+ "description": "The listing's rooms and the beds in each \u2014 what Airbnb shows as the sleeping arrangements and needs before a listing can go live. FULL replacement: the rooms you send become the whole set. Omit to leave rooms untouched; send `[]` to clear them.\n\nEvery entry is checked before anything is written, so a bad entry refuses the whole request with `422 invalid_params` naming it (e.g. `rooms[1].beds[0].quantity`) \u2014 a listing is never left with half its rooms.\n\nValues use Airbnb's vocabulary, which Booking.com room mapping also reads. This is a local write; publish to send it to a channel.",
6950
+ "items": {
6951
+ "type": "object",
6952
+ "required": [
6953
+ "roomType"
6954
+ ],
6955
+ "properties": {
6956
+ "roomType": {
6957
+ "type": "string",
6958
+ "description": "e.g. `bedroom`, `full_bathroom`, `half_bathroom`, `living_room`, `kitchen`. Not a closed list \u2014 Airbnb validates it at publish and its refusal comes back in the publish result.",
6959
+ "example": "bedroom"
6960
+ },
6961
+ "roomName": {
6962
+ "type": "string",
6963
+ "nullable": true,
6964
+ "description": "Your own label, e.g. \"Primary bedroom\"."
6965
+ },
6966
+ "roomNumber": {
6967
+ "type": "integer",
6968
+ "nullable": true,
6969
+ "minimum": 1,
6970
+ "description": "Order among rooms of the same type, from 1."
6971
+ },
6972
+ "isPrivate": {
6973
+ "type": "boolean",
6974
+ "nullable": true,
6975
+ "description": "Whether the room is private to the guest."
6976
+ },
6977
+ "beds": {
6978
+ "type": "array",
6979
+ "nullable": true,
6980
+ "items": {
6981
+ "type": "object",
6982
+ "required": [
6983
+ "bedType",
6984
+ "quantity"
6985
+ ],
6986
+ "properties": {
6987
+ "bedType": {
6988
+ "type": "string",
6989
+ "description": "e.g. `king_bed`, `queen_bed`, `double_bed`, `single_bed`, `sofa_bed`, `bunk_bed`.",
6990
+ "example": "queen_bed"
6991
+ },
6992
+ "quantity": {
6993
+ "type": "integer",
6994
+ "minimum": 1,
6995
+ "maximum": 20
6996
+ }
6997
+ }
6998
+ }
6999
+ }
7000
+ }
7001
+ }
7002
+ },
7003
+ "checkoutTasks": {
7004
+ "type": "array",
7005
+ "nullable": true,
7006
+ "description": "What the guest is asked to do before leaving. FULL replacement: omit to leave untouched; send `[]` to clear. An unknown `taskType` refuses the whole request with `422 invalid_params`.\n\nPublished to Airbnb, which is the only channel with checkout tasks. Airbnb accepts them only from partner apps it has certified for the feature; until then the publish result reports Airbnb's own refusal for this section and every other section still lands.",
7007
+ "items": {
7008
+ "type": "object",
7009
+ "required": [
7010
+ "taskType"
7011
+ ],
7012
+ "properties": {
7013
+ "taskType": {
7014
+ "type": "string",
7015
+ "enum": [
7016
+ "return_keys",
7017
+ "turn_things_off",
7018
+ "throw_trash",
7019
+ "lock_up",
7020
+ "gather_towels",
7021
+ "additional_requests"
7022
+ ],
7023
+ "description": "Any casing is accepted; stored lowercase."
7024
+ },
7025
+ "instructions": {
7026
+ "type": "string",
7027
+ "nullable": true,
7028
+ "description": "Detail shown to the guest with the task, e.g. \"Leave the keys on the kitchen counter\"."
7029
+ },
7030
+ "required": {
7031
+ "type": "boolean",
7032
+ "nullable": true
7033
+ }
7034
+ }
7035
+ }
7036
+ },
6946
7037
  "pricing": {
6947
7038
  "type": "object",
6948
7039
  "description": "The listing's standing rates. Partial like every other section: only the fields you send are written, and `null` clears one.\n\nChanging `defaultDailyPrice` or `weekendPrice` also moves the nights on the calendar that still carry the old rate and were written by us \u2014 a night you or a channel priced yourself is never touched, and neither is a blocked or reserved one. So a price change reaches the calendar without overwriting anyone's work.\n\nThis is still a local write. Publish to send the new rates to a channel.",
@@ -6972,12 +7063,16 @@
6972
7063
  "weeklyDiscount": {
6973
7064
  "type": "number",
6974
7065
  "nullable": true,
6975
- "description": "Fraction, not a percentage: `0.1` is 10% off a stay of a week or more."
7066
+ "minimum": 0,
7067
+ "maximum": 99,
7068
+ "description": "A percentage, not a fraction: `10` is 10% off a stay of a week or more. A value between 0 and 1 is refused (it would publish as a fraction of one percent) \u2014 send `10`, not `0.1`. `0` clears it."
6976
7069
  },
6977
7070
  "monthlyDiscount": {
6978
7071
  "type": "number",
6979
7072
  "nullable": true,
6980
- "description": "Fraction, not a percentage."
7073
+ "minimum": 0,
7074
+ "maximum": 99,
7075
+ "description": "A percentage, not a fraction: `20` is 20% off a stay of 28 nights or more. Values between 0 and 1 are refused, as for `weeklyDiscount`."
6981
7076
  },
6982
7077
  "guestsIncluded": {
6983
7078
  "type": "integer",
@@ -11134,6 +11229,93 @@
11134
11229
  }
11135
11230
  }
11136
11231
  },
11232
+ "MapBookingRoomRequest": {
11233
+ "type": "object",
11234
+ "required": [
11235
+ "roomBookingId",
11236
+ "listingId"
11237
+ ],
11238
+ "description": "Body for `POST /v1/channels/booking/listings/map`.",
11239
+ "properties": {
11240
+ "roomBookingId": {
11241
+ "type": "string",
11242
+ "description": "Booking.com's own room id. Discover it via `GET /v1/channels/booking/properties/{id}/rooms` (`rooms[].roomId`). A number is also accepted."
11243
+ },
11244
+ "listingId": {
11245
+ "type": "integer",
11246
+ "nullable": true,
11247
+ "description": "Canonical Repull listing id to link the room to. Must belong to your workspace and be active. `null` unmaps the room and removes its channel link. The field is required \u2014 omitting it is a 422, not an unmap."
11248
+ },
11249
+ "hotelId": {
11250
+ "type": "string",
11251
+ "description": "Optional. When present, must be the Booking.com property the room belongs to \u2014 guards against mapping a room of the wrong property when looping over several."
11252
+ },
11253
+ "syncEnabled": {
11254
+ "type": "boolean",
11255
+ "default": true,
11256
+ "description": "Whether the resulting channel link has sync enabled."
11257
+ }
11258
+ }
11259
+ },
11260
+ "MapBookingRoomResponse": {
11261
+ "type": "object",
11262
+ "required": [
11263
+ "success",
11264
+ "alreadyMapped",
11265
+ "roomBookingId",
11266
+ "listingId",
11267
+ "hotelId",
11268
+ "roomId"
11269
+ ],
11270
+ "description": "Id fields are strings (API-wide convention \u2014 bigint ids are stringified to avoid 53-bit JS-number precision loss).",
11271
+ "properties": {
11272
+ "success": {
11273
+ "type": "boolean",
11274
+ "example": true
11275
+ },
11276
+ "alreadyMapped": {
11277
+ "type": "boolean",
11278
+ "description": "True when the room already pointed at this listing (or was already unmapped) and its channel link agreed. Nothing was written."
11279
+ },
11280
+ "roomBookingId": {
11281
+ "type": "string",
11282
+ "nullable": true,
11283
+ "description": "Booking.com's room id, as recorded for this room."
11284
+ },
11285
+ "listingId": {
11286
+ "type": "string",
11287
+ "nullable": true,
11288
+ "description": "The listing the room now points at. Null after an unmap."
11289
+ },
11290
+ "previousListingId": {
11291
+ "type": "string",
11292
+ "nullable": true,
11293
+ "description": "The listing the room pointed at before this call; null when it was unmapped. Omitted on a no-op."
11294
+ },
11295
+ "hotelId": {
11296
+ "type": "string",
11297
+ "description": "The Booking.com property the room belongs to."
11298
+ },
11299
+ "roomId": {
11300
+ "type": "string",
11301
+ "description": "Repull-side id of the room record \u2014 the `roomId` the Connect room-mapping flow takes."
11302
+ },
11303
+ "roomName": {
11304
+ "type": "string",
11305
+ "nullable": true
11306
+ },
11307
+ "platformLinkId": {
11308
+ "type": "string",
11309
+ "nullable": true,
11310
+ "description": "Id of the resulting channel-link row. Null after an unmap, and for a room Booking.com has given us no room id for."
11311
+ },
11312
+ "reservationsImported": {
11313
+ "type": "integer",
11314
+ "nullable": true,
11315
+ "description": "Reservations Booking.com returned for the property and ran through the import after the room was mapped \u2014 the property's active bookings, which would otherwise never reach the listing. A reservation already present is left as it is, so this counts what was processed, not what was new, and re-sending never duplicates. Runs on every successful map, including a re-map to the same listing, so re-sending retries an import that did not run. `null` means the mapping succeeded but the import could not run; the room is still mapped. Absent after an unmap, when there is nothing to pull."
11316
+ }
11317
+ }
11318
+ },
11137
11319
  "AirbnbListingActionRequest": {
11138
11320
  "type": "object",
11139
11321
  "required": [
@@ -21639,7 +21821,7 @@
21639
21821
  "schema": {
21640
21822
  "type": "boolean"
21641
21823
  },
21642
- "description": "When true, returns room-level (vs rate-plan-level) state."
21824
+ "description": "Defaults to `true`: availability per room, which is how Booking.com keeps inventory and how Vanio reads it. Send `false` for the per-rate read \u2014 its `roomsToSell` is often 0 for rooms that are on sale."
21643
21825
  }
21644
21826
  ],
21645
21827
  "responses": {
@@ -21732,38 +21914,213 @@
21732
21914
  "get": {
21733
21915
  "operationId": "get_booking_content",
21734
21916
  "summary": "Get Booking.com content",
21735
- "description": "Fetch the current content (descriptions, amenities, photos) for a Booking.com property. Used to round-trip edits through Repull.\n\n`property_id` must be a Booking.com property connected to this workspace (`GET /v1/channels/booking/properties` lists them). Any other id \u2014 including one connected to a different workspace \u2014 returns `404 not_found`, the same answer as an id that does not exist.\n\nReturns `403 listing_inactive` when any listing mapped to the Booking.com property is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.",
21917
+ "description": "Read one kind of content for a Booking.com property, straight from Booking.com.\n\n| `type` | What it is |\n|---|---|\n| `photos` | The property's photos. Add `room_id` to read one room's gallery. |\n| `facilities` | Property facilities, or a room's with `room_id` (Booking.com's ids \u2014 `GET` returns them). |\n| `description` | The property description. Booking.com rewrites what you send into its own multilingual copy; allow about 3 hours to appear. |\n| `settings` | House rules, pets, children, damage deposit, invoice recipient, booking model. |\n| `policies` | Cancellation and prepayment policies. |\n| `licences` | The region's licence rules and the licence on file. |\n| `checkin_methods` | How guests get in (holiday homes). |\n| `contacts` | Who Booking.com contacts about the property. |\n\n`amenities` is accepted as another name for `facilities`, and `descriptions` for `description`.\n\n`property_id` must be a Booking.com property connected to this workspace (`GET /v1/channels/booking/properties` lists them). Any other id \u2014 including one connected to a different workspace \u2014 returns `404 not_found`, the same answer as an id that does not exist.\n\nReturns `403 listing_inactive` when any listing mapped to the Booking.com property is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.",
21736
21918
  "tags": [
21737
21919
  "Booking.com"
21738
21920
  ],
21921
+ "parameters": [
21922
+ {
21923
+ "name": "property_id",
21924
+ "in": "query",
21925
+ "required": true,
21926
+ "schema": {
21927
+ "type": "string"
21928
+ },
21929
+ "description": "Booking.com property id."
21930
+ },
21931
+ {
21932
+ "name": "type",
21933
+ "in": "query",
21934
+ "required": false,
21935
+ "schema": {
21936
+ "type": "string",
21937
+ "enum": [
21938
+ "photos",
21939
+ "facilities",
21940
+ "description",
21941
+ "settings",
21942
+ "policies",
21943
+ "licences",
21944
+ "checkin_methods",
21945
+ "contacts"
21946
+ ],
21947
+ "default": "photos"
21948
+ },
21949
+ "description": "Which content to read."
21950
+ },
21951
+ {
21952
+ "name": "room_id",
21953
+ "in": "query",
21954
+ "required": false,
21955
+ "schema": {
21956
+ "type": "string"
21957
+ },
21958
+ "description": "A Booking.com room id, for `photos`, `facilities` and `licences`."
21959
+ }
21960
+ ],
21739
21961
  "responses": {
21740
21962
  "200": {
21741
- "description": "Content"
21963
+ "description": "The content, under a key named for the type (`photos`, `facilities`, `description`, `settings`, `policies`, `rules` + `data`, `methods` + `available`, `contacts`)."
21964
+ },
21965
+ "401": {
21966
+ "$ref": "#/components/responses/Unauthorized"
21742
21967
  },
21743
21968
  "403": {
21744
21969
  "$ref": "#/components/responses/ListingInactive"
21745
21970
  },
21746
21971
  "404": {
21747
21972
  "$ref": "#/components/responses/NotFound"
21973
+ },
21974
+ "422": {
21975
+ "$ref": "#/components/responses/UnprocessableEntity"
21748
21976
  }
21749
21977
  }
21750
21978
  },
21751
21979
  "post": {
21752
21980
  "operationId": "update_booking_content",
21753
21981
  "summary": "Update Booking.com content",
21754
- "description": "Push content changes (descriptions, amenities, photos) to Booking.com. Booking enforces editorial review on text fields \u2014 changes appear after their content moderation queue clears.\n\n`property_id` must be a Booking.com property connected to this workspace (`GET /v1/channels/booking/properties` lists them). Any other id \u2014 including one connected to a different workspace \u2014 returns `404 not_found`, the same answer as an id that does not exist.\n\nReturns `403 listing_inactive` when any listing mapped to the Booking.com property is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.",
21982
+ "description": "Write one kind of content to a Booking.com property only. Nothing on the canonical listing or on Airbnb changes. To send the listing's own content to every channel instead, use `PUT /v1/listings/{id}/content` and publish.\n\n| `type` | What it is |\n|---|---|\n| `photos` | The property's photos. Add `room_id` to read one room's gallery. |\n| `facilities` | Property facilities, or a room's with `room_id` (Booking.com's ids \u2014 `GET` returns them). |\n| `description` | The property description. Booking.com rewrites what you send into its own multilingual copy; allow about 3 hours to appear. |\n| `settings` | House rules, pets, children, damage deposit, invoice recipient, booking model. |\n| `policies` | Cancellation and prepayment policies. |\n| `licences` | The region's licence rules and the licence on file. |\n| `checkin_methods` | How guests get in (holiday homes). |\n| `contacts` | Who Booking.com contacts about the property. |\n\n`amenities` is accepted as another name for `facilities`, and `descriptions` for `description`.\n\nWhat each `type` takes:\n\n- `description`: `text`, optional `language` (default `en`).\n- `facilities`: `facilities: [{ facility_id | room_facility_id, state: \"PRESENT\" | \"MISSING\", instances? }]`. Facilities you do not send stay as they are.\n- `photos`: `photos: [{ url }]`, uploaded in the background. With `room_id`, send `photo_ids` instead to add photos that have finished processing to that room.\n- `settings`: `settings: { <block>: {\u2026} }`, for example `{ \"pets\": { \"pets_allowed\": \"PETS_ALLOWED\" } }`. Each block is written separately and reported in `results`.\n- `policies`: `policyCode` (152 = free cancellation at any time, 1 = non-refundable, \u2026), optional `prepaymentRequired`; add `policyId` to change an existing policy. A property holds at most 7 policies and none can be deleted.\n- `licences`: `variantId` and `contentData: [{ name, value }]`, from the rules `GET ?type=licences` returns; optional `room_id`.\n- `checkin_methods`: `methods: [{ checkin_method }]`, using a name from `GET ?type=checkin_methods` `available`.\n- `contacts`: `contacts: [...]` in Booking.com's contact shape.\n\nIf Booking.com refuses the write, the response is `422 booking_rejected` with Booking.com's reason, even when Booking.com answered HTTP 200. Resending the same body will be refused again.\n\n`property_id` must be a Booking.com property connected to this workspace (`GET /v1/channels/booking/properties` lists them). Any other id \u2014 including one connected to a different workspace \u2014 returns `404 not_found`, the same answer as an id that does not exist.\n\nReturns `403 listing_inactive` when any listing mapped to the Booking.com property is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.",
21755
21983
  "tags": [
21756
21984
  "Booking.com"
21757
21985
  ],
21986
+ "requestBody": {
21987
+ "required": true,
21988
+ "content": {
21989
+ "application/json": {
21990
+ "schema": {
21991
+ "type": "object",
21992
+ "required": [
21993
+ "type",
21994
+ "property_id"
21995
+ ],
21996
+ "properties": {
21997
+ "type": {
21998
+ "type": "string",
21999
+ "enum": [
22000
+ "photos",
22001
+ "facilities",
22002
+ "description",
22003
+ "settings",
22004
+ "policies",
22005
+ "licences",
22006
+ "checkin_methods",
22007
+ "contacts"
22008
+ ]
22009
+ },
22010
+ "property_id": {
22011
+ "type": "string",
22012
+ "description": "Booking.com property id."
22013
+ },
22014
+ "room_id": {
22015
+ "type": "string",
22016
+ "description": "A Booking.com room id, for `facilities`, `photos` (gallery) and `licences`."
22017
+ },
22018
+ "text": {
22019
+ "type": "string",
22020
+ "description": "`description`: the property description, up to 65,535 characters."
22021
+ },
22022
+ "language": {
22023
+ "type": "string",
22024
+ "description": "`description`: language code, e.g. `en` or `es`."
22025
+ },
22026
+ "facilities": {
22027
+ "type": "array",
22028
+ "items": {
22029
+ "type": "object",
22030
+ "additionalProperties": true
22031
+ }
22032
+ },
22033
+ "photos": {
22034
+ "type": "array",
22035
+ "items": {
22036
+ "type": "object",
22037
+ "properties": {
22038
+ "url": {
22039
+ "type": "string"
22040
+ }
22041
+ },
22042
+ "required": [
22043
+ "url"
22044
+ ]
22045
+ }
22046
+ },
22047
+ "photo_ids": {
22048
+ "type": "array",
22049
+ "items": {
22050
+ "type": "string"
22051
+ }
22052
+ },
22053
+ "settings": {
22054
+ "type": "object",
22055
+ "additionalProperties": true
22056
+ },
22057
+ "policyCode": {
22058
+ "type": "integer"
22059
+ },
22060
+ "policyId": {
22061
+ "type": "string"
22062
+ },
22063
+ "prepaymentRequired": {
22064
+ "type": "boolean"
22065
+ },
22066
+ "variantId": {
22067
+ "type": "integer"
22068
+ },
22069
+ "contentData": {
22070
+ "type": "array",
22071
+ "items": {
22072
+ "type": "object",
22073
+ "properties": {
22074
+ "name": {
22075
+ "type": "string"
22076
+ },
22077
+ "value": {
22078
+ "type": "string"
22079
+ }
22080
+ }
22081
+ }
22082
+ },
22083
+ "methods": {
22084
+ "type": "array",
22085
+ "items": {
22086
+ "type": "object",
22087
+ "additionalProperties": true
22088
+ },
22089
+ "description": "`checkin_methods`: [{ checkin_method }]."
22090
+ },
22091
+ "contacts": {
22092
+ "type": "array",
22093
+ "items": {
22094
+ "type": "object",
22095
+ "additionalProperties": true
22096
+ }
22097
+ }
22098
+ }
22099
+ },
22100
+ "example": {
22101
+ "type": "description",
22102
+ "property_id": "17319836",
22103
+ "text": "Bright one-bedroom one block from the sand\u2026",
22104
+ "language": "en"
22105
+ }
22106
+ }
22107
+ }
22108
+ },
21758
22109
  "responses": {
21759
22110
  "200": {
21760
- "description": "Updated"
22111
+ "description": "Written. `settings` answers with `results` per block."
22112
+ },
22113
+ "401": {
22114
+ "$ref": "#/components/responses/Unauthorized"
21761
22115
  },
21762
22116
  "403": {
21763
22117
  "$ref": "#/components/responses/ListingInactive"
21764
22118
  },
21765
22119
  "404": {
21766
22120
  "$ref": "#/components/responses/NotFound"
22121
+ },
22122
+ "422": {
22123
+ "$ref": "#/components/responses/UnprocessableEntity"
21767
22124
  }
21768
22125
  }
21769
22126
  }
@@ -22027,7 +22384,7 @@
22027
22384
  "schema": {
22028
22385
  "type": "boolean"
22029
22386
  },
22030
- "description": "When true, returns room-level (vs rate-plan-level) availability."
22387
+ "description": "Defaults to `true`: availability per room, which is how Booking.com keeps inventory and how Vanio reads it. Send `false` for the per-rate read \u2014 its `roomsToSell` is often 0 for rooms that are on sale."
22031
22388
  },
22032
22389
  {
22033
22390
  "name": "hotel_id",
@@ -22559,7 +22916,7 @@
22559
22916
  "post": {
22560
22917
  "operationId": "booking_setup",
22561
22918
  "summary": "Booking.com property setup actions",
22562
- "description": "Action-router for putting a property onto Booking.com \u2014 including building one from nothing. Select the step with `action`.\n\n## Opening a property\n\n- `create-property` \u2014 create a NEW Booking.com property for a Repull listing (`listing_id`). Creates the property, its first room, a rate plan and the room-rate product that makes the room sellable, seeds availability and rates, syncs the calendar, then sends the notification that starts Booking's validation. Returns 201.\n- `add-room` \u2014 add another room type (and its sellable product) to a property (`listing_id`, `property_id`). Returns 201.\n- `add-unit` \u2014 raise the number of identical units on an existing room (`listing_id`, `property_id`, `room_id`).\n- `advance` \u2014 re-send the summary notification for a property (`property_id`) to move it out of the \"XML: Being built\" stage.\n\n## Account and policy steps\n\n- `create-legal-entity` \u2014 register a legal entity directly (returns 201). Not normally needed: see the legal-entity rules below.\n- `check-legal-status` \u2014 always `404`. A legal entity's details are readable for any id on the connectivity-provider credentials every workspace shares, and nothing records which workspace registered which entity, so no entity can be shown to be yours. `create-property` resolves it for you.\n- `check-readiness` \u2014 check whether a property is ready to open (`property_id`).\n- `open-property` \u2014 open the property for sale (`property_id`).\n- `set-contacts` \u2014 set property contacts (`property_id`, `contacts`).\n- `set-policies` \u2014 set property policies (`property_id`, plus policy fields).\n\n## Three things about Booking.com that cost real money\n\n**A newly created property is NOT sellable.** Booking holds it at \"XML: Being built\" until it validates the summary notification. `create-property` sends that notification, but it can fail on its own after everything else succeeded \u2014 the response always reports `status: \"being_built\"` and `sellable: false`, never a guess. Use `advance` to re-send it, and check the Extranet for the stage.\n\n**A room with no ACTIVE rate plan is invisible.** Booking only renders rooms that have at least one active product linkage (room \u00d7 rate plan). A room can be created successfully, return a `roomId`, and never appear on the property page. If `rateId` comes back `null` from `create-property` or `add-room`, that is exactly what happened: activate a rate plan on the property in the Extranet, then add the room again.\n\n**The room name is shown to travellers.** It is taken from the listing's name and appears on the Booking.com property page. Internal nicknames belong on the property's partner reference, not on the room.\n\n## The legal entity is resolved, not asked for\n\nA property is created against the legal entity Booking.com contracts with, invoices and pays. You do not normally send one:\n\n1. If this workspace already creates properties under a legal entity, that one is reused. A second is never registered.\n2. If it has none and the request carries `legal_entity` (`company_name`, `legal_contact_name`, `legal_contact_email`), one is registered and used. Booking.com emails the legal contact a contract; creation only succeeds once it is signed.\n3. If it has none and no `legal_entity`, the request is refused with `422 legal_entity_required` naming the fields \u2014 a contracted company is never invented.\n\n`legal_entity_id` overrides all of that. An id that already carries another workspace's properties is refused with `403 legal_entity_not_yours` before anything is created.\n\n## What you do not control\n\nProperties are created against Booking's **production** target only. A test-target property cannot be sold through and there is no route back from one, so `target` is not a parameter \u2014 sending it changes nothing.\n\nThese are fixed on every created property and are not parameters: property category (Apartment), initial room count (1), and the property contact record (a placeholder name, email and phone). Set the real contacts afterwards with `set-contacts`. Latitude and longitude come from the listing and are adjusted slightly to clear Booking.com's duplicate detection \u2014 send the property's true position on the listing and do not pre-adjust it yourself.\n\nThe listing's name, check-in/check-out times, currency, capacity and price come from the listing. Its postal code is taken from the listing's own `postalCode`; when the listing has none, it falls back to a connected Airbnb listing. A listing with neither is created without a postal code, so set `postalCode` on the listing first.\n\n## Guards\n\nEvery action that takes a `property_id` requires a property connected to this workspace; any other id returns `404 not_found`. Every action that takes a `listing_id` requires a listing in this workspace; any other id returns `404 not_found`.\n\n`create-property` refuses a listing with no coordinates (`422 missing_coordinates`) before anything is created \u2014 creating a Booking.com property cannot be undone.\n\n`create-property` is subject to the same published-listing gate as the dashboard: no plan, or the plan's listing limit reached, returns `403 billing_error` with `used` and `limit`, and nothing is created.\n\nReturns `403 listing_inactive` when the listing \u2014 or any listing mapped to the Booking.com property \u2014 is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.\n\nIf a property is created and a later step fails, the response is `422 booking_create_partial` carrying `property_id`. The property EXISTS. Do not retry `create-property`, which would open a second one \u2014 continue with `add-room` and `advance`.",
22919
+ "description": "Action-router for putting a property onto Booking.com \u2014 including building one from nothing. Select the step with `action`.\n\n## Opening a property\n\n- `create-property` \u2014 create a NEW Booking.com property for a Repull listing (`listing_id`). Creates the property, its first room with the listing's beds, a rate plan and the room-rate product that makes the room sellable (under the listing's cancellation policy), sets the contact and invoice details and the facilities, seeds availability and rates, syncs the calendar, then runs Booking.com's readiness check and reports what still blocks opening in `warnings`. Send `contact` (`name`, `email`, `phone` in international form); without it the workspace owner is used, and a workspace with no usable contact is refused before anything is created. Returns 201.\n- `add-room` \u2014 add another room type (and its sellable product) to a property (`listing_id`, `property_id`). Returns 201.\n- `add-unit` \u2014 raise the number of identical units on an existing room (`listing_id`, `property_id`, `room_id`).\n- `advance` \u2014 run Booking.com's readiness check for a property (`property_id`) and, when it passes, open it. Returns `checked`, `opened`, `sellable` and `blockers` \u2014 Booking.com's own reasons it cannot open yet.\n\n## Account and policy steps\n\n- `create-legal-entity` \u2014 register a legal entity directly (returns 201). Not normally needed: see the legal-entity rules below.\n- `check-legal-status` \u2014 always `404`. A legal entity's details are readable for any id on the connectivity-provider credentials every workspace shares, and nothing records which workspace registered which entity, so no entity can be shown to be yours. `create-property` resolves it for you.\n- `check-readiness` \u2014 whether a property is ready to open (`property_id`): `ready` and `blockers`, without trying to open it.\n- `open-property` \u2014 open the property for sale (`property_id`). Refused with `422 booking_rejected` naming the blockers when it is not ready.\n- `set-contacts` \u2014 set property contacts (`property_id`, `contacts` in Booking.com's Contacts API shape; at most one carries the `general` profile).\n- `set-policies` \u2014 add a cancellation policy (`property_id`, `policyCode`, optional `prepaymentRequired`). House rules, pets, children and the damage deposit are `POST /v1/channels/booking/content` with `type: \"settings\"`.\n\n## Three things about Booking.com that cost real money\n\n**A newly created property is NOT sellable.** Booking.com opens it only when its readiness check passes, and the check names what is missing \u2014 a main photo still processing, no availability, a licence the region requires. The response always reports `status: \"being_built\"` and `sellable: false`, never a guess, with the reasons in `warnings`. Resolve them, then `advance`.\n\n**A room with no ACTIVE rate plan is invisible.** Booking only renders rooms that have at least one active product linkage (room \u00d7 rate plan). A room can be created successfully, return a `roomId`, and never appear on the property page. If `rateId` comes back `null` from `create-property` or `add-room`, that is exactly what happened: activate a rate plan on the property in the Extranet, then add the room again.\n\n**Room names are Booking.com's.** Travellers see one of Booking.com's standard names (\"Two-Bedroom Apartment\"), chosen from the listing's bedrooms. The listing's own name is kept as the operator-side reference, never shown to guests.\n\n## The legal entity is resolved, not asked for\n\nA property is created against the legal entity Booking.com contracts with, invoices and pays. You do not normally send one:\n\n1. If this workspace already creates properties under a legal entity, that one is reused. A second is never registered.\n2. If it has none and the request carries `legal_entity` (`company_name`, `legal_contact_name`, `legal_contact_email`), one is registered and used. Booking.com emails the legal contact a contract; creation only succeeds once it is signed.\n3. If it has none and no `legal_entity`, the request is refused with `422 legal_entity_required` naming the fields \u2014 a contracted company is never invented.\n\n`legal_entity_id` overrides all of that. An id that already carries another workspace's properties is refused with `403 legal_entity_not_yours` before anything is created.\n\n## What you do not control\n\nProperties are created against Booking's **production** target only. A test-target property cannot be sold through and there is no route back from one, so `target` is not a parameter \u2014 sending it changes nothing.\n\nThe property category comes from the listing's property type (Apartment when it has none; Holiday home, Villa or Chalet when it says so). The initial room count is 1. Latitude and longitude come from the listing and are adjusted slightly to clear Booking.com's duplicate detection \u2014 send the property's true position on the listing and do not pre-adjust it yourself.\n\nThe listing's name, check-in/check-out times, currency, capacity and price come from the listing. Its postal code is taken from the listing's own `postalCode`; when the listing has none, it falls back to a connected Airbnb listing. A listing with neither is created without a postal code, so set `postalCode` on the listing first.\n\n## Guards\n\nEvery action that takes a `property_id` requires a property connected to this workspace; any other id returns `404 not_found`. Every action that takes a `listing_id` requires a listing in this workspace; any other id returns `404 not_found`.\n\n`create-property` refuses a listing with no coordinates (`422 missing_coordinates`) before anything is created \u2014 creating a Booking.com property cannot be undone.\n\n`create-property` is subject to the same published-listing gate as the dashboard: no plan, or the plan's listing limit reached, returns `403 billing_error` with `used` and `limit`, and nothing is created.\n\nReturns `403 listing_inactive` when the listing \u2014 or any listing mapped to the Booking.com property \u2014 is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.\n\nIf a property is created and a later step fails, the response is `422 booking_create_partial` carrying `property_id`. The property EXISTS. Do not retry `create-property`, which would open a second one \u2014 continue with `add-room` and `advance`.",
22563
22920
  "tags": [
22564
22921
  "Booking.com"
22565
22922
  ],
@@ -29511,6 +29868,50 @@
29511
29868
  }
29512
29869
  }
29513
29870
  }
29871
+ },
29872
+ "/v1/channels/booking/listings/map": {
29873
+ "post": {
29874
+ "operationId": "map_booking_room",
29875
+ "summary": "Map a Booking.com room to a Repull listing",
29876
+ "description": "Link a Booking.com room to a canonical Repull listing \u2014 the API-key equivalent of the room mapping the hosted Connect flow performs, and the counterpart of `POST /v1/channels/airbnb/listings/map`.\n\nDiscover `roomBookingId` with `GET /v1/channels/booking/properties/{id}/rooms`, which returns every room of a property with the `roomId` this route takes.\n\nBooking.com attaches at the ROOM level: a property is a building and its rooms are what a guest books, so each room maps to one listing. Pass `listingId: null` to unmap a room and remove its channel link.\n\nThe room mapping and its channel link are repointed together in one transaction, so a link can never outlive the mapping it describes \u2014 a stale link keeps routing that room's reservations to the previous listing. Re-sending a mapping that is already in place writes nothing (`alreadyMapped: true`).\n\n**The property's reservations are pulled as part of the call.** Once the room is mapped, every active reservation Booking.com holds for the property is imported and attached to its listing \u2014 `reservationsImported` says how many were processed. One already present is left as it is, so re-sending never duplicates. You do not need a follow-up call: reservations that arrived before the room was mapped are never picked up by the regular sync, so this is the moment they are brought in. It runs on every successful map, including a re-send, so re-sending retries an import that did not run. If the import cannot run, the mapping still stands and `reservationsImported` is `null`. A property with a long booking history can take tens of seconds. Unmapping pulls nothing.\n\nUnlike the Airbnb route, there is no conflict when the target listing already carries another Booking.com room: one listing served by several rooms is a normal arrangement and is not refused.\n\nScope is enforced on both sides against your workspace \u2014 the room's property and the target listing. A room or listing belonging to another workspace returns the same 404 as one that does not exist.\n\nReturns `403 listing_inactive` when the target listing, or the listing the room is mapped to now, is inactive; nothing is changed.",
29877
+ "tags": [
29878
+ "Booking.com"
29879
+ ],
29880
+ "requestBody": {
29881
+ "required": true,
29882
+ "content": {
29883
+ "application/json": {
29884
+ "schema": {
29885
+ "$ref": "#/components/schemas/MapBookingRoomRequest"
29886
+ }
29887
+ }
29888
+ }
29889
+ },
29890
+ "responses": {
29891
+ "200": {
29892
+ "description": "Mapped",
29893
+ "content": {
29894
+ "application/json": {
29895
+ "schema": {
29896
+ "$ref": "#/components/schemas/MapBookingRoomResponse"
29897
+ }
29898
+ }
29899
+ }
29900
+ },
29901
+ "403": {
29902
+ "$ref": "#/components/responses/ListingInactive"
29903
+ },
29904
+ "404": {
29905
+ "$ref": "#/components/responses/NotFound"
29906
+ },
29907
+ "409": {
29908
+ "$ref": "#/components/responses/Conflict"
29909
+ },
29910
+ "422": {
29911
+ "$ref": "#/components/responses/UnprocessableEntity"
29912
+ }
29913
+ }
29914
+ }
29514
29915
  }
29515
29916
  }
29516
29917
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: repull
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.18
4
+ version: 0.2.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nikolov
@@ -354,12 +354,15 @@ files:
354
354
  - lib/repull/models/listing_content_update_request_address.rb
355
355
  - lib/repull/models/listing_content_update_request_amenities.rb
356
356
  - lib/repull/models/listing_content_update_request_amenities_one_of_inner.rb
357
+ - lib/repull/models/listing_content_update_request_checkout_tasks_inner.rb
357
358
  - lib/repull/models/listing_content_update_request_details.rb
358
359
  - lib/repull/models/listing_content_update_request_occupancy.rb
359
360
  - lib/repull/models/listing_content_update_request_photos_inner.rb
360
361
  - lib/repull/models/listing_content_update_request_photos_inner_one_of.rb
361
362
  - lib/repull/models/listing_content_update_request_policies.rb
362
363
  - lib/repull/models/listing_content_update_request_pricing.rb
364
+ - lib/repull/models/listing_content_update_request_rooms_inner.rb
365
+ - lib/repull/models/listing_content_update_request_rooms_inner_beds_inner.rb
363
366
  - lib/repull/models/listing_content_update_response.rb
364
367
  - lib/repull/models/listing_create_request.rb
365
368
  - lib/repull/models/listing_create_response.rb
@@ -417,6 +420,8 @@ files:
417
420
  - lib/repull/models/listing_webhook_object_channels_inner.rb
418
421
  - lib/repull/models/map_airbnb_listing_request.rb
419
422
  - lib/repull/models/map_airbnb_listing_response.rb
423
+ - lib/repull/models/map_booking_room_request.rb
424
+ - lib/repull/models/map_booking_room_response.rb
420
425
  - lib/repull/models/map_connect_booking_rooms_request.rb
421
426
  - lib/repull/models/map_connect_booking_rooms_response.rb
422
427
  - lib/repull/models/market_browse_category.rb
@@ -589,6 +594,9 @@ files:
589
594
  - lib/repull/models/update_airbnb_listing_safety_disclosures200_response.rb
590
595
  - lib/repull/models/update_airbnb_message_request.rb
591
596
  - lib/repull/models/update_booking_charges_request.rb
597
+ - lib/repull/models/update_booking_content_request.rb
598
+ - lib/repull/models/update_booking_content_request_content_data_inner.rb
599
+ - lib/repull/models/update_booking_content_request_photos_inner.rb
592
600
  - lib/repull/models/update_listing_pricing_strategy200_response.rb
593
601
  - lib/repull/models/update_webhook_request.rb
594
602
  - lib/repull/models/upload_airbnb_listing_photos_request.rb