repull 0.2.15 → 0.2.17

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.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/lib/repull/api/airbnb_api.rb +149 -54
  3. data/lib/repull/api/billing_api.rb +4 -4
  4. data/lib/repull/api/booking_com_api.rb +122 -29
  5. data/lib/repull/api/conversations_api.rb +398 -4
  6. data/lib/repull/api/guests_api.rb +2 -2
  7. data/lib/repull/api/listings_api.rb +186 -16
  8. data/lib/repull/api/reservations_api.rb +157 -6
  9. data/lib/repull/api/webhooks_api.rb +10 -3
  10. data/lib/repull/models/accept_reservation_request200_response.rb +321 -0
  11. data/lib/repull/models/account_created_event.rb +95 -31
  12. data/lib/repull/models/account_disconnected_event.rb +95 -31
  13. data/lib/repull/models/ai_operation_completed_event.rb +95 -31
  14. data/lib/repull/models/ai_operation_failed_event.rb +95 -31
  15. data/lib/repull/models/airbnb_publish_result.rb +41 -2
  16. data/lib/repull/models/airbnb_reservation_action200_response.rb +157 -0
  17. data/lib/repull/models/airbnb_reservation_action_request.rb +248 -0
  18. data/lib/repull/models/booking_availability_update.rb +4 -20
  19. data/lib/repull/models/booking_availability_update_date_range.rb +193 -0
  20. data/lib/repull/models/booking_availability_update_request.rb +14 -3
  21. data/lib/repull/models/booking_pricing_rate_update.rb +32 -4
  22. data/lib/repull/models/booking_pricing_rate_update_date_range.rb +3 -0
  23. data/lib/repull/models/booking_pricing_rate_update_restrictions.rb +10 -10
  24. data/lib/repull/models/booking_pricing_response.rb +16 -4
  25. data/lib/repull/models/booking_pricing_update_response.rb +82 -18
  26. data/lib/repull/models/booking_property.rb +107 -36
  27. data/lib/repull/models/booking_property_action_request.rb +176 -0
  28. data/lib/repull/models/booking_property_action_response.rb +281 -0
  29. data/lib/repull/models/booking_property_listings_inner.rb +244 -0
  30. data/lib/repull/models/booking_publish_result.rb +245 -0
  31. data/lib/repull/models/booking_publish_section_error.rb +220 -0
  32. data/lib/repull/models/booking_rate_write_occupancy.rb +187 -0
  33. data/lib/repull/models/booking_rate_write_price_half.rb +188 -0
  34. data/lib/repull/models/booking_rate_write_restriction_half.rb +212 -0
  35. data/lib/repull/models/booking_rate_write_verification.rb +200 -0
  36. data/lib/repull/models/booking_rate_write_verification_row.rb +196 -0
  37. data/lib/repull/models/booking_restriction_request_row.rb +199 -0
  38. data/lib/repull/models/booking_restriction_verification.rb +208 -0
  39. data/lib/repull/models/booking_restriction_verification_row.rb +203 -0
  40. data/lib/repull/models/booking_restriction_verification_row_booking_value.rb +105 -0
  41. data/lib/repull/models/booking_restriction_verification_row_expected.rb +105 -0
  42. data/lib/repull/models/booking_rooms_rates_response.rb +41 -7
  43. data/lib/repull/models/booking_rooms_rates_response_rooms_inner.rb +12 -1
  44. data/lib/repull/models/booking_rooms_rates_response_rooms_inner_rates_inner.rb +1 -0
  45. data/lib/repull/models/booking_setup_request.rb +44 -5
  46. data/lib/repull/models/booking_setup_request_legal_entity.rb +235 -0
  47. data/lib/repull/models/booking_upstream_failure.rb +204 -0
  48. data/lib/repull/models/calendar_updated_event.rb +95 -31
  49. data/lib/repull/models/channel_market_state_item.rb +291 -0
  50. data/lib/repull/models/conversation_message_attachment.rb +28 -1
  51. data/lib/repull/models/create_airbnb_offer_request.rb +93 -8
  52. data/lib/repull/models/create_airbnb_offer_request_guest_details.rb +279 -0
  53. data/lib/repull/models/create_conversation_special_offer201_response.rb +293 -0
  54. data/lib/repull/models/create_conversation_special_offer201_response_guests.rb +189 -0
  55. data/lib/repull/models/create_conversation_special_offer_request.rb +263 -0
  56. data/lib/repull/models/create_conversation_special_offer_request_guests.rb +263 -0
  57. data/lib/repull/models/decline_reservation_request_request.rb +234 -0
  58. data/lib/repull/models/error_error.rb +11 -1
  59. data/lib/repull/models/get_airbnb_offer200_response.rb +289 -0
  60. data/lib/repull/models/get_usage_summary200_response.rb +10 -1
  61. data/lib/repull/models/get_usage_summary200_response_limits.rb +11 -1
  62. data/lib/repull/models/get_usage_summary200_response_remaining.rb +11 -1
  63. data/lib/repull/models/get_usage_summary200_response_used.rb +10 -1
  64. data/lib/repull/models/get_usage_tier200_response.rb +10 -1
  65. data/lib/repull/models/get_usage_tier200_response_limits.rb +11 -1
  66. data/lib/repull/models/get_usage_tier200_response_remaining.rb +11 -1
  67. data/lib/repull/models/get_usage_tier200_response_used.rb +10 -1
  68. data/lib/repull/models/inquiry_created_event.rb +281 -0
  69. data/lib/repull/models/inquiry_created_payload.rb +185 -0
  70. data/lib/repull/models/inquiry_updated_event.rb +281 -0
  71. data/lib/repull/models/inquiry_updated_payload.rb +213 -0
  72. data/lib/repull/models/inquiry_webhook_object.rb +323 -0
  73. data/lib/repull/models/inquiry_webhook_object_expected_payout.rb +158 -0
  74. data/lib/repull/models/inquiry_webhook_object_guests.rb +188 -0
  75. data/lib/repull/models/list_airbnb_thread_messages200_response.rb +170 -0
  76. data/lib/repull/models/list_airbnb_thread_messages200_response_data_inner.rb +274 -0
  77. data/lib/repull/models/list_airbnb_thread_messages200_response_pagination.rb +158 -0
  78. data/lib/repull/models/list_inquiries200_response.rb +192 -0
  79. data/lib/repull/models/list_inquiries200_response_data_inner.rb +418 -0
  80. data/lib/repull/models/list_inquiries200_response_data_inner_expected_payout.rb +159 -0
  81. data/lib/repull/models/list_inquiries200_response_data_inner_guests.rb +188 -0
  82. data/lib/repull/models/listing_address_readiness.rb +171 -0
  83. data/lib/repull/models/listing_content_update_request_address.rb +40 -3
  84. data/lib/repull/models/listing_create_request.rb +48 -2
  85. data/lib/repull/models/listing_created_event.rb +95 -31
  86. data/lib/repull/models/listing_deleted_event.rb +95 -31
  87. data/lib/repull/models/listing_deleted_payload.rb +55 -21
  88. data/lib/repull/models/listing_market_state_request.rb +149 -0
  89. data/lib/repull/models/listing_market_state_response.rb +221 -0
  90. data/lib/repull/models/listing_publish_booking_request.rb +149 -0
  91. data/lib/repull/models/{listing_publish_response.rb → listing_publish_booking_response.rb} +4 -5
  92. data/lib/repull/models/listing_publish_status_channel.rb +32 -1
  93. data/lib/repull/models/listing_publish_status_connection.rb +17 -5
  94. data/lib/repull/models/listing_publish_status_response.rb +13 -1
  95. data/lib/repull/models/listing_reactivated_event.rb +281 -0
  96. data/lib/repull/models/listing_suspended_event.rb +281 -0
  97. data/lib/repull/models/listing_suspension_payload.rb +202 -0
  98. data/lib/repull/models/listing_updated_event.rb +95 -31
  99. data/lib/repull/models/listing_updated_payload.rb +50 -22
  100. data/lib/repull/models/listing_webhook_object.rb +291 -0
  101. data/lib/repull/models/listing_webhook_object_address.rb +168 -0
  102. data/lib/repull/models/listing_webhook_object_channels_inner.rb +184 -0
  103. data/lib/repull/models/message.rb +1 -0
  104. data/lib/repull/models/payment_completed_event.rb +95 -31
  105. data/lib/repull/models/payment_completed_payload.rb +46 -44
  106. data/lib/repull/models/payment_refunded_event.rb +95 -31
  107. data/lib/repull/models/payment_refunded_payload.rb +46 -44
  108. data/lib/repull/models/payment_webhook_object.rb +351 -0
  109. data/lib/repull/models/preapprove_conversation201_response.rb +253 -0
  110. data/lib/repull/models/preapprove_conversation_request.rb +150 -0
  111. data/lib/repull/models/replay_webhook_delivery_request.rb +150 -0
  112. data/lib/repull/models/repull_ping_event.rb +95 -31
  113. data/lib/repull/models/reservation.rb +22 -2
  114. data/lib/repull/models/reservation_alteration_created_event.rb +95 -31
  115. data/lib/repull/models/reservation_alteration_responded_event.rb +95 -31
  116. data/lib/repull/models/reservation_cancelled_event.rb +95 -31
  117. data/lib/repull/models/reservation_created_event.rb +95 -32
  118. data/lib/repull/models/reservation_message_received_event.rb +95 -31
  119. data/lib/repull/models/reservation_message_received_payload.rb +17 -4
  120. data/lib/repull/models/reservation_request_created_event.rb +281 -0
  121. data/lib/repull/models/reservation_request_created_payload.rb +224 -0
  122. data/lib/repull/models/reservation_request_updated_event.rb +281 -0
  123. data/lib/repull/models/reservation_request_updated_payload.rb +251 -0
  124. data/lib/repull/models/reservation_updated_event.rb +95 -31
  125. data/lib/repull/models/review_created_event.rb +95 -31
  126. data/lib/repull/models/review_responded_event.rb +95 -31
  127. data/lib/repull/models/send_airbnb_message201_response.rb +104 -0
  128. data/lib/repull/models/send_airbnb_message_request.rb +4 -20
  129. data/lib/repull/models/send_message_attachment.rb +225 -0
  130. data/lib/repull/models/send_message_part.rb +201 -0
  131. data/lib/repull/models/send_message_request.rb +44 -19
  132. data/lib/repull/models/send_message_response.rb +29 -5
  133. data/lib/repull/models/sent_attachment.rb +196 -0
  134. data/lib/repull/models/usage_quota_warning_event.rb +281 -0
  135. data/lib/repull/models/usage_quota_warning_payload.rb +224 -0
  136. data/lib/repull/models/usage_quota_warning_payload_top_operation.rb +167 -0
  137. data/lib/repull/models/webhook_event.rb +17 -3
  138. data/lib/repull/models/webhook_event_account.rb +171 -0
  139. data/lib/repull/models/webhook_event_type.rb +8 -1
  140. data/lib/repull/models/withdraw_conversation_special_offer200_response.rb +240 -0
  141. data/lib/repull/version.rb +1 -1
  142. data/lib/repull.rb +71 -1
  143. data/openapi/v1.json +19706 -13248
  144. data/scripts/regen.sh +1 -1
  145. metadata +73 -3
