repull 0.2.14 → 0.2.16

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 (227) hide show
  1. checksums.yaml +4 -4
  2. data/lib/repull/api/airbnb_api.rb +1387 -152
  3. data/lib/repull/api/availability_api.rb +2 -2
  4. data/lib/repull/api/billing_api.rb +4 -4
  5. data/lib/repull/api/booking_com_api.rb +36 -27
  6. data/lib/repull/api/connect_api.rb +4 -4
  7. data/lib/repull/api/conversations_api.rb +398 -4
  8. data/lib/repull/api/guests_api.rb +2 -2
  9. data/lib/repull/api/listings_api.rb +97 -13
  10. data/lib/repull/api/reservations_api.rb +157 -6
  11. data/lib/repull/api/webhooks_api.rb +10 -3
  12. data/lib/repull/models/accept_reservation_request200_response.rb +321 -0
  13. data/lib/repull/models/account_created_event.rb +95 -31
  14. data/lib/repull/models/account_disconnected_event.rb +95 -31
  15. data/lib/repull/models/ai_operation_completed_event.rb +95 -31
  16. data/lib/repull/models/ai_operation_failed_event.rb +95 -31
  17. data/lib/repull/models/airbnb_account_freshness.rb +239 -0
  18. data/lib/repull/models/airbnb_alteration.rb +46 -2
  19. data/lib/repull/models/airbnb_alteration_create_request.rb +264 -0
  20. data/lib/repull/models/airbnb_connection.rb +69 -2
  21. data/lib/repull/models/airbnb_connection_host.rb +1 -1
  22. data/lib/repull/models/airbnb_content_write_response.rb +275 -0
  23. data/lib/repull/models/airbnb_data_freshness.rb +22 -10
  24. data/lib/repull/models/airbnb_description_write_request.rb +192 -0
  25. data/lib/repull/models/airbnb_description_write_request_description.rb +365 -0
  26. data/lib/repull/models/airbnb_listing.rb +12 -1
  27. data/lib/repull/models/airbnb_listing_action200_response.rb +105 -0
  28. data/lib/repull/models/airbnb_listing_action200_response_one_of.rb +157 -0
  29. data/lib/repull/models/airbnb_listing_action200_response_one_of1.rb +175 -0
  30. data/lib/repull/models/airbnb_listing_action_request.rb +2 -2
  31. data/lib/repull/models/airbnb_listing_details_response.rb +284 -0
  32. data/lib/repull/models/airbnb_listing_details_write_request.rb +209 -0
  33. data/lib/repull/models/airbnb_listing_details_write_request_check_in_option.rb +214 -0
  34. data/lib/repull/models/airbnb_listing_details_write_request_quiet_hours_inner.rb +190 -0
  35. data/lib/repull/models/airbnb_listing_lifecycle_response.rb +196 -0
  36. data/lib/repull/models/airbnb_permits_response.rb +163 -0
  37. data/lib/repull/models/airbnb_permits_response_cached_inner.rb +200 -0
  38. data/lib/repull/models/airbnb_permits_write_request.rb +176 -0
  39. data/lib/repull/models/airbnb_permits_write_request_permits_inner.rb +228 -0
  40. data/lib/repull/models/airbnb_permits_write_request_permits_inner_answers_inner.rb +198 -0
  41. data/lib/repull/models/airbnb_photo_position.rb +159 -0
  42. data/lib/repull/models/airbnb_publish_result.rb +263 -0
  43. data/lib/repull/models/airbnb_reservation.rb +23 -1
  44. data/lib/repull/models/{create_airbnb_alteration_request.rb → airbnb_reservation_action200_response.rb} +12 -50
  45. data/lib/repull/models/airbnb_reservation_action_request.rb +248 -0
  46. data/lib/repull/models/airbnb_reservation_list_response.rb +13 -4
  47. data/lib/repull/models/airbnb_review.rb +23 -1
  48. data/lib/repull/models/airbnb_review_list_response.rb +13 -4
  49. data/lib/repull/models/airbnb_safety_disclosure.rb +202 -0
  50. data/lib/repull/models/airbnb_safety_disclosures_response.rb +162 -0
  51. data/lib/repull/models/airbnb_safety_disclosures_write_request.rb +176 -0
  52. data/lib/repull/models/airbnb_thread.rb +23 -1
  53. data/lib/repull/models/airbnb_thread_list_response.rb +13 -4
  54. data/lib/repull/models/airbnb_transaction.rb +23 -1
  55. data/lib/repull/models/booking_availability_update.rb +4 -20
  56. data/lib/repull/models/booking_availability_update_date_range.rb +193 -0
  57. data/lib/repull/models/booking_availability_update_request.rb +14 -3
  58. data/lib/repull/models/booking_pricing_rate_update.rb +32 -4
  59. data/lib/repull/models/booking_pricing_rate_update_date_range.rb +3 -0
  60. data/lib/repull/models/booking_pricing_rate_update_restrictions.rb +10 -10
  61. data/lib/repull/models/booking_pricing_response.rb +16 -4
  62. data/lib/repull/models/booking_pricing_update_response.rb +82 -18
  63. data/lib/repull/models/booking_property.rb +107 -36
  64. data/lib/repull/models/booking_property_listings_inner.rb +244 -0
  65. data/lib/repull/models/booking_rate_write_occupancy.rb +187 -0
  66. data/lib/repull/models/booking_rate_write_price_half.rb +188 -0
  67. data/lib/repull/models/booking_rate_write_restriction_half.rb +212 -0
  68. data/lib/repull/models/booking_rate_write_verification.rb +200 -0
  69. data/lib/repull/models/booking_rate_write_verification_row.rb +196 -0
  70. data/lib/repull/models/booking_restriction_request_row.rb +199 -0
  71. data/lib/repull/models/booking_restriction_verification.rb +208 -0
  72. data/lib/repull/models/booking_restriction_verification_row.rb +203 -0
  73. data/lib/repull/models/booking_restriction_verification_row_booking_value.rb +105 -0
  74. data/lib/repull/models/booking_restriction_verification_row_expected.rb +105 -0
  75. data/lib/repull/models/booking_rooms_rates_response.rb +41 -7
  76. data/lib/repull/models/booking_rooms_rates_response_rooms_inner.rb +12 -1
  77. data/lib/repull/models/booking_rooms_rates_response_rooms_inner_rates_inner.rb +1 -0
  78. data/lib/repull/models/booking_upstream_failure.rb +204 -0
  79. data/lib/repull/models/calendar_updated_event.rb +95 -31
  80. data/lib/repull/models/conversation_message_attachment.rb +28 -1
  81. data/lib/repull/models/create_airbnb_listing_room_request.rb +315 -0
  82. data/lib/repull/models/create_airbnb_offer_request.rb +93 -8
  83. data/lib/repull/models/create_airbnb_offer_request_guest_details.rb +279 -0
  84. data/lib/repull/models/create_conversation_special_offer201_response.rb +293 -0
  85. data/lib/repull/models/create_conversation_special_offer201_response_guests.rb +189 -0
  86. data/lib/repull/models/create_conversation_special_offer_request.rb +263 -0
  87. data/lib/repull/models/create_conversation_special_offer_request_guests.rb +263 -0
  88. data/lib/repull/models/decline_reservation_request_request.rb +234 -0
  89. data/lib/repull/models/delete_airbnb_listing_photo200_response.rb +14 -4
  90. data/lib/repull/models/delete_airbnb_listing_room200_response.rb +157 -0
  91. data/lib/repull/models/error_error.rb +31 -1
  92. data/lib/repull/models/get_airbnb_booking_settings200_response.rb +190 -0
  93. data/lib/repull/models/get_airbnb_booking_settings200_response_data.rb +246 -0
  94. data/lib/repull/models/get_airbnb_booking_settings200_response_data_advance_notice.rb +172 -0
  95. data/lib/repull/models/get_airbnb_booking_settings200_response_data_booking_window.rb +160 -0
  96. data/lib/repull/models/get_airbnb_booking_settings200_response_data_cancellation.rb +203 -0
  97. data/lib/repull/models/get_airbnb_booking_settings200_response_data_cancellation_non_refundable.rb +218 -0
  98. data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_in.rb +159 -0
  99. data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_in_start.rb +104 -0
  100. data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_out.rb +172 -0
  101. data/lib/repull/models/get_airbnb_booking_settings200_response_data_instant_book.rb +206 -0
  102. data/lib/repull/models/get_airbnb_booking_settings200_response_data_preparation_time.rb +173 -0
  103. data/lib/repull/models/get_airbnb_listing_details200_response.rb +192 -0
  104. data/lib/repull/models/get_airbnb_offer200_response.rb +289 -0
  105. data/lib/repull/models/get_usage_summary200_response.rb +10 -1
  106. data/lib/repull/models/get_usage_summary200_response_limits.rb +11 -1
  107. data/lib/repull/models/get_usage_summary200_response_remaining.rb +11 -1
  108. data/lib/repull/models/get_usage_summary200_response_used.rb +10 -1
  109. data/lib/repull/models/get_usage_tier200_response.rb +10 -1
  110. data/lib/repull/models/get_usage_tier200_response_limits.rb +11 -1
  111. data/lib/repull/models/get_usage_tier200_response_remaining.rb +11 -1
  112. data/lib/repull/models/get_usage_tier200_response_used.rb +10 -1
  113. data/lib/repull/models/inquiry_created_event.rb +281 -0
  114. data/lib/repull/models/inquiry_created_payload.rb +185 -0
  115. data/lib/repull/models/inquiry_updated_event.rb +281 -0
  116. data/lib/repull/models/inquiry_updated_payload.rb +213 -0
  117. data/lib/repull/models/inquiry_webhook_object.rb +323 -0
  118. data/lib/repull/models/inquiry_webhook_object_expected_payout.rb +158 -0
  119. data/lib/repull/models/inquiry_webhook_object_guests.rb +188 -0
  120. data/lib/repull/models/list_airbnb_listing_permits200_response.rb +190 -0
  121. data/lib/repull/models/list_airbnb_listing_safety_disclosures200_response.rb +190 -0
  122. data/lib/repull/models/list_airbnb_thread_messages200_response.rb +170 -0
  123. data/lib/repull/models/list_airbnb_thread_messages200_response_data_inner.rb +274 -0
  124. data/lib/repull/models/list_airbnb_thread_messages200_response_pagination.rb +158 -0
  125. data/lib/repull/models/list_inquiries200_response.rb +192 -0
  126. data/lib/repull/models/list_inquiries200_response_data_inner.rb +418 -0
  127. data/lib/repull/models/list_inquiries200_response_data_inner_expected_payout.rb +159 -0
  128. data/lib/repull/models/list_inquiries200_response_data_inner_guests.rb +188 -0
  129. data/lib/repull/models/listing.rb +2 -1
  130. data/lib/repull/models/listing_content.rb +13 -2
  131. data/lib/repull/models/listing_content_update_request.rb +21 -2
  132. data/lib/repull/models/listing_content_update_request_details.rb +206 -0
  133. data/lib/repull/models/listing_content_update_request_policies.rb +95 -5
  134. data/lib/repull/models/listing_content_update_response.rb +1 -1
  135. data/lib/repull/models/listing_created_event.rb +95 -31
  136. data/lib/repull/models/listing_deleted_event.rb +95 -31
  137. data/lib/repull/models/listing_deleted_payload.rb +55 -21
  138. data/lib/repull/models/listing_publish_airbnb_response.rb +165 -0
  139. data/lib/repull/models/listing_pull_airbnb_request.rb +149 -0
  140. data/lib/repull/models/listing_pull_response.rb +231 -0
  141. data/lib/repull/models/listing_reactivated_event.rb +281 -0
  142. data/lib/repull/models/listing_suspended_event.rb +281 -0
  143. data/lib/repull/models/listing_suspension_payload.rb +202 -0
  144. data/lib/repull/models/listing_updated_event.rb +95 -31
  145. data/lib/repull/models/listing_updated_payload.rb +50 -22
  146. data/lib/repull/models/listing_webhook_object.rb +291 -0
  147. data/lib/repull/models/listing_webhook_object_address.rb +168 -0
  148. data/lib/repull/models/listing_webhook_object_channels_inner.rb +184 -0
  149. data/lib/repull/models/message.rb +1 -0
  150. data/lib/repull/models/payment_completed_event.rb +95 -31
  151. data/lib/repull/models/payment_completed_payload.rb +46 -44
  152. data/lib/repull/models/payment_refunded_event.rb +95 -31
  153. data/lib/repull/models/payment_refunded_payload.rb +46 -44
  154. data/lib/repull/models/payment_webhook_object.rb +351 -0
  155. data/lib/repull/models/preapprove_conversation201_response.rb +253 -0
  156. data/lib/repull/models/preapprove_conversation_request.rb +150 -0
  157. data/lib/repull/models/publish_section_error.rb +232 -0
  158. data/lib/repull/models/reorder_airbnb_listing_photos200_response.rb +191 -0
  159. data/lib/repull/models/reorder_airbnb_listing_photos200_response_data.rb +172 -0
  160. data/lib/repull/models/reorder_airbnb_listing_photos_request.rb +185 -0
  161. data/lib/repull/models/replay_webhook_delivery_request.rb +150 -0
  162. data/lib/repull/models/repull_ping_event.rb +95 -31
  163. data/lib/repull/models/reservation.rb +44 -2
  164. data/lib/repull/models/reservation_alteration_created_event.rb +95 -31
  165. data/lib/repull/models/reservation_alteration_responded_event.rb +95 -31
  166. data/lib/repull/models/reservation_cancelled_event.rb +95 -31
  167. data/lib/repull/models/reservation_created_event.rb +95 -32
  168. data/lib/repull/models/reservation_message_received_event.rb +95 -31
  169. data/lib/repull/models/reservation_message_received_payload.rb +17 -4
  170. data/lib/repull/models/reservation_request_created_event.rb +281 -0
  171. data/lib/repull/models/reservation_request_created_payload.rb +224 -0
  172. data/lib/repull/models/reservation_request_updated_event.rb +281 -0
  173. data/lib/repull/models/reservation_request_updated_payload.rb +251 -0
  174. data/lib/repull/models/reservation_updated_event.rb +95 -31
  175. data/lib/repull/models/reservation_webhook_object.rb +38 -5
  176. data/lib/repull/models/review_created_event.rb +95 -31
  177. data/lib/repull/models/review_responded_event.rb +95 -31
  178. data/lib/repull/models/send_airbnb_message201_response.rb +104 -0
  179. data/lib/repull/models/send_airbnb_message_request.rb +4 -20
  180. data/lib/repull/models/send_message_attachment.rb +225 -0
  181. data/lib/repull/models/send_message_part.rb +201 -0
  182. data/lib/repull/models/send_message_request.rb +44 -19
  183. data/lib/repull/models/send_message_response.rb +29 -5
  184. data/lib/repull/models/sent_attachment.rb +196 -0
  185. data/lib/repull/models/set_airbnb_listing_cover_photo200_response.rb +191 -0
  186. data/lib/repull/models/set_airbnb_listing_cover_photo200_response_data.rb +171 -0
  187. data/lib/repull/models/set_airbnb_listing_cover_photo_request.rb +165 -0
  188. data/lib/repull/models/update_airbnb_booking_settings200_response.rb +164 -0
  189. data/lib/repull/models/update_airbnb_booking_settings200_response_data.rb +205 -0
  190. data/lib/repull/models/update_airbnb_booking_settings_request.rb +202 -0
  191. data/lib/repull/models/update_airbnb_booking_settings_request_advance_notice.rb +183 -0
  192. data/lib/repull/models/update_airbnb_booking_settings_request_booking_window.rb +183 -0
  193. data/lib/repull/models/update_airbnb_booking_settings_request_cancellation.rb +201 -0
  194. data/lib/repull/models/update_airbnb_booking_settings_request_cancellation_non_refundable.rb +183 -0
  195. data/lib/repull/models/update_airbnb_booking_settings_request_check_in.rb +159 -0
  196. data/lib/repull/models/update_airbnb_booking_settings_request_check_out.rb +182 -0
  197. data/lib/repull/models/update_airbnb_booking_settings_request_instant_book.rb +203 -0
  198. data/lib/repull/models/update_airbnb_booking_settings_request_preparation_time.rb +182 -0
  199. data/lib/repull/models/update_airbnb_listing_amenities200_response.rb +191 -0
  200. data/lib/repull/models/update_airbnb_listing_amenities200_response_data.rb +158 -0
  201. data/lib/repull/models/update_airbnb_listing_amenities_request.rb +199 -0
  202. data/lib/repull/models/update_airbnb_listing_amenities_request_accessibility_amenities_inner.rb +246 -0
  203. data/lib/repull/models/update_airbnb_listing_amenities_request_amenities_inner.rb +218 -0
  204. data/lib/repull/models/update_airbnb_listing_permits200_response.rb +168 -0
  205. data/lib/repull/models/update_airbnb_listing_photo200_response.rb +194 -0
  206. data/lib/repull/models/update_airbnb_listing_photo_request.rb +242 -0
  207. data/lib/repull/models/update_airbnb_listing_room200_response.rb +194 -0
  208. data/lib/repull/models/update_airbnb_listing_room_request.rb +293 -0
  209. data/lib/repull/models/update_airbnb_listing_room_request_beds_inner.rb +209 -0
  210. data/lib/repull/models/update_airbnb_listing_room_request_room_amenities_inner.rb +182 -0
  211. data/lib/repull/models/update_airbnb_listing_room_request_room_amenities_inner_value.rb +105 -0
  212. data/lib/repull/models/update_airbnb_listing_safety_disclosures200_response.rb +180 -0
  213. data/lib/repull/models/upload_airbnb_listing_photos_request.rb +184 -0
  214. data/lib/repull/models/upload_airbnb_listing_photos_request_photos_inner.rb +305 -0
  215. data/lib/repull/models/upload_airbnb_listing_photos_request_photos_inner_listing_id.rb +105 -0
  216. data/lib/repull/models/usage_quota_warning_event.rb +281 -0
  217. data/lib/repull/models/usage_quota_warning_payload.rb +224 -0
  218. data/lib/repull/models/usage_quota_warning_payload_top_operation.rb +167 -0
  219. data/lib/repull/models/webhook_event.rb +17 -3
  220. data/lib/repull/models/webhook_event_account.rb +171 -0
  221. data/lib/repull/models/webhook_event_type.rb +8 -1
  222. data/lib/repull/models/withdraw_conversation_special_offer200_response.rb +240 -0
  223. data/lib/repull/version.rb +1 -1
  224. data/lib/repull.rb +138 -1
  225. data/openapi/v1.json +19578 -10662
  226. data/scripts/regen.sh +1 -1
  227. metadata +140 -3
@@ -89,23 +89,25 @@ module Repull
89
89
  return data, status_code, headers
90
90
  end
91
91
 
92
- # Listing action (delete/push/publish)
93
- # Apply a state action to a listing by id. The path `id` is the canonical Repull listing id. `delete` is a **deactivate of the Repull record only** — it sets the listing inactive and KEEPS the row; it does NOT touch the upstream Airbnb listing (Repull never deletes or deactivates on Airbnb's side). Use it to exclude a listing / trim back under the plan-listings cap; reactivate via `PATCH /v1/listings/{id}` with `{ \"active\": true }`. Idempotent. `push` / `publish` push the listing's content to Airbnb via the same host-side sync orchestrator as `POST /v1/listings/{id}/publish/airbnb` — pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create + publish a new one under that host. `force` re-pushes every field, ignoring dirty-field tracking. Any other action (e.g. `pull`, `unlist`) returns a structured 422 naming the supported actions. Returns `403 listing_inactive` for `push`/`publish` when the listing is inactive. `delete` (deactivation) is always accepted.
92
+ # Listing action (delete/push/publish/unlist/relist)
93
+ # Apply a state action to a listing by id. The path `id` is the canonical Repull listing id. **Deactivating in Repull and unlisting on Airbnb are different operations.** `delete` is a **deactivate of the Repull record only** — it sets the listing inactive and KEEPS the row; it does NOT touch the Airbnb listing, which stays live and keeps taking bookings. Use it to exclude a listing from the API / trim back under the plan-listings cap; reactivate via `PATCH /v1/listings/{id}` with `{ \"active\": true }`. Idempotent. `unlist` calls Airbnb and **takes the live listing down**: it is deactivated with a valid deactivation reason and then READ BACK, so \"Airbnb accepted the call but the listing is still live\" is reported as a failure rather than a success. Requires `airbnbConnectionId` — a listing can be connected to more than one Airbnb listing, and taking down the wrong one is not undoable through this API. `relist` puts it back up (re-enables sync and makes the listing available again); it does not push content. `push` / `publish` push the listing's content to Airbnb via the same host-side sync orchestrator as `POST /v1/listings/{id}/publish/airbnb` — pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create + publish a new one under that host. `force` re-pushes every field, ignoring dirty-field tracking. The result is per-section: see `AirbnbPublishResult`. Any other action (e.g. `pull`) returns a structured 422 naming the supported actions. Returns `403 listing_inactive` for `push`/`publish`/`unlist`/`relist` when the listing is inactive. `delete` (deactivation) is always accepted.
94
94
  # @param id [String]
95
95
  # @param [Hash] opts the optional parameters
96
+ # @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 `Idempotency-Status: cached` — 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 → `409 idempotency_key_in_use`. - Same key with a DIFFERENT payload → `422 idempotency_key_reused`. 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 >= 500, `408`, `425` and `429`, and the refusals that happen before anything is done and tell you to fix something outside the request first — `connection_reauth_required`, `listing_inactive`, and the rate/daily limits. Every other answer, including a final refusal such as `422 airbnb_rejected`, is stored and replayed.
96
97
  # @option opts [AirbnbListingActionRequest] :airbnb_listing_action_request
97
- # @return [nil]
98
+ # @return [AirbnbListingAction200Response]
98
99
  def airbnb_listing_action(id, opts = {})
99
- airbnb_listing_action_with_http_info(id, opts)
100
- nil
100
+ data, _status_code, _headers = airbnb_listing_action_with_http_info(id, opts)
101
+ data
101
102
  end
102
103
 
103
- # Listing action (delete/push/publish)
104
- # Apply a state action to a listing by id. The path `id` is the canonical Repull listing id. `delete` is a **deactivate of the Repull record only** — it sets the listing inactive and KEEPS the row; it does NOT touch the upstream Airbnb listing (Repull never deletes or deactivates on Airbnb's side). Use it to exclude a listing / trim back under the plan-listings cap; reactivate via `PATCH /v1/listings/{id}` with `{ \"active\": true }`. Idempotent. `push` / `publish` push the listing's content to Airbnb via the same host-side sync orchestrator as `POST /v1/listings/{id}/publish/airbnb` — pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create + publish a new one under that host. `force` re-pushes every field, ignoring dirty-field tracking. Any other action (e.g. `pull`, `unlist`) returns a structured 422 naming the supported actions. Returns `403 listing_inactive` for `push`/`publish` when the listing is inactive. `delete` (deactivation) is always accepted.
104
+ # Listing action (delete/push/publish/unlist/relist)
105
+ # Apply a state action to a listing by id. The path `id` is the canonical Repull listing id. **Deactivating in Repull and unlisting on Airbnb are different operations.** `delete` is a **deactivate of the Repull record only** — it sets the listing inactive and KEEPS the row; it does NOT touch the Airbnb listing, which stays live and keeps taking bookings. Use it to exclude a listing from the API / trim back under the plan-listings cap; reactivate via `PATCH /v1/listings/{id}` with `{ \"active\": true }`. Idempotent. `unlist` calls Airbnb and **takes the live listing down**: it is deactivated with a valid deactivation reason and then READ BACK, so \"Airbnb accepted the call but the listing is still live\" is reported as a failure rather than a success. Requires `airbnbConnectionId` — a listing can be connected to more than one Airbnb listing, and taking down the wrong one is not undoable through this API. `relist` puts it back up (re-enables sync and makes the listing available again); it does not push content. `push` / `publish` push the listing's content to Airbnb via the same host-side sync orchestrator as `POST /v1/listings/{id}/publish/airbnb` — pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create + publish a new one under that host. `force` re-pushes every field, ignoring dirty-field tracking. The result is per-section: see `AirbnbPublishResult`. Any other action (e.g. `pull`) returns a structured 422 naming the supported actions. Returns `403 listing_inactive` for `push`/`publish`/`unlist`/`relist` when the listing is inactive. `delete` (deactivation) is always accepted.
105
106
  # @param id [String]
106
107
  # @param [Hash] opts the optional parameters
108
+ # @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 `Idempotency-Status: cached` — 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 → `409 idempotency_key_in_use`. - Same key with a DIFFERENT payload → `422 idempotency_key_reused`. 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 >= 500, `408`, `425` and `429`, and the refusals that happen before anything is done and tell you to fix something outside the request first — `connection_reauth_required`, `listing_inactive`, and the rate/daily limits. Every other answer, including a final refusal such as `422 airbnb_rejected`, is stored and replayed.
107
109
  # @option opts [AirbnbListingActionRequest] :airbnb_listing_action_request
108
- # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
110
+ # @return [Array<(AirbnbListingAction200Response, Integer, Hash)>] AirbnbListingAction200Response data, response status code and response headers
109
111
  def airbnb_listing_action_with_http_info(id, opts = {})
110
112
  if @api_client.config.debugging
111
113
  @api_client.config.logger.debug 'Calling API: AirbnbApi.airbnb_listing_action ...'
@@ -114,6 +116,10 @@ module Repull
114
116
  if @api_client.config.client_side_validation && id.nil?
115
117
  fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.airbnb_listing_action"
116
118
  end
119
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
120
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling AirbnbApi.airbnb_listing_action, the character length must be smaller than or equal to 255.'
121
+ end
122
+
117
123
  # resource path
118
124
  local_var_path = '/v1/channels/airbnb/listings/{id}'.sub('{id}', CGI.escape(id.to_s))
119
125
 
@@ -129,6 +135,7 @@ module Repull
129
135
  if !content_type.nil?
130
136
  header_params['Content-Type'] = content_type
131
137
  end
138
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
132
139
 
133
140
  # form parameters
134
141
  form_params = opts[:form_params] || {}
@@ -137,7 +144,7 @@ module Repull
137
144
  post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'airbnb_listing_action_request'])
138
145
 
139
146
  # return_type
140
- return_type = opts[:debug_return_type]
147
+ return_type = opts[:debug_return_type] || 'AirbnbListingAction200Response'
141
148
 
142
149
  # auth_names
143
150
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -159,22 +166,26 @@ module Repull
159
166
  return data, status_code, headers
160
167
  end
161
168
 
