repull 0.2.10 → 0.2.15

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 (453) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/repull/api/airbnb_api.rb +1569 -196
  4. data/lib/repull/api/atlas_api.rb +5 -5
  5. data/lib/repull/api/availability_api.rb +145 -3
  6. data/lib/repull/api/billing_api.rb +7 -7
  7. data/lib/repull/api/booking_com_api.rb +210 -54
  8. data/lib/repull/api/connect_api.rb +763 -10
  9. data/lib/repull/api/conversations_api.rb +92 -11
  10. data/lib/repull/api/guests_api.rb +82 -7
  11. data/lib/repull/api/health_api.rb +318 -0
  12. data/lib/repull/api/kv_api.rb +1 -1
  13. data/lib/repull/api/listings_api.rb +392 -29
  14. data/lib/repull/api/markets_api.rb +3 -3
  15. data/lib/repull/api/plumguide_api.rb +19 -11
  16. data/lib/repull/api/pricing_api.rb +15 -15
  17. data/lib/repull/api/properties_api.rb +12 -9
  18. data/lib/repull/api/quotes_api.rb +109 -0
  19. data/lib/repull/api/reservations_api.rb +166 -7
  20. data/lib/repull/api/reviews_api.rb +81 -7
  21. data/lib/repull/api/schema_api.rb +1 -1
  22. data/lib/repull/api/system_api.rb +1 -1
  23. data/lib/repull/api/vrbo_api.rb +10 -10
  24. data/lib/repull/api/webhooks_api.rb +11 -9
  25. data/lib/repull/api_client.rb +1 -1
  26. data/lib/repull/api_error.rb +1 -1
  27. data/lib/repull/api_model_base.rb +1 -1
  28. data/lib/repull/configuration.rb +1 -1
  29. data/lib/repull/models/account_created_event.rb +1 -1
  30. data/lib/repull/models/account_created_payload.rb +1 -1
  31. data/lib/repull/models/account_disconnected_event.rb +1 -1
  32. data/lib/repull/models/account_disconnected_payload.rb +1 -1
  33. data/lib/repull/models/acknowledge_booking_reservations_request.rb +1 -1
  34. data/lib/repull/models/ai_operation.rb +1 -1
  35. data/lib/repull/models/ai_operation_completed_event.rb +1 -1
  36. data/lib/repull/models/ai_operation_completed_payload.rb +1 -1
  37. data/lib/repull/models/ai_operation_failed_event.rb +1 -1
  38. data/lib/repull/models/ai_operation_failed_payload.rb +1 -1
  39. data/lib/repull/models/ai_operation_failed_payload_error.rb +1 -1
  40. data/lib/repull/models/airbnb_account_freshness.rb +239 -0
  41. data/lib/repull/models/airbnb_alteration.rb +198 -10
  42. data/lib/repull/models/airbnb_alteration_create_request.rb +264 -0
  43. data/lib/repull/models/airbnb_amenity.rb +1 -1
  44. data/lib/repull/models/airbnb_availability_write_request.rb +20 -1
  45. data/lib/repull/models/airbnb_calendar_operation.rb +97 -8
  46. data/lib/repull/models/airbnb_connection.rb +73 -6
  47. data/lib/repull/models/airbnb_connection_accessibility_amenities_inner.rb +1 -1
  48. data/lib/repull/models/airbnb_connection_amenities_inner.rb +1 -1
  49. data/lib/repull/models/airbnb_connection_host.rb +2 -2
  50. data/lib/repull/models/airbnb_connection_response.rb +1 -1
  51. data/lib/repull/models/airbnb_connection_summary.rb +1 -1
  52. data/lib/repull/models/airbnb_content_write_response.rb +275 -0
  53. data/lib/repull/models/airbnb_data_freshness.rb +24 -12
  54. data/lib/repull/models/airbnb_description_write_request.rb +192 -0
  55. data/lib/repull/models/airbnb_description_write_request_description.rb +365 -0
  56. data/lib/repull/models/airbnb_listing.rb +14 -3
  57. data/lib/repull/models/airbnb_listing_action200_response.rb +105 -0
  58. data/lib/repull/models/airbnb_listing_action200_response_one_of.rb +157 -0
  59. data/lib/repull/models/airbnb_listing_action200_response_one_of1.rb +175 -0
  60. data/lib/repull/models/airbnb_listing_action_request.rb +3 -3
  61. data/lib/repull/models/airbnb_listing_details_response.rb +284 -0
  62. data/lib/repull/models/airbnb_listing_details_write_request.rb +209 -0
  63. data/lib/repull/models/airbnb_listing_details_write_request_check_in_option.rb +214 -0
  64. data/lib/repull/models/airbnb_listing_details_write_request_quiet_hours_inner.rb +190 -0
  65. data/lib/repull/models/airbnb_listing_lifecycle_response.rb +196 -0
  66. data/lib/repull/models/airbnb_listing_list_response.rb +2 -2
  67. data/lib/repull/models/airbnb_permits_response.rb +163 -0
  68. data/lib/repull/models/airbnb_permits_response_cached_inner.rb +200 -0
  69. data/lib/repull/models/airbnb_permits_write_request.rb +176 -0
  70. data/lib/repull/models/airbnb_permits_write_request_permits_inner.rb +228 -0
  71. data/lib/repull/models/airbnb_permits_write_request_permits_inner_answers_inner.rb +198 -0
  72. data/lib/repull/models/airbnb_photo_position.rb +159 -0
  73. data/lib/repull/models/airbnb_pricing_write_request.rb +54 -3
  74. data/lib/repull/models/airbnb_pricing_write_request_records_inner.rb +236 -0
  75. data/lib/repull/models/airbnb_publish_result.rb +263 -0
  76. data/lib/repull/models/airbnb_reservation.rb +24 -2
  77. data/lib/repull/models/airbnb_reservation_list_response.rb +15 -6
  78. data/lib/repull/models/airbnb_review.rb +24 -2
  79. data/lib/repull/models/airbnb_review_list_response.rb +14 -5
  80. data/lib/repull/models/airbnb_safety_disclosure.rb +202 -0
  81. data/lib/repull/models/airbnb_safety_disclosures_response.rb +162 -0
  82. data/lib/repull/models/airbnb_safety_disclosures_write_request.rb +176 -0
  83. data/lib/repull/models/airbnb_thread.rb +24 -2
  84. data/lib/repull/models/airbnb_thread_list_response.rb +14 -5
  85. data/lib/repull/models/airbnb_transaction.rb +524 -0
  86. data/lib/repull/models/airbnb_transaction_guest_breakdown.rb +171 -0
  87. data/lib/repull/models/airbnb_transaction_host_breakdown.rb +246 -0
  88. data/lib/repull/models/airbnb_transaction_payout.rb +175 -0
  89. data/lib/repull/models/alteration_change.rb +161 -0
  90. data/lib/repull/models/alteration_webhook_object.rb +296 -0
  91. data/lib/repull/models/availability_batch_write_request.rb +296 -0
  92. data/lib/repull/models/availability_write_request.rb +259 -0
  93. data/lib/repull/models/availability_write_result.rb +178 -0
  94. data/lib/repull/models/availability_write_result_synced.rb +176 -0
  95. data/lib/repull/models/availability_write_settings.rb +215 -0
  96. data/lib/repull/models/booking_availability_state_response.rb +149 -0
  97. data/lib/repull/models/booking_availability_update.rb +1 -1
  98. data/lib/repull/models/booking_availability_update_request.rb +1 -1
  99. data/lib/repull/models/booking_availability_update_request_property_id.rb +1 -1
  100. data/lib/repull/models/booking_availability_update_request_updates_inner.rb +1 -1
  101. data/lib/repull/models/booking_connect_listing_option.rb +1 -1
  102. data/lib/repull/models/booking_connect_room.rb +1 -1
  103. data/lib/repull/models/booking_connect_rooms_response.rb +39 -5
  104. data/lib/repull/models/booking_conversation.rb +1 -1
  105. data/lib/repull/models/booking_pricing_rate_update.rb +1 -1
  106. data/lib/repull/models/booking_pricing_rate_update_date_range.rb +1 -1
  107. data/lib/repull/models/booking_pricing_rate_update_restrictions.rb +1 -1
  108. data/lib/repull/models/booking_pricing_response.rb +1 -1
  109. data/lib/repull/models/booking_pricing_update_request.rb +1 -1
  110. data/lib/repull/models/booking_pricing_update_response.rb +1 -1
  111. data/lib/repull/models/booking_property.rb +1 -1
  112. data/lib/repull/models/booking_reservation.rb +277 -0
  113. data/lib/repull/models/booking_reservation_room.rb +271 -0
  114. data/lib/repull/models/booking_room_mapping.rb +18 -8
  115. data/lib/repull/models/booking_rooms_rates_response.rb +170 -0
  116. data/lib/repull/models/booking_rooms_rates_response_rooms_inner.rb +170 -0
  117. data/lib/repull/models/booking_rooms_rates_response_rooms_inner_rates_inner.rb +212 -0
  118. data/lib/repull/models/booking_setup_request.rb +1 -1
  119. data/lib/repull/models/booking_verify_hotel_request.rb +1 -1
  120. data/lib/repull/models/booking_verify_hotel_response.rb +40 -6
  121. data/lib/repull/models/bulk_pricing_failure.rb +1 -1
  122. data/lib/repull/models/bulk_pricing_item.rb +1 -1
  123. data/lib/repull/models/bulk_pricing_request.rb +1 -1
  124. data/lib/repull/models/bulk_pricing_response.rb +1 -1
  125. data/lib/repull/models/calendar_day.rb +1 -1
  126. data/lib/repull/models/calendar_response.rb +1 -1
  127. data/lib/repull/models/calendar_updated_event.rb +1 -1
  128. data/lib/repull/models/calendar_updated_payload.rb +1 -1
  129. data/lib/repull/models/calendar_updated_payload_range.rb +1 -1
  130. data/lib/repull/models/clear_kv200_response.rb +1 -1
  131. data/lib/repull/models/connect_host.rb +1 -1
  132. data/lib/repull/models/connect_provider.rb +1 -1
  133. data/lib/repull/models/connect_provider_list_response.rb +1 -1
  134. data/lib/repull/models/connect_session.rb +1 -1
  135. data/lib/repull/models/connect_status.rb +18 -6
  136. data/lib/repull/models/connect_status_accounts_inner.rb +188 -0
  137. data/lib/repull/models/connection.rb +1 -1
  138. data/lib/repull/models/connection_list_response.rb +1 -1
  139. data/lib/repull/models/conversation.rb +13 -2
  140. data/lib/repull/models/conversation_detail.rb +13 -2
  141. data/lib/repull/models/conversation_guest.rb +1 -1
  142. data/lib/repull/models/conversation_guest_contact.rb +1 -1
  143. data/lib/repull/models/conversation_host.rb +1 -1
  144. data/lib/repull/models/conversation_list_response.rb +1 -1
  145. data/lib/repull/models/conversation_message_attachment.rb +1 -1
  146. data/lib/repull/models/create_airbnb_listing_room_request.rb +315 -0
  147. data/lib/repull/models/create_airbnb_offer_request.rb +1 -1
  148. data/lib/repull/models/create_billing_checkout_request.rb +1 -1
  149. data/lib/repull/models/create_booking_webhook_request.rb +1 -1
  150. data/lib/repull/models/create_connect_session_request.rb +1 -1
  151. data/lib/repull/models/create_connection_request.rb +2 -2
  152. data/lib/repull/models/create_webhook_request.rb +1 -1
  153. data/lib/repull/models/custom_schema.rb +1 -1
  154. data/lib/repull/models/custom_schema_create.rb +1 -1
  155. data/lib/repull/models/custom_schema_create_response.rb +1 -1
  156. data/lib/repull/models/custom_schema_delete_response.rb +1 -1
  157. data/lib/repull/models/custom_schema_list_response.rb +1 -1
  158. data/lib/repull/models/custom_schema_summary.rb +1 -1
  159. data/lib/repull/models/custom_schema_update.rb +1 -1
  160. data/lib/repull/models/delete_airbnb_listing_photo200_response.rb +15 -5
  161. data/lib/repull/models/delete_airbnb_listing_room200_response.rb +157 -0
  162. data/lib/repull/models/delete_connection200_response.rb +234 -0
  163. data/lib/repull/models/delete_kv200_response.rb +1 -1
  164. data/lib/repull/models/error.rb +1 -1
  165. data/lib/repull/models/error_error.rb +44 -2
  166. data/lib/repull/models/error_error_support.rb +1 -1
  167. data/lib/repull/models/get_airbnb_alteration200_response.rb +2 -2
  168. data/lib/repull/models/get_airbnb_booking_settings200_response.rb +190 -0
  169. data/lib/repull/models/get_airbnb_booking_settings200_response_data.rb +246 -0
  170. data/lib/repull/models/get_airbnb_booking_settings200_response_data_advance_notice.rb +172 -0
  171. data/lib/repull/models/get_airbnb_booking_settings200_response_data_booking_window.rb +160 -0
  172. data/lib/repull/models/get_airbnb_booking_settings200_response_data_cancellation.rb +203 -0
  173. data/lib/repull/models/get_airbnb_booking_settings200_response_data_cancellation_non_refundable.rb +218 -0
  174. data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_in.rb +159 -0
  175. data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_in_start.rb +104 -0
  176. data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_out.rb +172 -0
  177. data/lib/repull/models/get_airbnb_booking_settings200_response_data_instant_book.rb +206 -0
  178. data/lib/repull/models/get_airbnb_booking_settings200_response_data_preparation_time.rb +173 -0
  179. data/lib/repull/models/get_airbnb_checkin_guide200_response.rb +192 -0
  180. data/lib/repull/models/get_airbnb_listing_details200_response.rb +192 -0
  181. data/lib/repull/models/get_airbnb_listing_quality200_response.rb +2 -2
  182. data/lib/repull/models/get_airbnb_listing_settings200_response.rb +2 -2
  183. data/lib/repull/models/get_airbnb_thread200_response.rb +2 -2
  184. data/lib/repull/models/get_health200_response.rb +1 -1
  185. data/lib/repull/models/get_usage_logs200_response.rb +1 -1
  186. data/lib/repull/models/get_usage_logs200_response_data_inner.rb +1 -1
  187. data/lib/repull/models/get_usage_logs200_response_pagination.rb +3 -3
  188. data/lib/repull/models/get_usage_summary200_response.rb +2 -2
  189. data/lib/repull/models/get_usage_summary200_response_breakdown_inner.rb +1 -1
  190. data/lib/repull/models/get_usage_summary200_response_limits.rb +3 -3
  191. data/lib/repull/models/get_usage_summary200_response_remaining.rb +2 -2
  192. data/lib/repull/models/get_usage_summary200_response_status_distribution.rb +1 -1
  193. data/lib/repull/models/get_usage_summary200_response_timeline_inner.rb +1 -1
  194. data/lib/repull/models/get_usage_summary200_response_totals.rb +1 -1
  195. data/lib/repull/models/get_usage_summary200_response_used.rb +2 -2
  196. data/lib/repull/models/get_usage_tier200_response.rb +2 -2
  197. data/lib/repull/models/get_usage_tier200_response_limits.rb +4 -4
  198. data/lib/repull/models/get_usage_tier200_response_remaining.rb +3 -3
  199. data/lib/repull/models/get_usage_tier200_response_used.rb +3 -3
  200. data/lib/repull/models/guest.rb +1 -1
  201. data/lib/repull/models/guest_contact.rb +1 -1
  202. data/lib/repull/models/guest_create_request.rb +250 -0
  203. data/lib/repull/models/guest_create_response.rb +227 -0
  204. data/lib/repull/models/guest_create_response_contacts_inner.rb +199 -0
  205. data/lib/repull/models/guest_flag.rb +1 -1
  206. data/lib/repull/models/guest_list_response.rb +1 -1
  207. data/lib/repull/models/guest_note.rb +1 -1
  208. data/lib/repull/models/guest_profile.rb +1 -1
  209. data/lib/repull/models/guest_reservations_summary.rb +1 -1
  210. data/lib/repull/models/list_airbnb_alterations200_response.rb +2 -2
  211. data/lib/repull/models/list_airbnb_listing_amenities200_response.rb +2 -2
  212. data/lib/repull/models/list_airbnb_listing_amenities200_response_data.rb +1 -1
  213. data/lib/repull/models/list_airbnb_listing_permits200_response.rb +190 -0
  214. data/lib/repull/models/list_airbnb_listing_safety_disclosures200_response.rb +190 -0
  215. data/lib/repull/models/list_airbnb_transactions200_response.rb +3 -3
  216. data/lib/repull/models/list_booking_reservations200_response.rb +104 -0
  217. data/lib/repull/models/list_kv200_response.rb +1 -1
  218. data/lib/repull/models/list_kv200_response_data_inner.rb +1 -1
  219. data/lib/repull/models/list_kv200_response_pagination.rb +2 -2
  220. data/lib/repull/models/listing.rb +3 -2
  221. data/lib/repull/models/listing_active_request.rb +2 -2
  222. data/lib/repull/models/listing_active_response.rb +1 -1
  223. data/lib/repull/models/listing_address.rb +1 -1
  224. data/lib/repull/models/listing_amenity.rb +1 -1
  225. data/lib/repull/models/listing_channel.rb +1 -1
  226. data/lib/repull/models/listing_comp.rb +1 -1
  227. data/lib/repull/models/listing_comp_nightly.rb +1 -1
  228. data/lib/repull/models/listing_comp_ratings.rb +1 -1
  229. data/lib/repull/models/listing_comps_response.rb +1 -1
  230. data/lib/repull/models/listing_content.rb +14 -3
  231. data/lib/repull/models/listing_content_update_request.rb +22 -3
  232. data/lib/repull/models/listing_content_update_request_address.rb +1 -1
  233. data/lib/repull/models/listing_content_update_request_amenities.rb +1 -1
  234. data/lib/repull/models/listing_content_update_request_amenities_one_of_inner.rb +1 -1
  235. data/lib/repull/models/listing_content_update_request_details.rb +206 -0
  236. data/lib/repull/models/listing_content_update_request_occupancy.rb +1 -1
  237. data/lib/repull/models/listing_content_update_request_photos_inner.rb +1 -1
  238. data/lib/repull/models/listing_content_update_request_photos_inner_one_of.rb +1 -1
  239. data/lib/repull/models/listing_content_update_request_policies.rb +96 -6
  240. data/lib/repull/models/listing_content_update_response.rb +2 -2
  241. data/lib/repull/models/listing_create_request.rb +1 -1
  242. data/lib/repull/models/listing_create_response.rb +1 -1
  243. data/lib/repull/models/listing_created_event.rb +1 -1
  244. data/lib/repull/models/listing_created_payload.rb +1 -1
  245. data/lib/repull/models/listing_created_payload_address.rb +1 -1
  246. data/lib/repull/models/listing_deleted_event.rb +1 -1
  247. data/lib/repull/models/listing_deleted_payload.rb +1 -1
  248. data/lib/repull/models/listing_details.rb +1 -1
  249. data/lib/repull/models/listing_generate_content_request.rb +1 -1
  250. data/lib/repull/models/listing_generate_content_response.rb +1 -1
  251. data/lib/repull/models/listing_list_response.rb +1 -1
  252. data/lib/repull/models/{studio_file.rb → listing_photo.rb} +23 -34
  253. data/lib/repull/models/listing_photo_delete_request.rb +165 -0
  254. data/lib/repull/models/{studio_error.rb → listing_photo_delete_response.rb} +20 -12
  255. data/lib/repull/models/listing_photo_upload_url_request.rb +203 -0
  256. data/lib/repull/models/listing_photo_upload_url_response.rb +198 -0
  257. data/lib/repull/models/{vrbo_listing_list_response.rb → listing_photos_response.rb} +19 -19
  258. data/lib/repull/models/listing_pricing_apply_request.rb +1 -1
  259. data/lib/repull/models/listing_pricing_apply_response.rb +1 -1
  260. data/lib/repull/models/listing_pricing_history_entry.rb +2 -2
  261. data/lib/repull/models/listing_pricing_history_response.rb +1 -1
  262. data/lib/repull/models/listing_pricing_recommendation.rb +1 -1
  263. data/lib/repull/models/listing_pricing_response.rb +1 -1
  264. data/lib/repull/models/listing_pricing_response_comp_summary.rb +1 -1
  265. data/lib/repull/models/listing_pricing_response_date_range.rb +1 -1
  266. data/lib/repull/models/listing_pricing_response_listing.rb +1 -1
  267. data/lib/repull/models/listing_pricing_strategy.rb +1 -1
  268. data/lib/repull/models/listing_pricing_strategy_input.rb +1 -1
  269. data/lib/repull/models/listing_publish_airbnb_request.rb +1 -1
  270. data/lib/repull/models/listing_publish_airbnb_response.rb +165 -0
  271. data/lib/repull/models/listing_publish_response.rb +1 -1
  272. data/lib/repull/models/listing_publish_status_channel.rb +1 -1
  273. data/lib/repull/models/listing_publish_status_connection.rb +1 -1
  274. data/lib/repull/models/listing_publish_status_response.rb +1 -1
  275. data/lib/repull/models/listing_pull_airbnb_request.rb +149 -0
  276. data/lib/repull/models/listing_pull_response.rb +231 -0
  277. data/lib/repull/models/listing_quality_tier.rb +1 -1
  278. data/lib/repull/models/listing_segment.rb +1 -1
  279. data/lib/repull/models/listing_segment_recommendation.rb +1 -1
  280. data/lib/repull/models/listing_segments_response.rb +1 -1
  281. data/lib/repull/models/listing_segments_response_scope.rb +1 -1
  282. data/lib/repull/models/listing_status_batch_request.rb +212 -0
  283. data/lib/repull/models/{sandbox_reset_result.rb → listing_status_batch_response.rb} +57 -51
  284. data/lib/repull/models/listing_updated_event.rb +1 -1
  285. data/lib/repull/models/listing_updated_payload.rb +1 -1
  286. data/lib/repull/models/map_airbnb_listing_request.rb +1 -1
  287. data/lib/repull/models/map_airbnb_listing_response.rb +1 -1
  288. data/lib/repull/models/map_connect_booking_rooms_request.rb +1 -1
  289. data/lib/repull/models/map_connect_booking_rooms_response.rb +16 -5
  290. data/lib/repull/models/market_browse_category.rb +1 -1
  291. data/lib/repull/models/market_browse_entry.rb +1 -1
  292. data/lib/repull/models/market_browse_featured.rb +1 -1
  293. data/lib/repull/models/market_browse_response.rb +1 -1
  294. data/lib/repull/models/market_calendar_day.rb +1 -1
  295. data/lib/repull/models/market_calendar_day_events_inner.rb +1 -1
  296. data/lib/repull/models/market_calendar_response.rb +1 -1
  297. data/lib/repull/models/market_detail_response.rb +1 -1
  298. data/lib/repull/models/market_detail_response_price_distribution_inner.rb +1 -1
  299. data/lib/repull/models/market_detail_response_property_type_mix_inner.rb +1 -1
  300. data/lib/repull/models/market_detail_response_supply_trend_inner.rb +1 -1
  301. data/lib/repull/models/market_detail_response_top_comps.rb +1 -1
  302. data/lib/repull/models/market_event.rb +1 -1
  303. data/lib/repull/models/market_my_listing.rb +1 -1
  304. data/lib/repull/models/market_summary.rb +1 -1
  305. data/lib/repull/models/market_top_comp.rb +1 -1
  306. data/lib/repull/models/markets_overview_response.rb +1 -1
  307. data/lib/repull/models/markets_overview_response_browse.rb +1 -1
  308. data/lib/repull/models/markets_overview_response_subscriptions.rb +1 -1
  309. data/lib/repull/models/markets_overview_response_totals.rb +1 -1
  310. data/lib/repull/models/message.rb +1 -1
  311. data/lib/repull/models/message_list_response.rb +1 -1
  312. data/lib/repull/models/pagination.rb +1 -1
  313. data/lib/repull/models/payment_completed_event.rb +1 -1
  314. data/lib/repull/models/payment_completed_payload.rb +1 -1
  315. data/lib/repull/models/payment_refunded_event.rb +1 -1
  316. data/lib/repull/models/payment_refunded_payload.rb +1 -1
  317. data/lib/repull/models/plumguide_listing.rb +1 -1
  318. data/lib/repull/models/plumguide_listing_list_response.rb +1 -1
  319. data/lib/repull/models/property.rb +17 -7
  320. data/lib/repull/models/property_availability.rb +33 -7
  321. data/lib/repull/models/property_availability_coverage.rb +222 -0
  322. data/lib/repull/models/property_availability_day.rb +4 -4
  323. data/lib/repull/models/property_list_response.rb +1 -1
  324. data/lib/repull/models/{studio_error_error.rb → publish_section_error.rb} +56 -36
  325. data/lib/repull/models/quote.rb +240 -0
  326. data/lib/repull/models/quote_pricing.rb +218 -0
  327. data/lib/repull/models/reorder_airbnb_listing_photos200_response.rb +191 -0
  328. data/lib/repull/models/reorder_airbnb_listing_photos200_response_data.rb +172 -0
  329. data/lib/repull/models/reorder_airbnb_listing_photos_request.rb +185 -0
  330. data/lib/repull/models/reply_booking_review200_response.rb +1 -1
  331. data/lib/repull/models/reply_booking_review_request.rb +1 -1
  332. data/lib/repull/models/reply_to_review201_response.rb +165 -0
  333. data/lib/repull/models/reply_to_review_request.rb +165 -0
  334. data/lib/repull/models/repull_ping_event.rb +1 -1
  335. data/lib/repull/models/repull_ping_payload.rb +1 -1
  336. data/lib/repull/models/reservation.rb +24 -2
  337. data/lib/repull/models/{studio_deployment.rb → reservation_alteration_created_event.rb} +67 -57
  338. data/lib/repull/models/reservation_alteration_created_payload.rb +177 -0
  339. data/lib/repull/models/reservation_alteration_responded_event.rb +217 -0
  340. data/lib/repull/models/reservation_alteration_responded_payload.rb +175 -0
  341. data/lib/repull/models/reservation_cancelled_event.rb +1 -1
  342. data/lib/repull/models/reservation_cancelled_payload.rb +1 -1
  343. data/lib/repull/models/reservation_create_request.rb +403 -0
  344. data/lib/repull/models/{create_airbnb_alteration_request.rb → reservation_create_response.rb} +73 -35
  345. data/lib/repull/models/reservation_created_event.rb +1 -1
  346. data/lib/repull/models/reservation_created_payload.rb +1 -1
  347. data/lib/repull/models/reservation_financials.rb +36 -8
  348. data/lib/repull/models/reservation_guest_financials.rb +173 -0
  349. data/lib/repull/models/reservation_guest_input.rb +193 -0
  350. data/lib/repull/models/reservation_host_financials.rb +207 -0
  351. data/lib/repull/models/reservation_list_response.rb +1 -1
  352. data/lib/repull/models/reservation_message_received_event.rb +1 -1
  353. data/lib/repull/models/reservation_message_received_payload.rb +1 -1
  354. data/lib/repull/models/reservation_message_received_payload_from.rb +1 -1
  355. data/lib/repull/models/reservation_money_line.rb +216 -0
  356. data/lib/repull/models/reservation_occupancy.rb +1 -1
  357. data/lib/repull/models/reservation_primary_guest.rb +1 -1
  358. data/lib/repull/models/reservation_update_request.rb +255 -0
  359. data/lib/repull/models/reservation_update_response.rb +240 -0
  360. data/lib/repull/models/reservation_updated_event.rb +1 -1
  361. data/lib/repull/models/reservation_updated_payload.rb +1 -1
  362. data/lib/repull/models/reservation_webhook_object.rb +39 -6
  363. data/lib/repull/models/respond_airbnb_review_request.rb +1 -1
  364. data/lib/repull/models/review.rb +14 -3
  365. data/lib/repull/models/review_category.rb +1 -1
  366. data/lib/repull/models/review_created_event.rb +217 -0
  367. data/lib/repull/models/review_created_payload.rb +165 -0
  368. data/lib/repull/models/review_list_response.rb +1 -1
  369. data/lib/repull/models/review_responded_event.rb +217 -0
  370. data/lib/repull/models/review_responded_payload.rb +175 -0
  371. data/lib/repull/models/review_response.rb +1 -1
  372. data/lib/repull/models/review_webhook_object.rb +277 -0
  373. data/lib/repull/models/rotate_webhook_secret200_response.rb +1 -1
  374. data/lib/repull/models/select_connect_provider_request.rb +1 -1
  375. data/lib/repull/models/select_provider_response.rb +1 -1
  376. data/lib/repull/models/send_airbnb_message_request.rb +187 -0
  377. data/lib/repull/models/{sandbox_reset_result_deleted.rb → send_booking_message_request.rb} +53 -50
  378. data/lib/repull/models/send_message_request.rb +193 -0
  379. data/lib/repull/models/send_message_response.rb +241 -0
  380. data/lib/repull/models/set_airbnb_listing_cover_photo200_response.rb +191 -0
  381. data/lib/repull/models/set_airbnb_listing_cover_photo200_response_data.rb +171 -0
  382. data/lib/repull/models/set_airbnb_listing_cover_photo_request.rb +165 -0
  383. data/lib/repull/models/set_kv_request.rb +1 -1
  384. data/lib/repull/models/{booking_property_list_response.rb → submit_beds24_credentials200_response.rb} +19 -19
  385. data/lib/repull/models/submit_beds24_credentials_request.rb +177 -0
  386. data/lib/repull/models/submit_bookingsync_credentials_request.rb +177 -0
  387. data/lib/repull/models/submit_guesty_credentials_request.rb +177 -0
  388. data/lib/repull/models/submit_hospitable_credentials_request.rb +177 -0
  389. data/lib/repull/models/submit_hostaway_credentials_request.rb +177 -0
  390. data/lib/repull/models/submit_igms_credentials_request.rb +177 -0
  391. data/lib/repull/models/submit_lodgify_credentials_request.rb +177 -0
  392. data/lib/repull/models/submit_ownerrez_credentials_request.rb +177 -0
  393. data/lib/repull/models/submit_smoobu_credentials_request.rb +177 -0
  394. data/lib/repull/models/submit_vrbo_credentials_request.rb +177 -0
  395. data/lib/repull/models/sync_airbnb_transactions200_response.rb +191 -0
  396. data/lib/repull/models/sync_airbnb_transactions_request.rb +201 -0
  397. data/lib/repull/models/test_webhook_request.rb +1 -1
  398. data/lib/repull/models/{booking_conversation_list_response.rb → update_airbnb_booking_settings200_response.rb} +26 -20
  399. data/lib/repull/models/update_airbnb_booking_settings200_response_data.rb +205 -0
  400. data/lib/repull/models/update_airbnb_booking_settings_request.rb +202 -0
  401. data/lib/repull/models/update_airbnb_booking_settings_request_advance_notice.rb +183 -0
  402. data/lib/repull/models/update_airbnb_booking_settings_request_booking_window.rb +183 -0
  403. data/lib/repull/models/update_airbnb_booking_settings_request_cancellation.rb +201 -0
  404. data/lib/repull/models/update_airbnb_booking_settings_request_cancellation_non_refundable.rb +183 -0
  405. data/lib/repull/models/update_airbnb_booking_settings_request_check_in.rb +159 -0
  406. data/lib/repull/models/update_airbnb_booking_settings_request_check_out.rb +182 -0
  407. data/lib/repull/models/update_airbnb_booking_settings_request_instant_book.rb +203 -0
  408. data/lib/repull/models/update_airbnb_booking_settings_request_preparation_time.rb +182 -0
  409. data/lib/repull/models/update_airbnb_listing_amenities200_response.rb +191 -0
  410. data/lib/repull/models/update_airbnb_listing_amenities200_response_data.rb +158 -0
  411. data/lib/repull/models/update_airbnb_listing_amenities_request.rb +199 -0
  412. data/lib/repull/models/update_airbnb_listing_amenities_request_accessibility_amenities_inner.rb +246 -0
  413. data/lib/repull/models/update_airbnb_listing_amenities_request_amenities_inner.rb +218 -0
  414. data/lib/repull/models/update_airbnb_listing_permits200_response.rb +168 -0
  415. data/lib/repull/models/update_airbnb_listing_photo200_response.rb +194 -0
  416. data/lib/repull/models/update_airbnb_listing_photo_request.rb +242 -0
  417. data/lib/repull/models/update_airbnb_listing_room200_response.rb +194 -0
  418. data/lib/repull/models/update_airbnb_listing_room_request.rb +293 -0
  419. data/lib/repull/models/update_airbnb_listing_room_request_beds_inner.rb +209 -0
  420. data/lib/repull/models/{sandbox_fixture_ref.rb → update_airbnb_listing_room_request_room_amenities_inner.rb} +26 -37
  421. data/lib/repull/models/update_airbnb_listing_room_request_room_amenities_inner_value.rb +105 -0
  422. data/lib/repull/models/update_airbnb_listing_safety_disclosures200_response.rb +180 -0
  423. data/lib/repull/models/update_airbnb_message_request.rb +1 -1
  424. data/lib/repull/models/update_booking_charges_request.rb +1 -1
  425. data/lib/repull/models/update_listing_pricing_strategy200_response.rb +1 -1
  426. data/lib/repull/models/update_webhook_request.rb +1 -1
  427. data/lib/repull/models/upload_airbnb_listing_photos_request.rb +184 -0
  428. data/lib/repull/models/upload_airbnb_listing_photos_request_photos_inner.rb +305 -0
  429. data/lib/repull/models/upload_airbnb_listing_photos_request_photos_inner_listing_id.rb +105 -0
  430. data/lib/repull/models/vrbo_listing.rb +1 -1
  431. data/lib/repull/models/vrbo_reservation.rb +1 -1
  432. data/lib/repull/models/vrbo_reservation_list_response.rb +1 -1
  433. data/lib/repull/models/webhook_delivery.rb +1 -1
  434. data/lib/repull/models/webhook_delivery_detail.rb +1 -1
  435. data/lib/repull/models/webhook_delivery_list_response.rb +1 -1
  436. data/lib/repull/models/webhook_event.rb +12 -4
  437. data/lib/repull/models/webhook_event_catalog.rb +1 -1
  438. data/lib/repull/models/webhook_event_catalog_domains_inner.rb +1 -1
  439. data/lib/repull/models/webhook_event_catalog_entry.rb +1 -1
  440. data/lib/repull/models/webhook_event_type.rb +6 -2
  441. data/lib/repull/models/webhook_list_response.rb +1 -1
  442. data/lib/repull/models/webhook_subscription.rb +1 -1
  443. data/lib/repull/version.rb +2 -2
  444. data/lib/repull.rb +153 -16
  445. data/openapi/v1.json +12620 -5281
  446. data/scripts/check-spec-freshness.py +399 -0
  447. data/scripts/regen.sh +32 -3
  448. metadata +155 -19
  449. data/lib/repull/api/sandbox_api.rb +0 -136
  450. data/lib/repull/models/sandbox_seed_result.rb +0 -278
  451. data/lib/repull/models/studio_generation.rb +0 -215
  452. data/lib/repull/models/studio_project.rb +0 -241
  453. data/spec/api/ai_api_spec.rb +0 -47