@@ -438,7 +438,7 @@ module Repull
438
438
  end
439
439
 
440
440
  # Per-channel publish status
441
- # Returns connection state and sync activity per channel. `channels` is sync activity (empty until first push). `connections` is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer `GET /v1/listings` and filter client-side. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
441
+ # Returns connection state and sync activity per channel. `channels` is sync activity (empty until first push). `connections` is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer `GET /v1/listings` and filter client-side. **When a push fails, this endpoint says why.** `channels[].pushError` carries the channel's own reason for the last failed push, verbatim — `\"Links and contact info can't be shared\"`, `\"Check-in start time must be before end time\"`, `\"property_type_group must be one of […]\"`. It is free text written by the channel, so render it next to the retry button rather than parsing it. `null` when the last push succeeded or none has run; pair it with `pushStatus` to tell those two apart. **It also says what you will not be allowed to change.** The `airbnb` entry in `connections` carries `lockedFields` — attributes Airbnb has locked on this listing. Airbnb does not refuse a write to one: it answers 200, reports the field as locked, and applies nothing, so a locked write is indistinguishable from a successful one unless you looked first. Read it before you let someone edit. Airbnb-only; no other channel has the concept, and no other entry carries the field. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
442
442
  # @param id [Integer]
443
443
  # @param [Hash] opts the optional parameters