162
- # Accept/decline/cancel Airbnb reservation
163
- # Apply a state action to an Airbnb reservation — `accept` / `decline` (for inquiries and reservation requests), `cancel` (host cancellation, carries penalties), `pre-approve` (for inquiries). Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
164
- # @param code [String]
169
+ # Accept, decline or cancel an Airbnb reservation
170
+ # Act on an Airbnb reservation by its Airbnb confirmation code. **Write-side** calls Airbnb upstream, as the Airbnb account that owns the booking. - `accept` accept a pending booking request. - `decline` — decline a pending booking request. Requires `reason` (one of Airbnb's decline reasons) and `message` (sent to the guest, at most 500 characters). - `cancel` — cancel a confirmed booking as the host. Requires `reason` (one of Airbnb's host-cancellation reasons). **Host cancellations carry Airbnb penalties.** The body is validated before anything reaches Airbnb; unknown fields are refused. There is no `pre-approve` action: a pre-approval answers an inquiry, which has no confirmation code — use `POST /v1/conversations/{id}/pre-approval`. For accept/decline, `POST /v1/reservations/{id}/accept` and `/decline` do the same by Repull id and also update Vanio. Airbnb refusals are mapped rather than returned as a 500: a request that already moved on is `409 request_no_longer_pending` (do not retry), an expired one `409 request_expired`, any other refusal `422 airbnb_rejected` with Airbnb's reason. Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated. Send `Idempotency-Key` to make a retry safe.
171
+ # @param code [String] Airbnb confirmation code, e.g. &#x60;HM9J2MFR3W&#x60;.
172
+ # @param airbnb_reservation_action_request [AirbnbReservationActionRequest]
165
173
  # @param [Hash] opts the optional parameters
166
- # @return [nil]
167
- def airbnb_reservation_action(code, opts = {})
168
- airbnb_reservation_action_with_http_info(code, opts)
169
- nil
174
+ # @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.
175
+ # @return [AirbnbReservationAction200Response]
176
+ def airbnb_reservation_action(code, airbnb_reservation_action_request, opts = {})
177
+ data, _status_code, _headers = airbnb_reservation_action_with_http_info(code, airbnb_reservation_action_request, opts)
178
+ data
170
179
  end
171
180
 
172
- # Accept/decline/cancel Airbnb reservation
173
- # Apply a state action to an Airbnb reservation — &#x60;accept&#x60; / &#x60;decline&#x60; (for inquiries and reservation requests), &#x60;cancel&#x60; (host cancellation, carries penalties), &#x60;pre-approve&#x60; (for inquiries). Returns &#x60;403 listing_inactive&#x60; when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
174
- # @param code [String]
181
+ # Accept, decline or cancel an Airbnb reservation
182
+ # Act on an Airbnb reservation by its Airbnb confirmation code. **Write-side** calls Airbnb upstream, as the Airbnb account that owns the booking. - &#x60;accept&#x60; accept a pending booking request. - &#x60;decline&#x60; — decline a pending booking request. Requires &#x60;reason&#x60; (one of Airbnb&#39;s decline reasons) and &#x60;message&#x60; (sent to the guest, at most 500 characters). - &#x60;cancel&#x60; — cancel a confirmed booking as the host. Requires &#x60;reason&#x60; (one of Airbnb&#39;s host-cancellation reasons). **Host cancellations carry Airbnb penalties.** The body is validated before anything reaches Airbnb; unknown fields are refused. There is no &#x60;pre-approve&#x60; action: a pre-approval answers an inquiry, which has no confirmation code — use &#x60;POST /v1/conversations/{id}/pre-approval&#x60;. For accept/decline, &#x60;POST /v1/reservations/{id}/accept&#x60; and &#x60;/decline&#x60; do the same by Repull id and also update Vanio. Airbnb refusals are mapped rather than returned as a 500: a request that already moved on is &#x60;409 request_no_longer_pending&#x60; (do not retry), an expired one &#x60;409 request_expired&#x60;, any other refusal &#x60;422 airbnb_rejected&#x60; with Airbnb&#39;s reason. Returns &#x60;403 listing_inactive&#x60; when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated. Send &#x60;Idempotency-Key&#x60; to make a retry safe.
183
+ # @param code [String] Airbnb confirmation code, e.g. &#x60;HM9J2MFR3W&#x60;.
184
+ # @param airbnb_reservation_action_request [AirbnbReservationActionRequest]
175
185
  # @param [Hash] opts the optional parameters
176
- # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
177
- def airbnb_reservation_action_with_http_info(code, opts = {})
186
+ # @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.
187
+ # @return [Array<(AirbnbReservationAction200Response, Integer, Hash)>] AirbnbReservationAction200Response data, response status code and response headers
188
+ def airbnb_reservation_action_with_http_info(code, airbnb_reservation_action_request, opts = {})
178
189
  if @api_client.config.debugging
179
190
  @api_client.config.logger.debug 'Calling API: AirbnbApi.airbnb_reservation_action ...'
180
191
  end
@@ -182,6 +193,14 @@ module Repull
182
193
  if @api_client.config.client_side_validation && code.nil?
183
194
  fail ArgumentError, "Missing the required parameter 'code' when calling AirbnbApi.airbnb_reservation_action"
184
195
  end
196
+ # verify the required parameter 'airbnb_reservation_action_request' is set
197
+ if @api_client.config.client_side_validation && airbnb_reservation_action_request.nil?
198
+ fail ArgumentError, "Missing the required parameter 'airbnb_reservation_action_request' when calling AirbnbApi.airbnb_reservation_action"
199
+ end
200
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
201
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling AirbnbApi.airbnb_reservation_action, the character length must be smaller than or equal to 255.'
202
+ end
203
+
185
204
  # resource path
186
205
  local_var_path = '/v1/channels/airbnb/reservations/{code}'.sub('{code}', CGI.escape(code.to_s))
187
206
 
@@ -192,15 +211,21 @@ module Repull
192
211
  header_params = opts[:header_params] || {}
193
212
  # HTTP header 'Accept' (if needed)
194
213
  header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
214
+ # HTTP header 'Content-Type'
215
+ content_type = @api_client.select_header_content_type(['application/json'])
216
+ if !content_type.nil?
217
+ header_params['Content-Type'] = content_type
218
+ end
219
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
195
220
 
196
221
  # form parameters
197
222
  form_params = opts[:form_params] || {}
198
223
 
199
224
  # http body (model)
200
- post_body = opts[:debug_body]
225
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(airbnb_reservation_action_request)
201
226
 
202
227
  # return_type
203
- return_type = opts[:debug_return_type]
228
+ return_type = opts[:debug_return_type] || 'AirbnbReservationAction200Response'
204
229
 
205
230
  # auth_names
206
231
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -222,28 +247,98 @@ module Repull
222
247
  return data, status_code, headers
223
248
  end
224
249
 
225
- # Create Airbnb alteration
226
- # Create a reservation alteration request (change dates, guest count, or price) on Airbnb. **Write-side** — calls Airbnb upstream. Requires a connected Airbnb host for the workspace, else `404 no_connection`. Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
227
- # @param create_airbnb_alteration_request [CreateAirbnbAlterationRequest]
250
+ # Cancel Airbnb alteration
251
+ # Withdraw an alteration you proposed, before the other side has answered it. **Write-side** — calls Airbnb upstream (`respondToAlteration` with status `canceled`). Use this when you sent the wrong dates, guest count, price or listing: the alteration stops being pending instead of sitting there until the guest acts on it. This is the third of Airbnb's three answers to a pending alteration, alongside `accept` and `decline`, and behaves identically to them: requires a connected Airbnb host for the workspace (else `404 no_connection`) and that the alteration id belongs to a reservation in your workspace (else `404 not_found`). No request body is required. Airbnb decides whether an alteration can still be withdrawn — one that has already been accepted or declined is refused upstream, and Airbnb's own reason comes back in `message`. Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
252
+ # @param id [String] Airbnb alteration id (the &#x60;alterationId&#x60; from a &#x60;GET /v1/channels/airbnb/alterations&#x60; row).
228
253
  # @param [Hash] opts the optional parameters
254
+ # @option opts [Object] :body
229
255
  # @return [nil]
230
- def create_airbnb_alteration(create_airbnb_alteration_request, opts = {})
231
- create_airbnb_alteration_with_http_info(create_airbnb_alteration_request, opts)
256
+ def cancel_airbnb_alteration(id, opts = {})
257
+ cancel_airbnb_alteration_with_http_info(id, opts)
232
258
  nil
233
259
  end
234
260
 
235
- # Create Airbnb alteration
236
- # Create a reservation alteration request (change dates, guest count, or price) on Airbnb. **Write-side** — calls Airbnb upstream. Requires a connected Airbnb host for the workspace, else &#x60;404 no_connection&#x60;. Returns &#x60;403 listing_inactive&#x60; when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
237
- # @param create_airbnb_alteration_request [CreateAirbnbAlterationRequest]
261
+ # Cancel Airbnb alteration
262
+ # Withdraw an alteration you proposed, before the other side has answered it. **Write-side** — calls Airbnb upstream (&#x60;respondToAlteration&#x60; with status &#x60;canceled&#x60;). Use this when you sent the wrong dates, guest count, price or listing: the alteration stops being pending instead of sitting there until the guest acts on it. This is the third of Airbnb&#39;s three answers to a pending alteration, alongside &#x60;accept&#x60; and &#x60;decline&#x60;, and behaves identically to them: requires a connected Airbnb host for the workspace (else &#x60;404 no_connection&#x60;) and that the alteration id belongs to a reservation in your workspace (else &#x60;404 not_found&#x60;). No request body is required. Airbnb decides whether an alteration can still be withdrawn — one that has already been accepted or declined is refused upstream, and Airbnb&#39;s own reason comes back in &#x60;message&#x60;. Returns &#x60;403 listing_inactive&#x60; when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
263
+ # @param id [String] Airbnb alteration id (the &#x60;alterationId&#x60; from a &#x60;GET /v1/channels/airbnb/alterations&#x60; row).
238
264
  # @param [Hash] opts the optional parameters
265
+ # @option opts [Object] :body
239
266
  # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
240
- def create_airbnb_alteration_with_http_info(create_airbnb_alteration_request, opts = {})
267
+ def cancel_airbnb_alteration_with_http_info(id, opts = {})
268
+ if @api_client.config.debugging
269
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.cancel_airbnb_alteration ...'
270
+ end
271
+ # verify the required parameter 'id' is set
272
+ if @api_client.config.client_side_validation && id.nil?
273
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.cancel_airbnb_alteration"
274
+ end
275
+ # resource path
276
+ local_var_path = '/v1/channels/airbnb/alterations/{id}/cancel'.sub('{id}', CGI.escape(id.to_s))
277
+
278
+ # query parameters
279
+ query_params = opts[:query_params] || {}
280
+
281
+ # header parameters
282
+ header_params = opts[:header_params] || {}
283
+ # HTTP header 'Accept' (if needed)
284
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
285
+ # HTTP header 'Content-Type'
286
+ content_type = @api_client.select_header_content_type(['application/json'])
287
+ if !content_type.nil?
288
+ header_params['Content-Type'] = content_type
289
+ end
290
+
291
+ # form parameters
292
+ form_params = opts[:form_params] || {}
293
+
294
+ # http body (model)
295
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'body'])
296
+
297
+ # return_type
298
+ return_type = opts[:debug_return_type]
299
+
300
+ # auth_names
301
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
302
+
303
+ new_options = opts.merge(
304
+ :operation => :"AirbnbApi.cancel_airbnb_alteration",
305
+ :header_params => header_params,
306
+ :query_params => query_params,
307
+ :form_params => form_params,
308
+ :body => post_body,
309
+ :auth_names => auth_names,
310
+ :return_type => return_type
311
+ )
312
+
313
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
314
+ if @api_client.config.debugging
315
+ @api_client.config.logger.debug "API called: AirbnbApi#cancel_airbnb_alteration\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
316
+ end
317
+ return data, status_code, headers
318
+ end
319
+
320
+ # Create Airbnb alteration
321
+ # Propose a change to an existing Airbnb reservation: new dates, a new guest count, a new total price, or a move to a different listing. **Write-side** — calls Airbnb upstream. Requires a connected Airbnb host for the workspace, else `404 no_connection`. The body is validated before anything reaches Airbnb. `confirmation_code` is required and **at least one** of `check_in`, `check_out`, `number_of_guests`, `total_price` or `listing_id` must be sent with it — an alteration that changes nothing is `422 invalid_params`, not a request Airbnb is asked to act on. Unknown fields are refused rather than ignored, so a misspelling can never look like a successful write. **Listing transfer.** `listing_id` moves the reservation to another listing in your workspace. Send the **Repull** listing id (the `id` from `GET /v1/properties`); Repull checks you own it, that it is active and connected to Airbnb, translates it to the Airbnb listing id and sends it upstream. Callers who hold the Airbnb-side id instead may send `airbnb_listing_id`. **Airbnb decides** whether to honour a listing change on an alteration — Repull sends it and reports Airbnb’s answer; a refusal comes back as `422 airbnb_rejected` carrying Airbnb’s own message. Returns `403 listing_inactive` when the reservation’s listing, or the listing it is being moved to, is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
322
+ # @param airbnb_alteration_create_request [AirbnbAlterationCreateRequest]
323
+ # @param [Hash] opts the optional parameters
324
+ # @return [AirbnbAlteration]
325
+ def create_airbnb_alteration(airbnb_alteration_create_request, opts = {})
326
+ data, _status_code, _headers = create_airbnb_alteration_with_http_info(airbnb_alteration_create_request, opts)
327
+ data
328
+ end
329
+
330
+ # Create Airbnb alteration
331
+ # Propose a change to an existing Airbnb reservation: new dates, a new guest count, a new total price, or a move to a different listing. **Write-side** — calls Airbnb upstream. Requires a connected Airbnb host for the workspace, else &#x60;404 no_connection&#x60;. The body is validated before anything reaches Airbnb. &#x60;confirmation_code&#x60; is required and **at least one** of &#x60;check_in&#x60;, &#x60;check_out&#x60;, &#x60;number_of_guests&#x60;, &#x60;total_price&#x60; or &#x60;listing_id&#x60; must be sent with it — an alteration that changes nothing is &#x60;422 invalid_params&#x60;, not a request Airbnb is asked to act on. Unknown fields are refused rather than ignored, so a misspelling can never look like a successful write. **Listing transfer.** &#x60;listing_id&#x60; moves the reservation to another listing in your workspace. Send the **Repull** listing id (the &#x60;id&#x60; from &#x60;GET /v1/properties&#x60;); Repull checks you own it, that it is active and connected to Airbnb, translates it to the Airbnb listing id and sends it upstream. Callers who hold the Airbnb-side id instead may send &#x60;airbnb_listing_id&#x60;. **Airbnb decides** whether to honour a listing change on an alteration — Repull sends it and reports Airbnb’s answer; a refusal comes back as &#x60;422 airbnb_rejected&#x60; carrying Airbnb’s own message. Returns &#x60;403 listing_inactive&#x60; when the reservation’s listing, or the listing it is being moved to, is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
332
+ # @param airbnb_alteration_create_request [AirbnbAlterationCreateRequest]
333
+ # @param [Hash] opts the optional parameters
334
+ # @return [Array<(AirbnbAlteration, Integer, Hash)>] AirbnbAlteration data, response status code and response headers
335
+ def create_airbnb_alteration_with_http_info(airbnb_alteration_create_request, opts = {})
241
336
  if @api_client.config.debugging
242
337
  @api_client.config.logger.debug 'Calling API: AirbnbApi.create_airbnb_alteration ...'
243
338
  end
244
- # verify the required parameter 'create_airbnb_alteration_request' is set
245
- if @api_client.config.client_side_validation && create_airbnb_alteration_request.nil?
246
- fail ArgumentError, "Missing the required parameter 'create_airbnb_alteration_request' when calling AirbnbApi.create_airbnb_alteration"
339
+ # verify the required parameter 'airbnb_alteration_create_request' is set
340
+ if @api_client.config.client_side_validation && airbnb_alteration_create_request.nil?
341
+ fail ArgumentError, "Missing the required parameter 'airbnb_alteration_create_request' when calling AirbnbApi.create_airbnb_alteration"
247
342
  end
248
343
  # resource path
249
344
  local_var_path = '/v1/channels/airbnb/alterations'
@@ -265,10 +360,10 @@ module Repull
265
360
  form_params = opts[:form_params] || {}
266
361
 
267
362
  # http body (model)
268
- post_body = opts[:debug_body] || @api_client.object_to_http_body(create_airbnb_alteration_request)
363
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(airbnb_alteration_create_request)
269
364
 
270
365
  # return_type
271
- return_type = opts[:debug_return_type]
366
+ return_type = opts[:debug_return_type] || 'AirbnbAlteration'
272
367
 
273
368
  # auth_names
274
369
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -291,23 +386,23 @@ module Repull
291
386
  end
292
387
 
293
388
  # Create an Airbnb room
294
- # Create a new room on an Airbnb listing. **Write-side** — calls Airbnb upstream. Body is the full room object minus `room_id`. Requires a connected Airbnb host, else `404 no_connection`. 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.
389
+ # Create a new room on an Airbnb listing, with its sleeping arrangement. **Write-side** — calls Airbnb upstream. Requires a connected Airbnb host, else `404 no_connection`. The response is the room object as Airbnb returned it. The new room is also seeded into our own copy, so the very next `GET /rooms` shows it rather than waiting for the sync. 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.
295
390
  # @param id [String] Repull listing id (numeric string).
296
- # @param request_body [Hash<String, Object>]
391
+ # @param create_airbnb_listing_room_request [CreateAirbnbListingRoomRequest]
297
392
  # @param [Hash] opts the optional parameters
298
393
  # @return [nil]
299
- def create_airbnb_listing_room(id, request_body, opts = {})
300
- create_airbnb_listing_room_with_http_info(id, request_body, opts)
394
+ def create_airbnb_listing_room(id, create_airbnb_listing_room_request, opts = {})
395
+ create_airbnb_listing_room_with_http_info(id, create_airbnb_listing_room_request, opts)
301
396
  nil
302
397
  end
303
398
 
304
399
  # Create an Airbnb room
305
- # Create a new room on an Airbnb listing. **Write-side** — calls Airbnb upstream. Body is the full room object minus &#x60;room_id&#x60;. Requires a connected Airbnb host, else &#x60;404 no_connection&#x60;. 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.
400
+ # Create a new room on an Airbnb listing, with its sleeping arrangement. **Write-side** — calls Airbnb upstream. Requires a connected Airbnb host, else &#x60;404 no_connection&#x60;. The response is the room object as Airbnb returned it. The new room is also seeded into our own copy, so the very next &#x60;GET /rooms&#x60; shows it rather than waiting for the sync. 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.
306
401
  # @param id [String] Repull listing id (numeric string).
307
- # @param request_body [Hash<String, Object>]
402
+ # @param create_airbnb_listing_room_request [CreateAirbnbListingRoomRequest]
308
403
  # @param [Hash] opts the optional parameters
309
404
  # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
310
- def create_airbnb_listing_room_with_http_info(id, request_body, opts = {})
405
+ def create_airbnb_listing_room_with_http_info(id, create_airbnb_listing_room_request, opts = {})
311
406
  if @api_client.config.debugging
312
407
  @api_client.config.logger.debug 'Calling API: AirbnbApi.create_airbnb_listing_room ...'
313
408
  end
@@ -315,9 +410,9 @@ module Repull
315
410
  if @api_client.config.client_side_validation && id.nil?
316
411
  fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.create_airbnb_listing_room"
317
412
  end
318
- # verify the required parameter 'request_body' is set
319
- if @api_client.config.client_side_validation && request_body.nil?
320
- fail ArgumentError, "Missing the required parameter 'request_body' when calling AirbnbApi.create_airbnb_listing_room"
413
+ # verify the required parameter 'create_airbnb_listing_room_request' is set
414
+ if @api_client.config.client_side_validation && create_airbnb_listing_room_request.nil?
415
+ fail ArgumentError, "Missing the required parameter 'create_airbnb_listing_room_request' when calling AirbnbApi.create_airbnb_listing_room"
321
416
  end
322
417
  # resource path
323
418
  local_var_path = '/v1/channels/airbnb/listings/{id}/rooms'.sub('{id}', CGI.escape(id.to_s))
@@ -339,7 +434,7 @@ module Repull
339
434
  form_params = opts[:form_params] || {}
340
435
 
341
436
  # http body (model)
342
- post_body = opts[:debug_body] || @api_client.object_to_http_body(request_body)
437
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(create_airbnb_listing_room_request)
343
438
 
344
439
  # return_type
345
440
  return_type = opts[:debug_return_type]
@@ -365,20 +460,22 @@ module Repull
365
460
  end
366
461
 
367
462
  # Create Airbnb special offer or pre-approval
368
- # Create a special offer or a pre-approval on Airbnb. **Write-side** — calls Airbnb upstream. The `type` discriminator selects the flavour: - `offer` — a special offer with custom terms (the remaining body fields are the offer params). - `preapproval` pre-approve an inquiry thread (requires `threadId`; optional `blockInstantBooking`). Requires a connected Airbnb host, else `404 no_connection`. Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
463
+ # Create a pre-approval or a special offer on an Airbnb thread, addressed by **Airbnb** ids. **Write-side** — calls Airbnb upstream. The Repull-id equivalents, which also update the inquiry in Vanio, are `POST /v1/conversations/{id}/pre-approval` and `POST /v1/conversations/{id}/special-offers` — prefer those unless you only hold Airbnb ids. - `type: \"preapproval\"` — let the guest book the dates and price they asked about. Requires `thread_id`; optional `block_instant_booking`. - `type: \"offer\"` your own terms. Requires `thread_id`, `listing_id` (the **Airbnb** listing id, as a string), `start_date`, `nights`, `total_price` (whole stay, listing currency) and `guest_details` with `number_of_guests` (or `number_of_adults`; Airbnb counts adults + children). The body is validated before anything reaches Airbnb (a `422 invalid_params` names the field), and unknown fields are refused. The legacy spellings `threadId` and `blockInstantBooking` still work. The request is sent as the Airbnb account that owns the thread or listing. Airbnb refusals are mapped rather than returned as a 500: `409 inquiry_no_longer_open` / `inquiry_expired` when the inquiry moved on, `422 airbnb_rejected` with Airbnb’s reason otherwise, `403 connection_reauth_required` when the grant does not allow it. Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated. Send `Idempotency-Key`: a repeat with the same key replays the first response instead of acting twice (a `409 idempotency_key_in_use` while the first is still running). A 5xx, a `429 airbnb_rate_limited` or a `403 connection_reauth_required` is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
369
464
  # @param create_airbnb_offer_request [CreateAirbnbOfferRequest]
370
465
  # @param [Hash] opts the optional parameters
371
- # @return [nil]
466
+ # @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.
467
+ # @return [GetAirbnbOffer200Response]
372
468
  def create_airbnb_offer(create_airbnb_offer_request, opts = {})
373
- create_airbnb_offer_with_http_info(create_airbnb_offer_request, opts)
374
- nil
469
+ data, _status_code, _headers = create_airbnb_offer_with_http_info(create_airbnb_offer_request, opts)
470
+ data
375
471
  end
376
472
 
377
473
  # Create Airbnb special offer or pre-approval
378
- # Create a special offer or a pre-approval on Airbnb. **Write-side** — calls Airbnb upstream. The &#x60;type&#x60; discriminator selects the flavour: - &#x60;offer&#x60; — a special offer with custom terms (the remaining body fields are the offer params). - &#x60;preapproval&#x60; pre-approve an inquiry thread (requires &#x60;threadId&#x60;; optional &#x60;blockInstantBooking&#x60;). Requires a connected Airbnb host, else &#x60;404 no_connection&#x60;. Returns &#x60;403 listing_inactive&#x60; when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
474
+ # Create a pre-approval or a special offer on an Airbnb thread, addressed by **Airbnb** ids. **Write-side** — calls Airbnb upstream. The Repull-id equivalents, which also update the inquiry in Vanio, are &#x60;POST /v1/conversations/{id}/pre-approval&#x60; and &#x60;POST /v1/conversations/{id}/special-offers&#x60; — prefer those unless you only hold Airbnb ids. - &#x60;type: \&quot;preapproval\&quot;&#x60; — let the guest book the dates and price they asked about. Requires &#x60;thread_id&#x60;; optional &#x60;block_instant_booking&#x60;. - &#x60;type: \&quot;offer\&quot;&#x60; your own terms. Requires &#x60;thread_id&#x60;, &#x60;listing_id&#x60; (the **Airbnb** listing id, as a string), &#x60;start_date&#x60;, &#x60;nights&#x60;, &#x60;total_price&#x60; (whole stay, listing currency) and &#x60;guest_details&#x60; with &#x60;number_of_guests&#x60; (or &#x60;number_of_adults&#x60;; Airbnb counts adults + children). The body is validated before anything reaches Airbnb (a &#x60;422 invalid_params&#x60; names the field), and unknown fields are refused. The legacy spellings &#x60;threadId&#x60; and &#x60;blockInstantBooking&#x60; still work. The request is sent as the Airbnb account that owns the thread or listing. Airbnb refusals are mapped rather than returned as a 500: &#x60;409 inquiry_no_longer_open&#x60; / &#x60;inquiry_expired&#x60; when the inquiry moved on, &#x60;422 airbnb_rejected&#x60; with Airbnb’s reason otherwise, &#x60;403 connection_reauth_required&#x60; when the grant does not allow it. Returns &#x60;403 listing_inactive&#x60; when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated. Send &#x60;Idempotency-Key&#x60;: a repeat with the same key replays the first response instead of acting twice (a &#x60;409 idempotency_key_in_use&#x60; while the first is still running). A 5xx, a &#x60;429 airbnb_rate_limited&#x60; or a &#x60;403 connection_reauth_required&#x60; is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
379
475
  # @param create_airbnb_offer_request [CreateAirbnbOfferRequest]
380
476
  # @param [Hash] opts the optional parameters
381
- # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
477
+ # @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.
478
+ # @return [Array<(GetAirbnbOffer200Response, Integer, Hash)>] GetAirbnbOffer200Response data, response status code and response headers
382
479
  def create_airbnb_offer_with_http_info(create_airbnb_offer_request, opts = {})
383
480
  if @api_client.config.debugging
384
481
  @api_client.config.logger.debug 'Calling API: AirbnbApi.create_airbnb_offer ...'
@@ -387,6 +484,10 @@ module Repull
387
484
  if @api_client.config.client_side_validation && create_airbnb_offer_request.nil?
388
485
  fail ArgumentError, "Missing the required parameter 'create_airbnb_offer_request' when calling AirbnbApi.create_airbnb_offer"
389
486
  end
487
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
488
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling AirbnbApi.create_airbnb_offer, the character length must be smaller than or equal to 255.'
489
+ end
490
+
390
491
  # resource path
391
492
  local_var_path = '/v1/channels/airbnb/offers'
392
493
 
@@ -402,6 +503,7 @@ module Repull
402
503
  if !content_type.nil?
403
504
  header_params['Content-Type'] = content_type
404
505
  end
506
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
405
507
 
406
508
  # form parameters
407
509
  form_params = opts[:form_params] || {}
@@ -410,7 +512,7 @@ module Repull
410
512
  post_body = opts[:debug_body] || @api_client.object_to_http_body(create_airbnb_offer_request)
411
513
 
412
514
  # return_type
413
- return_type = opts[:debug_return_type]
515
+ return_type = opts[:debug_return_type] || 'GetAirbnbOffer200Response'
414
516
 
415
517
  # auth_names
416
518
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -503,7 +605,7 @@ module Repull
503
605
  end
504
606
 
505
607
  # Delete an Airbnb photo
506
- # Remove a single photo from an Airbnb listing. Pass the Airbnb-side photo id as `?photoId=`. Write-side — calls Airbnb upstream; the local photo cache is reconciled by the sync worker afterwards. 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.
608
+ # Remove a single photo from an Airbnb listing. Pass the Airbnb-side photo id as `?photoId=`. **Write-side** — calls Airbnb upstream. The photo is proven to belong to the listing named in the path first; a photo from another listing returns `404`. Airbnb refuses to delete a listing's last photo. Both stored copies drop the photo on success — `stored` reports whether that succeeded. 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.
507
609
  # @param id [String]