@@ -1,7 +1,7 @@
1
1
  =begin
2
2
  #Repull API
3
3
 
4
- #The unified API for vacation rental tech. Connect to 50+ PMS platforms and 4 OTA channels through one REST API. Built-in AI operations for guest communication, pricing, and listing optimization. ## Designed for AI agents Every error response on this API includes machine-parseable fields so an LLM (Claude in MCP, Cursor, Cline, GPT, etc.) can self-recover without escalating to a human: - `error.code` — stable string identifier (e.g. `invalid_params`, `rate_limit_exceeded`) - `error.message` — human-readable cause - `error.fix` — exact recovery steps (e.g. \"Pass `check_in_after` as ISO 8601: `?check_in_after=2026-01-15`\") - `error.docs_url` — link to the canonical write-up at `https://repull.dev/docs/errors/{code}` - `error.request_id` — id to correlate with server-side logs - `error.field` / `error.value_received` / `error.valid_values` / `error.did_you_mean` — when the error is parameter-specific - `error.retry_after` — seconds to wait before retrying (rate-limit + transient upstream) `Access-Control-Expose-Headers` lists `x-request-id` and the `X-RateLimit-*` family so browsers can read them on cross-origin responses. ## Quick Start 1. Get an API key at https://repull.dev/dashboard 2. Connect a PMS: `POST /v1/connect/{provider}` 3. List properties: `GET /v1/properties` 4. Get reservations: `GET /v1/reservations` ## Authentication All requests require a Bearer token: ``` Authorization: Bearer sk_test_YOUR_API_KEY ``` Sandbox keys start with `sk_test_`, production with `sk_live_`. ## Request Correlation (X-Request-ID) Every response carries an `X-Request-ID` header, e.g. `X-Request-ID: req_01HXY...`. Include this id in support tickets and bug reports — we can trace the full request lifecycle (auth, rate limit, handler, downstream calls, log row) from a single id. You may set the header on the inbound request to forward your own trace id; we will echo it back instead of generating a new one. Accepted format: `^[\\\\w.-]{1,128}$`. The id is also embedded in error envelopes as `request_id` so server-side log diffs work even when the response headers are stripped by an intermediate proxy. ## Rate Limits The public API enforces a per-API-key sliding-window rate limit on top of the per-tier monthly + daily-AI quotas. **Default policy:** 600 requests per 60 seconds, per API key. Sliding window — there is no fixed-minute boundary you can burst across. Every response includes: | Header | Meaning | |---|---| | `X-RateLimit-Limit` | Requests permitted in the current window. | | `X-RateLimit-Remaining` | Requests left in the current window after this call. | | `X-RateLimit-Reset` | Unix epoch (seconds) when the next slot opens. | | `X-RateLimit-Policy` | Machine-readable policy descriptor, e.g. `600;w=60`. | | `Retry-After` | Seconds to wait before retrying. **Only present on 429 responses.** | **On 429 (rate_limit_exceeded):** the response body matches the standard error envelope with `code: \"rate_limit_exceeded\"`, plus `limit`, `window_seconds`, `retry_after`, and `request_id` fields. SDKs MUST honor `Retry-After` and use exponential backoff with jitter on subsequent retries — never a tight loop. Recommended backoff: ``` sleep_ms = (Retry-After * 1000) + random(0..250) ``` Monthly + daily-AI tier quotas (`free`, `starter`, `custom`) are enforced separately and also surface as 429s; they include `tier`, `scope`, and `resets_at` fields. ## Plan Limits (402 — `listings_limit_exceeded`) The Repull API also enforces a per-tier cap on **active listings**: | Tier | Active listings cap | |---|---| | `free` | 3 | | `starter` | 50 | | `custom` | unlimited | When a customer's active-listing count is above their tier cap, the API returns **`402 Payment Required`** with `error.code = \"listings_limit_exceeded\"` on every route EXCEPT: - `/v1/health` — uptime probes are never gated. - `/v1/usage/*` — so dashboards can render the over-cap state. - Any `DELETE` — so the customer can trim listings to get back under the cap without paying. Unlike 429, 402 is NOT a \"wait and retry\" condition — `Retry-After` is not set. The only paths back to 200 are: 1. `DELETE` enough listings to come back under the cap, or 2. Upgrade at `https://repull.dev/dashboard/billing`. The server-side usage cache is 60s, so the first 200 after an upgrade may take up to a minute. The envelope mirrors `rate_limit_exceeded` for SDK ergonomics: `tier`, `limit`, `active_listings`, `upgrade_url`, plus the standard `code` / `message` / `fix` / `docs_url` / `request_id`.
4
+ #The unified API for vacation rental tech. Connect to 50+ PMS platforms and 4 OTA channels through one REST API. Built-in AI operations for guest communication, pricing, and listing optimization. ## Designed for AI agents Every error response on this API includes machine-parseable fields so an LLM (Claude in MCP, Cursor, Cline, GPT, etc.) can self-recover without escalating to a human: - `error.code` — stable string identifier (e.g. `invalid_params`, `rate_limit_exceeded`) - `error.message` — human-readable cause - `error.fix` — exact recovery steps (e.g. \"Pass `check_in_after` as ISO 8601: `?check_in_after=2026-01-15`\") - `error.docs_url` — link to the canonical write-up at `https://repull.dev/docs/errors/{code}` - `error.request_id` — id to correlate with server-side logs - `error.field` / `error.value_received` / `error.valid_values` / `error.did_you_mean` — when the error is parameter-specific - `error.retry_after` — seconds to wait before retrying (rate-limit + transient upstream) `Access-Control-Expose-Headers` lists `x-request-id` and the `X-RateLimit-*` family so browsers can read them on cross-origin responses. ## Quick Start 1. Get an API key at https://repull.dev/dashboard 2. Connect a PMS: `POST /v1/connect/{provider}` 3. List properties: `GET /v1/properties` 4. Get reservations: `GET /v1/reservations` ## Authentication All requests require a Bearer token: ``` Authorization: Bearer sk_live_YOUR_API_KEY ``` ## Request Correlation (X-Request-ID) Every response carries an `X-Request-ID` header, e.g. `X-Request-ID: req_01HXY...`. Include this id in support tickets and bug reports — we can trace the full request lifecycle (auth, rate limit, handler, downstream calls, log row) from a single id. You may set the header on the inbound request to forward your own trace id; we will echo it back instead of generating a new one. Accepted format: `^[\\\\w.-]{1,128}$`. The id is also embedded in error envelopes as `request_id` so server-side log diffs work even when the response headers are stripped by an intermediate proxy. ## Rate Limits The public API enforces a per-API-key sliding-window rate limit on top of the per-tier monthly + daily-AI quotas. **Default policy:** 600 requests per 60 seconds, per API key. Sliding window — there is no fixed-minute boundary you can burst across. Every response includes: | Header | Meaning | |---|---| | `X-RateLimit-Limit` | Requests permitted in the current window. | | `X-RateLimit-Remaining` | Requests left in the current window after this call. | | `X-RateLimit-Reset` | Unix epoch (seconds) when the next slot opens. | | `X-RateLimit-Policy` | Machine-readable policy descriptor, e.g. `600;w=60`. | | `Retry-After` | Seconds to wait before retrying. **Only present on 429 responses.** | **On 429 (rate_limit_exceeded):** the response body matches the standard error envelope with `code: \"rate_limit_exceeded\"`, plus `limit`, `window_seconds`, `retry_after`, and `request_id` fields. SDKs MUST honor `Retry-After` and use exponential backoff with jitter on subsequent retries — never a tight loop. Recommended backoff: ``` sleep_ms = (Retry-After * 1000) + random(0..250) ``` Monthly + daily-AI tier quotas (`free`, `starter`, `custom`) are enforced separately and also surface as 429s; they include `tier`, `scope`, and `resetsAt` fields. ## Plan Limits (402 — `listings_limit_exceeded`) The Repull API also enforces a per-tier cap on **active listings**: | Tier | Active listings cap | |---|---| | `free` | 3 | | `starter` | 50 | | `custom` | unlimited | When a customer's active-listing count is above their tier cap, the API returns **`402 Payment Required`** with `error.code = \"listings_limit_exceeded\"` on every route EXCEPT: - `/v1/health` — uptime probes are never gated. - `/v1/usage/*` — so dashboards can render the over-cap state. - Any `DELETE` — so the customer can trim listings to get back under the cap without paying. Unlike 429, 402 is NOT a \"wait and retry\" condition — `Retry-After` is not set. The only paths back to 200 are: 1. `DELETE` enough listings to come back under the cap, or 2. Upgrade at `https://repull.dev/dashboard/billing`. The server-side usage cache is 60s, so the first 200 after an upgrade may take up to a minute. The envelope mirrors `rate_limit_exceeded` for SDK ergonomics: `tier`, `limit`, `active_listings`, `upgrade_url`, plus the standard `code` / `message` / `fix` / `docs_url` / `request_id`.
5
5
 