444
444
  # @return [ListingPublishStatusResponse]
@@ -448,7 +448,7 @@ module Repull
448
448
  end
449
449
 
450
450
  # Per-channel publish status
451
- # Returns connection state and sync activity per channel. `channels` is sync activity (empty until first push). `connections` is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer `GET /v1/listings` and filter client-side. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
451
+ # Returns connection state and sync activity per channel. `channels` is sync activity (empty until first push). `connections` is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer `GET /v1/listings` and filter client-side. **When a push fails, this endpoint says why.** `channels[].pushError` carries the channel's own reason for the last failed push, verbatim — `\"Links and contact info can't be shared\"`, `\"Check-in start time must be before end time\"`, `\"property_type_group must be one of […]\"`. It is free text written by the channel, so render it next to the retry button rather than parsing it. `null` when the last push succeeded or none has run; pair it with `pushStatus` to tell those two apart. **It also says what you will not be allowed to change.** The `airbnb` entry in `connections` carries `lockedFields` — attributes Airbnb has locked on this listing. Airbnb does not refuse a write to one: it answers 200, reports the field as locked, and applies nothing, so a locked write is indistinguishable from a successful one unless you looked first. Read it before you let someone edit. Airbnb-only; no other channel has the concept, and no other entry carries the field. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
452
452
  # @param id [Integer]
453
453
  # @param [Hash] opts the optional parameters
454
454
  # @return [Array<(ListingPublishStatusResponse, Integer, Hash)>] ListingPublishStatusResponse data, response status code and response headers
@@ -665,10 +665,10 @@ module Repull
665
665
  end
666
666
 
667
667
  # Publish a listing to Airbnb
668
- # Push a Repull listing's canonical content to Airbnb. Pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create a brand-new Airbnb listing under that host. **A publish is not one call to Airbnb.** It is up to eight independent ones — details, description, amenities, rooms, policies, photos, pricing, checkout_tasks — and each can fail on its own. `result.published` is true only when every attempted section landed; `result.sections` lists the ones that did and `result.errors[]` carries Airbnb's own reason, per section, for the ones that did not. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Publish again once you have fixed the failing sections — a re-publish of an unchanged section is harmless. `result.lockedFields` names the fields Airbnb will not let this listing change at all. They are not retryable by anyone: Airbnb answers 200 and applies nothing. `GET /v1/channels/airbnb/listings/{id}` reports the same list up front. **Which fields this pushes** — title, description sections and house rules (English/primary locale), amenities, rooms and beds, photos, nightly price and fees, cancellation policy and guest controls, check-in/out times, quiet hours, property and room type, checkout tasks. **Not pushed by this endpoint:** non-primary locales (`PUT /v1/channels/airbnb/listings/{id}/descriptions`), guest-safety disclosures (`PUT …/safety-disclosures`), check-in method (`PUT …/details`), permits (`PUT …/permits`), and the calendar (`PUT …/availability`). `force: true` re-pushes every section, ignoring dirty-field tracking. Without it only the sections changed since the last successful publish are sent. Send `Idempotency-Key` to make a retry safe: a timeout on a publish otherwise leaves you unable to tell whether it ran. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
668
+ # Push a Repull listing's canonical content to Airbnb. Pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create a brand-new Airbnb listing under that host. **A publish is not one call to Airbnb.** It is up to eight independent ones — details, description, amenities, rooms, policies, photos, pricing, checkout_tasks — and each can fail on its own. `result.published` is true only when every attempted section landed; `result.sections` lists the ones that did and `result.errors[]` carries Airbnb's own reason, per section, for the ones that did not. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Publish again once you have fixed the failing sections — a re-publish of an unchanged section is harmless. `result.live` is a different question from `result.published`. `published` is about CONTENT — every attempted section landed. `live` is about whether the listing takes bookings: it is true only when activation was actually performed and succeeded. A create can land all eight sections and still leave the listing inactive, because activation is skipped when instant-booking cannot be confirmed to be off — so `published: true` with `live: false` is a real and common outcome, and `result.warnings` says why. `live` is ABSENT, not `false`, when activation was never part of the operation: publishing to an already-mapped listing updates content and activates nothing. Only treat a listing as not-live when `live` is present and false. `result.warnings[]` lists steps that failed WITHOUT failing the publish — optional work the push carried on past. They were previously swallowed, so the only sign of one was a listing that was somehow not quite right afterwards. A publish can be `published: true` and still carry warnings; read them before concluding nothing needs doing. `result.lockedFields` names the fields Airbnb will not let this listing change at all. They are not retryable by anyone: Airbnb answers 200 and applies nothing. `GET /v1/channels/airbnb/listings/{id}` reports the same list up front. **Which fields this pushes** — title, description sections and house rules (English/primary locale), amenities, rooms and beds, photos, nightly price and fees, cancellation policy and guest controls, check-in/out times, quiet hours, property and room type, checkout tasks. **Not pushed by this endpoint:** non-primary locales (`PUT /v1/channels/airbnb/listings/{id}/descriptions`), guest-safety disclosures (`PUT …/safety-disclosures`), check-in method (`PUT …/details`), permits (`PUT …/permits`), and the calendar (`PUT …/availability`). `force: true` re-pushes every section, ignoring dirty-field tracking. Without it only the sections changed since the last successful publish are sent. Send `Idempotency-Key` to make a retry safe: a timeout on a publish otherwise leaves you unable to tell whether it ran. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
669
669
  # @param id [Integer]