508
610
  # @param photo_id [String] Airbnb-side photo id to delete.
509
611
  # @param [Hash] opts the optional parameters
@@ -514,7 +616,7 @@ module Repull
514
616
  end
515
617
 
516
618
  # Delete an Airbnb photo
517
- # Remove a single photo from an Airbnb listing. Pass the Airbnb-side photo id as &#x60;?photoId&#x3D;&#x60;. Write-side — calls Airbnb upstream; the local photo cache is reconciled by the sync worker afterwards. 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.
619
+ # Remove a single photo from an Airbnb listing. Pass the Airbnb-side photo id as &#x60;?photoId&#x3D;&#x60;. **Write-side** — calls Airbnb upstream. The photo is proven to belong to the listing named in the path first; a photo from another listing returns &#x60;404&#x60;. Airbnb refuses to delete a listing&#39;s last photo. Both stored copies drop the photo on success — &#x60;stored&#x60; reports whether that succeeded. 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.
518
620
  # @param id [String]
519
621
  # @param photo_id [String] Airbnb-side photo id to delete.
520
622
  # @param [Hash] opts the optional parameters
@@ -573,22 +675,22 @@ module Repull
573
675
  end
574
676
 
575
677
  # Delete an Airbnb room
576
- # Delete a room from an Airbnb listing. **Write-side** — calls Airbnb upstream. Pass the Airbnb-side room id as `?roomId=`. Requires a connected Airbnb host, else `404 no_connection`. 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.
678
+ # Delete a room from an Airbnb listing, and its beds with it. **Write-side** — calls Airbnb upstream. Pass the Airbnb-side room id as `?roomId=`. Requires a connected Airbnb host, else `404 no_connection`. The room is proven to belong to the listing named in the path first; a room from another listing returns `404`. Both stored copies drop the room on success — `stored` reports whether that succeeded. 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.
577
679
  # @param id [String] Repull listing id (numeric string).
578
680
  # @param room_id [String] Airbnb-side room id to delete.
579
681
  # @param [Hash] opts the optional parameters
580
- # @return [DeleteAirbnbListingPhoto200Response]
682
+ # @return [DeleteAirbnbListingRoom200Response]
581
683
  def delete_airbnb_listing_room(id, room_id, opts = {})
582
684
  data, _status_code, _headers = delete_airbnb_listing_room_with_http_info(id, room_id, opts)
583
685
  data
584
686
  end
585
687
 
586
688
  # Delete an Airbnb room
587
- # Delete a room from an Airbnb listing. **Write-side** — calls Airbnb upstream. Pass the Airbnb-side room id as &#x60;?roomId&#x3D;&#x60;. Requires a connected Airbnb host, else &#x60;404 no_connection&#x60;. 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.
689
+ # Delete a room from an Airbnb listing, and its beds with it. **Write-side** — calls Airbnb upstream. Pass the Airbnb-side room id as &#x60;?roomId&#x3D;&#x60;. Requires a connected Airbnb host, else &#x60;404 no_connection&#x60;. The room is proven to belong to the listing named in the path first; a room from another listing returns &#x60;404&#x60;. Both stored copies drop the room on success — &#x60;stored&#x60; reports whether that succeeded. 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.
588
690
  # @param id [String] Repull listing id (numeric string).
589
691
  # @param room_id [String] Airbnb-side room id to delete.
590
692
  # @param [Hash] opts the optional parameters
591
- # @return [Array<(DeleteAirbnbListingPhoto200Response, Integer, Hash)>] DeleteAirbnbListingPhoto200Response data, response status code and response headers
693
+ # @return [Array<(DeleteAirbnbListingRoom200Response, Integer, Hash)>] DeleteAirbnbListingRoom200Response data, response status code and response headers
592
694
  def delete_airbnb_listing_room_with_http_info(id, room_id, opts = {})
593
695
  if @api_client.config.debugging
594
696
  @api_client.config.logger.debug 'Calling API: AirbnbApi.delete_airbnb_listing_room ...'
@@ -620,7 +722,7 @@ module Repull
620
722
  post_body = opts[:debug_body]
621
723
 
622
724
  # return_type
623
- return_type = opts[:debug_return_type] || 'DeleteAirbnbListingPhoto200Response'
725
+ return_type = opts[:debug_return_type] || 'DeleteAirbnbListingRoom200Response'
624
726
 
625
727
  # auth_names
626
728
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -779,6 +881,69 @@ module Repull
779
881
  return data, status_code, headers
780
882
  end
781
883
 
884
+ # Get Airbnb booking settings
885
+ # Read how an Airbnb listing takes bookings and what happens when a guest cancels: booking mode, Instant Book state, the good-track-record requirement, check-in/check-out times, advance notice, preparation time, booking window, the short-stay and long-stay cancellation policies, and the non-refundable option. **This is Repull's stored copy, not a live call to Airbnb.** Values come from the local Airbnb mirror that the sync workers fill, so the response always carries `dataFreshness` — check `dataFreshness.stale` (and `dataFreshness.accounts[]` when the workspace has several Airbnb accounts) before treating a value as current. **Not exposed by Airbnb.** The pre-reservation message and automatic stay extension have no field on Airbnb's `booking_settings` resource, so neither can be read or written here; set the pre-reservation message in the Airbnb host dashboard, and handle extensions through `/v1/channels/airbnb/alterations`. Airbnb also expresses the same-day cutoff only as whole hours of advance notice, so `advanceNotice.hours` is as precise as the cutoff gets. Returns `404` when the listing has no Airbnb connection in this workspace, and `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.
886
+ # @param id [String] Repull listing id (numeric string), not the Airbnb listing id.
887
+ # @param [Hash] opts the optional parameters
888
+ # @return [GetAirbnbBookingSettings200Response]
889
+ def get_airbnb_booking_settings(id, opts = {})
890
+ data, _status_code, _headers = get_airbnb_booking_settings_with_http_info(id, opts)
891
+ data
892
+ end
893
+
894
+ # Get Airbnb booking settings
895
+ # Read how an Airbnb listing takes bookings and what happens when a guest cancels: booking mode, Instant Book state, the good-track-record requirement, check-in/check-out times, advance notice, preparation time, booking window, the short-stay and long-stay cancellation policies, and the non-refundable option. **This is Repull&#39;s stored copy, not a live call to Airbnb.** Values come from the local Airbnb mirror that the sync workers fill, so the response always carries &#x60;dataFreshness&#x60; — check &#x60;dataFreshness.stale&#x60; (and &#x60;dataFreshness.accounts[]&#x60; when the workspace has several Airbnb accounts) before treating a value as current. **Not exposed by Airbnb.** The pre-reservation message and automatic stay extension have no field on Airbnb&#39;s &#x60;booking_settings&#x60; resource, so neither can be read or written here; set the pre-reservation message in the Airbnb host dashboard, and handle extensions through &#x60;/v1/channels/airbnb/alterations&#x60;. Airbnb also expresses the same-day cutoff only as whole hours of advance notice, so &#x60;advanceNotice.hours&#x60; is as precise as the cutoff gets. Returns &#x60;404&#x60; when the listing has no Airbnb connection in this workspace, and &#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.
896
+ # @param id [String] Repull listing id (numeric string), not the Airbnb listing id.
897
+ # @param [Hash] opts the optional parameters
898
+ # @return [Array<(GetAirbnbBookingSettings200Response, Integer, Hash)>] GetAirbnbBookingSettings200Response data, response status code and response headers
899
+ def get_airbnb_booking_settings_with_http_info(id, opts = {})
900
+ if @api_client.config.debugging
901
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.get_airbnb_booking_settings ...'
902
+ end
903
+ # verify the required parameter 'id' is set
904
+ if @api_client.config.client_side_validation && id.nil?
905
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.get_airbnb_booking_settings"
906
+ end
907
+ # resource path
908
+ local_var_path = '/v1/channels/airbnb/listings/{id}/booking-settings'.sub('{id}', CGI.escape(id.to_s))
909
+
910
+ # query parameters
911
+ query_params = opts[:query_params] || {}
912
+
913
+ # header parameters
914
+ header_params = opts[:header_params] || {}
915
+ # HTTP header 'Accept' (if needed)
916
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
917
+
918
+ # form parameters
919
+ form_params = opts[:form_params] || {}
920
+
921
+ # http body (model)
922
+ post_body = opts[:debug_body]
923
+
924
+ # return_type
925
+ return_type = opts[:debug_return_type] || 'GetAirbnbBookingSettings200Response'
926
+
927
+ # auth_names
928
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
929
+
930
+ new_options = opts.merge(
931
+ :operation => :"AirbnbApi.get_airbnb_booking_settings",
932
+ :header_params => header_params,
933
+ :query_params => query_params,
934
+ :form_params => form_params,
935
+ :body => post_body,
936
+ :auth_names => auth_names,
937
+ :return_type => return_type
938
+ )
939
+
940
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
941
+ if @api_client.config.debugging
942
+ @api_client.config.logger.debug "API called: AirbnbApi#get_airbnb_booking_settings\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
943
+ end
944
+ return data, status_code, headers
945
+ end
946
+
782
947
  # Get Airbnb check-in guide
783
948
  # Return every published locale variant of an Airbnb listing's check-in guide. **Pure DB read** from `listings_airbnb_check_in_guides`. Pass `?locale=en` to filter to one locale (prefix match). Returns `404` when the listing has no Airbnb connection in this workspace. 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.
784
949
  # @param id [String] Repull listing id (numeric string).
@@ -966,7 +1131,7 @@ module Repull
966
1131
  end
967
1132
 
968
1133
  # Get Airbnb listing
969
- # Fetch all Airbnb connection rows for a single Vanio listing id. A property may be linked from multiple Airbnb hosts — every match is returned. Pass `?include=amenities` to enrich each row with its current Airbnb amenities. 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.
1134
+ # Fetch all Airbnb connection rows for a single Vanio listing id. A property may be linked from multiple Airbnb hosts — every match is returned. Pass `?include=amenities` to enrich each row with its current Airbnb amenities. Each row carries `syncCategory` — Airbnb's own per-listing API sync decision (`sync_all`, `sync_rates_and_availability`, or `none`) — and `writable`, which is `false` exactly when that category is `none`, meaning Airbnb refuses every write to the listing and Repull returns `403 listing_not_api_connected` without sending anything. `GET /v1/channels/airbnb/listings` reports both fields for the whole portfolio in one call. 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.
970
1135
  # @param id [String]
971
1136
  # @param [Hash] opts the optional parameters
972
1137
  # @option opts [String] :include Comma-separated expansions. Currently supported: &#x60;amenities&#x60;.
@@ -977,7 +1142,7 @@ module Repull
977
1142
  end
978
1143
 
979
1144
  # Get Airbnb listing
980
- # Fetch all Airbnb connection rows for a single Vanio listing id. A property may be linked from multiple Airbnb hosts — every match is returned. Pass &#x60;?include&#x3D;amenities&#x60; to enrich each row with its current Airbnb amenities. 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.
1145
+ # Fetch all Airbnb connection rows for a single Vanio listing id. A property may be linked from multiple Airbnb hosts — every match is returned. Pass &#x60;?include&#x3D;amenities&#x60; to enrich each row with its current Airbnb amenities. Each row carries &#x60;syncCategory&#x60; — Airbnb&#39;s own per-listing API sync decision (&#x60;sync_all&#x60;, &#x60;sync_rates_and_availability&#x60;, or &#x60;none&#x60;) — and &#x60;writable&#x60;, which is &#x60;false&#x60; exactly when that category is &#x60;none&#x60;, meaning Airbnb refuses every write to the listing and Repull returns &#x60;403 listing_not_api_connected&#x60; without sending anything. &#x60;GET /v1/channels/airbnb/listings&#x60; reports both fields for the whole portfolio in one call. 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.
981
1146
  # @param id [String]
982
1147
  # @param [Hash] opts the optional parameters
983
1148
  # @option opts [String] :include Comma-separated expansions. Currently supported: &#x60;amenities&#x60;.
@@ -1094,6 +1259,69 @@ module Repull
1094
1259
  return data, status_code, headers
1095
1260
  end
1096
1261
 
1262
+ # Get Airbnb listing details
1263
+ # What kind of property Airbnb thinks this is — property type group and category, room type, capacity — plus the check-in method (`checkInOption`), whether the listing is live (`hasAvailability`), and **`lockedFields`: the attributes Airbnb refuses to change on this listing**. **Pure DB read** from the local mirror, one entry per Airbnb connection. Read `lockedFields` before a content write. Airbnb does not refuse a write to a locked attribute: it returns 200, reports the attribute as locked, and applies nothing — which is why a write can look successful and change nothing. 1,180 of 5,917 synced listings carry at least one locked attribute. Returns `404` when the listing has no Airbnb connection in this workspace, and `403 listing_inactive` when the listing is inactive.
1264
+ # @param id [String] Repull listing id (numeric string).
1265
+ # @param [Hash] opts the optional parameters
1266
+ # @return [GetAirbnbListingDetails200Response]
1267
+ def get_airbnb_listing_details(id, opts = {})
1268
+ data, _status_code, _headers = get_airbnb_listing_details_with_http_info(id, opts)
1269
+ data
1270
+ end
1271
+
1272
+ # Get Airbnb listing details
1273
+ # What kind of property Airbnb thinks this is — property type group and category, room type, capacity — plus the check-in method (&#x60;checkInOption&#x60;), whether the listing is live (&#x60;hasAvailability&#x60;), and **&#x60;lockedFields&#x60;: the attributes Airbnb refuses to change on this listing**. **Pure DB read** from the local mirror, one entry per Airbnb connection. Read &#x60;lockedFields&#x60; before a content write. Airbnb does not refuse a write to a locked attribute: it returns 200, reports the attribute as locked, and applies nothing — which is why a write can look successful and change nothing. 1,180 of 5,917 synced listings carry at least one locked attribute. Returns &#x60;404&#x60; when the listing has no Airbnb connection in this workspace, and &#x60;403 listing_inactive&#x60; when the listing is inactive.
1274
+ # @param id [String] Repull listing id (numeric string).
1275
+ # @param [Hash] opts the optional parameters
1276
+ # @return [Array<(GetAirbnbListingDetails200Response, Integer, Hash)>] GetAirbnbListingDetails200Response data, response status code and response headers
1277
+ def get_airbnb_listing_details_with_http_info(id, opts = {})
1278
+ if @api_client.config.debugging
1279
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.get_airbnb_listing_details ...'
1280
+ end
1281
+ # verify the required parameter 'id' is set
1282
+ if @api_client.config.client_side_validation && id.nil?
1283
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.get_airbnb_listing_details"
1284
+ end
1285
+ # resource path
1286
+ local_var_path = '/v1/channels/airbnb/listings/{id}/details'.sub('{id}', CGI.escape(id.to_s))
1287
+
1288
+ # query parameters
1289
+ query_params = opts[:query_params] || {}
1290
+
1291
+ # header parameters
1292
+ header_params = opts[:header_params] || {}
1293
+ # HTTP header 'Accept' (if needed)
1294
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
1295
+
1296
+ # form parameters
1297
+ form_params = opts[:form_params] || {}
1298
+
1299
+ # http body (model)
1300
+ post_body = opts[:debug_body]
1301
+
1302
+ # return_type
1303
+ return_type = opts[:debug_return_type] || 'GetAirbnbListingDetails200Response'
1304
+
1305
+ # auth_names
1306
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
1307
+
1308
+ new_options = opts.merge(
1309
+ :operation => :"AirbnbApi.get_airbnb_listing_details",
1310
+ :header_params => header_params,
1311
+ :query_params => query_params,
1312
+ :form_params => form_params,
1313
+ :body => post_body,
1314
+ :auth_names => auth_names,
1315
+ :return_type => return_type
1316
+ )
1317
+
1318
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
1319
+ if @api_client.config.debugging
1320
+ @api_client.config.logger.debug "API called: AirbnbApi#get_airbnb_listing_details\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
1321
+ end
1322
+ return data, status_code, headers
1323
+ end
1324
+
1097
1325
  # Get Airbnb pricing
1098
1326
  # Read the current pricing config (base price, weekend uplift, length-of-stay discounts, smart-pricing bounds) for an Airbnb listing. 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.
1099
1327
  # @param id [String]
@@ -1297,6 +1525,70 @@ module Repull
1297
1525
  return data, status_code, headers
1298
1526
  end
1299
1527
 
1528
+ # Get Airbnb special offer
1529
+ # Read a pre-approval or special offer from Airbnb by its Airbnb id. **Live read** — calls Airbnb upstream. Pass the id as `?offerId=`. The Repull-id equivalent is `GET /v1/conversations/{id}/special-offers/{offerId}`, which also confirms the offer belongs to that conversation.
1530
+ # @param offer_id [String] Airbnb special-offer id (the &#x60;id&#x60; Airbnb returned when the offer was created).
1531
+ # @param [Hash] opts the optional parameters
1532
+ # @return [GetAirbnbOffer200Response]
1533
+ def get_airbnb_offer(offer_id, opts = {})
1534
+ data, _status_code, _headers = get_airbnb_offer_with_http_info(offer_id, opts)
1535
+ data
1536
+ end
1537
+
1538
+ # Get Airbnb special offer
1539
+ # Read a pre-approval or special offer from Airbnb by its Airbnb id. **Live read** — calls Airbnb upstream. Pass the id as &#x60;?offerId&#x3D;&#x60;. The Repull-id equivalent is &#x60;GET /v1/conversations/{id}/special-offers/{offerId}&#x60;, which also confirms the offer belongs to that conversation.
1540
+ # @param offer_id [String] Airbnb special-offer id (the &#x60;id&#x60; Airbnb returned when the offer was created).
1541
+ # @param [Hash] opts the optional parameters
1542
+ # @return [Array<(GetAirbnbOffer200Response, Integer, Hash)>] GetAirbnbOffer200Response data, response status code and response headers
1543
+ def get_airbnb_offer_with_http_info(offer_id, opts = {})
1544
+ if @api_client.config.debugging
1545
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.get_airbnb_offer ...'
1546
+ end
1547
+ # verify the required parameter 'offer_id' is set
1548
+ if @api_client.config.client_side_validation && offer_id.nil?
1549
+ fail ArgumentError, "Missing the required parameter 'offer_id' when calling AirbnbApi.get_airbnb_offer"
1550
+ end
1551
+ # resource path
1552
+ local_var_path = '/v1/channels/airbnb/offers'
1553
+
1554
+ # query parameters
1555
+ query_params = opts[:query_params] || {}
1556
+ query_params[:'offerId'] = offer_id
1557
+
1558
+ # header parameters
1559
+ header_params = opts[:header_params] || {}
1560
+ # HTTP header 'Accept' (if needed)
1561
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
1562
+
1563
+ # form parameters
1564
+ form_params = opts[:form_params] || {}
1565
+
1566
+ # http body (model)
1567
+ post_body = opts[:debug_body]
1568
+
1569
+ # return_type
1570
+ return_type = opts[:debug_return_type] || 'GetAirbnbOffer200Response'
1571
+
1572
+ # auth_names
1573
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
1574
+
1575
+ new_options = opts.merge(
1576
+ :operation => :"AirbnbApi.get_airbnb_offer",
1577
+ :header_params => header_params,
1578
+ :query_params => query_params,
1579
+ :form_params => form_params,
1580
+ :body => post_body,
1581
+ :auth_names => auth_names,
1582
+ :return_type => return_type
1583
+ )
1584
+
1585
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
1586
+ if @api_client.config.debugging
1587
+ @api_client.config.logger.debug "API called: AirbnbApi#get_airbnb_offer\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
1588
+ end
1589
+ return data, status_code, headers
1590
+ end
1591
+
1300
1592
  # Get Airbnb reservation
1301
1593
  # Fetch a single Airbnb reservation by Airbnb confirmation code (e.g. `HMABCDEF12`). Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1302
1594
  # @param code [String]
@@ -1424,8 +1716,9 @@ module Repull
1424
1716
  end
1425
1717
 
1426
1718
  # List Airbnb alterations
1427
- # List reservation alteration requests for Airbnb reservations in this workspace. **Pure DB read** from the local `reservation_alterations` mirror — never calls Airbnb upstream — scoped to your workspace via the reservations join. Default returns only pending alterations; pass `?type=all` for the full history. Filter to a single reservation with `?reservation_code=<confirmation code>`. Every response carries the `dataFreshness` envelope. Alterations of reservations on inactive listings are left out. Filtering by a reservation on an inactive listing (`reservation_code`) returns `403 listing_inactive`.
1719
+ # List reservation alteration requests for Airbnb reservations in this workspace. **Pure DB read** from the local `reservation_alterations` mirror — never calls Airbnb upstream — scoped to your workspace via the reservations join. Default returns only pending alterations; pass `?type=all` for the full history. Filter to a single reservation with `?reservation_code=<confirmation code>`. Every response carries the `dataFreshness` envelope. Each row carries the proposed change in its `new*` fields. A **listing transfer** shows up as `newListingId` (Repull listing id) and `newAirbnbListingId` (Airbnb's own id); both are `null` when the alteration does not move the reservation. Alterations of reservations on inactive listings are left out. Filtering by a reservation on an inactive listing (`reservation_code`) returns `403 listing_inactive`. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account's rows; pass `?account_id=<airbnb host id>` to scope to one. Every row carries `accountId` + `accountName` either way, and `dataFreshness.accounts[]` reports each account's freshness separately, so one disconnected host no longer marks the whole response stale.
1428
1720
  # @param [Hash] opts the optional parameters
1721
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
1429
1722
  # @option opts [String] :type Scope: &#x60;pending&#x60; (default) returns only alterations awaiting a decision; &#x60;all&#x60; returns every alteration. (default to 'pending')
1430
1723
  # @option opts [String] :reservation_code Airbnb confirmation code — restricts results to a single reservation. Returns an empty array when no reservation matches within your workspace.
1431
1724
  # @return [ListAirbnbAlterations200Response]
@@ -1435,8 +1728,9 @@ module Repull
1435
1728
  end
1436
1729
 
1437
1730
  # List Airbnb alterations
1438
- # List reservation alteration requests for Airbnb reservations in this workspace. **Pure DB read** from the local &#x60;reservation_alterations&#x60; mirror — never calls Airbnb upstream — scoped to your workspace via the reservations join. Default returns only pending alterations; pass &#x60;?type&#x3D;all&#x60; for the full history. Filter to a single reservation with &#x60;?reservation_code&#x3D;&lt;confirmation code&gt;&#x60;. Every response carries the &#x60;dataFreshness&#x60; envelope. Alterations of reservations on inactive listings are left out. Filtering by a reservation on an inactive listing (&#x60;reservation_code&#x60;) returns &#x60;403 listing_inactive&#x60;.
1731
+ # List reservation alteration requests for Airbnb reservations in this workspace. **Pure DB read** from the local &#x60;reservation_alterations&#x60; mirror — never calls Airbnb upstream — scoped to your workspace via the reservations join. Default returns only pending alterations; pass &#x60;?type&#x3D;all&#x60; for the full history. Filter to a single reservation with &#x60;?reservation_code&#x3D;&lt;confirmation code&gt;&#x60;. Every response carries the &#x60;dataFreshness&#x60; envelope. Each row carries the proposed change in its &#x60;new*&#x60; fields. A **listing transfer** shows up as &#x60;newListingId&#x60; (Repull listing id) and &#x60;newAirbnbListingId&#x60; (Airbnb&#39;s own id); both are &#x60;null&#x60; when the alteration does not move the reservation. Alterations of reservations on inactive listings are left out. Filtering by a reservation on an inactive listing (&#x60;reservation_code&#x60;) returns &#x60;403 listing_inactive&#x60;. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account&#39;s rows; pass &#x60;?account_id&#x3D;&lt;airbnb host id&gt;&#x60; to scope to one. Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, and &#x60;dataFreshness.accounts[]&#x60; reports each account&#39;s freshness separately, so one disconnected host no longer marks the whole response stale.
1439
1732
  # @param [Hash] opts the optional parameters
1733
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
1440
1734
  # @option opts [String] :type Scope: &#x60;pending&#x60; (default) returns only alterations awaiting a decision; &#x60;all&#x60; returns every alteration. (default to 'pending')
1441
1735
  # @option opts [String] :reservation_code Airbnb confirmation code — restricts results to a single reservation. Returns an empty array when no reservation matches within your workspace.
1442
1736
  # @return [Array<(ListAirbnbAlterations200Response, Integer, Hash)>] ListAirbnbAlterations200Response data, response status code and response headers
@@ -1453,6 +1747,7 @@ module Repull
1453
1747
 
1454
1748
  # query parameters
1455
1749
  query_params = opts[:query_params] || {}
1750
+ query_params[:'account_id'] = opts[:'account_id'] if !opts[:'account_id'].nil?
1456
1751
  query_params[:'type'] = opts[:'type'] if !opts[:'type'].nil?
1457
1752
  query_params[:'reservation_code'] = opts[:'reservation_code'] if !opts[:'reservation_code'].nil?
1458
1753
 
@@ -1622,34 +1917,41 @@ module Repull
1622
1917
  return data, status_code, headers
1623
1918
  end
1624
1919
 
1625
- # List Airbnb photos
1626
- # List photos attached to an Airbnb listing in display order. Returns the public CDN URL plus Airbnb-side metadata (id, caption, room). 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.
1627
- # @param id [String]
1920
+ # List Airbnb permits and licences
1921
+ # The regulatory permits, licences and registration numbers attached to an Airbnb listing. **DB-only by default.** `?source=cache` (the default) returns the permits as last mirrored by the sync worker — regulatory body, regulation type, status, permit number — with no upstream call. **`?source=live` also returns the QUESTIONS.** The mirror stores the RESULT of a permit, not what Airbnb asks for it, so a caller that is about to write needs `?source=live` once: it returns each permit flow with the `question_key`, `answer_type` and `options` of every question, and the answers already on file. Airbnb refuses a `question_key` it did not ask for on this listing, so this is not optional guesswork you can skip. Returns `404` when the listing has no Airbnb connection in this workspace, and `403 listing_inactive` when the listing is inactive.
1922
+ # @param id [String] Repull listing id (numeric string).
1628
1923
  # @param [Hash] opts the optional parameters
1629
- # @return [nil]
1630
- def list_airbnb_listing_photos(id, opts = {})
1631
- list_airbnb_listing_photos_with_http_info(id, opts)
1632
- nil
1924
+ # @option opts [String] :source &#x60;cache&#x60; (default) reads the local mirror only. &#x60;live&#x60; additionally asks Airbnb for the permit questions. (default to 'cache')
1925
+ # @return [ListAirbnbListingPermits200Response]
1926
+ def list_airbnb_listing_permits(id, opts = {})
1927
+ data, _status_code, _headers = list_airbnb_listing_permits_with_http_info(id, opts)
1928
+ data
1633
1929
  end
1634
1930
 