6
6
  The version of the OpenAPI document: 1.0.0
7
7
  Contact: ivan@vanio.ai
@@ -87,8 +87,82 @@ module Repull
87
87
  return data, status_code, headers
88
88
  end
89
89
 
90
+ # Mint a direct-to-storage photo upload URL
91
+ # Mints a short-lived signed upload URL + token for a listing photo. **The client PUTs the raw file bytes directly to the returned `uploadUrl` — the file bytes never pass through the Repull API or main vanio.** This endpoint only mints the URL; do not POST the file itself here, it will not be accepted. Flow: (1) POST here with `fileName`/`fileType`/optional `fileSize` to get `{ uploadUrl, token, path, publicUrl, expiresIn }`; (2) PUT the raw file bytes to `uploadUrl` from the client; (3) `publicUrl` is the durable URL for the uploaded photo — attach it to the listing via `PUT /v1/listings/{id}/content` (`photos` field) or list it back via `GET /v1/listings/{id}/photos`. 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.
92
+ # @param id [Integer] Repull listing id
93
+ # @param listing_photo_upload_url_request [ListingPhotoUploadUrlRequest]
94
+ # @param [Hash] opts the optional parameters
95
+ # @return [ListingPhotoUploadUrlResponse]
96
+ def create_listing_photo_upload_url(id, listing_photo_upload_url_request, opts = {})
97
+ data, _status_code, _headers = create_listing_photo_upload_url_with_http_info(id, listing_photo_upload_url_request, opts)
98
+ data
99
+ end
100
+
101
+ # Mint a direct-to-storage photo upload URL
102
+ # Mints a short-lived signed upload URL + token for a listing photo. **The client PUTs the raw file bytes directly to the returned `uploadUrl` — the file bytes never pass through the Repull API or main vanio.** This endpoint only mints the URL; do not POST the file itself here, it will not be accepted. Flow: (1) POST here with `fileName`/`fileType`/optional `fileSize` to get `{ uploadUrl, token, path, publicUrl, expiresIn }`; (2) PUT the raw file bytes to `uploadUrl` from the client; (3) `publicUrl` is the durable URL for the uploaded photo — attach it to the listing via `PUT /v1/listings/{id}/content` (`photos` field) or list it back via `GET /v1/listings/{id}/photos`. 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.
103
+ # @param id [Integer] Repull listing id
104
+ # @param listing_photo_upload_url_request [ListingPhotoUploadUrlRequest]
105
+ # @param [Hash] opts the optional parameters
106
+ # @return [Array<(ListingPhotoUploadUrlResponse, Integer, Hash)>] ListingPhotoUploadUrlResponse data, response status code and response headers
107
+ def create_listing_photo_upload_url_with_http_info(id, listing_photo_upload_url_request, opts = {})
108
+ if @api_client.config.debugging
109
+ @api_client.config.logger.debug 'Calling API: ListingsApi.create_listing_photo_upload_url ...'
110
+ end
111
+ # verify the required parameter 'id' is set
112
+ if @api_client.config.client_side_validation && id.nil?
113
+ fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.create_listing_photo_upload_url"
114
+ end
115
+ # verify the required parameter 'listing_photo_upload_url_request' is set
116
+ if @api_client.config.client_side_validation && listing_photo_upload_url_request.nil?
117
+ fail ArgumentError, "Missing the required parameter 'listing_photo_upload_url_request' when calling ListingsApi.create_listing_photo_upload_url"
118
+ end
119
+ # resource path
120
+ local_var_path = '/v1/listings/{id}/photos/upload-url'.sub('{id}', CGI.escape(id.to_s))
121
+
122
+ # query parameters
123
+ query_params = opts[:query_params] || {}
124
+
125
+ # header parameters
126
+ header_params = opts[:header_params] || {}
127
+ # HTTP header 'Accept' (if needed)
128
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
129
+ # HTTP header 'Content-Type'
130
+ content_type = @api_client.select_header_content_type(['application/json'])
131
+ if !content_type.nil?
132
+ header_params['Content-Type'] = content_type
133
+ end
134
+
135
+ # form parameters
136
+ form_params = opts[:form_params] || {}
137
+
138
+ # http body (model)
139
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(listing_photo_upload_url_request)
140
+
141
+ # return_type
142
+ return_type = opts[:debug_return_type] || 'ListingPhotoUploadUrlResponse'
143
+
144
+ # auth_names
145
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
146
+
147
+ new_options = opts.merge(
148
+ :operation => :"ListingsApi.create_listing_photo_upload_url",
149
+ :header_params => header_params,
150
+ :query_params => query_params,
151
+ :form_params => form_params,
152
+ :body => post_body,
153
+ :auth_names => auth_names,
154
+ :return_type => return_type
155
+ )
156
+
157
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
158
+ if @api_client.config.debugging
159
+ @api_client.config.logger.debug "API called: ListingsApi#create_listing_photo_upload_url\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
160
+ end
161
+ return data, status_code, headers
162
+ end
163
+
90
164
  # Deactivate (exclude) a listing