670
670
  # @param [Hash] opts the optional parameters
671
- # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Responses with status &gt;&#x3D; 500 are deliberately not stored, so a server error stays retryable.
671
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
672
672
  # @option opts [ListingPublishAirbnbRequest] :listing_publish_airbnb_request
673
673
  # @return [ListingPublishAirbnbResponse]
674
674
  def publish_listing_to_airbnb(id, opts = {})
@@ -677,10 +677,10 @@ module Repull
677
677
  end
678
678
 
679
679
  # Publish a listing to Airbnb
680
- # Push a Repull listing&#39;s canonical content to Airbnb. Pass &#x60;airbnbConnectionId&#x60; to update an already-mapped Airbnb listing, or &#x60;hostId&#x60; to create a brand-new Airbnb listing under that host. **A publish is not one call to Airbnb.** It is up to eight independent ones — details, description, amenities, rooms, policies, photos, pricing, checkout_tasks — and each can fail on its own. &#x60;result.published&#x60; is true only when every attempted section landed; &#x60;result.sections&#x60; lists the ones that did and &#x60;result.errors[]&#x60; carries Airbnb&#39;s own reason, per section, for the ones that did not. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Publish again once you have fixed the failing sections — a re-publish of an unchanged section is harmless. &#x60;result.lockedFields&#x60; names the fields Airbnb will not let this listing change at all. They are not retryable by anyone: Airbnb answers 200 and applies nothing. &#x60;GET /v1/channels/airbnb/listings/{id}&#x60; reports the same list up front. **Which fields this pushes** — title, description sections and house rules (English/primary locale), amenities, rooms and beds, photos, nightly price and fees, cancellation policy and guest controls, check-in/out times, quiet hours, property and room type, checkout tasks. **Not pushed by this endpoint:** non-primary locales (&#x60;PUT /v1/channels/airbnb/listings/{id}/descriptions&#x60;), guest-safety disclosures (&#x60;PUT …/safety-disclosures&#x60;), check-in method (&#x60;PUT …/details&#x60;), permits (&#x60;PUT …/permits&#x60;), and the calendar (&#x60;PUT …/availability&#x60;). &#x60;force: true&#x60; re-pushes every section, ignoring dirty-field tracking. Without it only the sections changed since the last successful publish are sent. Send &#x60;Idempotency-Key&#x60; to make a retry safe: a timeout on a publish otherwise leaves you unable to tell whether it ran. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
680
+ # Push a Repull listing&#39;s canonical content to Airbnb. Pass &#x60;airbnbConnectionId&#x60; to update an already-mapped Airbnb listing, or &#x60;hostId&#x60; to create a brand-new Airbnb listing under that host. **A publish is not one call to Airbnb.** It is up to eight independent ones — details, description, amenities, rooms, policies, photos, pricing, checkout_tasks — and each can fail on its own. &#x60;result.published&#x60; is true only when every attempted section landed; &#x60;result.sections&#x60; lists the ones that did and &#x60;result.errors[]&#x60; carries Airbnb&#39;s own reason, per section, for the ones that did not. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Publish again once you have fixed the failing sections — a re-publish of an unchanged section is harmless. &#x60;result.live&#x60; is a different question from &#x60;result.published&#x60;. &#x60;published&#x60; is about CONTENT — every attempted section landed. &#x60;live&#x60; is about whether the listing takes bookings: it is true only when activation was actually performed and succeeded. A create can land all eight sections and still leave the listing inactive, because activation is skipped when instant-booking cannot be confirmed to be off — so &#x60;published: true&#x60; with &#x60;live: false&#x60; is a real and common outcome, and &#x60;result.warnings&#x60; says why. &#x60;live&#x60; is ABSENT, not &#x60;false&#x60;, when activation was never part of the operation: publishing to an already-mapped listing updates content and activates nothing. Only treat a listing as not-live when &#x60;live&#x60; is present and false. &#x60;result.warnings[]&#x60; lists steps that failed WITHOUT failing the publish — optional work the push carried on past. They were previously swallowed, so the only sign of one was a listing that was somehow not quite right afterwards. A publish can be &#x60;published: true&#x60; and still carry warnings; read them before concluding nothing needs doing. &#x60;result.lockedFields&#x60; names the fields Airbnb will not let this listing change at all. They are not retryable by anyone: Airbnb answers 200 and applies nothing. &#x60;GET /v1/channels/airbnb/listings/{id}&#x60; reports the same list up front. **Which fields this pushes** — title, description sections and house rules (English/primary locale), amenities, rooms and beds, photos, nightly price and fees, cancellation policy and guest controls, check-in/out times, quiet hours, property and room type, checkout tasks. **Not pushed by this endpoint:** non-primary locales (&#x60;PUT /v1/channels/airbnb/listings/{id}/descriptions&#x60;), guest-safety disclosures (&#x60;PUT …/safety-disclosures&#x60;), check-in method (&#x60;PUT …/details&#x60;), permits (&#x60;PUT …/permits&#x60;), and the calendar (&#x60;PUT …/availability&#x60;). &#x60;force: true&#x60; re-pushes every section, ignoring dirty-field tracking. Without it only the sections changed since the last successful publish are sent. Send &#x60;Idempotency-Key&#x60; to make a retry safe: a timeout on a publish otherwise leaves you unable to tell whether it ran. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
681
681
  # @param id [Integer]