1635
- # List Airbnb photos
1636
- # List photos attached to an Airbnb listing in display order. Returns the public CDN URL plus Airbnb-side metadata (id, caption, room). 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.
1637
- # @param id [String]
1931
+ # List Airbnb permits and licences
1932
+ # The regulatory permits, licences and registration numbers attached to an Airbnb listing. **DB-only by default.** &#x60;?source&#x3D;cache&#x60; (the default) returns the permits as last mirrored by the sync worker — regulatory body, regulation type, status, permit number — with no upstream call. **&#x60;?source&#x3D;live&#x60; also returns the QUESTIONS.** The mirror stores the RESULT of a permit, not what Airbnb asks for it, so a caller that is about to write needs &#x60;?source&#x3D;live&#x60; once: it returns each permit flow with the &#x60;question_key&#x60;, &#x60;answer_type&#x60; and &#x60;options&#x60; of every question, and the answers already on file. Airbnb refuses a &#x60;question_key&#x60; it did not ask for on this listing, so this is not optional guesswork you can skip. Returns &#x60;404&#x60; when the listing has no Airbnb connection in this workspace, and &#x60;403 listing_inactive&#x60; when the listing is inactive.
1933
+ # @param id [String] Repull listing id (numeric string).
1638
1934
  # @param [Hash] opts the optional parameters
1639
- # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
1640
- def list_airbnb_listing_photos_with_http_info(id, opts = {})
1935
+ # @option opts [String] :source &#x60;cache&#x60; (default) reads the local mirror only. &#x60;live&#x60; additionally asks Airbnb for the permit questions. (default to 'cache')
1936
+ # @return [Array<(ListAirbnbListingPermits200Response, Integer, Hash)>] ListAirbnbListingPermits200Response data, response status code and response headers
1937
+ def list_airbnb_listing_permits_with_http_info(id, opts = {})
1641
1938
  if @api_client.config.debugging
1642
- @api_client.config.logger.debug 'Calling API: AirbnbApi.list_airbnb_listing_photos ...'
1939
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.list_airbnb_listing_permits ...'
1643
1940
  end
1644
1941
  # verify the required parameter 'id' is set
1645
1942
  if @api_client.config.client_side_validation && id.nil?
1646
- fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.list_airbnb_listing_photos"
1943
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.list_airbnb_listing_permits"
1944
+ end
1945
+ allowable_values = ["cache", "live"]
1946
+ if @api_client.config.client_side_validation && opts[:'source'] && !allowable_values.include?(opts[:'source'])
1947
+ fail ArgumentError, "invalid value for \"source\", must be one of #{allowable_values}"
1647
1948
  end
1648
1949
  # resource path
1649
- local_var_path = '/v1/channels/airbnb/listings/{id}/photos'.sub('{id}', CGI.escape(id.to_s))
1950
+ local_var_path = '/v1/channels/airbnb/listings/{id}/permits'.sub('{id}', CGI.escape(id.to_s))
1650
1951
 
1651
1952
  # query parameters
1652
1953
  query_params = opts[:query_params] || {}
1954
+ query_params[:'source'] = opts[:'source'] if !opts[:'source'].nil?
1653
1955
 
1654
1956
  # header parameters
1655
1957
  header_params = opts[:header_params] || {}
@@ -1663,7 +1965,70 @@ module Repull
1663
1965
  post_body = opts[:debug_body]
1664
1966
 
1665
1967
  # return_type
1666
- return_type = opts[:debug_return_type]
1968
+ return_type = opts[:debug_return_type] || 'ListAirbnbListingPermits200Response'
1969
+
1970
+ # auth_names
1971
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
1972
+
1973
+ new_options = opts.merge(
1974
+ :operation => :"AirbnbApi.list_airbnb_listing_permits",
1975
+ :header_params => header_params,
1976
+ :query_params => query_params,
1977
+ :form_params => form_params,
1978
+ :body => post_body,
1979
+ :auth_names => auth_names,
1980
+ :return_type => return_type
1981
+ )
1982
+
1983
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
1984
+ if @api_client.config.debugging
1985
+ @api_client.config.logger.debug "API called: AirbnbApi#list_airbnb_listing_permits\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
1986
+ end
1987
+ return data, status_code, headers
1988
+ end
1989
+
1990
+ # List Airbnb photos
1991
+ # List photos attached to an Airbnb listing in display order. Returns the public CDN URL plus Airbnb-side metadata (id, caption, room). 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.
1992
+ # @param id [String]
1993
+ # @param [Hash] opts the optional parameters
1994
+ # @return [nil]
1995
+ def list_airbnb_listing_photos(id, opts = {})
1996
+ list_airbnb_listing_photos_with_http_info(id, opts)
1997
+ nil
1998
+ end
1999
+
2000
+ # List Airbnb photos
2001
+ # List photos attached to an Airbnb listing in display order. Returns the public CDN URL plus Airbnb-side metadata (id, caption, room). 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.
2002
+ # @param id [String]
2003
+ # @param [Hash] opts the optional parameters
2004
+ # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
2005
+ def list_airbnb_listing_photos_with_http_info(id, opts = {})
2006
+ if @api_client.config.debugging
2007
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.list_airbnb_listing_photos ...'
2008
+ end
2009
+ # verify the required parameter 'id' is set
2010
+ if @api_client.config.client_side_validation && id.nil?
2011
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.list_airbnb_listing_photos"
2012
+ end
2013
+ # resource path
2014
+ local_var_path = '/v1/channels/airbnb/listings/{id}/photos'.sub('{id}', CGI.escape(id.to_s))
2015
+
2016
+ # query parameters
2017
+ query_params = opts[:query_params] || {}
2018
+
2019
+ # header parameters
2020
+ header_params = opts[:header_params] || {}
2021
+ # HTTP header 'Accept' (if needed)
2022
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
2023
+
2024
+ # form parameters
2025
+ form_params = opts[:form_params] || {}
2026
+
2027
+ # http body (model)
2028
+ post_body = opts[:debug_body]
2029
+
2030
+ # return_type
2031
+ return_type = opts[:debug_return_type]
1667
2032
 
1668
2033
  # auth_names
1669
2034
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -1686,7 +2051,7 @@ module Repull
1686
2051
  end
1687
2052
 
1688
2053
  # List Airbnb rooms
1689
- # List the rooms configured on an Airbnb listing, ordered by room number. **Pure DB read** from `listings_airbnb_rooms`. Returns `404` when the listing has no Airbnb connection in this workspace. 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.
2054
+ # List the rooms configured on an Airbnb listing, ordered by room number, each with its sleeping arrangement in `beds`. **Pure DB read** from `listings_airbnb_rooms` + `listings_airbnb_beds`. Returns `404` when the listing has no Airbnb connection in this workspace. 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.
1690
2055
  # @param id [String] Repull listing id (numeric string).
1691
2056
  # @param [Hash] opts the optional parameters
1692
2057
  # @return [GetAirbnbCheckinGuide200Response]
@@ -1696,7 +2061,7 @@ module Repull
1696
2061
  end
1697
2062
 
1698
2063
  # List Airbnb rooms
1699
- # List the rooms configured on an Airbnb listing, ordered by room number. **Pure DB read** from &#x60;listings_airbnb_rooms&#x60;. Returns &#x60;404&#x60; when the listing has no Airbnb connection in this workspace. 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.
2064
+ # List the rooms configured on an Airbnb listing, ordered by room number, each with its sleeping arrangement in &#x60;beds&#x60;. **Pure DB read** from &#x60;listings_airbnb_rooms&#x60; + &#x60;listings_airbnb_beds&#x60;. Returns &#x60;404&#x60; when the listing has no Airbnb connection in this workspace. 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.
1700
2065
  # @param id [String] Repull listing id (numeric string).
1701
2066
  # @param [Hash] opts the optional parameters
1702
2067
  # @return [Array<(GetAirbnbCheckinGuide200Response, Integer, Hash)>] GetAirbnbCheckinGuide200Response data, response status code and response headers
@@ -1748,10 +2113,74 @@ module Repull
1748
2113
  return data, status_code, headers
1749
2114
  end
1750
2115
 
2116
+ # List guest-safety disclosures
2117
+ # What a guest is told about the property before they book — exterior security cameras, a decibel noise monitor, pets on the property, stairs, a pool with no fence, weapons, shared spaces, limited parking. Airbnb calls them `listing_expectations_for_guests` and shows them at booking time. **Pure DB read** from the local mirror. EVERY supported disclosure type is returned, including the ones this listing has not declared (`value: false`), so \"does this property have cameras?\" has an answer rather than a missing key — `declared` tells you whether Airbnb holds an explicit answer. Types Airbnb returns that are not in the documented set are passed through rather than dropped. Where a listing is connected to several Airbnb listings, a disclosure declared on any of them is reported as true of the property. Returns `404` when the listing has no Airbnb connection in this workspace, and `403 listing_inactive` when the listing is inactive.
2118
+ # @param id [String] Repull listing id (numeric string).
2119
+ # @param [Hash] opts the optional parameters
2120
+ # @return [ListAirbnbListingSafetyDisclosures200Response]
2121
+ def list_airbnb_listing_safety_disclosures(id, opts = {})
2122
+ data, _status_code, _headers = list_airbnb_listing_safety_disclosures_with_http_info(id, opts)
2123
+ data
2124
+ end
2125
+
2126
+ # List guest-safety disclosures
2127
+ # What a guest is told about the property before they book — exterior security cameras, a decibel noise monitor, pets on the property, stairs, a pool with no fence, weapons, shared spaces, limited parking. Airbnb calls them &#x60;listing_expectations_for_guests&#x60; and shows them at booking time. **Pure DB read** from the local mirror. EVERY supported disclosure type is returned, including the ones this listing has not declared (&#x60;value: false&#x60;), so \&quot;does this property have cameras?\&quot; has an answer rather than a missing key — &#x60;declared&#x60; tells you whether Airbnb holds an explicit answer. Types Airbnb returns that are not in the documented set are passed through rather than dropped. Where a listing is connected to several Airbnb listings, a disclosure declared on any of them is reported as true of the property. Returns &#x60;404&#x60; when the listing has no Airbnb connection in this workspace, and &#x60;403 listing_inactive&#x60; when the listing is inactive.
2128
+ # @param id [String] Repull listing id (numeric string).
2129
+ # @param [Hash] opts the optional parameters
2130
+ # @return [Array<(ListAirbnbListingSafetyDisclosures200Response, Integer, Hash)>] ListAirbnbListingSafetyDisclosures200Response data, response status code and response headers
2131
+ def list_airbnb_listing_safety_disclosures_with_http_info(id, opts = {})
2132
+ if @api_client.config.debugging
2133
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.list_airbnb_listing_safety_disclosures ...'
2134
+ end
2135
+ # verify the required parameter 'id' is set
2136
+ if @api_client.config.client_side_validation && id.nil?
2137
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.list_airbnb_listing_safety_disclosures"
2138
+ end
2139
+ # resource path
2140
+ local_var_path = '/v1/channels/airbnb/listings/{id}/safety-disclosures'.sub('{id}', CGI.escape(id.to_s))
2141
+
2142
+ # query parameters
2143
+ query_params = opts[:query_params] || {}
2144
+
2145
+ # header parameters
2146
+ header_params = opts[:header_params] || {}
2147
+ # HTTP header 'Accept' (if needed)
2148
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
2149
+
2150
+ # form parameters
2151
+ form_params = opts[:form_params] || {}
2152
+
2153
+ # http body (model)
2154
+ post_body = opts[:debug_body]
2155
+
2156
+ # return_type
2157
+ return_type = opts[:debug_return_type] || 'ListAirbnbListingSafetyDisclosures200Response'
2158
+
2159
+ # auth_names
2160
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
2161
+
2162
+ new_options = opts.merge(
2163
+ :operation => :"AirbnbApi.list_airbnb_listing_safety_disclosures",
2164
+ :header_params => header_params,
2165
+ :query_params => query_params,
2166
+ :form_params => form_params,
2167
+ :body => post_body,
2168
+ :auth_names => auth_names,
2169
+ :return_type => return_type
2170
+ )
2171
+
2172
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
2173
+ if @api_client.config.debugging
2174
+ @api_client.config.logger.debug "API called: AirbnbApi#list_airbnb_listing_safety_disclosures\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
2175
+ end
2176
+ return data, status_code, headers
2177
+ end
2178
+
1751
2179
  # List Airbnb listings
1752
- # List every Airbnb listing this workspace has access to via the connected Airbnb account. **Pure DB read — never calls Airbnb upstream.** The connect flow is what populates the local cache; the API serves what's already there. Customers with a disconnected host still see their last-synced data, with the top-level `dataFreshness` envelope flagging the staleness and pointing at the reconnect URL. Pass `?include=amenities` to enrich each connection with its locally-cached amenity set. Returns `null` per connection when the cache is empty. Inactive listings are left out; they keep syncing and reappear once activated. Use `GET /v1/listings?status=inactive` to find them.
2180
+ # List every Airbnb listing this workspace has access to via the connected Airbnb account. **Pure DB read — never calls Airbnb upstream.** The connect flow is what populates the local cache; the API serves what's already there. Customers with a disconnected host still see their last-synced data, with the top-level `dataFreshness` envelope flagging the staleness and pointing at the reconnect URL. Pass `?include=amenities` to enrich each connection with its locally-cached amenity set. Returns `null` per connection when the cache is empty. Pass `?include=thumbnail` to add `thumbnailUrl` to each listing — one extra column on the query that already runs, so a selection screen renders from a single request instead of one call per listing. `null` when the listing has no thumbnail stored. Combine comma-separated, e.g. `?include=amenities,thumbnail`. **Can this listing be written to?** Every connection carries `syncCategory` — Airbnb's own per-listing API sync decision (`sync_all`, `sync_rates_and_availability`, or `none`) — and `writable`, which is `false` exactly when that category is `none`. Airbnb authorises sync one listing at a time, so a connected account can still hold listings Airbnb refuses every write to; a write to one of those returns `403 listing_not_api_connected` before anything is sent, and reconnecting the account does not change it (the host must switch the listing on in Airbnb). Check `writable` here before a portfolio-wide push instead of discovering it one 403 at a time. Inactive listings are left out; they keep syncing and reappear once activated. Use `GET /v1/listings?status=inactive` to find them. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account's rows; pass `?account_id=<airbnb host id>` to scope to one. Every row carries `accountId` + `accountName` either way, and `dataFreshness.accounts[]` reports each account's freshness separately, so one disconnected host no longer marks the whole response stale.
1753
2181
  # @param [Hash] opts the optional parameters
1754
- # @option opts [String] :include Comma-separated expansions. Currently supported: &#x60;amenities&#x60; (adds &#x60;amenities&#x60; and &#x60;accessibility_amenities&#x60; arrays to each connection, sourced from the local &#x60;listings_airbnb_amenities&#x60; cache).
2182
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
2183
+ # @option opts [String] :include Comma-separated expansions. Currently supported: &#x60;amenities&#x60; (adds &#x60;amenities&#x60; and &#x60;accessibility_amenities&#x60; arrays to each connection, sourced from the local &#x60;listings_airbnb_amenities&#x60; cache) and &#x60;thumbnail&#x60; (adds &#x60;thumbnailUrl&#x60; to each listing). Unknown values return 422 with a &#x60;valid_values&#x60; envelope.
1755
2184
  # @return [AirbnbListingListResponse]
1756
2185
  def list_airbnb_listings(opts = {})
1757
2186
  data, _status_code, _headers = list_airbnb_listings_with_http_info(opts)
@@ -1759,9 +2188,10 @@ module Repull
1759
2188
  end
1760
2189
 
1761
2190
  # List Airbnb listings
1762
- # List every Airbnb listing this workspace has access to via the connected Airbnb account. **Pure DB read — never calls Airbnb upstream.** The connect flow is what populates the local cache; the API serves what&#39;s already there. Customers with a disconnected host still see their last-synced data, with the top-level &#x60;dataFreshness&#x60; envelope flagging the staleness and pointing at the reconnect URL. Pass &#x60;?include&#x3D;amenities&#x60; to enrich each connection with its locally-cached amenity set. Returns &#x60;null&#x60; per connection when the cache is empty. Inactive listings are left out; they keep syncing and reappear once activated. Use &#x60;GET /v1/listings?status&#x3D;inactive&#x60; to find them.
2191
+ # List every Airbnb listing this workspace has access to via the connected Airbnb account. **Pure DB read — never calls Airbnb upstream.** The connect flow is what populates the local cache; the API serves what&#39;s already there. Customers with a disconnected host still see their last-synced data, with the top-level &#x60;dataFreshness&#x60; envelope flagging the staleness and pointing at the reconnect URL. Pass &#x60;?include&#x3D;amenities&#x60; to enrich each connection with its locally-cached amenity set. Returns &#x60;null&#x60; per connection when the cache is empty. Pass &#x60;?include&#x3D;thumbnail&#x60; to add &#x60;thumbnailUrl&#x60; to each listing — one extra column on the query that already runs, so a selection screen renders from a single request instead of one call per listing. &#x60;null&#x60; when the listing has no thumbnail stored. Combine comma-separated, e.g. &#x60;?include&#x3D;amenities,thumbnail&#x60;. **Can this listing be written to?** Every connection carries &#x60;syncCategory&#x60; — Airbnb&#39;s own per-listing API sync decision (&#x60;sync_all&#x60;, &#x60;sync_rates_and_availability&#x60;, or &#x60;none&#x60;) — and &#x60;writable&#x60;, which is &#x60;false&#x60; exactly when that category is &#x60;none&#x60;. Airbnb authorises sync one listing at a time, so a connected account can still hold listings Airbnb refuses every write to; a write to one of those returns &#x60;403 listing_not_api_connected&#x60; before anything is sent, and reconnecting the account does not change it (the host must switch the listing on in Airbnb). Check &#x60;writable&#x60; here before a portfolio-wide push instead of discovering it one 403 at a time. Inactive listings are left out; they keep syncing and reappear once activated. Use &#x60;GET /v1/listings?status&#x3D;inactive&#x60; to find them. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account&#39;s rows; pass &#x60;?account_id&#x3D;&lt;airbnb host id&gt;&#x60; to scope to one. Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, and &#x60;dataFreshness.accounts[]&#x60; reports each account&#39;s freshness separately, so one disconnected host no longer marks the whole response stale.
1763
2192
  # @param [Hash] opts the optional parameters
1764
- # @option opts [String] :include Comma-separated expansions. Currently supported: &#x60;amenities&#x60; (adds &#x60;amenities&#x60; and &#x60;accessibility_amenities&#x60; arrays to each connection, sourced from the local &#x60;listings_airbnb_amenities&#x60; cache).
2193
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
2194
+ # @option opts [String] :include Comma-separated expansions. Currently supported: &#x60;amenities&#x60; (adds &#x60;amenities&#x60; and &#x60;accessibility_amenities&#x60; arrays to each connection, sourced from the local &#x60;listings_airbnb_amenities&#x60; cache) and &#x60;thumbnail&#x60; (adds &#x60;thumbnailUrl&#x60; to each listing). Unknown values return 422 with a &#x60;valid_values&#x60; envelope.
1765
2195
  # @return [Array<(AirbnbListingListResponse, Integer, Hash)>] AirbnbListingListResponse data, response status code and response headers
1766
2196
  def list_airbnb_listings_with_http_info(opts = {})
1767
2197
  if @api_client.config.debugging
@@ -1772,6 +2202,7 @@ module Repull
1772
2202
 
1773
2203
  # query parameters
1774
2204
  query_params = opts[:query_params] || {}
2205
+ query_params[:'account_id'] = opts[:'account_id'] if !opts[:'account_id'].nil?
1775
2206
  query_params[:'include'] = opts[:'include'] if !opts[:'include'].nil?
1776
2207
 
1777
2208
  # header parameters
@@ -1809,8 +2240,9 @@ module Repull
1809
2240
  end
1810
2241
 
1811
2242
  # List Airbnb reservations
1812
- # Cursor-paginated list of reservations sourced directly from Airbnb. Use this when you need Airbnb-specific fields (guest payout split, cancellation policy snapshot) that the unified `/v1/reservations` endpoint flattens away. Walk pages with `?cursor=<pagination.nextCursor>` until `pagination.hasMore` is `false`. The cursor is opaque — never construct or parse it client-side. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. Internally this walks upstream Airbnb cursor pages to skip rows, so deep offsets cost N/limit upstream round-trips; cursor remains the better choice for deep pagination. When `status` is omitted, all statuses are returned (Airbnb defaults to `accepted` only on its own surface, but this endpoint normalises to \"all\"). Pass `?status=accepted` to scope. Reservations on inactive listings are left out (counts and cursors included); they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (`listing_id`) returns `403 listing_inactive`.
2243
+ # Cursor-paginated list of reservations sourced directly from Airbnb. Use this when you need Airbnb-specific fields (guest payout split, cancellation policy snapshot) that the unified `/v1/reservations` endpoint flattens away. Walk pages with `?cursor=<pagination.nextCursor>` until `pagination.hasMore` is `false`. The cursor is opaque — never construct or parse it client-side. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. Internally this walks upstream Airbnb cursor pages to skip rows, so deep offsets cost N/limit upstream round-trips; cursor remains the better choice for deep pagination. When `status` is omitted, all statuses are returned (Airbnb defaults to `accepted` only on its own surface, but this endpoint normalises to \"all\"). Pass `?status=accepted` to scope. Reservations on inactive listings are left out (counts and cursors included); they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (`listing_id`) returns `403 listing_inactive`. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account's rows; pass `?account_id=<airbnb host id>` to scope to one. Every row carries `accountId` + `accountName` either way, and `dataFreshness.accounts[]` reports each account's freshness separately, so one disconnected host no longer marks the whole response stale.
1813
2244
  # @param [Hash] opts the optional parameters
2245
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
1814
2246
  # @option opts [String] :cursor Opaque cursor returned by the previous response&#39;s &#x60;pagination.nextCursor&#x60;. Omit to fetch the first page.
1815
2247
  # @option opts [Integer] :offset First-class alias for cursor-based pagination. Mutually exclusive with &#x60;cursor&#x60; — passing both returns 422. Accepts integers in &#x60;[0, 10000]&#x60;; deeper walks must use &#x60;cursor&#x60; (constant per-page cost). The response always includes &#x60;pagination.nextCursor&#x60; so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying. (default to 0)
1816
2248
  # @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 50)
@@ -1826,8 +2258,9 @@ module Repull
1826
2258
  end
1827
2259
 
1828
2260
  # List Airbnb reservations
1829
- # Cursor-paginated list of reservations sourced directly from Airbnb. Use this when you need Airbnb-specific fields (guest payout split, cancellation policy snapshot) that the unified &#x60;/v1/reservations&#x60; endpoint flattens away. Walk pages with &#x60;?cursor&#x3D;&lt;pagination.nextCursor&gt;&#x60; until &#x60;pagination.hasMore&#x60; is &#x60;false&#x60;. The cursor is opaque — never construct or parse it client-side. &#x60;?offset&#x3D;&#x60; is also accepted as a first-class alias for shallow paging (0..10000) — see the &#x60;offset&#x60; parameter below. Mutually exclusive with &#x60;cursor&#x60;. Internally this walks upstream Airbnb cursor pages to skip rows, so deep offsets cost N/limit upstream round-trips; cursor remains the better choice for deep pagination. When &#x60;status&#x60; is omitted, all statuses are returned (Airbnb defaults to &#x60;accepted&#x60; only on its own surface, but this endpoint normalises to \&quot;all\&quot;). Pass &#x60;?status&#x3D;accepted&#x60; to scope. Reservations on inactive listings are left out (counts and cursors included); they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (&#x60;listing_id&#x60;) returns &#x60;403 listing_inactive&#x60;.
2261
+ # Cursor-paginated list of reservations sourced directly from Airbnb. Use this when you need Airbnb-specific fields (guest payout split, cancellation policy snapshot) that the unified &#x60;/v1/reservations&#x60; endpoint flattens away. Walk pages with &#x60;?cursor&#x3D;&lt;pagination.nextCursor&gt;&#x60; until &#x60;pagination.hasMore&#x60; is &#x60;false&#x60;. The cursor is opaque — never construct or parse it client-side. &#x60;?offset&#x3D;&#x60; is also accepted as a first-class alias for shallow paging (0..10000) — see the &#x60;offset&#x60; parameter below. Mutually exclusive with &#x60;cursor&#x60;. Internally this walks upstream Airbnb cursor pages to skip rows, so deep offsets cost N/limit upstream round-trips; cursor remains the better choice for deep pagination. When &#x60;status&#x60; is omitted, all statuses are returned (Airbnb defaults to &#x60;accepted&#x60; only on its own surface, but this endpoint normalises to \&quot;all\&quot;). Pass &#x60;?status&#x3D;accepted&#x60; to scope. Reservations on inactive listings are left out (counts and cursors included); they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (&#x60;listing_id&#x60;) returns &#x60;403 listing_inactive&#x60;. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account&#39;s rows; pass &#x60;?account_id&#x3D;&lt;airbnb host id&gt;&#x60; to scope to one. Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, and &#x60;dataFreshness.accounts[]&#x60; reports each account&#39;s freshness separately, so one disconnected host no longer marks the whole response stale.
1830
2262
  # @param [Hash] opts the optional parameters
2263
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
1831
2264
  # @option opts [String] :cursor Opaque cursor returned by the previous response&#39;s &#x60;pagination.nextCursor&#x60;. Omit to fetch the first page.
1832
2265
  # @option opts [Integer] :offset First-class alias for cursor-based pagination. Mutually exclusive with &#x60;cursor&#x60; — passing both returns 422. Accepts integers in &#x60;[0, 10000]&#x60;; deeper walks must use &#x60;cursor&#x60; (constant per-page cost). The response always includes &#x60;pagination.nextCursor&#x60; so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying. (default to 0)
1833
2266
  # @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 50)
@@ -1866,6 +2299,7 @@ module Repull
1866
2299
 
1867
2300
  # query parameters
1868
2301
  query_params = opts[:query_params] || {}
2302
+ query_params[:'account_id'] = opts[:'account_id'] if !opts[:'account_id'].nil?
1869
2303
  query_params[:'cursor'] = opts[:'cursor'] if !opts[:'cursor'].nil?
1870
2304
  query_params[:'offset'] = opts[:'offset'] if !opts[:'offset'].nil?
1871
2305
  query_params[:'limit'] = opts[:'limit'] if !opts[:'limit'].nil?
@@ -1910,8 +2344,9 @@ module Repull
1910
2344
  end
1911
2345
 
1912
2346
  # List Airbnb reviews
1913
- # List reviews left by guests on Airbnb listings in this workspace. Includes both reviews of the host and reviews of the guest (where the host has not yet submitted theirs). Reviews of inactive listings are left out; they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (`listing_id`) returns `403 listing_inactive`.
2347
+ # List reviews left by guests on Airbnb listings in this workspace. Includes both reviews of the host and reviews of the guest (where the host has not yet submitted theirs). Reviews of inactive listings are left out; they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (`listing_id`) returns `403 listing_inactive`. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account's rows; pass `?account_id=<airbnb host id>` to scope to one. Every row carries `accountId` + `accountName` either way, and `dataFreshness.accounts[]` reports each account's freshness separately, so one disconnected host no longer marks the whole response stale.
1914
2348
  # @param [Hash] opts the optional parameters
2349
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
1915
2350
  # @return [AirbnbReviewListResponse]
1916
2351
  def list_airbnb_reviews(opts = {})
1917
2352
  data, _status_code, _headers = list_airbnb_reviews_with_http_info(opts)