91
- # Deactivate a listing — sets it inactive and excludes it from Repull. This is a **soft** operation: the listing row is KEPT (never hard-deleted) and the upstream channel (Airbnb / Hospitable / Booking.com) is NEVER touched. Repull only mutates its own copy. Equivalent to `PATCH /v1/listings/{id}` with `{ \"active\": false }`. This is the primary self-serve way for a free-tier customer to trim back under the plan-listings cap — `DELETE` is served even when the account is over the cap (a 402-locked account can still call it). To bring a listing back, use `PATCH` with `{ \"active\": true }`. Idempotent: deactivating an already-inactive listing returns 200.
165
+ # Deactivate a listing — sets it inactive and excludes it from Repull. This is a **soft** operation: the listing row is KEPT (never hard-deleted) and the upstream channel (Airbnb / Hospitable / Booking.com) is NEVER touched. Repull only mutates its own copy. Equivalent to `PATCH /v1/listings/{id}` with `{ \"active\": false }`. This is the primary self-serve way for a free-tier customer to trim back under the plan-listings cap — `DELETE` is served even when the account is over the cap (a 402-locked account can still call it). To bring a listing back, use `PATCH` with `{ \"active\": true }`. Idempotent: deactivating an already-inactive listing returns 200. To deactivate many listings at once, use `POST /v1/listings/status` with `{ \"active\": false }`.
92
166
  # @param id [Integer] Repull listing id
93
167
  # @param [Hash] opts the optional parameters
94
168
  # @return [ListingActiveResponse]
@@ -98,7 +172,7 @@ module Repull
98
172
  end
99
173
 
100
174
  # Deactivate (exclude) a listing