682
682
  # @param [Hash] opts the optional parameters
683
- # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Responses with status &gt;&#x3D; 500 are deliberately not stored, so a server error stays retryable.
683
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
684
684
  # @option opts [ListingPublishAirbnbRequest] :listing_publish_airbnb_request
685
685
  # @return [Array<(ListingPublishAirbnbResponse, Integer, Hash)>] ListingPublishAirbnbResponse data, response status code and response headers
686
686
  def publish_listing_to_airbnb_with_http_info(id, opts = {})
@@ -742,20 +742,24 @@ module Repull
742
742
  end
743
743
 
744
744
  # Publish a listing to Booking.com
745
- # Push a Repull listing to Booking.com. The listing must already be mapped to a Booking property + room (created via the Booking-claim Connect flow). Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
746
- # @param id [Integer]
745
+ # Push a Repull listing's content to Booking.com. The listing must already be mapped to a Booking.com property + room — claim the hotel through the Connect Booking flow, then map its rooms with `POST /v1/connect/booking/map-rooms`. **Which property the content lands in.** A listing can be mapped to more than one Booking.com property; the same unit re-listed under a new property keeps its old mapping, and workspaces routinely sit on five or six. When the listing has exactly one property you need send nothing. When it has several, name one with `hotelId` in the body (or `?hotel_id=` — the same value, accepted either way, body wins if you send both). Omit it on such a listing and the push is refused with **`409 ambiguous_booking_mapping`**, listing the candidate ids: content pushed into a property chosen for you lands on the wrong listing and reports success, which is worse than a refusal. `GET /v1/channels/booking/properties` lists every property with the listings mapped under it. Naming a property this listing is not mapped to is a `404` that names the ones it is. The property that actually received the content comes back as `result.hotelId`. **A publish is not one call to Booking.com.** It is several independent Content API calls — details, description, amenities, rooms, photos, pricing — and each can fail on its own. `result.published` is true only when every attempted section landed; `result.sections` lists the ones that did and `result.errors[]` carries Booking.com's own reason, per section, for the ones that did not. A property whose Content API credentials do not cover a section answers 403 for that section alone. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Fix the failing sections and publish again — re-publishing an unchanged section is harmless. A listing with no Booking.com property mapped at all is not an error: the call returns `result.published: false` with `result.reason` and `result.hotelId: null`, and nothing is pushed. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
746
+ # @param id [Integer] Repull listing id — NOT a Booking.com hotel id.
747
747
  # @param [Hash] opts the optional parameters
748
- # @return [ListingPublishResponse]
748
+ # @option opts [String] :hotel_id Booking.com property to publish into, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;, accepted so this route reads the same as every other Booking listing-addressed route. The body wins when both are sent.
749
+ # @option opts [ListingPublishBookingRequest] :listing_publish_booking_request
750
+ # @return [ListingPublishBookingResponse]
749
751
  def publish_listing_to_booking(id, opts = {})
750
752
  data, _status_code, _headers = publish_listing_to_booking_with_http_info(id, opts)
751
753
  data
752
754
  end
753
755
 
754
756
  # Publish a listing to Booking.com
755
- # Push a Repull listing to Booking.com. The listing must already be mapped to a Booking property + room (created via the Booking-claim Connect flow). Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
756
- # @param id [Integer]
757
+ # Push a Repull listing&#39;s content to Booking.com. The listing must already be mapped to a Booking.com property + room — claim the hotel through the Connect Booking flow, then map its rooms with &#x60;POST /v1/connect/booking/map-rooms&#x60;. **Which property the content lands in.** A listing can be mapped to more than one Booking.com property; the same unit re-listed under a new property keeps its old mapping, and workspaces routinely sit on five or six. When the listing has exactly one property you need send nothing. When it has several, name one with &#x60;hotelId&#x60; in the body (or &#x60;?hotel_id&#x3D;&#x60; — the same value, accepted either way, body wins if you send both). Omit it on such a listing and the push is refused with **&#x60;409 ambiguous_booking_mapping&#x60;**, listing the candidate ids: content pushed into a property chosen for you lands on the wrong listing and reports success, which is worse than a refusal. &#x60;GET /v1/channels/booking/properties&#x60; lists every property with the listings mapped under it. Naming a property this listing is not mapped to is a &#x60;404&#x60; that names the ones it is. The property that actually received the content comes back as &#x60;result.hotelId&#x60;. **A publish is not one call to Booking.com.** It is several independent Content API calls — details, description, amenities, rooms, photos, pricing — and each can fail on its own. &#x60;result.published&#x60; is true only when every attempted section landed; &#x60;result.sections&#x60; lists the ones that did and &#x60;result.errors[]&#x60; carries Booking.com&#39;s own reason, per section, for the ones that did not. A property whose Content API credentials do not cover a section answers 403 for that section alone. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Fix the failing sections and publish again — re-publishing an unchanged section is harmless. A listing with no Booking.com property mapped at all is not an error: the call returns &#x60;result.published: false&#x60; with &#x60;result.reason&#x60; and &#x60;result.hotelId: null&#x60;, and nothing is pushed. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
758
+ # @param id [Integer] Repull listing id — NOT a Booking.com hotel id.
757
759
  # @param [Hash] opts the optional parameters