@@ -1919,8 +2354,9 @@ module Repull
1919
2354
  end
1920
2355
 
1921
2356
  # List Airbnb reviews
1922
- # List reviews left by guests on Airbnb listings in this workspace. Includes both reviews of the host and reviews of the guest (where the host has not yet submitted theirs). Reviews of inactive listings are left out; they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (&#x60;listing_id&#x60;) returns &#x60;403 listing_inactive&#x60;.
2357
+ # List reviews left by guests on Airbnb listings in this workspace. Includes both reviews of the host and reviews of the guest (where the host has not yet submitted theirs). Reviews of inactive listings are left out; they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (&#x60;listing_id&#x60;) returns &#x60;403 listing_inactive&#x60;. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account&#39;s rows; pass &#x60;?account_id&#x3D;&lt;airbnb host id&gt;&#x60; to scope to one. Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, and &#x60;dataFreshness.accounts[]&#x60; reports each account&#39;s freshness separately, so one disconnected host no longer marks the whole response stale.
1923
2358
  # @param [Hash] opts the optional parameters
2359
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
1924
2360
  # @return [Array<(AirbnbReviewListResponse, Integer, Hash)>] AirbnbReviewListResponse data, response status code and response headers
1925
2361
  def list_airbnb_reviews_with_http_info(opts = {})
1926
2362
  if @api_client.config.debugging
@@ -1931,6 +2367,7 @@ module Repull
1931
2367
 
1932
2368
  # query parameters
1933
2369
  query_params = opts[:query_params] || {}
2370
+ query_params[:'account_id'] = opts[:'account_id'] if !opts[:'account_id'].nil?
1934
2371
 
1935
2372
  # header parameters
1936
2373
  header_params = opts[:header_params] || {}
@@ -1967,20 +2404,24 @@ module Repull
1967
2404
  end
1968
2405
 
1969
2406
  # Get Airbnb messages
1970
- # Fetch the full message log for an Airbnb thread, ordered oldest-to-newest. Walk pages with `?cursor=` until `pagination.hasMore` is `false`. Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
2407
+ # Messages stored for an Airbnb thread, as recorded rows (not the unified `Message` shape — use `GET /v1/conversations/{id}/messages` for that). By default returns 50 per page, newest first; walk older pages with `?cursor=` (the `pagination.nextCursor` of the previous page) until `pagination.hasMore` is `false`. `?all=true` returns up to 1000 rows oldest-first in one response, with no `pagination`. Each row carries `attachments` — photos and other files on that message, inbound or outbound — in the same shape as the unified endpoint. Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1971
2408
  # @param thread_id [String]
1972
2409
  # @param [Hash] opts the optional parameters
1973
- # @return [MessageListResponse]
2410
+ # @option opts [String] :cursor &#x60;pagination.nextCursor&#x60; from the previous page.
2411
+ # @option opts [Boolean] :all &#x60;true&#x60; returns up to 1000 messages oldest-first in one response, without &#x60;pagination&#x60;.
2412
+ # @return [ListAirbnbThreadMessages200Response]
1974
2413
  def list_airbnb_thread_messages(thread_id, opts = {})
1975
2414
  data, _status_code, _headers = list_airbnb_thread_messages_with_http_info(thread_id, opts)
1976
2415
  data
1977
2416
  end
1978
2417
 
1979
2418
  # Get Airbnb messages
1980
- # Fetch the full message log for an Airbnb thread, ordered oldest-to-newest. Walk pages with &#x60;?cursor&#x3D;&#x60; until &#x60;pagination.hasMore&#x60; is &#x60;false&#x60;. Returns &#x60;403 listing_inactive&#x60; when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
2419
+ # Messages stored for an Airbnb thread, as recorded rows (not the unified &#x60;Message&#x60; shape — use &#x60;GET /v1/conversations/{id}/messages&#x60; for that). By default returns 50 per page, newest first; walk older pages with &#x60;?cursor&#x3D;&#x60; (the &#x60;pagination.nextCursor&#x60; of the previous page) until &#x60;pagination.hasMore&#x60; is &#x60;false&#x60;. &#x60;?all&#x3D;true&#x60; returns up to 1000 rows oldest-first in one response, with no &#x60;pagination&#x60;. Each row carries &#x60;attachments&#x60; — photos and other files on that message, inbound or outbound — in the same shape as the unified endpoint. Returns &#x60;403 listing_inactive&#x60; when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1981
2420
  # @param thread_id [String]
1982
2421
  # @param [Hash] opts the optional parameters
1983
- # @return [Array<(MessageListResponse, Integer, Hash)>] MessageListResponse data, response status code and response headers
2422
+ # @option opts [String] :cursor &#x60;pagination.nextCursor&#x60; from the previous page.
2423
+ # @option opts [Boolean] :all &#x60;true&#x60; returns up to 1000 messages oldest-first in one response, without &#x60;pagination&#x60;.
2424
+ # @return [Array<(ListAirbnbThreadMessages200Response, Integer, Hash)>] ListAirbnbThreadMessages200Response data, response status code and response headers
1984
2425
  def list_airbnb_thread_messages_with_http_info(thread_id, opts = {})
1985
2426
  if @api_client.config.debugging
1986
2427
  @api_client.config.logger.debug 'Calling API: AirbnbApi.list_airbnb_thread_messages ...'
@@ -1994,6 +2435,8 @@ module Repull
1994
2435
 
1995
2436
  # query parameters
1996
2437
  query_params = opts[:query_params] || {}
2438
+ query_params[:'cursor'] = opts[:'cursor'] if !opts[:'cursor'].nil?
2439
+ query_params[:'all'] = opts[:'all'] if !opts[:'all'].nil?
1997
2440
 
1998
2441
  # header parameters
1999
2442
  header_params = opts[:header_params] || {}
@@ -2007,7 +2450,7 @@ module Repull
2007
2450
  post_body = opts[:debug_body]
2008
2451
 
2009
2452
  # return_type
2010
- return_type = opts[:debug_return_type] || 'MessageListResponse'
2453
+ return_type = opts[:debug_return_type] || 'ListAirbnbThreadMessages200Response'
2011
2454
 
2012
2455
  # auth_names
2013
2456
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -2030,8 +2473,9 @@ module Repull
2030
2473
  end
2031
2474
 
2032
2475
  # List Airbnb message threads
2033
- # List Airbnb message threads (one per guest conversation). Cursor-paginated. Each thread includes a preview of the latest message. Threads on inactive listings are left out; they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (`listing_id`) returns `403 listing_inactive`.
2476
+ # List Airbnb message threads (one per guest conversation). Cursor-paginated. Each thread includes a preview of the latest message. Threads on inactive listings are left out; they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (`listing_id`) returns `403 listing_inactive`. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account's rows; pass `?account_id=<airbnb host id>` to scope to one. Every row carries `accountId` + `accountName` either way, and `dataFreshness.accounts[]` reports each account's freshness separately, so one disconnected host no longer marks the whole response stale.
2034
2477
  # @param [Hash] opts the optional parameters
2478
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
2035
2479
  # @return [AirbnbThreadListResponse]
2036
2480
  def list_airbnb_threads(opts = {})
2037
2481
  data, _status_code, _headers = list_airbnb_threads_with_http_info(opts)
@@ -2039,8 +2483,9 @@ module Repull
2039
2483
  end
2040
2484
 
2041
2485
  # List Airbnb message threads
2042
- # List Airbnb message threads (one per guest conversation). Cursor-paginated. Each thread includes a preview of the latest message. Threads on inactive listings are left out; they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (&#x60;listing_id&#x60;) returns &#x60;403 listing_inactive&#x60;.
2486
+ # List Airbnb message threads (one per guest conversation). Cursor-paginated. Each thread includes a preview of the latest message. Threads on inactive listings are left out; they keep syncing and reappear once the listing is activated. Filtering by an inactive listing (&#x60;listing_id&#x60;) returns &#x60;403 listing_inactive&#x60;. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account&#39;s rows; pass &#x60;?account_id&#x3D;&lt;airbnb host id&gt;&#x60; to scope to one. Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, and &#x60;dataFreshness.accounts[]&#x60; reports each account&#39;s freshness separately, so one disconnected host no longer marks the whole response stale.
2043
2487
  # @param [Hash] opts the optional parameters
2488
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
2044
2489
  # @return [Array<(AirbnbThreadListResponse, Integer, Hash)>] AirbnbThreadListResponse data, response status code and response headers
2045
2490
  def list_airbnb_threads_with_http_info(opts = {})
2046
2491
  if @api_client.config.debugging
@@ -2051,6 +2496,7 @@ module Repull
2051
2496
 
2052
2497
  # query parameters
2053
2498
  query_params = opts[:query_params] || {}
2499
+ query_params[:'account_id'] = opts[:'account_id'] if !opts[:'account_id'].nil?
2054
2500
 
2055
2501
  # header parameters
2056
2502
  header_params = opts[:header_params] || {}
@@ -2087,8 +2533,9 @@ module Repull
2087
2533
  end
2088
2534
 
2089
2535
  # List Airbnb transactions
2090
- # List Airbnb host transactions (reservation earnings, payouts, resolution adjustments) for this workspace, newest first. **Pure DB read** — customer-facing reads never call Airbnb upstream; they serve the `airbnb_transactions` mirror. Each row carries the genuine host- and guest-side financial breakdown (accommodation subtotal, cleaning fee, host + guest service fees split base/VAT, tax buckets, expected/actual host payout with settlement status). Trigger a refresh with `POST` on this path. When the mirror is empty or the host disconnected, `dataFreshness.stale = true` with a `reason` (`never_synced`, `host_disconnected_<iso>`, `sync_lag_>_24h`). Transactions of reservations on inactive listings are left out; payout rows, which belong to no listing, are always included.
2536
+ # List Airbnb host transactions (reservation earnings, payouts, resolution adjustments) for this workspace, newest first. **Pure DB read** — customer-facing reads never call Airbnb upstream; they serve the `airbnb_transactions` mirror. Each row carries the genuine host- and guest-side financial breakdown (accommodation subtotal, cleaning fee, host + guest service fees split base/VAT, tax buckets, expected/actual host payout with settlement status). Trigger a refresh with `POST` on this path. When the mirror is empty or the host disconnected, `dataFreshness.stale = true` with a `reason` (`never_synced`, `host_disconnected_<iso>`, `sync_lag_>_24h`). Transactions of reservations on inactive listings are left out; payout rows, which belong to no listing, are always included. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account's rows; pass `?account_id=<airbnb host id>` to scope to one. Every row carries `accountId` + `accountName` either way, and `dataFreshness.accounts[]` reports each account's freshness separately, so one disconnected host no longer marks the whole response stale.
2091
2537
  # @param [Hash] opts the optional parameters
2538
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
2092
2539
  # @return [ListAirbnbTransactions200Response]
2093
2540
  def list_airbnb_transactions(opts = {})
2094
2541
  data, _status_code, _headers = list_airbnb_transactions_with_http_info(opts)
@@ -2096,8 +2543,9 @@ module Repull
2096
2543
  end
2097
2544
 
2098
2545
  # List Airbnb transactions
2099
- # List Airbnb host transactions (reservation earnings, payouts, resolution adjustments) for this workspace, newest first. **Pure DB read** — customer-facing reads never call Airbnb upstream; they serve the &#x60;airbnb_transactions&#x60; mirror. Each row carries the genuine host- and guest-side financial breakdown (accommodation subtotal, cleaning fee, host + guest service fees split base/VAT, tax buckets, expected/actual host payout with settlement status). Trigger a refresh with &#x60;POST&#x60; on this path. When the mirror is empty or the host disconnected, &#x60;dataFreshness.stale &#x3D; true&#x60; with a &#x60;reason&#x60; (&#x60;never_synced&#x60;, &#x60;host_disconnected_&lt;iso&gt;&#x60;, &#x60;sync_lag_&gt;_24h&#x60;). Transactions of reservations on inactive listings are left out; payout rows, which belong to no listing, are always included.
2546
+ # List Airbnb host transactions (reservation earnings, payouts, resolution adjustments) for this workspace, newest first. **Pure DB read** — customer-facing reads never call Airbnb upstream; they serve the &#x60;airbnb_transactions&#x60; mirror. Each row carries the genuine host- and guest-side financial breakdown (accommodation subtotal, cleaning fee, host + guest service fees split base/VAT, tax buckets, expected/actual host payout with settlement status). Trigger a refresh with &#x60;POST&#x60; on this path. When the mirror is empty or the host disconnected, &#x60;dataFreshness.stale &#x3D; true&#x60; with a &#x60;reason&#x60; (&#x60;never_synced&#x60;, &#x60;host_disconnected_&lt;iso&gt;&#x60;, &#x60;sync_lag_&gt;_24h&#x60;). Transactions of reservations on inactive listings are left out; payout rows, which belong to no listing, are always included. **Several Airbnb accounts?** A workspace can connect more than one. By default this returns every connected account&#39;s rows; pass &#x60;?account_id&#x3D;&lt;airbnb host id&gt;&#x60; to scope to one. Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, and &#x60;dataFreshness.accounts[]&#x60; reports each account&#39;s freshness separately, so one disconnected host no longer marks the whole response stale.
2100
2547
  # @param [Hash] opts the optional parameters
2548
+ # @option opts [String] :account_id Scope the response to ONE connected Airbnb account. The value is the Airbnb host id — the same &#x60;accounts[].externalAccountId&#x60; that &#x60;GET /v1/connect/airbnb&#x60; returns and &#x60;DELETE /v1/connect/airbnb?accountId&#x3D;&#x60; accepts. A workspace can connect several Airbnb accounts. Omit this and you get every account&#39;s rows (the default, unchanged). Every row carries &#x60;accountId&#x60; + &#x60;accountName&#x60; either way, so you can group without a second call. An id that is not connected to THIS workspace returns &#x60;404 not_found&#x60; with your own ids in &#x60;valid_values&#x60; — we do not distinguish \&quot;no such host\&quot; from \&quot;someone else&#39;s host\&quot;, because confirming the latter would leak another workspace&#39;s account. Note this is NOT the &#x60;X-Account-Id&#x60; header, which carries a connection id and cannot tell two Airbnb hosts apart.
2101
2549
  # @return [Array<(ListAirbnbTransactions200Response, Integer, Hash)>] ListAirbnbTransactions200Response data, response status code and response headers
2102
2550
  def list_airbnb_transactions_with_http_info(opts = {})
2103
2551
  if @api_client.config.debugging
@@ -2108,6 +2556,7 @@ module Repull
2108
2556
 
2109
2557
  # query parameters
2110
2558
  query_params = opts[:query_params] || {}
2559
+ query_params[:'account_id'] = opts[:'account_id'] if !opts[:'account_id'].nil?
2111
2560
 
2112
2561
  # header parameters
2113
2562
  header_params = opts[:header_params] || {}
@@ -2211,6 +2660,80 @@ module Repull
2211
2660
  return data, status_code, headers
2212
2661
  end
2213
2662
 
2663
+ # Reorder the Airbnb photo tour
2664
+ # Set the order of a listing's photo tour in one call. **Write-side** — calls Airbnb upstream. Send the photo ids in the order you want them shown, first photo first. Ids you leave out keep their current relative order behind the ones you list, so moving one photo to the front is `{\"photo_ids\": [\"<id>\"]}`. Positions are then written as a dense run starting at 1. Airbnb has no bulk photo endpoint — order is one `sort_order` per photo — so this saves a loop of up to 200 requests against your rate limit and makes the partial-failure case reportable. How much is atomic: - Everything is validated before anything is written. A duplicate id, an id that is not on this listing, an inactive listing or a missing connection all fail with **zero** upstream writes. - Only photos whose position actually changes are written; re-sending the order you already have writes nothing. - On the first upstream failure the run stops — nothing after it is attempted. The error carries `applied`, `failed_photo_id` and `not_attempted`, uses Airbnb's own status (`422` rejected / `403` reauth / `429` / `502`), and the operation is idempotent: re-send the identical body to finish the run. - Our stored copy records what actually landed, never the intent. Validation is against our cached copy of the tour, so a listing whose photos have never synced returns `404` — use `PATCH /photos` (which needs no cache) until the first sync lands. 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.
2665
+ # @param id [String] Repull listing id (numeric string).
2666
+ # @param reorder_airbnb_listing_photos_request [ReorderAirbnbListingPhotosRequest]
2667
+ # @param [Hash] opts the optional parameters
2668
+ # @return [ReorderAirbnbListingPhotos200Response]
2669
+ def reorder_airbnb_listing_photos(id, reorder_airbnb_listing_photos_request, opts = {})
2670
+ data, _status_code, _headers = reorder_airbnb_listing_photos_with_http_info(id, reorder_airbnb_listing_photos_request, opts)
2671
+ data
2672
+ end
2673
+
2674
+ # Reorder the Airbnb photo tour
2675
+ # Set the order of a listing&#39;s photo tour in one call. **Write-side** — calls Airbnb upstream. Send the photo ids in the order you want them shown, first photo first. Ids you leave out keep their current relative order behind the ones you list, so moving one photo to the front is &#x60;{\&quot;photo_ids\&quot;: [\&quot;&lt;id&gt;\&quot;]}&#x60;. Positions are then written as a dense run starting at 1. Airbnb has no bulk photo endpoint — order is one &#x60;sort_order&#x60; per photo — so this saves a loop of up to 200 requests against your rate limit and makes the partial-failure case reportable. How much is atomic: - Everything is validated before anything is written. A duplicate id, an id that is not on this listing, an inactive listing or a missing connection all fail with **zero** upstream writes. - Only photos whose position actually changes are written; re-sending the order you already have writes nothing. - On the first upstream failure the run stops — nothing after it is attempted. The error carries &#x60;applied&#x60;, &#x60;failed_photo_id&#x60; and &#x60;not_attempted&#x60;, uses Airbnb&#39;s own status (&#x60;422&#x60; rejected / &#x60;403&#x60; reauth / &#x60;429&#x60; / &#x60;502&#x60;), and the operation is idempotent: re-send the identical body to finish the run. - Our stored copy records what actually landed, never the intent. Validation is against our cached copy of the tour, so a listing whose photos have never synced returns &#x60;404&#x60; — use &#x60;PATCH /photos&#x60; (which needs no cache) until the first sync lands. 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.
2676
+ # @param id [String] Repull listing id (numeric string).
2677
+ # @param reorder_airbnb_listing_photos_request [ReorderAirbnbListingPhotosRequest]
2678
+ # @param [Hash] opts the optional parameters
2679
+ # @return [Array<(ReorderAirbnbListingPhotos200Response, Integer, Hash)>] ReorderAirbnbListingPhotos200Response data, response status code and response headers
2680
+ def reorder_airbnb_listing_photos_with_http_info(id, reorder_airbnb_listing_photos_request, opts = {})
2681
+ if @api_client.config.debugging
2682
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.reorder_airbnb_listing_photos ...'
2683
+ end
2684
+ # verify the required parameter 'id' is set
2685
+ if @api_client.config.client_side_validation && id.nil?
2686
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.reorder_airbnb_listing_photos"
2687
+ end
2688
+ # verify the required parameter 'reorder_airbnb_listing_photos_request' is set
2689
+ if @api_client.config.client_side_validation && reorder_airbnb_listing_photos_request.nil?
2690
+ fail ArgumentError, "Missing the required parameter 'reorder_airbnb_listing_photos_request' when calling AirbnbApi.reorder_airbnb_listing_photos"
2691
+ end
2692
+ # resource path
2693
+ local_var_path = '/v1/channels/airbnb/listings/{id}/photos/order'.sub('{id}', CGI.escape(id.to_s))
2694
+
2695
+ # query parameters
2696
+ query_params = opts[:query_params] || {}
2697
+
2698
+ # header parameters
2699
+ header_params = opts[:header_params] || {}
2700
+ # HTTP header 'Accept' (if needed)
2701
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
2702
+ # HTTP header 'Content-Type'
2703
+ content_type = @api_client.select_header_content_type(['application/json'])
2704
+ if !content_type.nil?
2705
+ header_params['Content-Type'] = content_type
2706
+ end
2707
+
2708
+ # form parameters
2709
+ form_params = opts[:form_params] || {}
2710
+
2711
+ # http body (model)
2712
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(reorder_airbnb_listing_photos_request)
2713
+
2714
+ # return_type
2715
+ return_type = opts[:debug_return_type] || 'ReorderAirbnbListingPhotos200Response'
2716
+
2717
+ # auth_names
2718
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
2719
+
2720
+ new_options = opts.merge(
2721
+ :operation => :"AirbnbApi.reorder_airbnb_listing_photos",
2722
+ :header_params => header_params,
2723
+ :query_params => query_params,
2724
+ :form_params => form_params,
2725
+ :body => post_body,
2726
+ :auth_names => auth_names,
2727
+ :return_type => return_type
2728
+ )
2729
+
2730
+ data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
2731
+ if @api_client.config.debugging
2732
+ @api_client.config.logger.debug "API called: AirbnbApi#reorder_airbnb_listing_photos\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
2733
+ end
2734
+ return data, status_code, headers
2735
+ end
2736
+
2214
2737
  # Respond to Airbnb review
2215
2738
  # Post a public host response to a guest review. Airbnb allows one response per review — repeated POSTs return 409. Response text is capped at 1000 characters. Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
2216
2739
  # @param id [String] Airbnb review id.
@@ -2343,22 +2866,22 @@ module Repull
2343
2866
  end
2344
2867
 
2345
2868
  # Send Airbnb message
2346
- # Send a message in an Airbnb thread as the host. Airbnb enforces content rules (no off-platform contact info, no external URLs) — violating messages are rejected upstream and surface as `airbnb_error`. The `{threadId}` is the Airbnb thread id — the `externalThreadId` field on a unified `Conversation` (`GET /v1/conversations`). Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
2869
+ # Send a message in an Airbnb thread as the host. Airbnb enforces content rules (no off-platform contact info, no external URLs) — violating messages are rejected upstream and surface as `airbnb_error`. ### Sending a photo or video (`mediaUrl`) Airbnb only accepts media uploaded to a signed URL it issues, one file per message and no text on the same message. With `mediaUrl`, Repull downloads the file (public `https://` only, 10 MB max), reads its real type from the bytes (JPEG, PNG, GIF, WebP — converted to JPEG — or MP4/QuickTime), uploads it to Airbnb and sends it; `message`, if given, follows as a separate message. This is the same flow as `POST /v1/conversations/{id}/messages` with `attachments` — prefer that endpoint, which also takes several files per request. The response is a `SendMessageResponse`, the send is recorded in the conversation, and failures are the 422 codes documented there (`attachment_type_not_supported`, `attachment_too_large`, `message_not_sent` for a pre-booking thread, …). The thread must already be synced to Repull (`GET /v1/conversations` lists them), otherwise `404`. Text-only sends (no `mediaUrl`) go straight to Airbnb and return Airbnb's message object. The `{threadId}` is the Airbnb thread id — the `externalThreadId` field on a unified `Conversation` (`GET /v1/conversations`). Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
2347
2870
  # @param thread_id [String] Airbnb thread id (the &#x60;externalThreadId&#x60; on a unified &#x60;Conversation&#x60;).
2348
2871
  # @param send_airbnb_message_request [SendAirbnbMessageRequest]
2349
2872
  # @param [Hash] opts the optional parameters
2350
- # @return [nil]
2873
+ # @return [SendAirbnbMessage201Response]
2351
2874
  def send_airbnb_message(thread_id, send_airbnb_message_request, opts = {})
2352
- send_airbnb_message_with_http_info(thread_id, send_airbnb_message_request, opts)
2353
- nil
2875
+ data, _status_code, _headers = send_airbnb_message_with_http_info(thread_id, send_airbnb_message_request, opts)
2876
+ data
2354
2877
  end
2355
2878
 
2356
2879
  # Send Airbnb message
2357
- # Send a message in an Airbnb thread as the host. Airbnb enforces content rules (no off-platform contact info, no external URLs) — violating messages are rejected upstream and surface as &#x60;airbnb_error&#x60;. The &#x60;{threadId}&#x60; is the Airbnb thread id — the &#x60;externalThreadId&#x60; field on a unified &#x60;Conversation&#x60; (&#x60;GET /v1/conversations&#x60;). Returns &#x60;403 listing_inactive&#x60; when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
2880
+ # Send a message in an Airbnb thread as the host. Airbnb enforces content rules (no off-platform contact info, no external URLs) — violating messages are rejected upstream and surface as &#x60;airbnb_error&#x60;. ### Sending a photo or video (&#x60;mediaUrl&#x60;) Airbnb only accepts media uploaded to a signed URL it issues, one file per message and no text on the same message. With &#x60;mediaUrl&#x60;, Repull downloads the file (public &#x60;https://&#x60; only, 10 MB max), reads its real type from the bytes (JPEG, PNG, GIF, WebP — converted to JPEG — or MP4/QuickTime), uploads it to Airbnb and sends it; &#x60;message&#x60;, if given, follows as a separate message. This is the same flow as &#x60;POST /v1/conversations/{id}/messages&#x60; with &#x60;attachments&#x60; — prefer that endpoint, which also takes several files per request. The response is a &#x60;SendMessageResponse&#x60;, the send is recorded in the conversation, and failures are the 422 codes documented there (&#x60;attachment_type_not_supported&#x60;, &#x60;attachment_too_large&#x60;, &#x60;message_not_sent&#x60; for a pre-booking thread, …). The thread must already be synced to Repull (&#x60;GET /v1/conversations&#x60; lists them), otherwise &#x60;404&#x60;. Text-only sends (no &#x60;mediaUrl&#x60;) go straight to Airbnb and return Airbnb&#39;s message object. The &#x60;{threadId}&#x60; is the Airbnb thread id — the &#x60;externalThreadId&#x60; field on a unified &#x60;Conversation&#x60; (&#x60;GET /v1/conversations&#x60;). Returns &#x60;403 listing_inactive&#x60; when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
2358
2881
  # @param thread_id [String] Airbnb thread id (the &#x60;externalThreadId&#x60; on a unified &#x60;Conversation&#x60;).
2359
2882
  # @param send_airbnb_message_request [SendAirbnbMessageRequest]
2360
2883
  # @param [Hash] opts the optional parameters
2361
- # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
2884
+ # @return [Array<(SendAirbnbMessage201Response, Integer, Hash)>] SendAirbnbMessage201Response data, response status code and response headers
2362
2885
  def send_airbnb_message_with_http_info(thread_id, send_airbnb_message_request, opts = {})
2363
2886
  if @api_client.config.debugging
2364
2887
  @api_client.config.logger.debug 'Calling API: AirbnbApi.send_airbnb_message ...'
@@ -2394,7 +2917,7 @@ module Repull
2394
2917
  post_body = opts[:debug_body] || @api_client.object_to_http_body(send_airbnb_message_request)
2395
2918
 
2396
2919
  # return_type
2397
- return_type = opts[:debug_return_type]
2920
+ return_type = opts[:debug_return_type] || 'SendAirbnbMessage201Response'
2398
2921
 
2399
2922
  # auth_names
2400
2923
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -2416,6 +2939,80 @@ module Repull
2416
2939
  return data, status_code, headers
2417
2940
  end
2418
2941
 