101
- # Deactivate a listing — sets it inactive and excludes it from Repull. This is a **soft** operation: the listing row is KEPT (never hard-deleted) and the upstream channel (Airbnb / Hospitable / Booking.com) is NEVER touched. Repull only mutates its own copy. Equivalent to &#x60;PATCH /v1/listings/{id}&#x60; with &#x60;{ \&quot;active\&quot;: false }&#x60;. This is the primary self-serve way for a free-tier customer to trim back under the plan-listings cap — &#x60;DELETE&#x60; is served even when the account is over the cap (a 402-locked account can still call it). To bring a listing back, use &#x60;PATCH&#x60; with &#x60;{ \&quot;active\&quot;: true }&#x60;. Idempotent: deactivating an already-inactive listing returns 200.
175
+ # Deactivate a listing — sets it inactive and excludes it from Repull. This is a **soft** operation: the listing row is KEPT (never hard-deleted) and the upstream channel (Airbnb / Hospitable / Booking.com) is NEVER touched. Repull only mutates its own copy. Equivalent to &#x60;PATCH /v1/listings/{id}&#x60; with &#x60;{ \&quot;active\&quot;: false }&#x60;. This is the primary self-serve way for a free-tier customer to trim back under the plan-listings cap — &#x60;DELETE&#x60; is served even when the account is over the cap (a 402-locked account can still call it). To bring a listing back, use &#x60;PATCH&#x60; with &#x60;{ \&quot;active\&quot;: true }&#x60;. Idempotent: deactivating an already-inactive listing returns 200. To deactivate many listings at once, use &#x60;POST /v1/listings/status&#x60; with &#x60;{ \&quot;active\&quot;: false }&#x60;.
102
176
  # @param id [Integer] Repull listing id
103
177
  # @param [Hash] opts the optional parameters
104
178
  # @return [Array<(ListingActiveResponse, Integer, Hash)>] ListingActiveResponse data, response status code and response headers
@@ -150,8 +224,82 @@ module Repull
150
224
  return data, status_code, headers
151
225
  end
152
226
 
227
+ # Delete a stored listing photo
228
+ # Deletes a single stored photo by its storage `path` (as returned by `GET /v1/listings/{id}/photos` or `POST /v1/listings/{id}/photos/upload-url`). 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.
229
+ # @param id [Integer] Repull listing id
230
+ # @param listing_photo_delete_request [ListingPhotoDeleteRequest]
231
+ # @param [Hash] opts the optional parameters
232
+ # @return [ListingPhotoDeleteResponse]
233
+ def delete_listing_photo(id, listing_photo_delete_request, opts = {})
234
+ data, _status_code, _headers = delete_listing_photo_with_http_info(id, listing_photo_delete_request, opts)
235
+ data
236
+ end
237
+
238
+ # Delete a stored listing photo
239
+ # Deletes a single stored photo by its storage &#x60;path&#x60; (as returned by &#x60;GET /v1/listings/{id}/photos&#x60; or &#x60;POST /v1/listings/{id}/photos/upload-url&#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.
240
+ # @param id [Integer] Repull listing id
241
+ # @param listing_photo_delete_request [ListingPhotoDeleteRequest]
242
+ # @param [Hash] opts the optional parameters
243
+ # @return [Array<(ListingPhotoDeleteResponse, Integer, Hash)>] ListingPhotoDeleteResponse data, response status code and response headers
244
+ def delete_listing_photo_with_http_info(id, listing_photo_delete_request, opts = {})
245
+ if @api_client.config.debugging
246
+ @api_client.config.logger.debug 'Calling API: ListingsApi.delete_listing_photo ...'
247
+ end
248
+ # verify the required parameter 'id' is set
249
+ if @api_client.config.client_side_validation && id.nil?
250
+ fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.delete_listing_photo"
251
+ end
252
+ # verify the required parameter 'listing_photo_delete_request' is set
253
+ if @api_client.config.client_side_validation && listing_photo_delete_request.nil?
254
+ fail ArgumentError, "Missing the required parameter 'listing_photo_delete_request' when calling ListingsApi.delete_listing_photo"
255
+ end
256
+ # resource path
257
+ local_var_path = '/v1/listings/{id}/photos'.sub('{id}', CGI.escape(id.to_s))
258
+
259
+ # query parameters
260
+ query_params = opts[:query_params] || {}
261
+
262
+ # header parameters
263
+ header_params = opts[:header_params] || {}
264
+ # HTTP header 'Accept' (if needed)
265
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
266
+ # HTTP header 'Content-Type'
267
+ content_type = @api_client.select_header_content_type(['application/json'])
268
+ if !content_type.nil?
269
+ header_params['Content-Type'] = content_type
270
+ end
271
+
272
+ # form parameters
273
+ form_params = opts[:form_params] || {}
274
+
275
+ # http body (model)
276
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(listing_photo_delete_request)
277
+
278
+ # return_type
279
+ return_type = opts[:debug_return_type] || 'ListingPhotoDeleteResponse'
280
+
281
+ # auth_names
282
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
283
+
284
+ new_options = opts.merge(
285
+ :operation => :"ListingsApi.delete_listing_photo",
286
+ :header_params => header_params,
287
+ :query_params => query_params,
288
+ :form_params => form_params,
289
+ :body => post_body,
290
+ :auth_names => auth_names,
291
+ :return_type => return_type
292
+ )
293
+
294
+ data, status_code, headers = @api_client.call_api(:DELETE, local_var_path, new_options)
295
+ if @api_client.config.debugging
296
+ @api_client.config.logger.debug "API called: ListingsApi#delete_listing_photo\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
297
+ end
298
+ return data, status_code, headers
299
+ end
300
+
153
301
  # AI-generate listing content
154
- # Generate guest-facing copy (title, summary, description, amenities, etc.) for a listing using Repull AI. When `photos` are provided the vision model is used for photo-grounded copy. Persists into the listing by default.
302
+ # Generate guest-facing copy (title, summary, description, amenities, etc.) for a listing using Repull AI. When `photos` are provided the vision model is used for photo-grounded copy. Persists into the listing by default. 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.
155
303
  # @param id [Integer]
156
304
  # @param [Hash] opts the optional parameters
157
305
  # @option opts [ListingGenerateContentRequest] :listing_generate_content_request
@@ -162,7 +310,7 @@ module Repull
162
310
  end
163
311
 
164
312
  # AI-generate listing content
165
- # Generate guest-facing copy (title, summary, description, amenities, etc.) for a listing using Repull AI. When &#x60;photos&#x60; are provided the vision model is used for photo-grounded copy. Persists into the listing by default.
313
+ # Generate guest-facing copy (title, summary, description, amenities, etc.) for a listing using Repull AI. When &#x60;photos&#x60; are provided the vision model is used for photo-grounded copy. Persists into the listing by default. 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.
166
314
  # @param id [Integer]
167
315
  # @param [Hash] opts the optional parameters
168
316
  # @option opts [ListingGenerateContentRequest] :listing_generate_content_request
@@ -221,7 +369,7 @@ module Repull
221
369
  end
222
370
 
223
371
  # Get a listing
224
- # Fetch a single listing by id. Returns the same shape as one element of the `GET /v1/listings` response, so you can bind the result to the same model. Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403, never reveals the listing's existence. **Optional expansions:** Pass `?include=amenities` to enrich the response with the listing's amenity rows (`[]` when the listing has none). Pass `?include=content` for the rich content slab (summary, description, space, house rules, etc. — sourced from `listings_descriptions` for the `en` locale; `null` when no row is stored). Pass `?include=details` for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.; `null` when no row is stored). Combine comma-separated, e.g. `?include=amenities,content,details`. The default response stays lean; consumers must opt in.
372
+ # Fetch a single listing by id. Returns the same shape as one element of the `GET /v1/listings` response, so you can bind the result to the same model. Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403, never reveals the listing's existence. **Optional expansions:** Pass `?include=amenities` to enrich the response with the listing's amenity rows (`[]` when the listing has none). Pass `?include=content` for the rich content slab (summary, description, space, house rules, etc. — sourced from `listings_descriptions` for the `en` locale; `null` when no row is stored). Pass `?include=details` for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.; `null` when no row is stored). Combine comma-separated, e.g. `?include=amenities,content,details`. The default response stays lean; consumers must opt in. 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.
225
373
  # @param id [Integer] Repull listing id
226
374
  # @param [Hash] opts the optional parameters
227
375
  # @option opts [String] :x_schema Apply a custom or built-in schema to transform the response. Built-in: &#x60;native&#x60; (default), &#x60;calry&#x60;, &#x60;calry-v1&#x60;. Custom: any schema name created via &#x60;POST /v1/schema/custom&#x60;. Unknown / inactive schema names fall back to &#x60;native&#x60;.
@@ -233,7 +381,7 @@ module Repull
233
381
  end
234
382
 
235
383
  # Get a listing
236
- # Fetch a single listing by id. Returns the same shape as one element of the &#x60;GET /v1/listings&#x60; response, so you can bind the result to the same model. Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403, never reveals the listing&#39;s existence. **Optional expansions:** Pass &#x60;?include&#x3D;amenities&#x60; to enrich the response with the listing&#39;s amenity rows (&#x60;[]&#x60; when the listing has none). Pass &#x60;?include&#x3D;content&#x60; for the rich content slab (summary, description, space, house rules, etc. — sourced from &#x60;listings_descriptions&#x60; for the &#x60;en&#x60; locale; &#x60;null&#x60; when no row is stored). Pass &#x60;?include&#x3D;details&#x60; for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.; &#x60;null&#x60; when no row is stored). Combine comma-separated, e.g. &#x60;?include&#x3D;amenities,content,details&#x60;. The default response stays lean; consumers must opt in.
384
+ # Fetch a single listing by id. Returns the same shape as one element of the &#x60;GET /v1/listings&#x60; response, so you can bind the result to the same model. Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403, never reveals the listing&#39;s existence. **Optional expansions:** Pass &#x60;?include&#x3D;amenities&#x60; to enrich the response with the listing&#39;s amenity rows (&#x60;[]&#x60; when the listing has none). Pass &#x60;?include&#x3D;content&#x60; for the rich content slab (summary, description, space, house rules, etc. — sourced from &#x60;listings_descriptions&#x60; for the &#x60;en&#x60; locale; &#x60;null&#x60; when no row is stored). Pass &#x60;?include&#x3D;details&#x60; for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.; &#x60;null&#x60; when no row is stored). Combine comma-separated, e.g. &#x60;?include&#x3D;amenities,content,details&#x60;. The default response stays lean; consumers must opt in. 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.
237
385
  # @param id [Integer] Repull listing id
238
386
  # @param [Hash] opts the optional parameters
239
387
  # @option opts [String] :x_schema Apply a custom or built-in schema to transform the response. Built-in: &#x60;native&#x60; (default), &#x60;calry&#x60;, &#x60;calry-v1&#x60;. Custom: any schema name created via &#x60;POST /v1/schema/custom&#x60;. Unknown / inactive schema names fall back to &#x60;native&#x60;.
@@ -290,7 +438,7 @@ module Repull
290
438
  end
291
439
 
292
440
  # Per-channel publish status
293
- # Returns connection state and sync activity per channel. `channels` is sync activity (empty until first push). `connections` is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer `GET /v1/listings` and filter client-side.
441
+ # Returns connection state and sync activity per channel. `channels` is sync activity (empty until first push). `connections` is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer `GET /v1/listings` and filter client-side. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
294
442
  # @param id [Integer]
295
443
  # @param [Hash] opts the optional parameters
296
444
  # @return [ListingPublishStatusResponse]
@@ -300,7 +448,7 @@ module Repull
300
448
  end
301
449
 
302
450
  # Per-channel publish status
303
- # Returns connection state and sync activity per channel. &#x60;channels&#x60; is sync activity (empty until first push). &#x60;connections&#x60; is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer &#x60;GET /v1/listings&#x60; and filter client-side.
451
+ # Returns connection state and sync activity per channel. &#x60;channels&#x60; is sync activity (empty until first push). &#x60;connections&#x60; is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer &#x60;GET /v1/listings&#x60; and filter client-side. 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.
304
452
  # @param id [Integer]
305
453
  # @param [Hash] opts the optional parameters
306
454
  # @return [Array<(ListingPublishStatusResponse, Integer, Hash)>] ListingPublishStatusResponse data, response status code and response headers
@@ -352,17 +500,80 @@ module Repull
352
500
  return data, status_code, headers
353
501
  end
354
502
 