758
- # @return [Array<(ListingPublishResponse, Integer, Hash)>] ListingPublishResponse data, response status code and response headers
760
+ # @option opts [String] :hotel_id Booking.com property to publish into, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;, accepted so this route reads the same as every other Booking listing-addressed route. The body wins when both are sent.
761
+ # @option opts [ListingPublishBookingRequest] :listing_publish_booking_request
762
+ # @return [Array<(ListingPublishBookingResponse, Integer, Hash)>] ListingPublishBookingResponse data, response status code and response headers
759
763
  def publish_listing_to_booking_with_http_info(id, opts = {})
760
764
  if @api_client.config.debugging
761
765
  @api_client.config.logger.debug 'Calling API: ListingsApi.publish_listing_to_booking ...'
@@ -769,20 +773,26 @@ module Repull
769
773
 
770
774
  # query parameters
771
775
  query_params = opts[:query_params] || {}
776
+ query_params[:'hotel_id'] = opts[:'hotel_id'] if !opts[:'hotel_id'].nil?
772
777
 
773
778
  # header parameters
774
779
  header_params = opts[:header_params] || {}
775
780
  # HTTP header 'Accept' (if needed)
776
781
  header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
782
+ # HTTP header 'Content-Type'
783
+ content_type = @api_client.select_header_content_type(['application/json'])
784
+ if !content_type.nil?
785
+ header_params['Content-Type'] = content_type
786
+ end
777
787
 
778
788
  # form parameters
779
789
  form_params = opts[:form_params] || {}
780
790
 
781
791
  # http body (model)
782
- post_body = opts[:debug_body]
792
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'listing_publish_booking_request'])
783
793
 
784
794
  # return_type
785
- return_type = opts[:debug_return_type] || 'ListingPublishResponse'
795
+ return_type = opts[:debug_return_type] || 'ListingPublishBookingResponse'
786
796
 
787
797
  # auth_names
788
798
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -942,6 +952,166 @@ module Repull
942
952
  return data, status_code, headers
943
953
  end
944
954
 