2942
+ # Set the Airbnb cover photo
2943
+ # Choose which photo leads the listing. **Write-side** — calls Airbnb upstream. Airbnb has no \"cover\" field: the cover is the first photo of the tour, so this is a position write. Usually it is a single upstream request — the chosen photo takes a position below the current first one and nothing else moves. When the tour already starts at position 1 and there is no room below it, the tour is renumbered instead, one request per photo whose position actually changes, with the same stop-at-first-failure reporting as `PUT /photos/order` (`applied`, `failed_photo_id`, `not_attempted`; re-send the identical body to finish). The listing thumbnail — what every list view renders — is repointed at the new cover, so the change is not visible only inside the photo tour. The photo must already be in our cached copy of the tour; one uploaded since the last sync returns `404`, and `PATCH /photos` can set its position in the meantime. 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.
2944
+ # @param id [String] Repull listing id (numeric string).
2945
+ # @param set_airbnb_listing_cover_photo_request [SetAirbnbListingCoverPhotoRequest]
2946
+ # @param [Hash] opts the optional parameters
2947
+ # @return [SetAirbnbListingCoverPhoto200Response]
2948
+ def set_airbnb_listing_cover_photo(id, set_airbnb_listing_cover_photo_request, opts = {})
2949
+ data, _status_code, _headers = set_airbnb_listing_cover_photo_with_http_info(id, set_airbnb_listing_cover_photo_request, opts)
2950
+ data
2951
+ end
2952
+
2953
+ # Set the Airbnb cover photo
2954
+ # Choose which photo leads the listing. **Write-side** — calls Airbnb upstream. Airbnb has no \&quot;cover\&quot; field: the cover is the first photo of the tour, so this is a position write. Usually it is a single upstream request — the chosen photo takes a position below the current first one and nothing else moves. When the tour already starts at position 1 and there is no room below it, the tour is renumbered instead, one request per photo whose position actually changes, with the same stop-at-first-failure reporting as &#x60;PUT /photos/order&#x60; (&#x60;applied&#x60;, &#x60;failed_photo_id&#x60;, &#x60;not_attempted&#x60;; re-send the identical body to finish). The listing thumbnail — what every list view renders — is repointed at the new cover, so the change is not visible only inside the photo tour. The photo must already be in our cached copy of the tour; one uploaded since the last sync returns &#x60;404&#x60;, and &#x60;PATCH /photos&#x60; can set its position in the meantime. 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.
2955
+ # @param id [String] Repull listing id (numeric string).
2956
+ # @param set_airbnb_listing_cover_photo_request [SetAirbnbListingCoverPhotoRequest]
2957
+ # @param [Hash] opts the optional parameters
2958
+ # @return [Array<(SetAirbnbListingCoverPhoto200Response, Integer, Hash)>] SetAirbnbListingCoverPhoto200Response data, response status code and response headers
2959
+ def set_airbnb_listing_cover_photo_with_http_info(id, set_airbnb_listing_cover_photo_request, opts = {})
2960
+ if @api_client.config.debugging
2961
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.set_airbnb_listing_cover_photo ...'
2962
+ end
2963
+ # verify the required parameter 'id' is set
2964
+ if @api_client.config.client_side_validation && id.nil?
2965
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.set_airbnb_listing_cover_photo"
2966
+ end
2967
+ # verify the required parameter 'set_airbnb_listing_cover_photo_request' is set
2968
+ if @api_client.config.client_side_validation && set_airbnb_listing_cover_photo_request.nil?
2969
+ fail ArgumentError, "Missing the required parameter 'set_airbnb_listing_cover_photo_request' when calling AirbnbApi.set_airbnb_listing_cover_photo"
2970
+ end
2971
+ # resource path
2972
+ local_var_path = '/v1/channels/airbnb/listings/{id}/photos/cover'.sub('{id}', CGI.escape(id.to_s))
2973
+
2974
+ # query parameters
2975
+ query_params = opts[:query_params] || {}
2976
+
2977
+ # header parameters
2978
+ header_params = opts[:header_params] || {}
2979
+ # HTTP header 'Accept' (if needed)
2980
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
2981
+ # HTTP header 'Content-Type'
2982
+ content_type = @api_client.select_header_content_type(['application/json'])
2983
+ if !content_type.nil?
2984
+ header_params['Content-Type'] = content_type
2985
+ end
2986
+
2987
+ # form parameters
2988
+ form_params = opts[:form_params] || {}
2989
+
2990
+ # http body (model)
2991
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(set_airbnb_listing_cover_photo_request)
2992
+
2993
+ # return_type
2994
+ return_type = opts[:debug_return_type] || 'SetAirbnbListingCoverPhoto200Response'
2995
+
2996
+ # auth_names
2997
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
2998
+
2999
+ new_options = opts.merge(
3000
+ :operation => :"AirbnbApi.set_airbnb_listing_cover_photo",
3001
+ :header_params => header_params,
3002
+ :query_params => query_params,
3003
+ :form_params => form_params,
3004
+ :body => post_body,
3005
+ :auth_names => auth_names,
3006
+ :return_type => return_type
3007
+ )
3008
+
3009
+ data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
3010
+ if @api_client.config.debugging
3011
+ @api_client.config.logger.debug "API called: AirbnbApi#set_airbnb_listing_cover_photo\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
3012
+ end
3013
+ return data, status_code, headers
3014
+ end
3015
+
2419
3016
  # Sync Airbnb transactions
2420
3017
  # Refresh the Airbnb transactions mirror for this workspace by pulling from Airbnb upstream and upserting the breakdown that `GET` serves. Optional JSON body `{ start_date, end_date, transaction_type }` (`transaction_type` is `COMPLETED` or `UPCOMING`; both are synced when omitted). Returns `{ synced, count }`.
2421
3018
  # @param [Hash] opts the optional parameters
@@ -2480,57 +3077,65 @@ module Repull
2480
3077
  return data, status_code, headers
2481
3078
  end
2482
3079
 
2483
- # Upsert Airbnb check-in guide
2484
- # Upsert the check-in guide for one locale on an Airbnb listing. **Write-side** calls Airbnb upstream; the DB mirror is reconciled by the sync worker once the upstream call returns. Target the locale with `?locale=en` (defaults to `en`). Requires a connected Airbnb host, else `404 no_connection`. 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.
2485
- # @param id [String] Repull listing id (numeric string).
3080
+ # Update Airbnb booking settings
3081
+ # Set any subset of a listing's booking settings on Airbnb. Partial — a field you do not send is left as it is. `{id}` is the **Repull listing id** (from `GET /v1/properties` or `GET /v1/channels/airbnb/listings`), not the Airbnb listing id; Repull translates it before calling Airbnb. The body is validated before anything reaches Airbnb, so a bad value is a `422` naming the field rather than a failed upstream call. Unknown fields are refused rather than dropped. **Two groups, applied in order.** Instant Book, check-in/out and the cancellation fields go to Airbnb's booking-settings resource. Advance notice, preparation time and booking window go to Airbnb's availability rules — Airbnb replaces that whole document, so Repull reads the current rules first and merges your change onto them, which is why setting a preparation time does not blank the listing's min/max nights. The response's `applied` array names the groups that were written. **Non-refundable is a percentage here, a factor on Airbnb.** Airbnb stores `non_refundable_price_factor` between 0.7 and 1.0; send `cancellation.nonRefundable.discountPercent` (0-30) and Repull converts — 10% becomes 0.9. `enabled: false` sets the factor to 1.0. **Not exposed by Airbnb:** `preReservationMessage` and `automaticStayExtension`. Sending either returns a `422` explaining where to set it instead. **Errors:** `403 connection_reauth_required` — Airbnb no longer accepts the connection for this listing (reconnect; retrying won't help). `403 listing_inactive` the listing is inactive. `404 not_found` — no Airbnb-connected listing with this id in the workspace. `422 invalid_params` the body is wrong; `field` names it. `422 airbnb_rejected` — Airbnb refused the change; `message` carries its reason. `429 airbnb_rate_limited` — back off. `502 airbnb_error` — Airbnb outage or timeout; retry.
3082
+ # @param id [String] Repull listing id (numeric string), not the Airbnb listing id.
3083
+ # @param update_airbnb_booking_settings_request [UpdateAirbnbBookingSettingsRequest]
2486
3084
  # @param [Hash] opts the optional parameters
2487
- # @option opts [String] :locale Locale to upsert. Defaults to &#x60;en&#x60;. (default to 'en')
2488
- # @return [nil]
2489
- def update_airbnb_checkin_guide(id, opts = {})
2490
- update_airbnb_checkin_guide_with_http_info(id, opts)
2491
- nil
3085
+ # @return [UpdateAirbnbBookingSettings200Response]
3086
+ def update_airbnb_booking_settings(id, update_airbnb_booking_settings_request, opts = {})
3087
+ data, _status_code, _headers = update_airbnb_booking_settings_with_http_info(id, update_airbnb_booking_settings_request, opts)
3088
+ data
2492
3089
  end
2493
3090
 
2494
- # Upsert Airbnb check-in guide
2495
- # Upsert the check-in guide for one locale on an Airbnb listing. **Write-side** calls Airbnb upstream; the DB mirror is reconciled by the sync worker once the upstream call returns. Target the locale with &#x60;?locale&#x3D;en&#x60; (defaults to &#x60;en&#x60;). Requires a connected Airbnb host, else &#x60;404 no_connection&#x60;. 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.
2496
- # @param id [String] Repull listing id (numeric string).
3091
+ # Update Airbnb booking settings
3092
+ # Set any subset of a listing&#39;s booking settings on Airbnb. Partial — a field you do not send is left as it is. &#x60;{id}&#x60; is the **Repull listing id** (from &#x60;GET /v1/properties&#x60; or &#x60;GET /v1/channels/airbnb/listings&#x60;), not the Airbnb listing id; Repull translates it before calling Airbnb. The body is validated before anything reaches Airbnb, so a bad value is a &#x60;422&#x60; naming the field rather than a failed upstream call. Unknown fields are refused rather than dropped. **Two groups, applied in order.** Instant Book, check-in/out and the cancellation fields go to Airbnb&#39;s booking-settings resource. Advance notice, preparation time and booking window go to Airbnb&#39;s availability rules — Airbnb replaces that whole document, so Repull reads the current rules first and merges your change onto them, which is why setting a preparation time does not blank the listing&#39;s min/max nights. The response&#39;s &#x60;applied&#x60; array names the groups that were written. **Non-refundable is a percentage here, a factor on Airbnb.** Airbnb stores &#x60;non_refundable_price_factor&#x60; between 0.7 and 1.0; send &#x60;cancellation.nonRefundable.discountPercent&#x60; (0-30) and Repull converts — 10% becomes 0.9. &#x60;enabled: false&#x60; sets the factor to 1.0. **Not exposed by Airbnb:** &#x60;preReservationMessage&#x60; and &#x60;automaticStayExtension&#x60;. Sending either returns a &#x60;422&#x60; explaining where to set it instead. **Errors:** &#x60;403 connection_reauth_required&#x60; — Airbnb no longer accepts the connection for this listing (reconnect; retrying won&#39;t help). &#x60;403 listing_inactive&#x60; the listing is inactive. &#x60;404 not_found&#x60; — no Airbnb-connected listing with this id in the workspace. &#x60;422 invalid_params&#x60; the body is wrong; &#x60;field&#x60; names it. &#x60;422 airbnb_rejected&#x60; — Airbnb refused the change; &#x60;message&#x60; carries its reason. &#x60;429 airbnb_rate_limited&#x60; — back off. &#x60;502 airbnb_error&#x60; — Airbnb outage or timeout; retry.
3093
+ # @param id [String] Repull listing id (numeric string), not the Airbnb listing id.
3094
+ # @param update_airbnb_booking_settings_request [UpdateAirbnbBookingSettingsRequest]
2497
3095
  # @param [Hash] opts the optional parameters
2498
- # @option opts [String] :locale Locale to upsert. Defaults to &#x60;en&#x60;. (default to 'en')
2499
- # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
2500
- def update_airbnb_checkin_guide_with_http_info(id, opts = {})
3096
+ # @return [Array<(UpdateAirbnbBookingSettings200Response, Integer, Hash)>] UpdateAirbnbBookingSettings200Response data, response status code and response headers
3097
+ def update_airbnb_booking_settings_with_http_info(id, update_airbnb_booking_settings_request, opts = {})
2501
3098
  if @api_client.config.debugging
2502
- @api_client.config.logger.debug 'Calling API: AirbnbApi.update_airbnb_checkin_guide ...'
3099
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.update_airbnb_booking_settings ...'
2503
3100
  end
2504
3101
  # verify the required parameter 'id' is set
2505
3102
  if @api_client.config.client_side_validation && id.nil?
2506
- fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.update_airbnb_checkin_guide"
3103
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.update_airbnb_booking_settings"
3104
+ end
3105
+ # verify the required parameter 'update_airbnb_booking_settings_request' is set
3106
+ if @api_client.config.client_side_validation && update_airbnb_booking_settings_request.nil?
3107
+ fail ArgumentError, "Missing the required parameter 'update_airbnb_booking_settings_request' when calling AirbnbApi.update_airbnb_booking_settings"
2507
3108
  end
2508
3109
  # resource path
2509
- local_var_path = '/v1/channels/airbnb/listings/{id}/checkin-guide'.sub('{id}', CGI.escape(id.to_s))
3110
+ local_var_path = '/v1/channels/airbnb/listings/{id}/booking-settings'.sub('{id}', CGI.escape(id.to_s))
2510
3111
 
2511
3112
  # query parameters
2512
3113
  query_params = opts[:query_params] || {}
2513
- query_params[:'locale'] = opts[:'locale'] if !opts[:'locale'].nil?
2514
3114
 
2515
3115
  # header parameters
2516
3116
  header_params = opts[:header_params] || {}
2517
3117
  # HTTP header 'Accept' (if needed)
2518
3118
  header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
3119
+ # HTTP header 'Content-Type'
3120
+ content_type = @api_client.select_header_content_type(['application/json'])
3121
+ if !content_type.nil?
3122
+ header_params['Content-Type'] = content_type
3123
+ end
2519
3124
 
2520
3125
  # form parameters
2521
3126
  form_params = opts[:form_params] || {}
2522
3127
 
2523
3128
  # http body (model)
2524
- post_body = opts[:debug_body]
3129
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(update_airbnb_booking_settings_request)
2525
3130
 
2526
3131
  # return_type
2527
- return_type = opts[:debug_return_type]
3132
+ return_type = opts[:debug_return_type] || 'UpdateAirbnbBookingSettings200Response'
2528
3133
 
2529
3134
  # auth_names
2530
3135
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
2531
3136
 