503
+ # List a listing's stored photos
504
+ # Returns the photo set currently stored for this 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.
505
+ # @param id [Integer] Repull listing id
506
+ # @param [Hash] opts the optional parameters
507
+ # @return [ListingPhotosResponse]
508
+ def list_listing_photos(id, opts = {})
509
+ data, _status_code, _headers = list_listing_photos_with_http_info(id, opts)
510
+ data
511
+ end
512
+
513
+ # List a listing&#39;s stored photos
514
+ # Returns the photo set currently stored for this listing. 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.
515
+ # @param id [Integer] Repull listing id
516
+ # @param [Hash] opts the optional parameters
517
+ # @return [Array<(ListingPhotosResponse, Integer, Hash)>] ListingPhotosResponse data, response status code and response headers
518
+ def list_listing_photos_with_http_info(id, opts = {})
519
+ if @api_client.config.debugging
520
+ @api_client.config.logger.debug 'Calling API: ListingsApi.list_listing_photos ...'
521
+ end
522
+ # verify the required parameter 'id' is set
523
+ if @api_client.config.client_side_validation && id.nil?
524
+ fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.list_listing_photos"
525
+ end
526
+ # resource path
527
+ local_var_path = '/v1/listings/{id}/photos'.sub('{id}', CGI.escape(id.to_s))
528
+
529
+ # query parameters
530
+ query_params = opts[:query_params] || {}
531
+
532
+ # header parameters
533
+ header_params = opts[:header_params] || {}
534
+ # HTTP header 'Accept' (if needed)
535
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
536
+
537
+ # form parameters
538
+ form_params = opts[:form_params] || {}
539
+
540
+ # http body (model)
541
+ post_body = opts[:debug_body]
542
+
543
+ # return_type
544
+ return_type = opts[:debug_return_type] || 'ListingPhotosResponse'
545
+
546
+ # auth_names
547
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
548
+
549
+ new_options = opts.merge(
550
+ :operation => :"ListingsApi.list_listing_photos",
551
+ :header_params => header_params,
552
+ :query_params => query_params,
553
+ :form_params => form_params,
554
+ :body => post_body,
555
+ :auth_names => auth_names,
556
+ :return_type => return_type
557
+ )
558
+
559
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
560
+ if @api_client.config.debugging
561
+ @api_client.config.logger.debug "API called: ListingsApi#list_listing_photos\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
562
+ end
563
+ return data, status_code, headers
564
+ end
565
+
355
566
  # List listings
356
- # Cursor-paginated list of listings owned by the authenticated workspace. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request to walk the full set. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. Filters: `q` (substring on name/street/city), `status`, `channel`. **Optional expansions:** Pass `?include=content` to enrich each row with the rich content slab (summary, description, space, house rules, etc. — sourced from `listings_descriptions` for the `en` locale). Pass `?include=details` for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.). Both default to `null` per row when the underlying `listings_descriptions` / `listings_details` row is missing — distinct from the field being absent (which signals the expansion was not requested). Combine comma-separated, e.g. `?include=content,details`. The default response stays lean; consumers must opt in.
567
+ # Cursor-paginated list of listings owned by the authenticated workspace. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request to walk the full set. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. Filters: `q` (substring on name/street/city), `status`, `channel`. **Optional expansions:** Pass `?include=content` to enrich each row with the rich content slab (summary, description, space, house rules, etc. — sourced from `listings_descriptions` for the `en` locale). Pass `?include=details` for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.). Both default to `null` per row when the underlying `listings_descriptions` / `listings_details` row is missing — distinct from the field being absent (which signals the expansion was not requested). Pass `?include=thumbnail` to guarantee `thumbnailUrl` on every returned row — including the reduced inactive ones. Combine comma-separated, e.g. `?include=content,thumbnail`. The default response stays lean; consumers must opt in. **Inactive listings:** by default only active listings are returned. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated, so when `status` asks for inactive ones they carry only `id`, `name`, `status` and `channels` — enough to choose what to activate with `PATCH /v1/listings/{id}`. The `content` and `details` expansions are not applied to them. `?include=thumbnail` is the one exception: it adds `thumbnailUrl` to an inactive row so a single request can render an active/inactive selection screen with pictures, instead of one follow-up call per listing (which an inactive listing would answer with `403 listing_inactive` anyway).
357
568
  # @param [Hash] opts the optional parameters
358
569
  # @option opts [String] :x_schema Apply a custom or built-in schema to transform the response. Built-in: &#x60;native&#x60; (default), &#x60;calry&#x60;, &#x60;calry-v1&#x60;. Custom: any schema name created via &#x60;POST /v1/schema/custom&#x60;. Unknown / inactive schema names fall back to &#x60;native&#x60;.
359
570
  # @option opts [String] :cursor Opaque cursor returned in the previous response&#39;s &#x60;pagination.nextCursor&#x60;. Omit to fetch the first page.
360
- # @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.next_cursor&#x60; so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying. (default to 0)
571
+ # @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)
361
572
  # @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 20)
362
573
  # @option opts [String] :q Case-insensitive substring search on name, street, or city.
363
- # @option opts [String] :status Filter by listing status.
574
+ # @option opts [String] :status Filter by listing status. Defaults to &#x60;active&#x60;. Pass &#x60;inactive&#x60; to list the listings you can activate, &#x60;archived&#x60; for archived ones, or &#x60;all&#x60; for every status. Inactive listings are returned with identity fields only — &#x60;id&#x60;, &#x60;name&#x60;, &#x60;status&#x60; and &#x60;channels&#x60; — and never with &#x60;address&#x60;, &#x60;content&#x60; or &#x60;details&#x60;; activate one to see the rest. The only field you can add to an inactive row is &#x60;thumbnailUrl&#x60;, via &#x60;?include&#x3D;thumbnail&#x60;. (default to 'active')
364
575
  # @option opts [String] :channel Restrict to listings published on the given channel (&#x60;airbnb&#x60;, &#x60;booking&#x60;, &#x60;vrbo&#x60;, etc.). Joins through &#x60;listing_platform_links&#x60; and matches active links only.
365
- # @option opts [String] :include Comma-separated optional expansions. Currently supported: &#x60;content&#x60;, &#x60;details&#x60;. Unknown values return 422 with a &#x60;valid_values&#x60; envelope. (Note: &#x60;amenities&#x60; is not yet supported on the list endpoint — use the detail endpoint to fetch amenity rows for a single listing.)
576
+ # @option opts [String] :include Comma-separated optional expansions. Currently supported: &#x60;content&#x60;, &#x60;details&#x60;, &#x60;thumbnail&#x60;. &#x60;thumbnail&#x60; guarantees &#x60;thumbnailUrl&#x60; on every row and is the only expansion that applies to inactive listings. Unknown values return 422 with a &#x60;valid_values&#x60; envelope. (Note: &#x60;amenities&#x60; is not yet supported on the list endpoint — use the detail endpoint to fetch amenity rows for a single listing.)
366
577
  # @return [ListingListResponse]
367
578
  def list_listings(opts = {})
368
579
  data, _status_code, _headers = list_listings_with_http_info(opts)
@@ -370,16 +581,16 @@ module Repull
370
581
  end
371
582
 
372
583
  # List listings
373
- # Cursor-paginated list of listings owned by the authenticated workspace. Use &#x60;pagination.nextCursor&#x60; from one response as the &#x60;cursor&#x60; query param of the next request to walk the full set. &#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;. Filters: &#x60;q&#x60; (substring on name/street/city), &#x60;status&#x60;, &#x60;channel&#x60;. **Optional expansions:** Pass &#x60;?include&#x3D;content&#x60; to enrich each row with the rich content slab (summary, description, space, house rules, etc. — sourced from &#x60;listings_descriptions&#x60; for the &#x60;en&#x60; locale). Pass &#x60;?include&#x3D;details&#x60; for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.). Both default to &#x60;null&#x60; per row when the underlying &#x60;listings_descriptions&#x60; / &#x60;listings_details&#x60; row is missing — distinct from the field being absent (which signals the expansion was not requested). Combine comma-separated, e.g. &#x60;?include&#x3D;content,details&#x60;. The default response stays lean; consumers must opt in.
584
+ # Cursor-paginated list of listings owned by the authenticated workspace. Use &#x60;pagination.nextCursor&#x60; from one response as the &#x60;cursor&#x60; query param of the next request to walk the full set. &#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;. Filters: &#x60;q&#x60; (substring on name/street/city), &#x60;status&#x60;, &#x60;channel&#x60;. **Optional expansions:** Pass &#x60;?include&#x3D;content&#x60; to enrich each row with the rich content slab (summary, description, space, house rules, etc. — sourced from &#x60;listings_descriptions&#x60; for the &#x60;en&#x60; locale). Pass &#x60;?include&#x3D;details&#x60; for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.). Both default to &#x60;null&#x60; per row when the underlying &#x60;listings_descriptions&#x60; / &#x60;listings_details&#x60; row is missing — distinct from the field being absent (which signals the expansion was not requested). Pass &#x60;?include&#x3D;thumbnail&#x60; to guarantee &#x60;thumbnailUrl&#x60; on every returned row — including the reduced inactive ones. Combine comma-separated, e.g. &#x60;?include&#x3D;content,thumbnail&#x60;. The default response stays lean; consumers must opt in. **Inactive listings:** by default only active listings are returned. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated, so when &#x60;status&#x60; asks for inactive ones they carry only &#x60;id&#x60;, &#x60;name&#x60;, &#x60;status&#x60; and &#x60;channels&#x60; — enough to choose what to activate with &#x60;PATCH /v1/listings/{id}&#x60;. The &#x60;content&#x60; and &#x60;details&#x60; expansions are not applied to them. &#x60;?include&#x3D;thumbnail&#x60; is the one exception: it adds &#x60;thumbnailUrl&#x60; to an inactive row so a single request can render an active/inactive selection screen with pictures, instead of one follow-up call per listing (which an inactive listing would answer with &#x60;403 listing_inactive&#x60; anyway).
374
585
  # @param [Hash] opts the optional parameters
375
586
  # @option opts [String] :x_schema Apply a custom or built-in schema to transform the response. Built-in: &#x60;native&#x60; (default), &#x60;calry&#x60;, &#x60;calry-v1&#x60;. Custom: any schema name created via &#x60;POST /v1/schema/custom&#x60;. Unknown / inactive schema names fall back to &#x60;native&#x60;.
376
587
  # @option opts [String] :cursor Opaque cursor returned in the previous response&#39;s &#x60;pagination.nextCursor&#x60;. Omit to fetch the first page.
377
- # @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.next_cursor&#x60; so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying. (default to 0)
588
+ # @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)
378
589
  # @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 20)
379
590
  # @option opts [String] :q Case-insensitive substring search on name, street, or city.
380
- # @option opts [String] :status Filter by listing status.
591
+ # @option opts [String] :status Filter by listing status. Defaults to &#x60;active&#x60;. Pass &#x60;inactive&#x60; to list the listings you can activate, &#x60;archived&#x60; for archived ones, or &#x60;all&#x60; for every status. Inactive listings are returned with identity fields only — &#x60;id&#x60;, &#x60;name&#x60;, &#x60;status&#x60; and &#x60;channels&#x60; — and never with &#x60;address&#x60;, &#x60;content&#x60; or &#x60;details&#x60;; activate one to see the rest. The only field you can add to an inactive row is &#x60;thumbnailUrl&#x60;, via &#x60;?include&#x3D;thumbnail&#x60;. (default to 'active')
381
592
  # @option opts [String] :channel Restrict to listings published on the given channel (&#x60;airbnb&#x60;, &#x60;booking&#x60;, &#x60;vrbo&#x60;, etc.). Joins through &#x60;listing_platform_links&#x60; and matches active links only.
382
- # @option opts [String] :include Comma-separated optional expansions. Currently supported: &#x60;content&#x60;, &#x60;details&#x60;. Unknown values return 422 with a &#x60;valid_values&#x60; envelope. (Note: &#x60;amenities&#x60; is not yet supported on the list endpoint — use the detail endpoint to fetch amenity rows for a single listing.)
593
+ # @option opts [String] :include Comma-separated optional expansions. Currently supported: &#x60;content&#x60;, &#x60;details&#x60;, &#x60;thumbnail&#x60;. &#x60;thumbnail&#x60; guarantees &#x60;thumbnailUrl&#x60; on every row and is the only expansion that applies to inactive listings. Unknown values return 422 with a &#x60;valid_values&#x60; envelope. (Note: &#x60;amenities&#x60; is not yet supported on the list endpoint — use the detail endpoint to fetch amenity rows for a single listing.)
383
594
  # @return [Array<(ListingListResponse, Integer, Hash)>] ListingListResponse data, response status code and response headers
384
595
  def list_listings_with_http_info(opts = {})
385
596
  if @api_client.config.debugging
@@ -401,7 +612,7 @@ module Repull
401
612
  fail ArgumentError, 'invalid value for "opts[:"limit"]" when calling ListingsApi.list_listings, must be greater than or equal to 1.'
402
613
  end
403
614
 
404
- allowable_values = ["active", "inactive", "archived"]
615
+ allowable_values = ["active", "inactive", "archived", "all"]
405
616
  if @api_client.config.client_side_validation && opts[:'status'] && !allowable_values.include?(opts[:'status'])
406
617
  fail ArgumentError, "invalid value for \"status\", must be one of #{allowable_values}"
407
618
  end
@@ -454,22 +665,24 @@ module Repull
454
665
  end
455
666
 
456
667
  # Publish a listing to Airbnb