955
+ # Take a listing off the market
956
+ # Stop this listing being sold, on every channel it is connected to, in one call. What that means differs per channel and you do not have to know which is which. On **Airbnb** the live listing is deactivated with a valid deactivation reason and then READ BACK — Airbnb accepts some deactivations and leaves the listing up, so \"we sent the request\" is never reported as success. On **Booking.com** there is no unlist at all; the equivalent is closing the room's availability across the whole forward window, which is what happens. **This is not the same as deactivating the listing in Repull.** The two get confused because both sound like removal, and they have opposite consequences: | | Take offline (this endpoint) | Deactivate in Repull (`PATCH /v1/listings/{id}` `{\"active\": false}`) | |---|---|---| | The guest-facing listing | **Stops taking bookings** | Stays live and keeps taking bookings | | Billing and plan limits | Unchanged | No longer billed, no longer counts toward the cap | | API access to the listing | Unchanged — you can still read and write it | `403 listing_inactive` until reactivated | | Reverse it with | `POST /v1/listings/{id}/online` | `PATCH /v1/listings/{id}` `{\"active\": true}` | | Data kept | Yes | Yes, and it keeps syncing | Neither one deletes anything, on either side. **The answer is per channel item.** A listing can sit on several Airbnb connections and a Booking.com property at once; they fail independently and a partial result is the ordinary outcome, so every item reports its own `state`, `code` and `message` and there is no top-level success flag to mislead you. Nothing is rolled back — re-send the same request to retry the items that did not land. **Booking.com ambiguity is reported, not fanned out.** A listing mapped to more than one active Booking.com property comes back with that item refused (`ambiguous_booking_mapping`) while the Airbnb items still run: closing the wrong property's availability takes real inventory off sale, and taking a listing off Airbnb is not less urgent because its Booking.com mapping is untidy. Name the property with `hotelId` and send it again. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
957
+ # @param id [Integer] Repull listing id.
958
+ # @param [Hash] opts the optional parameters
959
+ # @option opts [String] :hotel_id Booking.com property to act on, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;; the body wins when both are sent.
960
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
961
+ # @option opts [ListingMarketStateRequest] :listing_market_state_request
962
+ # @return [ListingMarketStateResponse]
963
+ def take_listing_offline(id, opts = {})
964
+ data, _status_code, _headers = take_listing_offline_with_http_info(id, opts)
965
+ data
966
+ end
967
+
968
+ # Take a listing off the market
969
+ # Stop this listing being sold, on every channel it is connected to, in one call. What that means differs per channel and you do not have to know which is which. On **Airbnb** the live listing is deactivated with a valid deactivation reason and then READ BACK — Airbnb accepts some deactivations and leaves the listing up, so \&quot;we sent the request\&quot; is never reported as success. On **Booking.com** there is no unlist at all; the equivalent is closing the room&#39;s availability across the whole forward window, which is what happens. **This is not the same as deactivating the listing in Repull.** The two get confused because both sound like removal, and they have opposite consequences: | | Take offline (this endpoint) | Deactivate in Repull (&#x60;PATCH /v1/listings/{id}&#x60; &#x60;{\&quot;active\&quot;: false}&#x60;) | |---|---|---| | The guest-facing listing | **Stops taking bookings** | Stays live and keeps taking bookings | | Billing and plan limits | Unchanged | No longer billed, no longer counts toward the cap | | API access to the listing | Unchanged — you can still read and write it | &#x60;403 listing_inactive&#x60; until reactivated | | Reverse it with | &#x60;POST /v1/listings/{id}/online&#x60; | &#x60;PATCH /v1/listings/{id}&#x60; &#x60;{\&quot;active\&quot;: true}&#x60; | | Data kept | Yes | Yes, and it keeps syncing | Neither one deletes anything, on either side. **The answer is per channel item.** A listing can sit on several Airbnb connections and a Booking.com property at once; they fail independently and a partial result is the ordinary outcome, so every item reports its own &#x60;state&#x60;, &#x60;code&#x60; and &#x60;message&#x60; and there is no top-level success flag to mislead you. Nothing is rolled back — re-send the same request to retry the items that did not land. **Booking.com ambiguity is reported, not fanned out.** A listing mapped to more than one active Booking.com property comes back with that item refused (&#x60;ambiguous_booking_mapping&#x60;) while the Airbnb items still run: closing the wrong property&#39;s availability takes real inventory off sale, and taking a listing off Airbnb is not less urgent because its Booking.com mapping is untidy. Name the property with &#x60;hotelId&#x60; and send it again. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
970
+ # @param id [Integer] Repull listing id.
971
+ # @param [Hash] opts the optional parameters
972
+ # @option opts [String] :hotel_id Booking.com property to act on, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;; the body wins when both are sent.
973
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
974
+ # @option opts [ListingMarketStateRequest] :listing_market_state_request
975
+ # @return [Array<(ListingMarketStateResponse, Integer, Hash)>] ListingMarketStateResponse data, response status code and response headers
976
+ def take_listing_offline_with_http_info(id, opts = {})
977
+ if @api_client.config.debugging
978
+ @api_client.config.logger.debug 'Calling API: ListingsApi.take_listing_offline ...'
979
+ end
980
+ # verify the required parameter 'id' is set
981
+ if @api_client.config.client_side_validation && id.nil?
982
+ fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.take_listing_offline"
983
+ end
984
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
985
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling ListingsApi.take_listing_offline, the character length must be smaller than or equal to 255.'
986
+ end
987
+
988
+ # resource path
989
+ local_var_path = '/v1/listings/{id}/offline'.sub('{id}', CGI.escape(id.to_s))
990
+
991
+ # query parameters
992
+ query_params = opts[:query_params] || {}
993
+ query_params[:'hotel_id'] = opts[:'hotel_id'] if !opts[:'hotel_id'].nil?
994
+
995
+ # header parameters
996
+ header_params = opts[:header_params] || {}
997
+ # HTTP header 'Accept' (if needed)
998
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
999
+ # HTTP header 'Content-Type'
1000
+ content_type = @api_client.select_header_content_type(['application/json'])
1001
+ if !content_type.nil?
1002
+ header_params['Content-Type'] = content_type
1003
+ end
1004
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
1005
+
1006
+ # form parameters
1007
+ form_params = opts[:form_params] || {}
1008
+
1009
+ # http body (model)
1010
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'listing_market_state_request'])
1011
+
1012
+ # return_type
1013
+ return_type = opts[:debug_return_type] || 'ListingMarketStateResponse'
1014
+
1015
+ # auth_names
1016
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
1017
+
1018
+ new_options = opts.merge(
1019
+ :operation => :"ListingsApi.take_listing_offline",
1020
+ :header_params => header_params,
1021
+ :query_params => query_params,
1022
+ :form_params => form_params,
1023
+ :body => post_body,
1024
+ :auth_names => auth_names,
1025
+ :return_type => return_type
1026
+ )
1027
+
1028
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
1029
+ if @api_client.config.debugging
1030
+ @api_client.config.logger.debug "API called: ListingsApi#take_listing_offline\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
1031
+ end
1032
+ return data, status_code, headers
1033
+ end
1034
+
1035
+ # Put a listing back on the market
1036
+ # Put this listing back on sale, on every channel it is connected to. The counterpart of `POST /v1/listings/{id}/offline`, which documents the per-item response and the difference between this and deactivating a listing in Repull. **It does not push content.** On **Airbnb** it re-enables sync and makes the listing available again; anything that changed while the listing was down is still unpublished, so follow with `POST /v1/listings/{id}/publish/airbnb` if the content moved. On **Booking.com** it re-syncs the true calendar rather than opening everything: dates that are genuinely blocked — a reservation, an owner stay — stay blocked, and only the closure `offline` wrote lifts. The two directions are not mirror images, and that is deliberate. **One asymmetry worth planning for.** Taking a listing down passes no billing gate; putting it back up goes through the channel-publish gate. So on a workspace whose subscription has lapsed, `offline` still works and this endpoint answers `402 payment_required` — a listing can be left off the market until billing is sorted out. That refusal is reported as a billing refusal with the action that fixes it, never as a channel error: retrying, or reconnecting the channel, does nothing for it. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1037
+ # @param id [Integer] Repull listing id.
1038
+ # @param [Hash] opts the optional parameters
1039
+ # @option opts [String] :hotel_id Booking.com property to act on, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;; the body wins when both are sent.
1040
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
1041
+ # @option opts [ListingMarketStateRequest] :listing_market_state_request
1042
+ # @return [ListingMarketStateResponse]
1043
+ def take_listing_online(id, opts = {})
1044
+ data, _status_code, _headers = take_listing_online_with_http_info(id, opts)
1045
+ data
1046
+ end
1047
+
1048
+ # Put a listing back on the market
1049
+ # Put this listing back on sale, on every channel it is connected to. The counterpart of &#x60;POST /v1/listings/{id}/offline&#x60;, which documents the per-item response and the difference between this and deactivating a listing in Repull. **It does not push content.** On **Airbnb** it re-enables sync and makes the listing available again; anything that changed while the listing was down is still unpublished, so follow with &#x60;POST /v1/listings/{id}/publish/airbnb&#x60; if the content moved. On **Booking.com** it re-syncs the true calendar rather than opening everything: dates that are genuinely blocked — a reservation, an owner stay — stay blocked, and only the closure &#x60;offline&#x60; wrote lifts. The two directions are not mirror images, and that is deliberate. **One asymmetry worth planning for.** Taking a listing down passes no billing gate; putting it back up goes through the channel-publish gate. So on a workspace whose subscription has lapsed, &#x60;offline&#x60; still works and this endpoint answers &#x60;402 payment_required&#x60; — a listing can be left off the market until billing is sorted out. That refusal is reported as a billing refusal with the action that fixes it, never as a channel error: retrying, or reconnecting the channel, does nothing for it. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1050
+ # @param id [Integer] Repull listing id.
1051
+ # @param [Hash] opts the optional parameters
1052
+ # @option opts [String] :hotel_id Booking.com property to act on, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;; the body wins when both are sent.
1053
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
1054
+ # @option opts [ListingMarketStateRequest] :listing_market_state_request
1055
+ # @return [Array<(ListingMarketStateResponse, Integer, Hash)>] ListingMarketStateResponse data, response status code and response headers
1056
+ def take_listing_online_with_http_info(id, opts = {})
1057
+ if @api_client.config.debugging
1058
+ @api_client.config.logger.debug 'Calling API: ListingsApi.take_listing_online ...'
1059
+ end
1060
+ # verify the required parameter 'id' is set
1061
+ if @api_client.config.client_side_validation && id.nil?
1062
+ fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.take_listing_online"
1063
+ end
1064
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
1065
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling ListingsApi.take_listing_online, the character length must be smaller than or equal to 255.'
1066
+ end
1067
+
1068
+ # resource path
1069
+ local_var_path = '/v1/listings/{id}/online'.sub('{id}', CGI.escape(id.to_s))
1070
+
1071
+ # query parameters
1072
+ query_params = opts[:query_params] || {}
1073
+ query_params[:'hotel_id'] = opts[:'hotel_id'] if !opts[:'hotel_id'].nil?
1074
+
1075
+ # header parameters
1076
+ header_params = opts[:header_params] || {}
1077
+ # HTTP header 'Accept' (if needed)
1078
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
1079
+ # HTTP header 'Content-Type'
1080
+ content_type = @api_client.select_header_content_type(['application/json'])
1081
+ if !content_type.nil?
1082
+ header_params['Content-Type'] = content_type
1083
+ end
1084
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
1085
+
1086
+ # form parameters
1087
+ form_params = opts[:form_params] || {}
1088
+
1089
+ # http body (model)
1090
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'listing_market_state_request'])
1091
+
1092
+ # return_type
1093
+ return_type = opts[:debug_return_type] || 'ListingMarketStateResponse'
1094
+
1095
+ # auth_names
1096
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
1097
+
1098
+ new_options = opts.merge(
1099
+ :operation => :"ListingsApi.take_listing_online",
1100
+ :header_params => header_params,
1101
+ :query_params => query_params,
1102
+ :form_params => form_params,
1103
+ :body => post_body,
1104
+ :auth_names => auth_names,
1105
+ :return_type => return_type
1106
+ )
1107
+
1108
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
1109
+ if @api_client.config.debugging
1110
+ @api_client.config.logger.debug "API called: ListingsApi#take_listing_online\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
1111
+ end
1112
+ return data, status_code, headers
1113
+ end
1114
+
945
1115
  # Deactivate or reactivate a listing