2532
3137
  new_options = opts.merge(
2533
- :operation => :"AirbnbApi.update_airbnb_checkin_guide",
3138
+ :operation => :"AirbnbApi.update_airbnb_booking_settings",
2534
3139
  :header_params => header_params,
2535
3140
  :query_params => query_params,
2536
3141
  :form_params => form_params,
@@ -2541,15 +3146,155 @@ module Repull
2541
3146
 
2542
3147
  data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
2543
3148
  if @api_client.config.debugging
2544
- @api_client.config.logger.debug "API called: AirbnbApi#update_airbnb_checkin_guide\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
3149
+ @api_client.config.logger.debug "API called: AirbnbApi#update_airbnb_booking_settings\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
2545
3150
  end
2546
3151
  return data, status_code, headers
2547
3152
  end
2548
3153
 
2549
- # Update Airbnb availability
2550
- # Push availability + restrictions to Airbnb. `type: \"calendar\"` writes per-date restrictions min/max nights, closed-to-arrival, closed-to-departure, and stop-sell (`availability: \"unavailable\"`) — via a batch of operations that each target either a date range or an explicit date list. `type: \"rules\"` writes listing-level availability rules (default min/max nights, booking lead time, turnover days, seasonal/day-of-week min nights). Restrictions never leak across channels — this endpoint writes only to Airbnb. `{id}` is the **Repull listing id** (from `GET /v1/properties` or `GET /v1/channels/airbnb/listings`), not the Airbnb listing id — Repull translates it before calling Airbnb. The body is validated before anything reaches Airbnb: a malformed body is `422 invalid_params` naming the `field`. Calendar operations accept only the documented fields. **Blocking dates:** Airbnb requires a `busy_subtype` whenever `availability` is `\"unavailable\"`. If an operation leaves it out, Repull sends `busy_subtype: \"BLOCKED_BY_HOST\"`; send `\"OUTSIDE_RESERVATION\"` for dates held by a booking made on another channel. **Errors:** `403 connection_reauth_required` — Airbnb no longer accepts the connection for this listing (reconnect; retrying won't help). `403 listing_inactive` the listing is inactive. `404 not_found` — no Airbnb-connected listing with this id in the workspace. `422 airbnb_rejected` Airbnb refused the change; `message` carries its reason. `429 airbnb_rate_limited` — back off. `502 airbnb_error` — Airbnb outage or timeout; retry.
2551
- # @param id [String]
2552
- # @param airbnb_availability_write_request [AirbnbAvailabilityWriteRequest]
3154
+ # Upsert Airbnb check-in guide
3155
+ # Upsert the check-in guide for one locale on an Airbnb listing. **Write-side** calls Airbnb upstream; the DB mirror is reconciled by the sync worker once the upstream call returns. Target the locale with `?locale=en` (defaults to `en`). Requires a connected Airbnb host, else `404 no_connection`. 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.
3156
+ # @param id [String] Repull listing id (numeric string).
3157
+ # @param [Hash] opts the optional parameters
3158
+ # @option opts [String] :locale Locale to upsert. Defaults to &#x60;en&#x60;. (default to 'en')
3159
+ # @return [nil]
3160
+ def update_airbnb_checkin_guide(id, opts = {})
3161
+ update_airbnb_checkin_guide_with_http_info(id, opts)
3162
+ nil
3163
+ end
3164
+
3165
+ # Upsert Airbnb check-in guide
3166
+ # Upsert the check-in guide for one locale on an Airbnb listing. **Write-side** — calls Airbnb upstream; the DB mirror is reconciled by the sync worker once the upstream call returns. Target the locale with &#x60;?locale&#x3D;en&#x60; (defaults to &#x60;en&#x60;). Requires a connected Airbnb host, else &#x60;404 no_connection&#x60;. 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.
3167
+ # @param id [String] Repull listing id (numeric string).
3168
+ # @param [Hash] opts the optional parameters
3169
+ # @option opts [String] :locale Locale to upsert. Defaults to &#x60;en&#x60;. (default to 'en')
3170
+ # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
3171
+ def update_airbnb_checkin_guide_with_http_info(id, opts = {})
3172
+ if @api_client.config.debugging
3173
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.update_airbnb_checkin_guide ...'
3174
+ end
3175
+ # verify the required parameter 'id' is set
3176
+ if @api_client.config.client_side_validation && id.nil?
3177
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.update_airbnb_checkin_guide"
3178
+ end
3179
+ # resource path
3180
+ local_var_path = '/v1/channels/airbnb/listings/{id}/checkin-guide'.sub('{id}', CGI.escape(id.to_s))
3181
+
3182
+ # query parameters
3183
+ query_params = opts[:query_params] || {}
3184
+ query_params[:'locale'] = opts[:'locale'] if !opts[:'locale'].nil?
3185
+
3186
+ # header parameters
3187
+ header_params = opts[:header_params] || {}
3188
+ # HTTP header 'Accept' (if needed)
3189
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
3190
+
3191
+ # form parameters
3192
+ form_params = opts[:form_params] || {}
3193
+
3194
+ # http body (model)
3195
+ post_body = opts[:debug_body]
3196
+
3197
+ # return_type
3198
+ return_type = opts[:debug_return_type]
3199
+
3200
+ # auth_names
3201
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
3202
+
3203
+ new_options = opts.merge(
3204
+ :operation => :"AirbnbApi.update_airbnb_checkin_guide",
3205
+ :header_params => header_params,
3206
+ :query_params => query_params,
3207
+ :form_params => form_params,
3208
+ :body => post_body,
3209
+ :auth_names => auth_names,
3210
+ :return_type => return_type
3211
+ )
3212
+
3213
+ data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
3214
+ if @api_client.config.debugging
3215
+ @api_client.config.logger.debug "API called: AirbnbApi#update_airbnb_checkin_guide\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
3216
+ end
3217
+ return data, status_code, headers
3218
+ end
3219
+
3220
+ # Update Airbnb amenities
3221
+ # Set amenities on an Airbnb listing. **Write-side** — calls Airbnb upstream. **Partial by design**: only the amenities you name change, so turning one off is a one-line body and nothing else on the listing moves. Ids are the `id` values `GET /amenities` returns (e.g. `wireless_internet`, `ac`, `kitchen`); case is ignored. Airbnb refuses ids outside its vocabulary — that comes back as `422 airbnb_rejected` carrying Airbnb's own message. `accessibility_amenities` go to Airbnb's separate accessibility resource, which has **no read side at all** — Airbnb offers no endpoint to fetch them back, and the combined amenities GET 404s on production listings. What you can read back is our own copy: this endpoint updates it on success, and `GET /amenities` returns it under `accessibilityAmenities`. Airbnb may also hold an accessibility claim for review until photo evidence is attached; pass `photo_ids` to supply it. Our Airbnb copy is updated on success so a read straight after this write returns the new values. The platform-neutral copy behind `GET /v1/listings/{id}?include=amenities` uses a different amenity vocabulary and is refreshed by the next sync, except where an id happens to be identical in both. 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.
3222
+ # @param id [String] Repull listing id (numeric string).
3223
+ # @param update_airbnb_listing_amenities_request [UpdateAirbnbListingAmenitiesRequest]
3224
+ # @param [Hash] opts the optional parameters
3225
+ # @return [UpdateAirbnbListingAmenities200Response]
3226
+ def update_airbnb_listing_amenities(id, update_airbnb_listing_amenities_request, opts = {})
3227
+ data, _status_code, _headers = update_airbnb_listing_amenities_with_http_info(id, update_airbnb_listing_amenities_request, opts)
3228
+ data
3229
+ end
3230
+
3231
+ # Update Airbnb amenities
3232
+ # Set amenities on an Airbnb listing. **Write-side** — calls Airbnb upstream. **Partial by design**: only the amenities you name change, so turning one off is a one-line body and nothing else on the listing moves. Ids are the &#x60;id&#x60; values &#x60;GET /amenities&#x60; returns (e.g. &#x60;wireless_internet&#x60;, &#x60;ac&#x60;, &#x60;kitchen&#x60;); case is ignored. Airbnb refuses ids outside its vocabulary — that comes back as &#x60;422 airbnb_rejected&#x60; carrying Airbnb&#39;s own message. &#x60;accessibility_amenities&#x60; go to Airbnb&#39;s separate accessibility resource, which has **no read side at all** — Airbnb offers no endpoint to fetch them back, and the combined amenities GET 404s on production listings. What you can read back is our own copy: this endpoint updates it on success, and &#x60;GET /amenities&#x60; returns it under &#x60;accessibilityAmenities&#x60;. Airbnb may also hold an accessibility claim for review until photo evidence is attached; pass &#x60;photo_ids&#x60; to supply it. Our Airbnb copy is updated on success so a read straight after this write returns the new values. The platform-neutral copy behind &#x60;GET /v1/listings/{id}?include&#x3D;amenities&#x60; uses a different amenity vocabulary and is refreshed by the next sync, except where an id happens to be identical in both. 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.
3233
+ # @param id [String] Repull listing id (numeric string).
3234
+ # @param update_airbnb_listing_amenities_request [UpdateAirbnbListingAmenitiesRequest]
3235
+ # @param [Hash] opts the optional parameters
3236
+ # @return [Array<(UpdateAirbnbListingAmenities200Response, Integer, Hash)>] UpdateAirbnbListingAmenities200Response data, response status code and response headers
3237
+ def update_airbnb_listing_amenities_with_http_info(id, update_airbnb_listing_amenities_request, opts = {})
3238
+ if @api_client.config.debugging
3239
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.update_airbnb_listing_amenities ...'
3240
+ end
3241
+ # verify the required parameter 'id' is set
3242
+ if @api_client.config.client_side_validation && id.nil?
3243
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.update_airbnb_listing_amenities"
3244
+ end
3245
+ # verify the required parameter 'update_airbnb_listing_amenities_request' is set
3246
+ if @api_client.config.client_side_validation && update_airbnb_listing_amenities_request.nil?
3247
+ fail ArgumentError, "Missing the required parameter 'update_airbnb_listing_amenities_request' when calling AirbnbApi.update_airbnb_listing_amenities"
3248
+ end
3249
+ # resource path
3250
+ local_var_path = '/v1/channels/airbnb/listings/{id}/amenities'.sub('{id}', CGI.escape(id.to_s))
3251
+
3252
+ # query parameters
3253
+ query_params = opts[:query_params] || {}
3254
+
3255
+ # header parameters
3256
+ header_params = opts[:header_params] || {}
3257
+ # HTTP header 'Accept' (if needed)
3258
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
3259
+ # HTTP header 'Content-Type'
3260
+ content_type = @api_client.select_header_content_type(['application/json'])
3261
+ if !content_type.nil?
3262
+ header_params['Content-Type'] = content_type
3263
+ end
3264
+
3265
+ # form parameters
3266
+ form_params = opts[:form_params] || {}
3267
+
3268
+ # http body (model)
3269
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(update_airbnb_listing_amenities_request)
3270
+
3271
+ # return_type
3272
+ return_type = opts[:debug_return_type] || 'UpdateAirbnbListingAmenities200Response'
3273
+
3274
+ # auth_names
3275
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
3276
+
3277
+ new_options = opts.merge(
3278
+ :operation => :"AirbnbApi.update_airbnb_listing_amenities",
3279
+ :header_params => header_params,
3280
+ :query_params => query_params,
3281
+ :form_params => form_params,
3282
+ :body => post_body,
3283
+ :auth_names => auth_names,
3284
+ :return_type => return_type
3285
+ )
3286
+
3287
+ data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
3288
+ if @api_client.config.debugging
3289
+ @api_client.config.logger.debug "API called: AirbnbApi#update_airbnb_listing_amenities\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
3290
+ end
3291
+ return data, status_code, headers
3292
+ end
3293
+
3294
+ # Update Airbnb availability
3295
+ # Push availability + restrictions to Airbnb. `type: \"calendar\"` writes per-date restrictions — min/max nights, closed-to-arrival, closed-to-departure, and stop-sell (`availability: \"unavailable\"`) — via a batch of operations that each target either a date range or an explicit date list. `type: \"rules\"` writes listing-level availability rules (default min/max nights, booking lead time, turnover days, seasonal/day-of-week min nights). Restrictions never leak across channels — this endpoint writes only to Airbnb. `{id}` is the **Repull listing id** (from `GET /v1/properties` or `GET /v1/channels/airbnb/listings`), not the Airbnb listing id — Repull translates it before calling Airbnb. The body is validated before anything reaches Airbnb: a malformed body is `422 invalid_params` naming the `field`. Calendar operations accept only the documented fields. **Blocking dates:** Airbnb requires a `busy_subtype` whenever `availability` is `\"unavailable\"`. If an operation leaves it out, Repull sends `busy_subtype: \"BLOCKED_BY_HOST\"`; send `\"OUTSIDE_RESERVATION\"` for dates held by a booking made on another channel. **Errors:** `403 listing_not_api_connected` — Airbnb was never told to sync this listing (its `syncCategory` is `none`); the host must switch API sync on for it in Airbnb, reconnecting the account will not help. `403 connection_reauth_required` — Airbnb no longer accepts the connection at all (reconnect; retrying won't help). `403 listing_inactive` — the listing is inactive. `404 not_found` — no Airbnb-connected listing with this id in the workspace. `422 airbnb_rejected` — Airbnb refused the change; `message` carries its reason. `429 airbnb_rate_limited` — back off. `502 airbnb_error` — Airbnb outage or timeout; retry.
3296
+ # @param id [String]
3297
+ # @param airbnb_availability_write_request [AirbnbAvailabilityWriteRequest]
2553
3298
  # @param [Hash] opts the optional parameters
2554
3299
  # @return [nil]
2555
3300
  def update_airbnb_listing_availability(id, airbnb_availability_write_request, opts = {})
@@ -2558,7 +3303,7 @@ module Repull
2558
3303
  end
2559
3304
 
2560
3305
  # Update Airbnb availability
2561
- # Push availability + restrictions to Airbnb. &#x60;type: \&quot;calendar\&quot;&#x60; writes per-date restrictions — min/max nights, closed-to-arrival, closed-to-departure, and stop-sell (&#x60;availability: \&quot;unavailable\&quot;&#x60;) — via a batch of operations that each target either a date range or an explicit date list. &#x60;type: \&quot;rules\&quot;&#x60; writes listing-level availability rules (default min/max nights, booking lead time, turnover days, seasonal/day-of-week min nights). Restrictions never leak across channels — this endpoint writes only to Airbnb. &#x60;{id}&#x60; is the **Repull listing id** (from &#x60;GET /v1/properties&#x60; or &#x60;GET /v1/channels/airbnb/listings&#x60;), not the Airbnb listing id — Repull translates it before calling Airbnb. The body is validated before anything reaches Airbnb: a malformed body is &#x60;422 invalid_params&#x60; naming the &#x60;field&#x60;. Calendar operations accept only the documented fields. **Blocking dates:** Airbnb requires a &#x60;busy_subtype&#x60; whenever &#x60;availability&#x60; is &#x60;\&quot;unavailable\&quot;&#x60;. If an operation leaves it out, Repull sends &#x60;busy_subtype: \&quot;BLOCKED_BY_HOST\&quot;&#x60;; send &#x60;\&quot;OUTSIDE_RESERVATION\&quot;&#x60; for dates held by a booking made on another channel. **Errors:** &#x60;403 connection_reauth_required&#x60; — Airbnb no longer accepts the connection for this listing (reconnect; retrying won&#39;t help). &#x60;403 listing_inactive&#x60; — the listing is inactive. &#x60;404 not_found&#x60; — no Airbnb-connected listing with this id in the workspace. &#x60;422 airbnb_rejected&#x60; — Airbnb refused the change; &#x60;message&#x60; carries its reason. &#x60;429 airbnb_rate_limited&#x60; — back off. &#x60;502 airbnb_error&#x60; — Airbnb outage or timeout; retry.
3306
+ # Push availability + restrictions to Airbnb. &#x60;type: \&quot;calendar\&quot;&#x60; writes per-date restrictions — min/max nights, closed-to-arrival, closed-to-departure, and stop-sell (&#x60;availability: \&quot;unavailable\&quot;&#x60;) — via a batch of operations that each target either a date range or an explicit date list. &#x60;type: \&quot;rules\&quot;&#x60; writes listing-level availability rules (default min/max nights, booking lead time, turnover days, seasonal/day-of-week min nights). Restrictions never leak across channels — this endpoint writes only to Airbnb. &#x60;{id}&#x60; is the **Repull listing id** (from &#x60;GET /v1/properties&#x60; or &#x60;GET /v1/channels/airbnb/listings&#x60;), not the Airbnb listing id — Repull translates it before calling Airbnb. The body is validated before anything reaches Airbnb: a malformed body is &#x60;422 invalid_params&#x60; naming the &#x60;field&#x60;. Calendar operations accept only the documented fields. **Blocking dates:** Airbnb requires a &#x60;busy_subtype&#x60; whenever &#x60;availability&#x60; is &#x60;\&quot;unavailable\&quot;&#x60;. If an operation leaves it out, Repull sends &#x60;busy_subtype: \&quot;BLOCKED_BY_HOST\&quot;&#x60;; send &#x60;\&quot;OUTSIDE_RESERVATION\&quot;&#x60; for dates held by a booking made on another channel. **Errors:** &#x60;403 listing_not_api_connected&#x60; — Airbnb was never told to sync this listing (its &#x60;syncCategory&#x60; is &#x60;none&#x60;); the host must switch API sync on for it in Airbnb, reconnecting the account will not help. &#x60;403 connection_reauth_required&#x60; — Airbnb no longer accepts the connection at all (reconnect; retrying won&#39;t help). &#x60;403 listing_inactive&#x60; — the listing is inactive. &#x60;404 not_found&#x60; — no Airbnb-connected listing with this id in the workspace. &#x60;422 airbnb_rejected&#x60; — Airbnb refused the change; &#x60;message&#x60; carries its reason. &#x60;429 airbnb_rate_limited&#x60; — back off. &#x60;502 airbnb_error&#x60; — Airbnb outage or timeout; retry.
2562
3307
  # @param id [String]
2563
3308
  # @param airbnb_availability_write_request [AirbnbAvailabilityWriteRequest]
2564
3309
  # @param [Hash] opts the optional parameters
@@ -2620,8 +3365,325 @@ module Repull
2620
3365
  return data, status_code, headers
2621
3366
  end
2622
3367
 
3368
+ # Update an Airbnb description for one locale
3369
+ # Write one locale's copy to the live Airbnb listing. Airbnb keeps a SEPARATE description per locale (`PUT /v2/listing_descriptions/{listingId}/{locale}`), which is why `locale` is part of the request and not a guess: a listing can carry twelve of them, and writing Italian copy into the English row is how a translation gets lost. Only the fields you send are written; Airbnb keeps the rest. `GET /v1/channels/airbnb/listings/{id}/settings?type=locales` lists the locales already synced for the listing. `description` is not an accepted field: Airbnb composes the public description from the sections (`summary`, `space`, `access`, …) and ignores a directly-supplied one. **A 200 does not by itself mean the change was applied.** On an established listing Airbnb LOCKS host-managed description fields — the write returns 200, reports them as locked, and applies nothing for them. The response reports `blockedFields`: the fields YOU sent that Airbnb dropped. `blockedFields: []` is what a landed write looks like; a non-empty list is still a 200 (the other fields really were written) with a `message` naming what was not. Reporting that as a clean success is the bug behind \"the description does not push to Airbnb\". This writes to AIRBNB. To write Repull's own canonical copy — the content a later publish distributes — use `PUT /v1/listings/{id}/content` with `locale`. Send `Idempotency-Key` to make a retry safe. Returns `403 listing_inactive` when the listing is inactive.
3370
+ # @param id [String] Repull listing id (numeric string).
3371
+ # @param airbnb_description_write_request [AirbnbDescriptionWriteRequest]
3372
+ # @param [Hash] opts the optional parameters
3373
+ # @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.
3374
+ # @return [AirbnbContentWriteResponse]
3375
+ def update_airbnb_listing_description(id, airbnb_description_write_request, opts = {})
3376
+ data, _status_code, _headers = update_airbnb_listing_description_with_http_info(id, airbnb_description_write_request, opts)
3377
+ data
3378
+ end
3379
+
3380
+ # Update an Airbnb description for one locale
3381
+ # Write one locale&#39;s copy to the live Airbnb listing. Airbnb keeps a SEPARATE description per locale (&#x60;PUT /v2/listing_descriptions/{listingId}/{locale}&#x60;), which is why &#x60;locale&#x60; is part of the request and not a guess: a listing can carry twelve of them, and writing Italian copy into the English row is how a translation gets lost. Only the fields you send are written; Airbnb keeps the rest. &#x60;GET /v1/channels/airbnb/listings/{id}/settings?type&#x3D;locales&#x60; lists the locales already synced for the listing. &#x60;description&#x60; is not an accepted field: Airbnb composes the public description from the sections (&#x60;summary&#x60;, &#x60;space&#x60;, &#x60;access&#x60;, …) and ignores a directly-supplied one. **A 200 does not by itself mean the change was applied.** On an established listing Airbnb LOCKS host-managed description fields — the write returns 200, reports them as locked, and applies nothing for them. The response reports &#x60;blockedFields&#x60;: the fields YOU sent that Airbnb dropped. &#x60;blockedFields: []&#x60; is what a landed write looks like; a non-empty list is still a 200 (the other fields really were written) with a &#x60;message&#x60; naming what was not. Reporting that as a clean success is the bug behind \&quot;the description does not push to Airbnb\&quot;. This writes to AIRBNB. To write Repull&#39;s own canonical copy — the content a later publish distributes — use &#x60;PUT /v1/listings/{id}/content&#x60; with &#x60;locale&#x60;. Send &#x60;Idempotency-Key&#x60; to make a retry safe. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive.
3382
+ # @param id [String] Repull listing id (numeric string).
3383
+ # @param airbnb_description_write_request [AirbnbDescriptionWriteRequest]
3384
+ # @param [Hash] opts the optional parameters
3385
+ # @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.
3386
+ # @return [Array<(AirbnbContentWriteResponse, Integer, Hash)>] AirbnbContentWriteResponse data, response status code and response headers
3387
+ def update_airbnb_listing_description_with_http_info(id, airbnb_description_write_request, opts = {})
3388
+ if @api_client.config.debugging
3389
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.update_airbnb_listing_description ...'
3390
+ end
3391
+ # verify the required parameter 'id' is set
3392
+ if @api_client.config.client_side_validation && id.nil?
3393
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.update_airbnb_listing_description"
3394
+ end
3395
+ # verify the required parameter 'airbnb_description_write_request' is set
3396
+ if @api_client.config.client_side_validation && airbnb_description_write_request.nil?
3397
+ fail ArgumentError, "Missing the required parameter 'airbnb_description_write_request' when calling AirbnbApi.update_airbnb_listing_description"
3398
+ end
3399
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
3400
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling AirbnbApi.update_airbnb_listing_description, the character length must be smaller than or equal to 255.'
3401
+ end
3402
+
3403
+ # resource path
3404
+ local_var_path = '/v1/channels/airbnb/listings/{id}/descriptions'.sub('{id}', CGI.escape(id.to_s))
3405
+
3406
+ # query parameters
3407
+ query_params = opts[:query_params] || {}
3408
+
3409
+ # header parameters
3410
+ header_params = opts[:header_params] || {}
3411
+ # HTTP header 'Accept' (if needed)
3412
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
3413
+ # HTTP header 'Content-Type'
3414
+ content_type = @api_client.select_header_content_type(['application/json'])
3415
+ if !content_type.nil?
3416
+ header_params['Content-Type'] = content_type
3417
+ end
3418
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
3419
+
3420
+ # form parameters
3421
+ form_params = opts[:form_params] || {}
3422
+
3423
+ # http body (model)
3424
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(airbnb_description_write_request)
3425
+
3426
+ # return_type
3427
+ return_type = opts[:debug_return_type] || 'AirbnbContentWriteResponse'
3428
+
3429
+ # auth_names
3430
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
3431
+
3432
+ new_options = opts.merge(
3433
+ :operation => :"AirbnbApi.update_airbnb_listing_description",
3434
+ :header_params => header_params,
3435
+ :query_params => query_params,
3436
+ :form_params => form_params,
3437
+ :body => post_body,
3438
+ :auth_names => auth_names,
3439
+ :return_type => return_type
3440
+ )
3441
+
3442
+ data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
3443
+ if @api_client.config.debugging
3444
+ @api_client.config.logger.debug "API called: AirbnbApi#update_airbnb_listing_description\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
3445
+ end
3446
+ return data, status_code, headers
3447
+ end
3448
+
3449
+ # Update property type, room type, quiet hours or check-in method
3450
+ # Change what kind of property the Airbnb listing is, when its quiet hours are, or how the guest gets in. Partial: only the fields you send are written. At least one required; an unknown field is refused by name rather than dropped. This is the UPDATE path for fields that previously had none. `POST /v1/listings` accepts a `propertyType` when a listing is CREATED and nothing could change it afterwards, so a listing mis-typed at import stayed mis-typed; the check-in method was mirrored and never exposed at all. **A 200 does not by itself mean the change was applied.** `property_type_category`, `property_type_group` and `check_in_option` are among the attributes Airbnb locks on established listings: the write returns 200, and Airbnb applies nothing for the locked ones. The response reports `blockedFields` — the fields YOU sent that Airbnb dropped — and `blockedFields: []` is what a landed write looks like. `GET …/details` reports the same list as `lockedFields` so you can check first. Canonical property type (the value Repull keeps and republishes) is set with `PUT /v1/listings/{id}/content` under `details`; this endpoint writes straight to Airbnb. Send `Idempotency-Key` to make a retry safe.
3451
+ # @param id [String] Repull listing id (numeric string).
3452
+ # @param airbnb_listing_details_write_request [AirbnbListingDetailsWriteRequest]
3453
+ # @param [Hash] opts the optional parameters
3454
+ # @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.
3455
+ # @return [AirbnbContentWriteResponse]
3456
+ def update_airbnb_listing_details(id, airbnb_listing_details_write_request, opts = {})
3457
+ data, _status_code, _headers = update_airbnb_listing_details_with_http_info(id, airbnb_listing_details_write_request, opts)
3458
+ data
3459
+ end
3460
+
3461
+ # Update property type, room type, quiet hours or check-in method
3462
+ # Change what kind of property the Airbnb listing is, when its quiet hours are, or how the guest gets in. Partial: only the fields you send are written. At least one required; an unknown field is refused by name rather than dropped. This is the UPDATE path for fields that previously had none. &#x60;POST /v1/listings&#x60; accepts a &#x60;propertyType&#x60; when a listing is CREATED and nothing could change it afterwards, so a listing mis-typed at import stayed mis-typed; the check-in method was mirrored and never exposed at all. **A 200 does not by itself mean the change was applied.** &#x60;property_type_category&#x60;, &#x60;property_type_group&#x60; and &#x60;check_in_option&#x60; are among the attributes Airbnb locks on established listings: the write returns 200, and Airbnb applies nothing for the locked ones. The response reports &#x60;blockedFields&#x60; — the fields YOU sent that Airbnb dropped — and &#x60;blockedFields: []&#x60; is what a landed write looks like. &#x60;GET …/details&#x60; reports the same list as &#x60;lockedFields&#x60; so you can check first. Canonical property type (the value Repull keeps and republishes) is set with &#x60;PUT /v1/listings/{id}/content&#x60; under &#x60;details&#x60;; this endpoint writes straight to Airbnb. Send &#x60;Idempotency-Key&#x60; to make a retry safe.
3463
+ # @param id [String] Repull listing id (numeric string).
3464
+ # @param airbnb_listing_details_write_request [AirbnbListingDetailsWriteRequest]
3465
+ # @param [Hash] opts the optional parameters
3466
+ # @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.
3467
+ # @return [Array<(AirbnbContentWriteResponse, Integer, Hash)>] AirbnbContentWriteResponse data, response status code and response headers
3468
+ def update_airbnb_listing_details_with_http_info(id, airbnb_listing_details_write_request, opts = {})
3469
+ if @api_client.config.debugging
3470
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.update_airbnb_listing_details ...'
3471
+ end
3472
+ # verify the required parameter 'id' is set
3473
+ if @api_client.config.client_side_validation && id.nil?
3474
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.update_airbnb_listing_details"
3475
+ end
3476
+ # verify the required parameter 'airbnb_listing_details_write_request' is set
3477
+ if @api_client.config.client_side_validation && airbnb_listing_details_write_request.nil?
3478
+ fail ArgumentError, "Missing the required parameter 'airbnb_listing_details_write_request' when calling AirbnbApi.update_airbnb_listing_details"
3479
+ end
3480
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
3481
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling AirbnbApi.update_airbnb_listing_details, the character length must be smaller than or equal to 255.'
3482
+ end
3483
+
3484
+ # resource path
3485
+ local_var_path = '/v1/channels/airbnb/listings/{id}/details'.sub('{id}', CGI.escape(id.to_s))
3486
+
3487
+ # query parameters
3488
+ query_params = opts[:query_params] || {}
3489
+
3490
+ # header parameters
3491
+ header_params = opts[:header_params] || {}
3492
+ # HTTP header 'Accept' (if needed)
3493
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
3494
+ # HTTP header 'Content-Type'
3495
+ content_type = @api_client.select_header_content_type(['application/json'])
3496
+ if !content_type.nil?
3497
+ header_params['Content-Type'] = content_type
3498
+ end
3499
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
3500
+
3501
+ # form parameters
3502
+ form_params = opts[:form_params] || {}
3503
+
3504
+ # http body (model)
3505
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(airbnb_listing_details_write_request)
3506
+
3507
+ # return_type
3508
+ return_type = opts[:debug_return_type] || 'AirbnbContentWriteResponse'
3509
+
3510
+ # auth_names
3511
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
3512
+
3513
+ new_options = opts.merge(
3514
+ :operation => :"AirbnbApi.update_airbnb_listing_details",
3515
+ :header_params => header_params,
3516
+ :query_params => query_params,
3517
+ :form_params => form_params,
3518
+ :body => post_body,
3519
+ :auth_names => auth_names,
3520
+ :return_type => return_type
3521
+ )
3522
+
3523
+ data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
3524
+ if @api_client.config.debugging
3525
+ @api_client.config.logger.debug "API called: AirbnbApi#update_airbnb_listing_details\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
3526
+ end
3527
+ return data, status_code, headers
3528
+ end
3529
+
3530
+ # Answer Airbnb permit questions
3531
+ # Answer the regulatory permit questions for a listing — the licence or registration number a city requires to keep the listing up. Read the questions first with `GET …/permits?source=live`: every answer is keyed by a `question_key` Airbnb asks for THIS listing, and the question's `answer_type` decides which value field applies (`text_value`, `date_value`, or `selected_options_value`). Answers are forwarded verbatim — nothing is defaulted or inferred, because a wrong licence number can take a listing down in a regulated city. Send `Idempotency-Key`: a timeout here leaves you unable to tell \"never arrived\" from \"arrived, response lost\", and this is a compliance filing. Airbnb refusing the answers (an unknown question key, a malformed licence number) is `422 airbnb_rejected` carrying Airbnb's own reason. An expired or revoked Airbnb connection is `403 connection_reauth_required`.
3532
+ # @param id [String] Repull listing id (numeric string).
3533
+ # @param airbnb_permits_write_request [AirbnbPermitsWriteRequest]
3534
+ # @param [Hash] opts the optional parameters
3535
+ # @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.
3536
+ # @return [UpdateAirbnbListingPermits200Response]
3537
+ def update_airbnb_listing_permits(id, airbnb_permits_write_request, opts = {})
3538
+ data, _status_code, _headers = update_airbnb_listing_permits_with_http_info(id, airbnb_permits_write_request, opts)
3539
+ data
3540
+ end
3541
+
3542
+ # Answer Airbnb permit questions
3543
+ # Answer the regulatory permit questions for a listing — the licence or registration number a city requires to keep the listing up. Read the questions first with &#x60;GET …/permits?source&#x3D;live&#x60;: every answer is keyed by a &#x60;question_key&#x60; Airbnb asks for THIS listing, and the question&#39;s &#x60;answer_type&#x60; decides which value field applies (&#x60;text_value&#x60;, &#x60;date_value&#x60;, or &#x60;selected_options_value&#x60;). Answers are forwarded verbatim — nothing is defaulted or inferred, because a wrong licence number can take a listing down in a regulated city. Send &#x60;Idempotency-Key&#x60;: a timeout here leaves you unable to tell \&quot;never arrived\&quot; from \&quot;arrived, response lost\&quot;, and this is a compliance filing. Airbnb refusing the answers (an unknown question key, a malformed licence number) is &#x60;422 airbnb_rejected&#x60; carrying Airbnb&#39;s own reason. An expired or revoked Airbnb connection is &#x60;403 connection_reauth_required&#x60;.
3544
+ # @param id [String] Repull listing id (numeric string).
3545
+ # @param airbnb_permits_write_request [AirbnbPermitsWriteRequest]
3546
+ # @param [Hash] opts the optional parameters
3547
+ # @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.
3548
+ # @return [Array<(UpdateAirbnbListingPermits200Response, Integer, Hash)>] UpdateAirbnbListingPermits200Response data, response status code and response headers
3549
+ def update_airbnb_listing_permits_with_http_info(id, airbnb_permits_write_request, opts = {})
3550
+ if @api_client.config.debugging
3551
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.update_airbnb_listing_permits ...'
3552
+ end
3553
+ # verify the required parameter 'id' is set
3554
+ if @api_client.config.client_side_validation && id.nil?
3555
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.update_airbnb_listing_permits"
3556
+ end
3557
+ # verify the required parameter 'airbnb_permits_write_request' is set
3558
+ if @api_client.config.client_side_validation && airbnb_permits_write_request.nil?
3559
+ fail ArgumentError, "Missing the required parameter 'airbnb_permits_write_request' when calling AirbnbApi.update_airbnb_listing_permits"
3560
+ end
3561
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
3562
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling AirbnbApi.update_airbnb_listing_permits, the character length must be smaller than or equal to 255.'
3563
+ end
3564
+
3565
+ # resource path
3566
+ local_var_path = '/v1/channels/airbnb/listings/{id}/permits'.sub('{id}', CGI.escape(id.to_s))
3567
+
3568
+ # query parameters
3569
+ query_params = opts[:query_params] || {}
3570
+
3571
+ # header parameters
3572
+ header_params = opts[:header_params] || {}
3573
+ # HTTP header 'Accept' (if needed)
3574
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
3575
+ # HTTP header 'Content-Type'
3576
+ content_type = @api_client.select_header_content_type(['application/json'])
3577
+ if !content_type.nil?
3578
+ header_params['Content-Type'] = content_type
3579
+ end
3580
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
3581
+
3582
+ # form parameters
3583
+ form_params = opts[:form_params] || {}
3584
+
3585
+ # http body (model)
3586
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(airbnb_permits_write_request)
3587
+
3588
+ # return_type
3589
+ return_type = opts[:debug_return_type] || 'UpdateAirbnbListingPermits200Response'
3590
+
3591
+ # auth_names
3592
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
3593
+
3594
+ new_options = opts.merge(
3595
+ :operation => :"AirbnbApi.update_airbnb_listing_permits",
3596
+ :header_params => header_params,
3597
+ :query_params => query_params,
3598
+ :form_params => form_params,
3599
+ :body => post_body,
3600
+ :auth_names => auth_names,
3601
+ :return_type => return_type
3602
+ )
3603
+
3604
+ data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
3605
+ if @api_client.config.debugging
3606
+ @api_client.config.logger.debug "API called: AirbnbApi#update_airbnb_listing_permits\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
3607
+ end
3608
+ return data, status_code, headers
3609
+ end
3610
+
3611
+ # Update an Airbnb photo
3612
+ # Change one photo's caption, its position in the tour, the room it is filed under, or its metadata. **Write-side** — calls Airbnb upstream. Airbnb's photo endpoints are keyed by photo id alone, so the photo is proven to belong to the listing named in the path before anything is sent; a photo from another listing returns `404`, the same answer a photo that does not exist gets. On success both stored copies are updated — the Airbnb mirror `GET /photos` serves AND the canonical photo tour behind `GET /v1/listings/{id}` — so a read straight after this write returns the new value instead of waiting for the next sync. `stored` says whether that succeeded; `false` means Airbnb accepted the change but our copy will only catch up at the next sync. To move several photos at once use `PUT /photos/order`: it is one call instead of N, it validates the whole order before writing anything, and it reports exactly what landed if Airbnb refuses part-way. 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.
3613
+ # @param id [String] Repull listing id (numeric string).
3614
+ # @param update_airbnb_listing_photo_request [UpdateAirbnbListingPhotoRequest]
3615
+ # @param [Hash] opts the optional parameters
3616
+ # @return [UpdateAirbnbListingPhoto200Response]
3617
+ def update_airbnb_listing_photo(id, update_airbnb_listing_photo_request, opts = {})
3618
+ data, _status_code, _headers = update_airbnb_listing_photo_with_http_info(id, update_airbnb_listing_photo_request, opts)
3619
+ data
3620
+ end
3621
+
3622
+ # Update an Airbnb photo
3623
+ # Change one photo&#39;s caption, its position in the tour, the room it is filed under, or its metadata. **Write-side** — calls Airbnb upstream. Airbnb&#39;s photo endpoints are keyed by photo id alone, so the photo is proven to belong to the listing named in the path before anything is sent; a photo from another listing returns &#x60;404&#x60;, the same answer a photo that does not exist gets. On success both stored copies are updated — the Airbnb mirror &#x60;GET /photos&#x60; serves AND the canonical photo tour behind &#x60;GET /v1/listings/{id}&#x60; — so a read straight after this write returns the new value instead of waiting for the next sync. &#x60;stored&#x60; says whether that succeeded; &#x60;false&#x60; means Airbnb accepted the change but our copy will only catch up at the next sync. To move several photos at once use &#x60;PUT /photos/order&#x60;: it is one call instead of N, it validates the whole order before writing anything, and it reports exactly what landed if Airbnb refuses part-way. 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.
3624
+ # @param id [String] Repull listing id (numeric string).
3625
+ # @param update_airbnb_listing_photo_request [UpdateAirbnbListingPhotoRequest]
3626
+ # @param [Hash] opts the optional parameters
3627
+ # @return [Array<(UpdateAirbnbListingPhoto200Response, Integer, Hash)>] UpdateAirbnbListingPhoto200Response data, response status code and response headers
3628
+ def update_airbnb_listing_photo_with_http_info(id, update_airbnb_listing_photo_request, opts = {})
3629
+ if @api_client.config.debugging
3630
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.update_airbnb_listing_photo ...'
3631
+ end
3632
+ # verify the required parameter 'id' is set
3633
+ if @api_client.config.client_side_validation && id.nil?
3634
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.update_airbnb_listing_photo"
3635
+ end
3636
+ # verify the required parameter 'update_airbnb_listing_photo_request' is set
3637
+ if @api_client.config.client_side_validation && update_airbnb_listing_photo_request.nil?
3638
+ fail ArgumentError, "Missing the required parameter 'update_airbnb_listing_photo_request' when calling AirbnbApi.update_airbnb_listing_photo"
3639
+ end
3640
+ # resource path
3641
+ local_var_path = '/v1/channels/airbnb/listings/{id}/photos'.sub('{id}', CGI.escape(id.to_s))
3642
+
3643
+ # query parameters
3644
+ query_params = opts[:query_params] || {}
3645
+
3646
+ # header parameters
3647
+ header_params = opts[:header_params] || {}
3648
+ # HTTP header 'Accept' (if needed)
3649
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
3650
+ # HTTP header 'Content-Type'
3651
+ content_type = @api_client.select_header_content_type(['application/json'])
3652
+ if !content_type.nil?
3653
+ header_params['Content-Type'] = content_type
3654
+ end
3655
+
3656
+ # form parameters
3657
+ form_params = opts[:form_params] || {}
3658
+
3659
+ # http body (model)
3660
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(update_airbnb_listing_photo_request)
3661
+
3662
+ # return_type
3663
+ return_type = opts[:debug_return_type] || 'UpdateAirbnbListingPhoto200Response'
3664
+
3665
+ # auth_names
3666
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
3667
+
3668
+ new_options = opts.merge(
3669
+ :operation => :"AirbnbApi.update_airbnb_listing_photo",
3670
+ :header_params => header_params,
3671
+ :query_params => query_params,
3672
+ :form_params => form_params,
3673
+ :body => post_body,
3674
+ :auth_names => auth_names,
3675
+ :return_type => return_type
3676
+ )
3677
+
3678
+ data, status_code, headers = @api_client.call_api(:PATCH, local_var_path, new_options)
3679
+ if @api_client.config.debugging
3680
+ @api_client.config.logger.debug "API called: AirbnbApi#update_airbnb_listing_photo\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
3681
+ end
3682
+ return data, status_code, headers
3683
+ end
3684
+
2623
3685
  # Update Airbnb pricing
2624
- # Push pricing changes to Airbnb. The `type` discriminator selects the sub-resource (model, standard settings, LOS, rate-plan, fees, currency, rule, or per-date `calendar`). `type: \"calendar\"` carries the full per-date restriction set — nightly price, min/max nights, closed-to-arrival, closed-to-departure, and stop-sell (`availability: \"unavailable\"`). For settings sub-resources the full object is replaced — GET first, mutate locally, then PUT the whole object. `{id}` is the **Repull listing id** (from `GET /v1/properties` or `GET /v1/channels/airbnb/listings`), not the Airbnb listing id — Repull translates it before calling Airbnb. The body is validated before anything reaches Airbnb: a malformed body is `422 invalid_params` naming the `field`. Calendar operations accept only the documented fields. **Blocking dates:** Airbnb requires a `busy_subtype` whenever `availability` is `\"unavailable\"`. If an operation leaves it out, Repull sends `busy_subtype: \"BLOCKED_BY_HOST\"`; send `\"OUTSIDE_RESERVATION\"` for dates held by a booking made on another channel. **Errors:** `403 connection_reauth_required` — Airbnb no longer accepts the connection for this listing (reconnect; retrying won't help). `403 listing_inactive` — the listing is inactive. `404 not_found` — no Airbnb-connected listing with this id in the workspace. `422 airbnb_rejected` — Airbnb refused the change; `message` carries its reason. `429 airbnb_rate_limited` — back off. `502 airbnb_error` — Airbnb outage or timeout; retry.
3686
+ # Push pricing changes to Airbnb. The `type` discriminator selects the sub-resource (model, standard settings, LOS, rate-plan, fees, currency, rule, or per-date `calendar`). `type: \"calendar\"` carries the full per-date restriction set — nightly price, min/max nights, closed-to-arrival, closed-to-departure, and stop-sell (`availability: \"unavailable\"`). For settings sub-resources the full object is replaced — GET first, mutate locally, then PUT the whole object. `{id}` is the **Repull listing id** (from `GET /v1/properties` or `GET /v1/channels/airbnb/listings`), not the Airbnb listing id — Repull translates it before calling Airbnb. The body is validated before anything reaches Airbnb: a malformed body is `422 invalid_params` naming the `field`. Calendar operations accept only the documented fields. **Blocking dates:** Airbnb requires a `busy_subtype` whenever `availability` is `\"unavailable\"`. If an operation leaves it out, Repull sends `busy_subtype: \"BLOCKED_BY_HOST\"`; send `\"OUTSIDE_RESERVATION\"` for dates held by a booking made on another channel. **Errors:** `403 listing_not_api_connected` — Airbnb was never told to sync this listing (its `syncCategory` is `none`); the host must switch API sync on for it in Airbnb, reconnecting the account will not help. `403 connection_reauth_required` — Airbnb no longer accepts the connection at all (reconnect; retrying won't help). `403 listing_inactive` — the listing is inactive. `404 not_found` — no Airbnb-connected listing with this id in the workspace. `422 airbnb_rejected` — Airbnb refused the change; `message` carries its reason. `429 airbnb_rate_limited` — back off. `502 airbnb_error` — Airbnb outage or timeout; retry.
2625
3687
  # @param id [String]
2626
3688
  # @param airbnb_pricing_write_request [AirbnbPricingWriteRequest]
2627
3689
  # @param [Hash] opts the optional parameters
@@ -2632,7 +3694,7 @@ module Repull
2632
3694
  end
2633
3695
 
2634
3696
  # Update Airbnb pricing
2635
- # Push pricing changes to Airbnb. The &#x60;type&#x60; discriminator selects the sub-resource (model, standard settings, LOS, rate-plan, fees, currency, rule, or per-date &#x60;calendar&#x60;). &#x60;type: \&quot;calendar\&quot;&#x60; carries the full per-date restriction set — nightly price, min/max nights, closed-to-arrival, closed-to-departure, and stop-sell (&#x60;availability: \&quot;unavailable\&quot;&#x60;). For settings sub-resources the full object is replaced — GET first, mutate locally, then PUT the whole object. &#x60;{id}&#x60; is the **Repull listing id** (from &#x60;GET /v1/properties&#x60; or &#x60;GET /v1/channels/airbnb/listings&#x60;), not the Airbnb listing id — Repull translates it before calling Airbnb. The body is validated before anything reaches Airbnb: a malformed body is &#x60;422 invalid_params&#x60; naming the &#x60;field&#x60;. Calendar operations accept only the documented fields. **Blocking dates:** Airbnb requires a &#x60;busy_subtype&#x60; whenever &#x60;availability&#x60; is &#x60;\&quot;unavailable\&quot;&#x60;. If an operation leaves it out, Repull sends &#x60;busy_subtype: \&quot;BLOCKED_BY_HOST\&quot;&#x60;; send &#x60;\&quot;OUTSIDE_RESERVATION\&quot;&#x60; for dates held by a booking made on another channel. **Errors:** &#x60;403 connection_reauth_required&#x60; — Airbnb no longer accepts the connection for this listing (reconnect; retrying won&#39;t help). &#x60;403 listing_inactive&#x60; — the listing is inactive. &#x60;404 not_found&#x60; — no Airbnb-connected listing with this id in the workspace. &#x60;422 airbnb_rejected&#x60; — Airbnb refused the change; &#x60;message&#x60; carries its reason. &#x60;429 airbnb_rate_limited&#x60; — back off. &#x60;502 airbnb_error&#x60; — Airbnb outage or timeout; retry.
3697
+ # Push pricing changes to Airbnb. The &#x60;type&#x60; discriminator selects the sub-resource (model, standard settings, LOS, rate-plan, fees, currency, rule, or per-date &#x60;calendar&#x60;). &#x60;type: \&quot;calendar\&quot;&#x60; carries the full per-date restriction set — nightly price, min/max nights, closed-to-arrival, closed-to-departure, and stop-sell (&#x60;availability: \&quot;unavailable\&quot;&#x60;). For settings sub-resources the full object is replaced — GET first, mutate locally, then PUT the whole object. &#x60;{id}&#x60; is the **Repull listing id** (from &#x60;GET /v1/properties&#x60; or &#x60;GET /v1/channels/airbnb/listings&#x60;), not the Airbnb listing id — Repull translates it before calling Airbnb. The body is validated before anything reaches Airbnb: a malformed body is &#x60;422 invalid_params&#x60; naming the &#x60;field&#x60;. Calendar operations accept only the documented fields. **Blocking dates:** Airbnb requires a &#x60;busy_subtype&#x60; whenever &#x60;availability&#x60; is &#x60;\&quot;unavailable\&quot;&#x60;. If an operation leaves it out, Repull sends &#x60;busy_subtype: \&quot;BLOCKED_BY_HOST\&quot;&#x60;; send &#x60;\&quot;OUTSIDE_RESERVATION\&quot;&#x60; for dates held by a booking made on another channel. **Errors:** &#x60;403 listing_not_api_connected&#x60; — Airbnb was never told to sync this listing (its &#x60;syncCategory&#x60; is &#x60;none&#x60;); the host must switch API sync on for it in Airbnb, reconnecting the account will not help. &#x60;403 connection_reauth_required&#x60; — Airbnb no longer accepts the connection at all (reconnect; retrying won&#39;t help). &#x60;403 listing_inactive&#x60; — the listing is inactive. &#x60;404 not_found&#x60; — no Airbnb-connected listing with this id in the workspace. &#x60;422 airbnb_rejected&#x60; — Airbnb refused the change; &#x60;message&#x60; carries its reason. &#x60;429 airbnb_rate_limited&#x60; — back off. &#x60;502 airbnb_error&#x60; — Airbnb outage or timeout; retry.
2636
3698
  # @param id [String]
2637
3699
  # @param airbnb_pricing_write_request [AirbnbPricingWriteRequest]
2638
3700
  # @param [Hash] opts the optional parameters
@@ -2694,6 +3756,168 @@ module Repull
2694
3756
  return data, status_code, headers
2695
3757
  end
2696
3758
 
3759
+ # Update an Airbnb room
3760
+ # Change a room's type, number, privacy or sleeping arrangement. **Write-side** — calls Airbnb upstream. Pass the Airbnb-side room id as `?roomId=` and send only the fields you want to change. `beds` REPLACES the room's whole arrangement — that is Airbnb's semantics for the field — so send every bed the room has, not just the changed one. Airbnb's room endpoints are keyed by room id alone, so the room is proven to belong to the listing named in the path before anything is sent; a room from another listing returns `404`, the same answer a room that does not exist gets. On success both stored copies are rebuilt to match, so a read straight after this write returns the new arrangement. `stored` says whether that succeeded. 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.
3761
+ # @param id [String] Repull listing id (numeric string).
3762
+ # @param room_id [String] Airbnb-side room id to update.
3763
+ # @param update_airbnb_listing_room_request [UpdateAirbnbListingRoomRequest]
3764
+ # @param [Hash] opts the optional parameters
3765
+ # @return [UpdateAirbnbListingRoom200Response]
3766
+ def update_airbnb_listing_room(id, room_id, update_airbnb_listing_room_request, opts = {})
3767
+ data, _status_code, _headers = update_airbnb_listing_room_with_http_info(id, room_id, update_airbnb_listing_room_request, opts)
3768
+ data
3769
+ end
3770
+
3771
+ # Update an Airbnb room
3772
+ # Change a room&#39;s type, number, privacy or sleeping arrangement. **Write-side** — calls Airbnb upstream. Pass the Airbnb-side room id as &#x60;?roomId&#x3D;&#x60; and send only the fields you want to change. &#x60;beds&#x60; REPLACES the room&#39;s whole arrangement — that is Airbnb&#39;s semantics for the field — so send every bed the room has, not just the changed one. Airbnb&#39;s room endpoints are keyed by room id alone, so the room is proven to belong to the listing named in the path before anything is sent; a room from another listing returns &#x60;404&#x60;, the same answer a room that does not exist gets. On success both stored copies are rebuilt to match, so a read straight after this write returns the new arrangement. &#x60;stored&#x60; says whether that succeeded. 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.
3773
+ # @param id [String] Repull listing id (numeric string).
3774
+ # @param room_id [String] Airbnb-side room id to update.
3775
+ # @param update_airbnb_listing_room_request [UpdateAirbnbListingRoomRequest]
3776
+ # @param [Hash] opts the optional parameters
3777
+ # @return [Array<(UpdateAirbnbListingRoom200Response, Integer, Hash)>] UpdateAirbnbListingRoom200Response data, response status code and response headers
3778
+ def update_airbnb_listing_room_with_http_info(id, room_id, update_airbnb_listing_room_request, opts = {})
3779
+ if @api_client.config.debugging
3780
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.update_airbnb_listing_room ...'
3781
+ end
3782
+ # verify the required parameter 'id' is set
3783
+ if @api_client.config.client_side_validation && id.nil?
3784
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.update_airbnb_listing_room"
3785
+ end
3786
+ # verify the required parameter 'room_id' is set
3787
+ if @api_client.config.client_side_validation && room_id.nil?
3788
+ fail ArgumentError, "Missing the required parameter 'room_id' when calling AirbnbApi.update_airbnb_listing_room"
3789
+ end
3790
+ # verify the required parameter 'update_airbnb_listing_room_request' is set
3791
+ if @api_client.config.client_side_validation && update_airbnb_listing_room_request.nil?
3792
+ fail ArgumentError, "Missing the required parameter 'update_airbnb_listing_room_request' when calling AirbnbApi.update_airbnb_listing_room"
3793
+ end
3794
+ # resource path
3795
+ local_var_path = '/v1/channels/airbnb/listings/{id}/rooms'.sub('{id}', CGI.escape(id.to_s))
3796
+
3797
+ # query parameters
3798
+ query_params = opts[:query_params] || {}
3799
+ query_params[:'roomId'] = room_id
3800
+
3801
+ # header parameters
3802
+ header_params = opts[:header_params] || {}
3803
+ # HTTP header 'Accept' (if needed)
3804
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
3805
+ # HTTP header 'Content-Type'
3806
+ content_type = @api_client.select_header_content_type(['application/json'])
3807
+ if !content_type.nil?
3808
+ header_params['Content-Type'] = content_type
3809
+ end
3810
+
3811
+ # form parameters
3812
+ form_params = opts[:form_params] || {}
3813
+
3814
+ # http body (model)
3815
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(update_airbnb_listing_room_request)
3816
+
3817
+ # return_type
3818
+ return_type = opts[:debug_return_type] || 'UpdateAirbnbListingRoom200Response'
3819
+
3820
+ # auth_names
3821
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
3822
+
3823
+ new_options = opts.merge(
3824
+ :operation => :"AirbnbApi.update_airbnb_listing_room",
3825
+ :header_params => header_params,
3826
+ :query_params => query_params,
3827
+ :form_params => form_params,
3828
+ :body => post_body,
3829
+ :auth_names => auth_names,
3830
+ :return_type => return_type
3831
+ )
3832
+
3833
+ data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
3834
+ if @api_client.config.debugging
3835
+ @api_client.config.logger.debug "API called: AirbnbApi#update_airbnb_listing_room\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
3836
+ end
3837
+ return data, status_code, headers
3838
+ end
3839
+
3840
+ # Update guest-safety disclosures
3841
+ # Declare or retract the guest-safety disclosures on the live Airbnb listing. **This is a MERGE, not a replacement.** Airbnb keeps one value per disclosure type: a type you leave out keeps the value it has, and to retract one you send it with `value: false`. A full replacement would let a partial request silently un-declare a security camera — a guest-safety statement, not a preference. Only the disclosures are sent upstream. The same Airbnb endpoint carries the cancellation policy and instant-book settings, and this endpoint never touches them. Send `Idempotency-Key` to make a retry safe. Airbnb refusing the change is `422 airbnb_rejected` with Airbnb's own reason; an expired or revoked connection is `403 connection_reauth_required`.
3842
+ # @param id [String] Repull listing id (numeric string).
3843
+ # @param airbnb_safety_disclosures_write_request [AirbnbSafetyDisclosuresWriteRequest]
3844
+ # @param [Hash] opts the optional parameters
3845
+ # @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.
3846
+ # @return [UpdateAirbnbListingSafetyDisclosures200Response]
3847
+ def update_airbnb_listing_safety_disclosures(id, airbnb_safety_disclosures_write_request, opts = {})
3848
+ data, _status_code, _headers = update_airbnb_listing_safety_disclosures_with_http_info(id, airbnb_safety_disclosures_write_request, opts)
3849
+ data
3850
+ end
3851
+
3852
+ # Update guest-safety disclosures
3853
+ # Declare or retract the guest-safety disclosures on the live Airbnb listing. **This is a MERGE, not a replacement.** Airbnb keeps one value per disclosure type: a type you leave out keeps the value it has, and to retract one you send it with &#x60;value: false&#x60;. A full replacement would let a partial request silently un-declare a security camera — a guest-safety statement, not a preference. Only the disclosures are sent upstream. The same Airbnb endpoint carries the cancellation policy and instant-book settings, and this endpoint never touches them. Send &#x60;Idempotency-Key&#x60; to make a retry safe. Airbnb refusing the change is &#x60;422 airbnb_rejected&#x60; with Airbnb&#39;s own reason; an expired or revoked connection is &#x60;403 connection_reauth_required&#x60;.
3854
+ # @param id [String] Repull listing id (numeric string).
3855
+ # @param airbnb_safety_disclosures_write_request [AirbnbSafetyDisclosuresWriteRequest]
3856
+ # @param [Hash] opts the optional parameters
3857
+ # @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.
3858
+ # @return [Array<(UpdateAirbnbListingSafetyDisclosures200Response, Integer, Hash)>] UpdateAirbnbListingSafetyDisclosures200Response data, response status code and response headers
3859
+ def update_airbnb_listing_safety_disclosures_with_http_info(id, airbnb_safety_disclosures_write_request, opts = {})
3860
+ if @api_client.config.debugging
3861
+ @api_client.config.logger.debug 'Calling API: AirbnbApi.update_airbnb_listing_safety_disclosures ...'
3862
+ end
3863
+ # verify the required parameter 'id' is set
3864
+ if @api_client.config.client_side_validation && id.nil?
3865
+ fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.update_airbnb_listing_safety_disclosures"
3866
+ end
3867
+ # verify the required parameter 'airbnb_safety_disclosures_write_request' is set
3868
+ if @api_client.config.client_side_validation && airbnb_safety_disclosures_write_request.nil?
3869
+ fail ArgumentError, "Missing the required parameter 'airbnb_safety_disclosures_write_request' when calling AirbnbApi.update_airbnb_listing_safety_disclosures"
3870
+ end
3871
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
3872
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling AirbnbApi.update_airbnb_listing_safety_disclosures, the character length must be smaller than or equal to 255.'
3873
+ end
3874
+
3875
+ # resource path
3876
+ local_var_path = '/v1/channels/airbnb/listings/{id}/safety-disclosures'.sub('{id}', CGI.escape(id.to_s))
3877
+
3878
+ # query parameters
3879
+ query_params = opts[:query_params] || {}
3880
+
3881
+ # header parameters
3882
+ header_params = opts[:header_params] || {}
3883
+ # HTTP header 'Accept' (if needed)
3884
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
3885
+ # HTTP header 'Content-Type'
3886
+ content_type = @api_client.select_header_content_type(['application/json'])
3887
+ if !content_type.nil?
3888
+ header_params['Content-Type'] = content_type
3889
+ end
3890
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
3891
+
3892
+ # form parameters
3893
+ form_params = opts[:form_params] || {}
3894
+
3895
+ # http body (model)
3896
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(airbnb_safety_disclosures_write_request)
3897
+
3898
+ # return_type
3899
+ return_type = opts[:debug_return_type] || 'UpdateAirbnbListingSafetyDisclosures200Response'
3900
+
3901
+ # auth_names
3902
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
3903
+
3904
+ new_options = opts.merge(
3905
+ :operation => :"AirbnbApi.update_airbnb_listing_safety_disclosures",
3906
+ :header_params => header_params,
3907
+ :query_params => query_params,
3908
+ :form_params => form_params,
3909
+ :body => post_body,
3910
+ :auth_names => auth_names,
3911
+ :return_type => return_type
3912
+ )
3913
+
3914
+ data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
3915
+ if @api_client.config.debugging
3916
+ @api_client.config.logger.debug "API called: AirbnbApi#update_airbnb_listing_safety_disclosures\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
3917
+ end
3918
+ return data, status_code, headers
3919
+ end
3920
+
2697
3921
  # Edit / react to / mark an Airbnb message
2698
3922
  # Act on a single message in an Airbnb thread. **Write-side** — calls Airbnb upstream. The `action` discriminator selects the operation: - `edit` — replace message text (requires `message`). - `unsend` — retract the message. - `read` — mark the message as read. - `react` — add a reaction (requires `reaction`). Requires a connected Airbnb host, else `404 no_connection`. Returns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
2699
3923
  # @param thread_id [String] Airbnb thread id.
@@ -2775,21 +3999,23 @@ module Repull
2775
3999
  end
2776
4000
 
2777
4001
  # Upload photos to Airbnb
2778
- # Upload one or more photos to an Airbnb listing. Accepts public image URLs (Airbnb fetches them) direct binary upload is not supported on this endpoint. 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.
4002
+ # Upload one or more photos to an Airbnb listing. `image` is base64 image DATA, not a url — a `data:image/jpeg;base64,…` prefix is accepted and stripped, and the decoded image must be under 25 MB. (This operation previously documented public image urls that Airbnb would fetch. It never did: a url arrived at Airbnb as a ~60-byte image.) Airbnb assigns the photo id and CDN urls, so the newly uploaded photos appear in `GET /photos` after the next sync. Caption, order and room assignment can be set straight away with `PATCH /photos`, `PUT /photos/order` and `PUT /photos/cover`. 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.
2779
4003
  # @param id [String]
4004
+ # @param upload_airbnb_listing_photos_request [UploadAirbnbListingPhotosRequest]
2780
4005
  # @param [Hash] opts the optional parameters
2781
4006
  # @return [nil]
2782
- def upload_airbnb_listing_photos(id, opts = {})
2783
- upload_airbnb_listing_photos_with_http_info(id, opts)
4007
+ def upload_airbnb_listing_photos(id, upload_airbnb_listing_photos_request, opts = {})
4008
+ upload_airbnb_listing_photos_with_http_info(id, upload_airbnb_listing_photos_request, opts)
2784
4009
  nil
2785
4010
  end
2786
4011
 
2787
4012
  # Upload photos to Airbnb
2788
- # Upload one or more photos to an Airbnb listing. Accepts public image URLs (Airbnb fetches them) direct binary upload is not supported on this endpoint. 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.
4013
+ # Upload one or more photos to an Airbnb listing. &#x60;image&#x60; is base64 image DATA, not a url — a &#x60;data:image/jpeg;base64,…&#x60; prefix is accepted and stripped, and the decoded image must be under 25 MB. (This operation previously documented public image urls that Airbnb would fetch. It never did: a url arrived at Airbnb as a ~60-byte image.) Airbnb assigns the photo id and CDN urls, so the newly uploaded photos appear in &#x60;GET /photos&#x60; after the next sync. Caption, order and room assignment can be set straight away with &#x60;PATCH /photos&#x60;, &#x60;PUT /photos/order&#x60; and &#x60;PUT /photos/cover&#x60;. 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.
2789
4014
  # @param id [String]
4015
+ # @param upload_airbnb_listing_photos_request [UploadAirbnbListingPhotosRequest]
2790
4016
  # @param [Hash] opts the optional parameters
2791
4017
  # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
2792
- def upload_airbnb_listing_photos_with_http_info(id, opts = {})
4018
+ def upload_airbnb_listing_photos_with_http_info(id, upload_airbnb_listing_photos_request, opts = {})
2793
4019
  if @api_client.config.debugging
2794
4020
  @api_client.config.logger.debug 'Calling API: AirbnbApi.upload_airbnb_listing_photos ...'
2795
4021
  end
@@ -2797,6 +4023,10 @@ module Repull
2797
4023
  if @api_client.config.client_side_validation && id.nil?
2798
4024
  fail ArgumentError, "Missing the required parameter 'id' when calling AirbnbApi.upload_airbnb_listing_photos"
2799
4025
  end
4026
+ # verify the required parameter 'upload_airbnb_listing_photos_request' is set
4027
+ if @api_client.config.client_side_validation && upload_airbnb_listing_photos_request.nil?
4028
+ fail ArgumentError, "Missing the required parameter 'upload_airbnb_listing_photos_request' when calling AirbnbApi.upload_airbnb_listing_photos"
4029
+ end
2800
4030
  # resource path
2801
4031
  local_var_path = '/v1/channels/airbnb/listings/{id}/photos'.sub('{id}', CGI.escape(id.to_s))
2802
4032
 
@@ -2807,12 +4037,17 @@ module Repull
2807
4037
  header_params = opts[:header_params] || {}
2808
4038
  # HTTP header 'Accept' (if needed)
2809
4039
  header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
4040
+ # HTTP header 'Content-Type'
4041
+ content_type = @api_client.select_header_content_type(['application/json'])
4042
+ if !content_type.nil?
4043
+ header_params['Content-Type'] = content_type
4044
+ end
2810
4045
 
2811
4046
  # form parameters
2812
4047
  form_params = opts[:form_params] || {}
2813
4048
 
2814
4049
  # http body (model)
2815
- post_body = opts[:debug_body]
4050
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(upload_airbnb_listing_photos_request)
2816
4051
 
2817
4052
  # return_type
2818
4053
  return_type = opts[:debug_return_type]
@@ -2838,20 +4073,20 @@ module Repull
2838
4073
  end
2839
4074
 
2840
4075
  # Withdraw Airbnb special offer
2841
- # Withdraw a previously-created Airbnb special offer. **Write-side** — calls Airbnb upstream. Pass the offer id as `?offerId=`. Requires a connected Airbnb host, else `404 no_connection`.
2842
- # @param offer_id [String] Airbnb special-offer id to withdraw.
4076
+ # Withdraw a special offer the guest has not booked. **Write-side** — calls Airbnb upstream. Pass the Airbnb offer id as `?offerId=`. The Repull-id equivalent is `DELETE /v1/conversations/{id}/special-offers/{offerId}`.
4077
+ # @param offer_id [String] Airbnb special-offer id (the &#x60;id&#x60; Airbnb returned when the offer was created).
2843
4078
  # @param [Hash] opts the optional parameters
2844
- # @return [nil]
4079
+ # @return [GetAirbnbOffer200Response]
2845
4080
  def withdraw_airbnb_offer(offer_id, opts = {})
2846
- withdraw_airbnb_offer_with_http_info(offer_id, opts)
2847
- nil
4081
+ data, _status_code, _headers = withdraw_airbnb_offer_with_http_info(offer_id, opts)
4082
+ data
2848
4083
  end
2849
4084
 
2850
4085
  # Withdraw Airbnb special offer
2851
- # Withdraw a previously-created Airbnb special offer. **Write-side** — calls Airbnb upstream. Pass the offer id as &#x60;?offerId&#x3D;&#x60;. Requires a connected Airbnb host, else &#x60;404 no_connection&#x60;.
2852
- # @param offer_id [String] Airbnb special-offer id to withdraw.
4086
+ # Withdraw a special offer the guest has not booked. **Write-side** — calls Airbnb upstream. Pass the Airbnb offer id as &#x60;?offerId&#x3D;&#x60;. The Repull-id equivalent is &#x60;DELETE /v1/conversations/{id}/special-offers/{offerId}&#x60;.
4087
+ # @param offer_id [String] Airbnb special-offer id (the &#x60;id&#x60; Airbnb returned when the offer was created).
2853
4088
  # @param [Hash] opts the optional parameters
2854
- # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
4089
+ # @return [Array<(GetAirbnbOffer200Response, Integer, Hash)>] GetAirbnbOffer200Response data, response status code and response headers
2855
4090
  def withdraw_airbnb_offer_with_http_info(offer_id, opts = {})
2856
4091
  if @api_client.config.debugging
2857
4092
  @api_client.config.logger.debug 'Calling API: AirbnbApi.withdraw_airbnb_offer ...'
@@ -2879,7 +4114,7 @@ module Repull
2879
4114
  post_body = opts[:debug_body]
2880
4115
 
2881
4116
  # return_type
2882
- return_type = opts[:debug_return_type]
4117
+ return_type = opts[:debug_return_type] || 'GetAirbnbOffer200Response'
2883
4118
 
2884
4119
  # auth_names
2885
4120
  auth_names = opts[:debug_auth_names] || ['bearerAuth']