457
- # Push a Repull listing to Airbnb. Pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create a brand-new Airbnb listing under that host.
668
+ # Push a Repull listing's canonical content to Airbnb. Pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create a brand-new Airbnb listing under that host. **A publish is not one call to Airbnb.** It is up to eight independent ones — details, description, amenities, rooms, policies, photos, pricing, checkout_tasks — and each can fail on its own. `result.published` is true only when every attempted section landed; `result.sections` lists the ones that did and `result.errors[]` carries Airbnb's own reason, per section, for the ones that did not. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Publish again once you have fixed the failing sections — a re-publish of an unchanged section is harmless. `result.lockedFields` names the fields Airbnb will not let this listing change at all. They are not retryable by anyone: Airbnb answers 200 and applies nothing. `GET /v1/channels/airbnb/listings/{id}` reports the same list up front. **Which fields this pushes** — title, description sections and house rules (English/primary locale), amenities, rooms and beds, photos, nightly price and fees, cancellation policy and guest controls, check-in/out times, quiet hours, property and room type, checkout tasks. **Not pushed by this endpoint:** non-primary locales (`PUT /v1/channels/airbnb/listings/{id}/descriptions`), guest-safety disclosures (`PUT …/safety-disclosures`), check-in method (`PUT …/details`), permits (`PUT …/permits`), and the calendar (`PUT …/availability`). `force: true` re-pushes every section, ignoring dirty-field tracking. Without it only the sections changed since the last successful publish are sent. Send `Idempotency-Key` to make a retry safe: a timeout on a publish otherwise leaves you unable to tell whether it ran. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
458
669
  # @param id [Integer]
459
670
  # @param [Hash] opts the optional parameters
671
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Responses with status &gt;&#x3D; 500 are deliberately not stored, so a server error stays retryable.
460
672
  # @option opts [ListingPublishAirbnbRequest] :listing_publish_airbnb_request
461
- # @return [ListingPublishResponse]
673
+ # @return [ListingPublishAirbnbResponse]
462
674
  def publish_listing_to_airbnb(id, opts = {})
463
675
  data, _status_code, _headers = publish_listing_to_airbnb_with_http_info(id, opts)
464
676
  data
465
677
  end
466
678
 
467
679
  # Publish a listing to Airbnb
468
- # Push a Repull listing to Airbnb. Pass &#x60;airbnbConnectionId&#x60; to update an already-mapped Airbnb listing, or &#x60;hostId&#x60; to create a brand-new Airbnb listing under that host.
680
+ # Push a Repull listing&#39;s canonical content to Airbnb. Pass &#x60;airbnbConnectionId&#x60; to update an already-mapped Airbnb listing, or &#x60;hostId&#x60; to create a brand-new Airbnb listing under that host. **A publish is not one call to Airbnb.** It is up to eight independent ones — details, description, amenities, rooms, policies, photos, pricing, checkout_tasks — and each can fail on its own. &#x60;result.published&#x60; is true only when every attempted section landed; &#x60;result.sections&#x60; lists the ones that did and &#x60;result.errors[]&#x60; carries Airbnb&#39;s own reason, per section, for the ones that did not. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Publish again once you have fixed the failing sections — a re-publish of an unchanged section is harmless. &#x60;result.lockedFields&#x60; names the fields Airbnb will not let this listing change at all. They are not retryable by anyone: Airbnb answers 200 and applies nothing. &#x60;GET /v1/channels/airbnb/listings/{id}&#x60; reports the same list up front. **Which fields this pushes** — title, description sections and house rules (English/primary locale), amenities, rooms and beds, photos, nightly price and fees, cancellation policy and guest controls, check-in/out times, quiet hours, property and room type, checkout tasks. **Not pushed by this endpoint:** non-primary locales (&#x60;PUT /v1/channels/airbnb/listings/{id}/descriptions&#x60;), guest-safety disclosures (&#x60;PUT …/safety-disclosures&#x60;), check-in method (&#x60;PUT …/details&#x60;), permits (&#x60;PUT …/permits&#x60;), and the calendar (&#x60;PUT …/availability&#x60;). &#x60;force: true&#x60; re-pushes every section, ignoring dirty-field tracking. Without it only the sections changed since the last successful publish are sent. Send &#x60;Idempotency-Key&#x60; to make a retry safe: a timeout on a publish otherwise leaves you unable to tell whether it ran. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
469
681
  # @param id [Integer]
470
682
  # @param [Hash] opts the optional parameters
683
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Responses with status &gt;&#x3D; 500 are deliberately not stored, so a server error stays retryable.
471
684
  # @option opts [ListingPublishAirbnbRequest] :listing_publish_airbnb_request
472
- # @return [Array<(ListingPublishResponse, Integer, Hash)>] ListingPublishResponse data, response status code and response headers
685
+ # @return [Array<(ListingPublishAirbnbResponse, Integer, Hash)>] ListingPublishAirbnbResponse data, response status code and response headers
473
686
  def publish_listing_to_airbnb_with_http_info(id, opts = {})
474
687
  if @api_client.config.debugging
475
688
  @api_client.config.logger.debug 'Calling API: ListingsApi.publish_listing_to_airbnb ...'
@@ -478,6 +691,10 @@ module Repull
478
691
  if @api_client.config.client_side_validation && id.nil?
479
692
  fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.publish_listing_to_airbnb"
480
693
  end
694
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
695
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling ListingsApi.publish_listing_to_airbnb, the character length must be smaller than or equal to 255.'
696
+ end
697
+
481
698
  # resource path
482
699
  local_var_path = '/v1/listings/{id}/publish/airbnb'.sub('{id}', CGI.escape(id.to_s))
483
700
 
@@ -493,6 +710,7 @@ module Repull
493
710
  if !content_type.nil?
494
711
  header_params['Content-Type'] = content_type
495
712
  end
713
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
496
714
 
497
715
  # form parameters
498
716
  form_params = opts[:form_params] || {}
@@ -501,7 +719,7 @@ module Repull
501
719
  post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'listing_publish_airbnb_request'])
502
720
 
503
721
  # return_type
504
- return_type = opts[:debug_return_type] || 'ListingPublishResponse'
722
+ return_type = opts[:debug_return_type] || 'ListingPublishAirbnbResponse'
505
723
 
506
724
  # auth_names
507
725
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -524,7 +742,7 @@ module Repull
524
742
  end
525
743
 
526
744
  # Publish a listing to Booking.com
527
- # Push a Repull listing to Booking.com. The listing must already be mapped to a Booking property + room (created via the Booking-claim Connect flow).
745
+ # Push a Repull listing to Booking.com. The listing must already be mapped to a Booking property + room (created via the Booking-claim Connect flow). Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
528
746
  # @param id [Integer]
529
747
  # @param [Hash] opts the optional parameters
530
748
  # @return [ListingPublishResponse]
@@ -534,7 +752,7 @@ module Repull
534
752
  end
535
753
 
536
754
  # Publish a listing to Booking.com
537
- # Push a Repull listing to Booking.com. The listing must already be mapped to a Booking property + room (created via the Booking-claim Connect flow).
755
+ # Push a Repull listing to Booking.com. The listing must already be mapped to a Booking property + room (created via the Booking-claim Connect flow). Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
538
756
  # @param id [Integer]
539
757
  # @param [Hash] opts the optional parameters
540
758
  # @return [Array<(ListingPublishResponse, Integer, Hash)>] ListingPublishResponse data, response status code and response headers
@@ -586,8 +804,146 @@ module Repull
586
804
  return data, status_code, headers
587
805
  end
588
806
 
807
+ # Refresh a listing from Airbnb
808
+ # Re-read this listing from Airbnb and update your stored copy, then report what was refreshed and when. The mirror image of `POST /v1/listings/{id}/publish/airbnb`. Every other Airbnb read on this API is served from our database. This endpoint is the one that goes and asks Airbnb — use it after a push, to see the values Airbnb actually kept, or when a host has changed something in the Airbnb app. **What it refreshes:** basic listing facts (property type, bedrooms, beds, bathrooms, capacity), descriptions, photos, rooms and beds, amenities, booking settings (check-in/check-out windows, guest controls, cancellation policy), stay rules (min/max nights, advance-booking window, turnover buffer), pricing settings and standard fees, permits, checkout tasks and the check-in guide. After it returns, those values are what `GET /v1/listings/{id}?include=content,details` and the `/v1/channels/airbnb/**` routes serve. **What it does NOT refresh:** the calendar (nightly rates and availability — see `GET /v1/channels/airbnb/listings/{id}/availability`), reservations, messages, reviews or payouts. Those arrive continuously through the channel's own sync and never need a manual pull. **Runs synchronously** — the response is the result, not a job id. Expect several seconds. **One pull per listing per 15 minutes.** A pull is roughly a dozen Airbnb calls; a second call inside the window returns `429 rate_limit_exceeded` with `Retry-After` and `nextPullAvailableAt`, and makes no Airbnb calls. Two simultaneous calls cannot both run. 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.
809
+ # @param id [Integer]
810
+ # @param [Hash] opts the optional parameters
811
+ # @option opts [ListingPullAirbnbRequest] :listing_pull_airbnb_request
812
+ # @return [ListingPullResponse]
813
+ def pull_listing_from_airbnb(id, opts = {})
814
+ data, _status_code, _headers = pull_listing_from_airbnb_with_http_info(id, opts)
815
+ data
816
+ end
817
+
818
+ # Refresh a listing from Airbnb
819
+ # Re-read this listing from Airbnb and update your stored copy, then report what was refreshed and when. The mirror image of &#x60;POST /v1/listings/{id}/publish/airbnb&#x60;. Every other Airbnb read on this API is served from our database. This endpoint is the one that goes and asks Airbnb — use it after a push, to see the values Airbnb actually kept, or when a host has changed something in the Airbnb app. **What it refreshes:** basic listing facts (property type, bedrooms, beds, bathrooms, capacity), descriptions, photos, rooms and beds, amenities, booking settings (check-in/check-out windows, guest controls, cancellation policy), stay rules (min/max nights, advance-booking window, turnover buffer), pricing settings and standard fees, permits, checkout tasks and the check-in guide. After it returns, those values are what &#x60;GET /v1/listings/{id}?include&#x3D;content,details&#x60; and the &#x60;/v1/channels/airbnb/**&#x60; routes serve. **What it does NOT refresh:** the calendar (nightly rates and availability — see &#x60;GET /v1/channels/airbnb/listings/{id}/availability&#x60;), reservations, messages, reviews or payouts. Those arrive continuously through the channel&#39;s own sync and never need a manual pull. **Runs synchronously** — the response is the result, not a job id. Expect several seconds. **One pull per listing per 15 minutes.** A pull is roughly a dozen Airbnb calls; a second call inside the window returns &#x60;429 rate_limit_exceeded&#x60; with &#x60;Retry-After&#x60; and &#x60;nextPullAvailableAt&#x60;, and makes no Airbnb calls. Two simultaneous calls cannot both run. 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.
820
+ # @param id [Integer]
821
+ # @param [Hash] opts the optional parameters
822
+ # @option opts [ListingPullAirbnbRequest] :listing_pull_airbnb_request
823
+ # @return [Array<(ListingPullResponse, Integer, Hash)>] ListingPullResponse data, response status code and response headers
824
+ def pull_listing_from_airbnb_with_http_info(id, opts = {})
825
+ if @api_client.config.debugging
826
+ @api_client.config.logger.debug 'Calling API: ListingsApi.pull_listing_from_airbnb ...'
827
+ end
828
+ # verify the required parameter 'id' is set
829
+ if @api_client.config.client_side_validation && id.nil?
830
+ fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.pull_listing_from_airbnb"
831
+ end
832
+ # resource path
833
+ local_var_path = '/v1/listings/{id}/pull/airbnb'.sub('{id}', CGI.escape(id.to_s))
834
+
835
+ # query parameters
836
+ query_params = opts[:query_params] || {}
837
+
838
+ # header parameters
839
+ header_params = opts[:header_params] || {}
840
+ # HTTP header 'Accept' (if needed)
841
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
842
+ # HTTP header 'Content-Type'
843
+ content_type = @api_client.select_header_content_type(['application/json'])
844
+ if !content_type.nil?
845
+ header_params['Content-Type'] = content_type
846
+ end
847
+
848
+ # form parameters
849
+ form_params = opts[:form_params] || {}
850
+
851
+ # http body (model)
852
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'listing_pull_airbnb_request'])
853
+
854
+ # return_type
855
+ return_type = opts[:debug_return_type] || 'ListingPullResponse'
856
+
857
+ # auth_names
858
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
859
+
860
+ new_options = opts.merge(
861
+ :operation => :"ListingsApi.pull_listing_from_airbnb",
862
+ :header_params => header_params,
863
+ :query_params => query_params,
864
+ :form_params => form_params,
865
+ :body => post_body,
866
+ :auth_names => auth_names,
867
+ :return_type => return_type
868
+ )
869
+
870
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
871
+ if @api_client.config.debugging
872
+ @api_client.config.logger.debug "API called: ListingsApi#pull_listing_from_airbnb\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
873
+ end
874
+ return data, status_code, headers
875
+ end
876
+
877
+ # Activate or deactivate listings in bulk
878
+ # Sets up to 500 listings active or inactive in one call. Send `{ \"listingIds\": [\"4118\", \"4119\"], \"active\": false }` to deactivate them, or `\"active\": true` to activate them. An inactive listing is not counted toward your plan's listing limit or billed. It is NOT deleted and the upstream channel (Airbnb / Booking.com / your PMS) is never touched — its data keeps syncing, so it is complete the moment you activate it again. Until then it cannot be read, changed, or receive webhooks. **All or nothing.** Nothing changes unless the whole request can be applied: - If any id is not one of your listings, the call returns `404` naming those ids. - If activating would take you over your plan's listing limit, the call returns `402 listings_limit_exceeded`. Only listings that are currently inactive count toward the new total, so re-sending ids that are already active never trips the limit. Deactivating is always allowed, including when your account is already over its limit — it is how you get back under it. **Idempotent.** Ids already in the requested state are returned in `unchanged`; ids this call changed are returned in `updated`. For a single listing, `PATCH /v1/listings/{id}` does the same.
879
+ # @param listing_status_batch_request [ListingStatusBatchRequest]
880
+ # @param [Hash] opts the optional parameters
881
+ # @return [ListingStatusBatchResponse]
882
+ def set_listings_status(listing_status_batch_request, opts = {})
883
+ data, _status_code, _headers = set_listings_status_with_http_info(listing_status_batch_request, opts)
884
+ data
885
+ end
886
+
887
+ # Activate or deactivate listings in bulk
888
+ # Sets up to 500 listings active or inactive in one call. Send &#x60;{ \&quot;listingIds\&quot;: [\&quot;4118\&quot;, \&quot;4119\&quot;], \&quot;active\&quot;: false }&#x60; to deactivate them, or &#x60;\&quot;active\&quot;: true&#x60; to activate them. An inactive listing is not counted toward your plan&#39;s listing limit or billed. It is NOT deleted and the upstream channel (Airbnb / Booking.com / your PMS) is never touched — its data keeps syncing, so it is complete the moment you activate it again. Until then it cannot be read, changed, or receive webhooks. **All or nothing.** Nothing changes unless the whole request can be applied: - If any id is not one of your listings, the call returns &#x60;404&#x60; naming those ids. - If activating would take you over your plan&#39;s listing limit, the call returns &#x60;402 listings_limit_exceeded&#x60;. Only listings that are currently inactive count toward the new total, so re-sending ids that are already active never trips the limit. Deactivating is always allowed, including when your account is already over its limit — it is how you get back under it. **Idempotent.** Ids already in the requested state are returned in &#x60;unchanged&#x60;; ids this call changed are returned in &#x60;updated&#x60;. For a single listing, &#x60;PATCH /v1/listings/{id}&#x60; does the same.
889
+ # @param listing_status_batch_request [ListingStatusBatchRequest]
890
+ # @param [Hash] opts the optional parameters
891
+ # @return [Array<(ListingStatusBatchResponse, Integer, Hash)>] ListingStatusBatchResponse data, response status code and response headers
892
+ def set_listings_status_with_http_info(listing_status_batch_request, opts = {})
893
+ if @api_client.config.debugging
894
+ @api_client.config.logger.debug 'Calling API: ListingsApi.set_listings_status ...'
895
+ end
896
+ # verify the required parameter 'listing_status_batch_request' is set
897
+ if @api_client.config.client_side_validation && listing_status_batch_request.nil?
898
+ fail ArgumentError, "Missing the required parameter 'listing_status_batch_request' when calling ListingsApi.set_listings_status"
899
+ end
900
+ # resource path
901
+ local_var_path = '/v1/listings/status'
902
+
903
+ # query parameters
904
+ query_params = opts[:query_params] || {}
905
+
906
+ # header parameters
907
+ header_params = opts[:header_params] || {}
908
+ # HTTP header 'Accept' (if needed)
909
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
910
+ # HTTP header 'Content-Type'
911
+ content_type = @api_client.select_header_content_type(['application/json'])
912
+ if !content_type.nil?
913
+ header_params['Content-Type'] = content_type
914
+ end
915
+
916
+ # form parameters
917
+ form_params = opts[:form_params] || {}
918
+
919
+ # http body (model)
920
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(listing_status_batch_request)
921
+
922
+ # return_type
923
+ return_type = opts[:debug_return_type] || 'ListingStatusBatchResponse'
924
+
925
+ # auth_names
926
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
927
+
928
+ new_options = opts.merge(
929
+ :operation => :"ListingsApi.set_listings_status",
930
+ :header_params => header_params,
931
+ :query_params => query_params,
932
+ :form_params => form_params,
933
+ :body => post_body,
934
+ :auth_names => auth_names,
935
+ :return_type => return_type
936
+ )
937
+
938
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
939
+ if @api_client.config.debugging
940
+ @api_client.config.logger.debug "API called: ListingsApi#set_listings_status\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
941
+ end
942
+ return data, status_code, headers
943
+ end
944
+
589
945
  # Deactivate or reactivate a listing