946
1116
  # Toggle a listing's active state. Send `{ \"active\": false }` to **deactivate** (exclude the listing from Repull) or `{ \"active\": true }` to **reactivate** it. \"Deactivate\" keeps the listing row — it is NOT a hard delete, and it NEVER touches the upstream channel (Airbnb / Hospitable / Booking.com). Repull only mutates its own copy of the inventory. Deactivating is the self-serve way to get back under the plan-listings cap without paying. Reactivation respects the plan-listings cap: if activating this listing would push you over the cap for your tier, the call returns `402 listings_limit_exceeded` and the listing stays inactive. Deactivate another listing or upgrade first. Idempotent: setting a listing to the state it's already in returns 200. To change many listings at once, all or nothing, use `POST /v1/listings/status`.
947
1117
  # @param id [Integer] Repull listing id
@@ -1021,7 +1191,7 @@ module Repull
1021
1191
  # @param id [Integer] Repull listing id
1022
1192
  # @param listing_content_update_request [ListingContentUpdateRequest]
1023
1193
  # @param [Hash] opts the optional parameters
1024
- # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Responses with status &gt;&#x3D; 500 are deliberately not stored, so a server error stays retryable.
1194
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
1025
1195
  # @return [ListingContentUpdateResponse]
1026
1196
  def update_listing_content(id, listing_content_update_request, opts = {})
1027
1197
  data, _status_code, _headers = update_listing_content_with_http_info(id, listing_content_update_request, opts)
@@ -1033,7 +1203,7 @@ module Repull
1033
1203
  # @param id [Integer] Repull listing id
1034
1204
  # @param listing_content_update_request [ListingContentUpdateRequest]
1035
1205
  # @param [Hash] opts the optional parameters
1036
- # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Responses with status &gt;&#x3D; 500 are deliberately not stored, so a server error stays retryable.
1206
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
1037
1207
  # @return [Array<(ListingContentUpdateResponse, Integer, Hash)>] ListingContentUpdateResponse data, response status code and response headers
1038
1208
  def update_listing_content_with_http_info(id, listing_content_update_request, opts = {})
1039
1209
  if @api_client.config.debugging