590
- # Toggle a listing's active state. Send `{ \"active\": false }` to **deactivate** (exclude the listing from Repull) or `{ \"active\": true }` to **reactivate** it. \"Deactivate\" keeps the listing row — it is NOT a hard delete, and it NEVER touches the upstream channel (Airbnb / Hospitable / Booking.com). Repull only mutates its own copy of the inventory. Deactivating is the self-serve way to get back under the plan-listings cap without paying. Reactivation respects the plan-listings cap: if activating this listing would push you over the cap for your tier, the call returns `402 listings_limit_exceeded` and the listing stays inactive. Deactivate another listing or upgrade first. Idempotent: setting a listing to the state it's already in returns 200.
946
+ # Toggle a listing's active state. Send `{ \"active\": false }` to **deactivate** (exclude the listing from Repull) or `{ \"active\": true }` to **reactivate** it. \"Deactivate\" keeps the listing row — it is NOT a hard delete, and it NEVER touches the upstream channel (Airbnb / Hospitable / Booking.com). Repull only mutates its own copy of the inventory. Deactivating is the self-serve way to get back under the plan-listings cap without paying. Reactivation respects the plan-listings cap: if activating this listing would push you over the cap for your tier, the call returns `402 listings_limit_exceeded` and the listing stays inactive. Deactivate another listing or upgrade first. Idempotent: setting a listing to the state it's already in returns 200. To change many listings at once, all or nothing, use `POST /v1/listings/status`.
591
947
  # @param id [Integer] Repull listing id
592
948
  # @param listing_active_request [ListingActiveRequest]
593
949
  # @param [Hash] opts the optional parameters
@@ -598,7 +954,7 @@ module Repull
598
954
  end
599
955
 
600
956
  # Deactivate or reactivate a listing
601
- # Toggle a listing&#39;s active state. Send &#x60;{ \&quot;active\&quot;: false }&#x60; to **deactivate** (exclude the listing from Repull) or &#x60;{ \&quot;active\&quot;: true }&#x60; to **reactivate** it. \&quot;Deactivate\&quot; keeps the listing row — it is NOT a hard delete, and it NEVER touches the upstream channel (Airbnb / Hospitable / Booking.com). Repull only mutates its own copy of the inventory. Deactivating is the self-serve way to get back under the plan-listings cap without paying. Reactivation respects the plan-listings cap: if activating this listing would push you over the cap for your tier, the call returns &#x60;402 listings_limit_exceeded&#x60; and the listing stays inactive. Deactivate another listing or upgrade first. Idempotent: setting a listing to the state it&#39;s already in returns 200.
957
+ # Toggle a listing&#39;s active state. Send &#x60;{ \&quot;active\&quot;: false }&#x60; to **deactivate** (exclude the listing from Repull) or &#x60;{ \&quot;active\&quot;: true }&#x60; to **reactivate** it. \&quot;Deactivate\&quot; keeps the listing row — it is NOT a hard delete, and it NEVER touches the upstream channel (Airbnb / Hospitable / Booking.com). Repull only mutates its own copy of the inventory. Deactivating is the self-serve way to get back under the plan-listings cap without paying. Reactivation respects the plan-listings cap: if activating this listing would push you over the cap for your tier, the call returns &#x60;402 listings_limit_exceeded&#x60; and the listing stays inactive. Deactivate another listing or upgrade first. Idempotent: setting a listing to the state it&#39;s already in returns 200. To change many listings at once, all or nothing, use &#x60;POST /v1/listings/status&#x60;.
602
958
  # @param id [Integer] Repull listing id
603
959
  # @param listing_active_request [ListingActiveRequest]
604
960
  # @param [Hash] opts the optional parameters
@@ -661,10 +1017,11 @@ module Repull
661
1017
  end
662
1018
 
663
1019
  # Update canonical listing content
664
- # Write your PMS's canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \"the PMS owns listing content, Repull distributes it\" enabler. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. `amenities` is a FULL replacement of the amenity set (omit to leave untouched, send `[]` to clear). **Local write only — NOT a channel publish.** This mutates Repull's own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided `photos` array is echoed back in the `deferred` field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio.
1020
+ # Write your PMS's canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \"the PMS owns listing content, Repull distributes it\" enabler. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. `amenities` is a FULL replacement of the amenity set (omit to leave untouched, send `[]` to clear). **Multilingual:** send `locale` to say which language this copy is in (`it`, `pt-BR`, …). Canonical content is stored per locale, so each language keeps its own row instead of overwriting the English one. Omit it for English. **Local write only — NOT a channel publish.** This mutates Repull's own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided `photos` array is echoed back in the `deferred` field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio. 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.
665
1021
  # @param id [Integer] Repull listing id
666
1022
  # @param listing_content_update_request [ListingContentUpdateRequest]
667
1023
  # @param [Hash] opts the optional parameters
1024
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Responses with status &gt;&#x3D; 500 are deliberately not stored, so a server error stays retryable.
668
1025
  # @return [ListingContentUpdateResponse]
669
1026
  def update_listing_content(id, listing_content_update_request, opts = {})
670
1027
  data, _status_code, _headers = update_listing_content_with_http_info(id, listing_content_update_request, opts)
@@ -672,10 +1029,11 @@ module Repull
672
1029
  end
673
1030
 
674
1031
  # Update canonical listing content
675
- # Write your PMS&#39;s canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \&quot;the PMS owns listing content, Repull distributes it\&quot; enabler. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. &#x60;amenities&#x60; is a FULL replacement of the amenity set (omit to leave untouched, send &#x60;[]&#x60; to clear). **Local write only — NOT a channel publish.** This mutates Repull&#39;s own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided &#x60;photos&#x60; array is echoed back in the &#x60;deferred&#x60; field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio.
1032
+ # Write your PMS&#39;s canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \&quot;the PMS owns listing content, Repull distributes it\&quot; enabler. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. &#x60;amenities&#x60; is a FULL replacement of the amenity set (omit to leave untouched, send &#x60;[]&#x60; to clear). **Multilingual:** send &#x60;locale&#x60; to say which language this copy is in (&#x60;it&#x60;, &#x60;pt-BR&#x60;, …). Canonical content is stored per locale, so each language keeps its own row instead of overwriting the English one. Omit it for English. **Local write only — NOT a channel publish.** This mutates Repull&#39;s own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided &#x60;photos&#x60; array is echoed back in the &#x60;deferred&#x60; field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio. 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.
676
1033
  # @param id [Integer] Repull listing id
677
1034
  # @param listing_content_update_request [ListingContentUpdateRequest]
678
1035
  # @param [Hash] opts the optional parameters
1036
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Responses with status &gt;&#x3D; 500 are deliberately not stored, so a server error stays retryable.
679
1037
  # @return [Array<(ListingContentUpdateResponse, Integer, Hash)>] ListingContentUpdateResponse data, response status code and response headers
680
1038
  def update_listing_content_with_http_info(id, listing_content_update_request, opts = {})
681
1039
  if @api_client.config.debugging
@@ -689,6 +1047,10 @@ module Repull
689
1047
  if @api_client.config.client_side_validation && listing_content_update_request.nil?
690
1048
  fail ArgumentError, "Missing the required parameter 'listing_content_update_request' when calling ListingsApi.update_listing_content"
691
1049
  end
1050
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
1051
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling ListingsApi.update_listing_content, the character length must be smaller than or equal to 255.'
1052
+ end
1053
+
692
1054
  # resource path
693
1055
  local_var_path = '/v1/listings/{id}/content'.sub('{id}', CGI.escape(id.to_s))
694
1056
 
@@ -704,6 +1066,7 @@ module Repull
704
1066
  if !content_type.nil?
705
1067
  header_params['Content-Type'] = content_type
706
1068
  end
1069
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
707
1070
 
708
1071
  # form parameters
709
1072
  form_params = opts[:form_params] || {}