repull 0.2.10 → 0.2.14

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 (376) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/repull/api/airbnb_api.rb +332 -99
  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 +761 -8
  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 +303 -24
  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_alteration.rb +154 -10
  41. data/lib/repull/models/airbnb_amenity.rb +1 -1
  42. data/lib/repull/models/airbnb_availability_write_request.rb +20 -1
  43. data/lib/repull/models/airbnb_calendar_operation.rb +97 -8
  44. data/lib/repull/models/airbnb_connection.rb +4 -4
  45. data/lib/repull/models/airbnb_connection_accessibility_amenities_inner.rb +1 -1
  46. data/lib/repull/models/airbnb_connection_amenities_inner.rb +1 -1
  47. data/lib/repull/models/airbnb_connection_host.rb +1 -1
  48. data/lib/repull/models/airbnb_connection_response.rb +1 -1
  49. data/lib/repull/models/airbnb_connection_summary.rb +1 -1
  50. data/lib/repull/models/airbnb_data_freshness.rb +3 -3
  51. data/lib/repull/models/airbnb_listing.rb +2 -2
  52. data/lib/repull/models/airbnb_listing_action_request.rb +1 -1
  53. data/lib/repull/models/airbnb_listing_list_response.rb +2 -2
  54. data/lib/repull/models/airbnb_pricing_write_request.rb +54 -3
  55. data/lib/repull/models/airbnb_pricing_write_request_records_inner.rb +236 -0
  56. data/lib/repull/models/airbnb_reservation.rb +1 -1
  57. data/lib/repull/models/airbnb_reservation_list_response.rb +2 -2
  58. data/lib/repull/models/airbnb_review.rb +1 -1
  59. data/lib/repull/models/airbnb_review_list_response.rb +1 -1
  60. data/lib/repull/models/airbnb_thread.rb +1 -1
  61. data/lib/repull/models/airbnb_thread_list_response.rb +1 -1
  62. data/lib/repull/models/airbnb_transaction.rb +502 -0
  63. data/lib/repull/models/airbnb_transaction_guest_breakdown.rb +171 -0
  64. data/lib/repull/models/airbnb_transaction_host_breakdown.rb +246 -0
  65. data/lib/repull/models/airbnb_transaction_payout.rb +175 -0
  66. data/lib/repull/models/{booking_conversation_list_response.rb → alteration_change.rb} +22 -19
  67. data/lib/repull/models/alteration_webhook_object.rb +296 -0
  68. data/lib/repull/models/availability_batch_write_request.rb +296 -0
  69. data/lib/repull/models/availability_write_request.rb +259 -0
  70. data/lib/repull/models/availability_write_result.rb +178 -0
  71. data/lib/repull/models/availability_write_result_synced.rb +176 -0
  72. data/lib/repull/models/availability_write_settings.rb +215 -0
  73. data/lib/repull/models/booking_availability_state_response.rb +149 -0
  74. data/lib/repull/models/booking_availability_update.rb +1 -1
  75. data/lib/repull/models/booking_availability_update_request.rb +1 -1
  76. data/lib/repull/models/booking_availability_update_request_property_id.rb +1 -1
  77. data/lib/repull/models/booking_availability_update_request_updates_inner.rb +1 -1
  78. data/lib/repull/models/booking_connect_listing_option.rb +1 -1
  79. data/lib/repull/models/booking_connect_room.rb +1 -1
  80. data/lib/repull/models/booking_connect_rooms_response.rb +39 -5
  81. data/lib/repull/models/booking_conversation.rb +1 -1
  82. data/lib/repull/models/booking_pricing_rate_update.rb +1 -1
  83. data/lib/repull/models/booking_pricing_rate_update_date_range.rb +1 -1
  84. data/lib/repull/models/booking_pricing_rate_update_restrictions.rb +1 -1
  85. data/lib/repull/models/booking_pricing_response.rb +1 -1
  86. data/lib/repull/models/booking_pricing_update_request.rb +1 -1
  87. data/lib/repull/models/booking_pricing_update_response.rb +1 -1
  88. data/lib/repull/models/booking_property.rb +1 -1
  89. data/lib/repull/models/booking_reservation.rb +277 -0
  90. data/lib/repull/models/booking_reservation_room.rb +271 -0
  91. data/lib/repull/models/booking_room_mapping.rb +18 -8
  92. data/lib/repull/models/booking_rooms_rates_response.rb +170 -0
  93. data/lib/repull/models/booking_rooms_rates_response_rooms_inner.rb +170 -0
  94. data/lib/repull/models/booking_rooms_rates_response_rooms_inner_rates_inner.rb +212 -0
  95. data/lib/repull/models/booking_setup_request.rb +1 -1
  96. data/lib/repull/models/booking_verify_hotel_request.rb +1 -1
  97. data/lib/repull/models/booking_verify_hotel_response.rb +40 -6
  98. data/lib/repull/models/bulk_pricing_failure.rb +1 -1
  99. data/lib/repull/models/bulk_pricing_item.rb +1 -1
  100. data/lib/repull/models/bulk_pricing_request.rb +1 -1
  101. data/lib/repull/models/bulk_pricing_response.rb +1 -1
  102. data/lib/repull/models/calendar_day.rb +1 -1
  103. data/lib/repull/models/calendar_response.rb +1 -1
  104. data/lib/repull/models/calendar_updated_event.rb +1 -1
  105. data/lib/repull/models/calendar_updated_payload.rb +1 -1
  106. data/lib/repull/models/calendar_updated_payload_range.rb +1 -1
  107. data/lib/repull/models/clear_kv200_response.rb +1 -1
  108. data/lib/repull/models/connect_host.rb +1 -1
  109. data/lib/repull/models/connect_provider.rb +1 -1
  110. data/lib/repull/models/connect_provider_list_response.rb +1 -1
  111. data/lib/repull/models/connect_session.rb +1 -1
  112. data/lib/repull/models/connect_status.rb +18 -6
  113. data/lib/repull/models/connect_status_accounts_inner.rb +188 -0
  114. data/lib/repull/models/connection.rb +1 -1
  115. data/lib/repull/models/connection_list_response.rb +1 -1
  116. data/lib/repull/models/conversation.rb +13 -2
  117. data/lib/repull/models/conversation_detail.rb +13 -2
  118. data/lib/repull/models/conversation_guest.rb +1 -1
  119. data/lib/repull/models/conversation_guest_contact.rb +1 -1
  120. data/lib/repull/models/conversation_host.rb +1 -1
  121. data/lib/repull/models/conversation_list_response.rb +1 -1
  122. data/lib/repull/models/conversation_message_attachment.rb +1 -1
  123. data/lib/repull/models/create_airbnb_alteration_request.rb +1 -1
  124. data/lib/repull/models/create_airbnb_offer_request.rb +1 -1
  125. data/lib/repull/models/create_billing_checkout_request.rb +1 -1
  126. data/lib/repull/models/create_booking_webhook_request.rb +1 -1
  127. data/lib/repull/models/create_connect_session_request.rb +1 -1
  128. data/lib/repull/models/create_connection_request.rb +2 -2
  129. data/lib/repull/models/create_webhook_request.rb +1 -1
  130. data/lib/repull/models/custom_schema.rb +1 -1
  131. data/lib/repull/models/custom_schema_create.rb +1 -1
  132. data/lib/repull/models/custom_schema_create_response.rb +1 -1
  133. data/lib/repull/models/custom_schema_delete_response.rb +1 -1
  134. data/lib/repull/models/custom_schema_list_response.rb +1 -1
  135. data/lib/repull/models/custom_schema_summary.rb +1 -1
  136. data/lib/repull/models/custom_schema_update.rb +1 -1
  137. data/lib/repull/models/delete_airbnb_listing_photo200_response.rb +1 -1
  138. data/lib/repull/models/delete_connection200_response.rb +234 -0
  139. data/lib/repull/models/delete_kv200_response.rb +1 -1
  140. data/lib/repull/models/error.rb +1 -1
  141. data/lib/repull/models/error_error.rb +14 -2
  142. data/lib/repull/models/error_error_support.rb +1 -1
  143. data/lib/repull/models/get_airbnb_alteration200_response.rb +2 -2
  144. data/lib/repull/models/get_airbnb_checkin_guide200_response.rb +192 -0
  145. data/lib/repull/models/get_airbnb_listing_quality200_response.rb +2 -2
  146. data/lib/repull/models/get_airbnb_listing_settings200_response.rb +2 -2
  147. data/lib/repull/models/get_airbnb_thread200_response.rb +2 -2
  148. data/lib/repull/models/get_health200_response.rb +1 -1
  149. data/lib/repull/models/get_usage_logs200_response.rb +1 -1
  150. data/lib/repull/models/get_usage_logs200_response_data_inner.rb +1 -1
  151. data/lib/repull/models/get_usage_logs200_response_pagination.rb +3 -3
  152. data/lib/repull/models/get_usage_summary200_response.rb +2 -2
  153. data/lib/repull/models/get_usage_summary200_response_breakdown_inner.rb +1 -1
  154. data/lib/repull/models/get_usage_summary200_response_limits.rb +3 -3
  155. data/lib/repull/models/get_usage_summary200_response_remaining.rb +2 -2
  156. data/lib/repull/models/get_usage_summary200_response_status_distribution.rb +1 -1
  157. data/lib/repull/models/get_usage_summary200_response_timeline_inner.rb +1 -1
  158. data/lib/repull/models/get_usage_summary200_response_totals.rb +1 -1
  159. data/lib/repull/models/get_usage_summary200_response_used.rb +2 -2
  160. data/lib/repull/models/get_usage_tier200_response.rb +2 -2
  161. data/lib/repull/models/get_usage_tier200_response_limits.rb +4 -4
  162. data/lib/repull/models/get_usage_tier200_response_remaining.rb +3 -3
  163. data/lib/repull/models/get_usage_tier200_response_used.rb +3 -3
  164. data/lib/repull/models/guest.rb +1 -1
  165. data/lib/repull/models/guest_contact.rb +1 -1
  166. data/lib/repull/models/guest_create_request.rb +250 -0
  167. data/lib/repull/models/guest_create_response.rb +227 -0
  168. data/lib/repull/models/guest_create_response_contacts_inner.rb +199 -0
  169. data/lib/repull/models/guest_flag.rb +1 -1
  170. data/lib/repull/models/guest_list_response.rb +1 -1
  171. data/lib/repull/models/guest_note.rb +1 -1
  172. data/lib/repull/models/guest_profile.rb +1 -1
  173. data/lib/repull/models/guest_reservations_summary.rb +1 -1
  174. data/lib/repull/models/list_airbnb_alterations200_response.rb +2 -2
  175. data/lib/repull/models/list_airbnb_listing_amenities200_response.rb +2 -2
  176. data/lib/repull/models/list_airbnb_listing_amenities200_response_data.rb +1 -1
  177. data/lib/repull/models/list_airbnb_transactions200_response.rb +3 -3
  178. data/lib/repull/models/list_booking_reservations200_response.rb +104 -0
  179. data/lib/repull/models/list_kv200_response.rb +1 -1
  180. data/lib/repull/models/list_kv200_response_data_inner.rb +1 -1
  181. data/lib/repull/models/list_kv200_response_pagination.rb +2 -2
  182. data/lib/repull/models/listing.rb +2 -2
  183. data/lib/repull/models/listing_active_request.rb +2 -2
  184. data/lib/repull/models/listing_active_response.rb +1 -1
  185. data/lib/repull/models/listing_address.rb +1 -1
  186. data/lib/repull/models/listing_amenity.rb +1 -1
  187. data/lib/repull/models/listing_channel.rb +1 -1
  188. data/lib/repull/models/listing_comp.rb +1 -1
  189. data/lib/repull/models/listing_comp_nightly.rb +1 -1
  190. data/lib/repull/models/listing_comp_ratings.rb +1 -1
  191. data/lib/repull/models/listing_comps_response.rb +1 -1
  192. data/lib/repull/models/listing_content.rb +1 -1
  193. data/lib/repull/models/listing_content_update_request.rb +1 -1
  194. data/lib/repull/models/listing_content_update_request_address.rb +1 -1
  195. data/lib/repull/models/listing_content_update_request_amenities.rb +1 -1
  196. data/lib/repull/models/listing_content_update_request_amenities_one_of_inner.rb +1 -1
  197. data/lib/repull/models/listing_content_update_request_occupancy.rb +1 -1
  198. data/lib/repull/models/listing_content_update_request_photos_inner.rb +1 -1
  199. data/lib/repull/models/listing_content_update_request_photos_inner_one_of.rb +1 -1
  200. data/lib/repull/models/listing_content_update_request_policies.rb +1 -1
  201. data/lib/repull/models/listing_content_update_response.rb +1 -1
  202. data/lib/repull/models/listing_create_request.rb +1 -1
  203. data/lib/repull/models/listing_create_response.rb +1 -1
  204. data/lib/repull/models/listing_created_event.rb +1 -1
  205. data/lib/repull/models/listing_created_payload.rb +1 -1
  206. data/lib/repull/models/listing_created_payload_address.rb +1 -1
  207. data/lib/repull/models/listing_deleted_event.rb +1 -1
  208. data/lib/repull/models/listing_deleted_payload.rb +1 -1
  209. data/lib/repull/models/listing_details.rb +1 -1
  210. data/lib/repull/models/listing_generate_content_request.rb +1 -1
  211. data/lib/repull/models/listing_generate_content_response.rb +1 -1
  212. data/lib/repull/models/listing_list_response.rb +1 -1
  213. data/lib/repull/models/{studio_file.rb → listing_photo.rb} +23 -34
  214. data/lib/repull/models/listing_photo_delete_request.rb +165 -0
  215. data/lib/repull/models/{studio_error.rb → listing_photo_delete_response.rb} +20 -12
  216. data/lib/repull/models/listing_photo_upload_url_request.rb +203 -0
  217. data/lib/repull/models/listing_photo_upload_url_response.rb +198 -0
  218. data/lib/repull/models/{vrbo_listing_list_response.rb → listing_photos_response.rb} +19 -19
  219. data/lib/repull/models/listing_pricing_apply_request.rb +1 -1
  220. data/lib/repull/models/listing_pricing_apply_response.rb +1 -1
  221. data/lib/repull/models/listing_pricing_history_entry.rb +2 -2
  222. data/lib/repull/models/listing_pricing_history_response.rb +1 -1
  223. data/lib/repull/models/listing_pricing_recommendation.rb +1 -1
  224. data/lib/repull/models/listing_pricing_response.rb +1 -1
  225. data/lib/repull/models/listing_pricing_response_comp_summary.rb +1 -1
  226. data/lib/repull/models/listing_pricing_response_date_range.rb +1 -1
  227. data/lib/repull/models/listing_pricing_response_listing.rb +1 -1
  228. data/lib/repull/models/listing_pricing_strategy.rb +1 -1
  229. data/lib/repull/models/listing_pricing_strategy_input.rb +1 -1
  230. data/lib/repull/models/listing_publish_airbnb_request.rb +1 -1
  231. data/lib/repull/models/listing_publish_response.rb +1 -1
  232. data/lib/repull/models/listing_publish_status_channel.rb +1 -1
  233. data/lib/repull/models/listing_publish_status_connection.rb +1 -1
  234. data/lib/repull/models/listing_publish_status_response.rb +1 -1
  235. data/lib/repull/models/listing_quality_tier.rb +1 -1
  236. data/lib/repull/models/listing_segment.rb +1 -1
  237. data/lib/repull/models/listing_segment_recommendation.rb +1 -1
  238. data/lib/repull/models/listing_segments_response.rb +1 -1
  239. data/lib/repull/models/listing_segments_response_scope.rb +1 -1
  240. data/lib/repull/models/listing_status_batch_request.rb +212 -0
  241. data/lib/repull/models/listing_status_batch_response.rb +223 -0
  242. data/lib/repull/models/listing_updated_event.rb +1 -1
  243. data/lib/repull/models/listing_updated_payload.rb +1 -1
  244. data/lib/repull/models/map_airbnb_listing_request.rb +1 -1
  245. data/lib/repull/models/map_airbnb_listing_response.rb +1 -1
  246. data/lib/repull/models/map_connect_booking_rooms_request.rb +1 -1
  247. data/lib/repull/models/map_connect_booking_rooms_response.rb +16 -5
  248. data/lib/repull/models/market_browse_category.rb +1 -1
  249. data/lib/repull/models/market_browse_entry.rb +1 -1
  250. data/lib/repull/models/market_browse_featured.rb +1 -1
  251. data/lib/repull/models/market_browse_response.rb +1 -1
  252. data/lib/repull/models/market_calendar_day.rb +1 -1
  253. data/lib/repull/models/market_calendar_day_events_inner.rb +1 -1
  254. data/lib/repull/models/market_calendar_response.rb +1 -1
  255. data/lib/repull/models/market_detail_response.rb +1 -1
  256. data/lib/repull/models/market_detail_response_price_distribution_inner.rb +1 -1
  257. data/lib/repull/models/market_detail_response_property_type_mix_inner.rb +1 -1
  258. data/lib/repull/models/market_detail_response_supply_trend_inner.rb +1 -1
  259. data/lib/repull/models/market_detail_response_top_comps.rb +1 -1
  260. data/lib/repull/models/market_event.rb +1 -1
  261. data/lib/repull/models/market_my_listing.rb +1 -1
  262. data/lib/repull/models/market_summary.rb +1 -1
  263. data/lib/repull/models/market_top_comp.rb +1 -1
  264. data/lib/repull/models/markets_overview_response.rb +1 -1
  265. data/lib/repull/models/markets_overview_response_browse.rb +1 -1
  266. data/lib/repull/models/markets_overview_response_subscriptions.rb +1 -1
  267. data/lib/repull/models/markets_overview_response_totals.rb +1 -1
  268. data/lib/repull/models/message.rb +1 -1
  269. data/lib/repull/models/message_list_response.rb +1 -1
  270. data/lib/repull/models/pagination.rb +1 -1
  271. data/lib/repull/models/payment_completed_event.rb +1 -1
  272. data/lib/repull/models/payment_completed_payload.rb +1 -1
  273. data/lib/repull/models/payment_refunded_event.rb +1 -1
  274. data/lib/repull/models/payment_refunded_payload.rb +1 -1
  275. data/lib/repull/models/plumguide_listing.rb +1 -1
  276. data/lib/repull/models/plumguide_listing_list_response.rb +1 -1
  277. data/lib/repull/models/property.rb +17 -7
  278. data/lib/repull/models/property_availability.rb +33 -7
  279. data/lib/repull/models/property_availability_coverage.rb +222 -0
  280. data/lib/repull/models/property_availability_day.rb +4 -4
  281. data/lib/repull/models/property_list_response.rb +1 -1
  282. data/lib/repull/models/quote.rb +240 -0
  283. data/lib/repull/models/quote_pricing.rb +218 -0
  284. data/lib/repull/models/reply_booking_review200_response.rb +1 -1
  285. data/lib/repull/models/reply_booking_review_request.rb +1 -1
  286. data/lib/repull/models/reply_to_review201_response.rb +165 -0
  287. data/lib/repull/models/reply_to_review_request.rb +165 -0
  288. data/lib/repull/models/repull_ping_event.rb +1 -1
  289. data/lib/repull/models/repull_ping_payload.rb +1 -1
  290. data/lib/repull/models/reservation.rb +1 -1
  291. data/lib/repull/models/{studio_deployment.rb → reservation_alteration_created_event.rb} +67 -57
  292. data/lib/repull/models/reservation_alteration_created_payload.rb +177 -0
  293. data/lib/repull/models/reservation_alteration_responded_event.rb +217 -0
  294. data/lib/repull/models/reservation_alteration_responded_payload.rb +175 -0
  295. data/lib/repull/models/reservation_cancelled_event.rb +1 -1
  296. data/lib/repull/models/reservation_cancelled_payload.rb +1 -1
  297. data/lib/repull/models/reservation_create_request.rb +403 -0
  298. data/lib/repull/models/reservation_create_response.rb +233 -0
  299. data/lib/repull/models/reservation_created_event.rb +1 -1
  300. data/lib/repull/models/reservation_created_payload.rb +1 -1
  301. data/lib/repull/models/reservation_financials.rb +36 -8
  302. data/lib/repull/models/reservation_guest_financials.rb +173 -0
  303. data/lib/repull/models/reservation_guest_input.rb +193 -0
  304. data/lib/repull/models/reservation_host_financials.rb +207 -0
  305. data/lib/repull/models/reservation_list_response.rb +1 -1
  306. data/lib/repull/models/reservation_message_received_event.rb +1 -1
  307. data/lib/repull/models/reservation_message_received_payload.rb +1 -1
  308. data/lib/repull/models/reservation_message_received_payload_from.rb +1 -1
  309. data/lib/repull/models/reservation_money_line.rb +216 -0
  310. data/lib/repull/models/reservation_occupancy.rb +1 -1
  311. data/lib/repull/models/reservation_primary_guest.rb +1 -1
  312. data/lib/repull/models/reservation_update_request.rb +255 -0
  313. data/lib/repull/models/reservation_update_response.rb +240 -0
  314. data/lib/repull/models/reservation_updated_event.rb +1 -1
  315. data/lib/repull/models/reservation_updated_payload.rb +1 -1
  316. data/lib/repull/models/reservation_webhook_object.rb +1 -1
  317. data/lib/repull/models/respond_airbnb_review_request.rb +1 -1
  318. data/lib/repull/models/review.rb +14 -3
  319. data/lib/repull/models/review_category.rb +1 -1
  320. data/lib/repull/models/{sandbox_reset_result.rb → review_created_event.rb} +59 -59
  321. data/lib/repull/models/review_created_payload.rb +165 -0
  322. data/lib/repull/models/review_list_response.rb +1 -1
  323. data/lib/repull/models/review_responded_event.rb +217 -0
  324. data/lib/repull/models/review_responded_payload.rb +175 -0
  325. data/lib/repull/models/review_response.rb +1 -1
  326. data/lib/repull/models/review_webhook_object.rb +277 -0
  327. data/lib/repull/models/rotate_webhook_secret200_response.rb +1 -1
  328. data/lib/repull/models/select_connect_provider_request.rb +1 -1
  329. data/lib/repull/models/select_provider_response.rb +1 -1
  330. data/lib/repull/models/send_airbnb_message_request.rb +187 -0
  331. data/lib/repull/models/{sandbox_reset_result_deleted.rb → send_booking_message_request.rb} +53 -50
  332. data/lib/repull/models/{studio_error_error.rb → send_message_request.rb} +31 -50
  333. data/lib/repull/models/send_message_response.rb +241 -0
  334. data/lib/repull/models/set_kv_request.rb +1 -1
  335. data/lib/repull/models/{booking_property_list_response.rb → submit_beds24_credentials200_response.rb} +19 -19
  336. data/lib/repull/models/submit_beds24_credentials_request.rb +177 -0
  337. data/lib/repull/models/submit_bookingsync_credentials_request.rb +177 -0
  338. data/lib/repull/models/submit_guesty_credentials_request.rb +177 -0
  339. data/lib/repull/models/submit_hospitable_credentials_request.rb +177 -0
  340. data/lib/repull/models/submit_hostaway_credentials_request.rb +177 -0
  341. data/lib/repull/models/submit_igms_credentials_request.rb +177 -0
  342. data/lib/repull/models/submit_lodgify_credentials_request.rb +177 -0
  343. data/lib/repull/models/submit_ownerrez_credentials_request.rb +177 -0
  344. data/lib/repull/models/submit_smoobu_credentials_request.rb +177 -0
  345. data/lib/repull/models/submit_vrbo_credentials_request.rb +177 -0
  346. data/lib/repull/models/{sandbox_fixture_ref.rb → sync_airbnb_transactions200_response.rb} +36 -38
  347. data/lib/repull/models/sync_airbnb_transactions_request.rb +201 -0
  348. data/lib/repull/models/test_webhook_request.rb +1 -1
  349. data/lib/repull/models/update_airbnb_message_request.rb +1 -1
  350. data/lib/repull/models/update_booking_charges_request.rb +1 -1
  351. data/lib/repull/models/update_listing_pricing_strategy200_response.rb +1 -1
  352. data/lib/repull/models/update_webhook_request.rb +1 -1
  353. data/lib/repull/models/vrbo_listing.rb +1 -1
  354. data/lib/repull/models/vrbo_reservation.rb +1 -1
  355. data/lib/repull/models/vrbo_reservation_list_response.rb +1 -1
  356. data/lib/repull/models/webhook_delivery.rb +1 -1
  357. data/lib/repull/models/webhook_delivery_detail.rb +1 -1
  358. data/lib/repull/models/webhook_delivery_list_response.rb +1 -1
  359. data/lib/repull/models/webhook_event.rb +12 -4
  360. data/lib/repull/models/webhook_event_catalog.rb +1 -1
  361. data/lib/repull/models/webhook_event_catalog_domains_inner.rb +1 -1
  362. data/lib/repull/models/webhook_event_catalog_entry.rb +1 -1
  363. data/lib/repull/models/webhook_event_type.rb +6 -2
  364. data/lib/repull/models/webhook_list_response.rb +1 -1
  365. data/lib/repull/models/webhook_subscription.rb +1 -1
  366. data/lib/repull/version.rb +2 -2
  367. data/lib/repull.rb +75 -15
  368. data/openapi/v1.json +6119 -2021
  369. data/scripts/check-spec-freshness.py +399 -0
  370. data/scripts/regen.sh +32 -3
  371. metadata +77 -18
  372. data/lib/repull/api/sandbox_api.rb +0 -136
  373. data/lib/repull/models/sandbox_seed_result.rb +0 -278
  374. data/lib/repull/models/studio_generation.rb +0 -215
  375. data/lib/repull/models/studio_project.rb +0 -241
  376. 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
@@ -20,7 +20,7 @@ module Repull
20
20
  @api_client = api_client
21
21
  end
22
22
  # Get conversation detail
23
- # Returns one thread (the same shape as the list-row `Conversation`) plus expanded `host` (from `airbnb_hosts` for the thread's `host_id`) and `guest` (resolved via the thread's `reservation_id`, with up to 50 contacts) blocks.
23
+ # Returns one thread (the same shape as the list-row `Conversation`) plus expanded `host` (from `airbnb_hosts` for the thread's `host_id`) and `guest` (resolved via the thread's `reservation_id`, with up to 50 contacts) blocks. A conversation that belongs to an inactive listing (by the thread's listing or its reservation's listing) returns `403 listing_inactive`. Inactive listings keep syncing; activate the listing to use it here.
24
24
  # @param id [Integer] Internal Repull thread id.
25
25
  # @param [Hash] opts the optional parameters
26
26
  # @option opts [String] :x_schema Apply a custom or built-in schema to transform the response. Built-in: `native` (default), `calry`, `calry-v1`. Custom: any schema name created via `POST /v1/schema/custom`. Unknown / inactive schema names fall back to `native`.
@@ -31,7 +31,7 @@ module Repull
31
31
  end
32
32
 
33
33
  # Get conversation detail
34
- # Returns one thread (the same shape as the list-row `Conversation`) plus expanded `host` (from `airbnb_hosts` for the thread's `host_id`) and `guest` (resolved via the thread's `reservation_id`, with up to 50 contacts) blocks.
34
+ # Returns one thread (the same shape as the list-row `Conversation`) plus expanded `host` (from `airbnb_hosts` for the thread's `host_id`) and `guest` (resolved via the thread's `reservation_id`, with up to 50 contacts) blocks. A conversation that belongs to an inactive listing (by the thread's listing or its reservation's listing) returns `403 listing_inactive`. Inactive listings keep syncing; activate the listing to use it here.
35
35
  # @param id [Integer] Internal Repull thread id.
36
36
  # @param [Hash] opts the optional parameters
37
37
  # @option opts [String] :x_schema Apply a custom or built-in schema to transform the response. Built-in: `native` (default), `calry`, `calry-v1`. Custom: any schema name created via `POST /v1/schema/custom`. Unknown / inactive schema names fall back to `native`.
@@ -86,12 +86,12 @@ module Repull
86
86
  end
87
87
 
88
88
  # List messages in a conversation
89
- # Cursor-paginated messages within one thread. Defaults to newest-first (`?order=desc`); pass `?order=asc` for chronological replay. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`.
89
+ # Cursor-paginated messages within one thread. Defaults to newest-first (`?order=desc`); pass `?order=asc` for chronological replay. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. A conversation that belongs to an inactive listing returns `403 listing_inactive`. Inactive listings keep syncing; activate the listing to use it here.
90
90
  # @param id [Integer] Internal Repull thread id.
91
91
  # @param [Hash] opts the optional parameters
92
92
  # @option opts [String] :x_schema Apply a custom or built-in schema to transform the response. Built-in: `native` (default), `calry`, `calry-v1`. Custom: any schema name created via `POST /v1/schema/custom`. Unknown / inactive schema names fall back to `native`.
93
93
  # @option opts [String] :cursor Opaque cursor returned in the previous response's `pagination.nextCursor`.
94
- # @option opts [Integer] :offset First-class alias for cursor-based pagination. Mutually exclusive with `cursor` — passing both returns 422. Accepts integers in `[0, 10000]`; deeper walks must use `cursor` (constant per-page cost). The response always includes `pagination.next_cursor` so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying. (default to 0)
94
+ # @option opts [Integer] :offset First-class alias for cursor-based pagination. Mutually exclusive with `cursor` — passing both returns 422. Accepts integers in `[0, 10000]`; deeper walks must use `cursor` (constant per-page cost). The response always includes `pagination.nextCursor` so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying. (default to 0)
95
95
  # @option opts [Integer] :limit (default to 20)
96
96
  # @option opts [String] :order `desc` (default) returns newest first. `asc` returns chronological replay. (default to 'desc')
97
97
  # @return [MessageListResponse]
@@ -101,12 +101,12 @@ module Repull
101
101
  end
102
102
 
103
103
  # List messages in a conversation
104
- # Cursor-paginated messages within one thread. Defaults to newest-first (`?order=desc`); pass `?order=asc` for chronological replay. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`.
104
+ # Cursor-paginated messages within one thread. Defaults to newest-first (`?order=desc`); pass `?order=asc` for chronological replay. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. A conversation that belongs to an inactive listing returns `403 listing_inactive`. Inactive listings keep syncing; activate the listing to use it here.
105
105
  # @param id [Integer] Internal Repull thread id.
106
106
  # @param [Hash] opts the optional parameters
107
107
  # @option opts [String] :x_schema Apply a custom or built-in schema to transform the response. Built-in: `native` (default), `calry`, `calry-v1`. Custom: any schema name created via `POST /v1/schema/custom`. Unknown / inactive schema names fall back to `native`.
108
108
  # @option opts [String] :cursor Opaque cursor returned in the previous response's `pagination.nextCursor`.
109
- # @option opts [Integer] :offset First-class alias for cursor-based pagination. Mutually exclusive with `cursor` — passing both returns 422. Accepts integers in `[0, 10000]`; deeper walks must use `cursor` (constant per-page cost). The response always includes `pagination.next_cursor` so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying. (default to 0)
109
+ # @option opts [Integer] :offset First-class alias for cursor-based pagination. Mutually exclusive with `cursor` — passing both returns 422. Accepts integers in `[0, 10000]`; deeper walks must use `cursor` (constant per-page cost). The response always includes `pagination.nextCursor` so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying. (default to 0)
110
110
  # @option opts [Integer] :limit (default to 20)
111
111
  # @option opts [String] :order `desc` (default) returns newest first. `asc` returns chronological replay. (default to 'desc')
112
112
  # @return [Array<(MessageListResponse, Integer, Hash)>] MessageListResponse data, response status code and response headers
@@ -184,11 +184,11 @@ module Repull
184
184
  end
185
185
 
186
186
  # List conversations
187
- # Cursor-paginated list of message threads owned by the workspace. Backed by main vanio's `/api/threads/list` which keyset-paginates against `(last_message_at, id)` for constant per-page cost. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. Filters: `platform` (`airbnb`|`booking`|`vrbo`|`website`|`email`), `status` (`open`|`archived` — `archived` is a stable no-op until the bit lands on `message_threads`).
187
+ # Cursor-paginated list of message threads owned by the workspace. Backed by main vanio's `/api/threads/list` which keyset-paginates against `(last_message_at, id)` for constant per-page cost. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. Filters: `platform` (`airbnb`|`booking`|`vrbo`|`website`|`email`), `status` (`open`|`archived` — `archived` is a stable no-op until the bit lands on `message_threads`). **Inactive listings:** conversations that belong to an inactive listing (by the thread's listing or its reservation's listing) are left out of the page and of `pagination.total`. Inactive listings keep syncing; activate the listing to use it here.
188
188
  # @param [Hash] opts the optional parameters
189
189
  # @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;.
190
190
  # @option opts [String] :cursor Opaque cursor returned in the previous response&#39;s &#x60;pagination.nextCursor&#x60;. Omit to fetch the first page.
191
- # @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)
191
+ # @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)
192
192
  # @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 20)
193
193
  # @option opts [String] :platform Restrict to threads on a single channel.
194
194
  # @option opts [String] :status Filter by archive status. &#x60;archived&#x60; currently always returns an empty page — kept for forward-compat.
@@ -199,11 +199,11 @@ module Repull
199
199
  end
200
200
 
201
201
  # List conversations
202
- # Cursor-paginated list of message threads owned by the workspace. Backed by main vanio&#39;s &#x60;/api/threads/list&#x60; which keyset-paginates against &#x60;(last_message_at, id)&#x60; for constant per-page cost. Use &#x60;pagination.nextCursor&#x60; from one response as the &#x60;cursor&#x60; query param of the next request. &#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;platform&#x60; (&#x60;airbnb&#x60;|&#x60;booking&#x60;|&#x60;vrbo&#x60;|&#x60;website&#x60;|&#x60;email&#x60;), &#x60;status&#x60; (&#x60;open&#x60;|&#x60;archived&#x60; — &#x60;archived&#x60; is a stable no-op until the bit lands on &#x60;message_threads&#x60;).
202
+ # Cursor-paginated list of message threads owned by the workspace. Backed by main vanio&#39;s &#x60;/api/threads/list&#x60; which keyset-paginates against &#x60;(last_message_at, id)&#x60; for constant per-page cost. Use &#x60;pagination.nextCursor&#x60; from one response as the &#x60;cursor&#x60; query param of the next request. &#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;platform&#x60; (&#x60;airbnb&#x60;|&#x60;booking&#x60;|&#x60;vrbo&#x60;|&#x60;website&#x60;|&#x60;email&#x60;), &#x60;status&#x60; (&#x60;open&#x60;|&#x60;archived&#x60; — &#x60;archived&#x60; is a stable no-op until the bit lands on &#x60;message_threads&#x60;). **Inactive listings:** conversations that belong to an inactive listing (by the thread&#39;s listing or its reservation&#39;s listing) are left out of the page and of &#x60;pagination.total&#x60;. Inactive listings keep syncing; activate the listing to use it here.
203
203
  # @param [Hash] opts the optional parameters
204
204
  # @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;.
205
205
  # @option opts [String] :cursor Opaque cursor returned in the previous response&#39;s &#x60;pagination.nextCursor&#x60;. Omit to fetch the first page.
206
- # @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)
206
+ # @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)
207
207
  # @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 20)
208
208
  # @option opts [String] :platform Restrict to threads on a single channel.
209
209
  # @option opts [String] :status Filter by archive status. &#x60;archived&#x60; currently always returns an empty page — kept for forward-compat.
@@ -281,5 +281,86 @@ module Repull
281
281
  end
282
282
  return data, status_code, headers
283
283
  end
284
+
285
+ # Send a message to the guest
286
+ # Sends a message to the guest on this conversation and records it in the thread. Omit `channel` and the message goes out on whichever channel the conversation already uses (Airbnb, Booking.com, SMS, email or the direct-booking site) — that is the right default. Pass `channel` only to force a specific one. The message is attributed to the API, not to Vanio AI: it is recorded with `aiGenerated` false so an API send is never counted as an automated reply. ### Airbnb rewrites links — check `contentRewritten` Airbnb rejects guest messages containing a link, an email address or a phone number, and names the offending text. When that happens the offending fragment is stripped and the remainder is re-sent once, which means **the guest receives a message that is not the one you wrote**. Reporting that as a plain success would be a lie, so every response carries `contentRewritten`; when it is `true`, `deliveredContent` is the text that actually reached the guest. Check it before assuming your message went out verbatim. When the text cannot be salvaged (the link is most of the message) nothing is delivered and the call returns `422 message_not_sent` with the channel's verbatim refusal in `statusReason`. Send `Idempotency-Key` — without it, retrying after a network timeout sends the guest the same message twice. **Inactive listings:** a conversation that belongs to an inactive listing returns `403 listing_inactive` and no message is sent. Activate the listing first.
287
+ # @param id [Integer] Internal Repull thread id.
288
+ # @param send_message_request [SendMessageRequest]
289
+ # @param [Hash] opts the optional parameters
290
+ # @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.
291
+ # @return [SendMessageResponse]
292
+ def send_conversation_message(id, send_message_request, opts = {})
293
+ data, _status_code, _headers = send_conversation_message_with_http_info(id, send_message_request, opts)
294
+ data
295
+ end
296
+
297
+ # Send a message to the guest
298
+ # Sends a message to the guest on this conversation and records it in the thread. Omit &#x60;channel&#x60; and the message goes out on whichever channel the conversation already uses (Airbnb, Booking.com, SMS, email or the direct-booking site) — that is the right default. Pass &#x60;channel&#x60; only to force a specific one. The message is attributed to the API, not to Vanio AI: it is recorded with &#x60;aiGenerated&#x60; false so an API send is never counted as an automated reply. ### Airbnb rewrites links — check &#x60;contentRewritten&#x60; Airbnb rejects guest messages containing a link, an email address or a phone number, and names the offending text. When that happens the offending fragment is stripped and the remainder is re-sent once, which means **the guest receives a message that is not the one you wrote**. Reporting that as a plain success would be a lie, so every response carries &#x60;contentRewritten&#x60;; when it is &#x60;true&#x60;, &#x60;deliveredContent&#x60; is the text that actually reached the guest. Check it before assuming your message went out verbatim. When the text cannot be salvaged (the link is most of the message) nothing is delivered and the call returns &#x60;422 message_not_sent&#x60; with the channel&#39;s verbatim refusal in &#x60;statusReason&#x60;. Send &#x60;Idempotency-Key&#x60; — without it, retrying after a network timeout sends the guest the same message twice. **Inactive listings:** a conversation that belongs to an inactive listing returns &#x60;403 listing_inactive&#x60; and no message is sent. Activate the listing first.
299
+ # @param id [Integer] Internal Repull thread id.
300
+ # @param send_message_request [SendMessageRequest]
301
+ # @param [Hash] opts the optional parameters
302
+ # @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.
303
+ # @return [Array<(SendMessageResponse, Integer, Hash)>] SendMessageResponse data, response status code and response headers
304
+ def send_conversation_message_with_http_info(id, send_message_request, opts = {})
305
+ if @api_client.config.debugging
306
+ @api_client.config.logger.debug 'Calling API: ConversationsApi.send_conversation_message ...'
307
+ end
308
+ # verify the required parameter 'id' is set
309
+ if @api_client.config.client_side_validation && id.nil?
310
+ fail ArgumentError, "Missing the required parameter 'id' when calling ConversationsApi.send_conversation_message"
311
+ end
312
+ # verify the required parameter 'send_message_request' is set
313
+ if @api_client.config.client_side_validation && send_message_request.nil?
314
+ fail ArgumentError, "Missing the required parameter 'send_message_request' when calling ConversationsApi.send_conversation_message"
315
+ end
316
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
317
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling ConversationsApi.send_conversation_message, the character length must be smaller than or equal to 255.'
318
+ end
319
+
320
+ # resource path
321
+ local_var_path = '/v1/conversations/{id}/messages'.sub('{id}', CGI.escape(id.to_s))
322
+
323
+ # query parameters
324
+ query_params = opts[:query_params] || {}
325
+
326
+ # header parameters
327
+ header_params = opts[:header_params] || {}
328
+ # HTTP header 'Accept' (if needed)
329
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
330
+ # HTTP header 'Content-Type'
331
+ content_type = @api_client.select_header_content_type(['application/json'])
332
+ if !content_type.nil?
333
+ header_params['Content-Type'] = content_type
334
+ end
335
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
336
+
337
+ # form parameters
338
+ form_params = opts[:form_params] || {}
339
+
340
+ # http body (model)
341
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(send_message_request)
342
+
343
+ # return_type
344
+ return_type = opts[:debug_return_type] || 'SendMessageResponse'
345
+
346
+ # auth_names
347
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
348
+
349
+ new_options = opts.merge(
350
+ :operation => :"ConversationsApi.send_conversation_message",
351
+ :header_params => header_params,
352
+ :query_params => query_params,
353
+ :form_params => form_params,
354
+ :body => post_body,
355
+ :auth_names => auth_names,
356
+ :return_type => return_type
357
+ )
358
+
359
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
360
+ if @api_client.config.debugging
361
+ @api_client.config.logger.debug "API called: ConversationsApi#send_conversation_message\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
362
+ end
363
+ return data, status_code, headers
364
+ end
284
365
  end
285
366
  end
@@ -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
@@ -19,8 +19,83 @@ module Repull
19
19
  def initialize(api_client = ApiClient.default)
20
20
  @api_client = api_client
21
21
  end
22
+ # Create a guest
23
+ # Creates a guest in the workspace, with contact normalisation applied (phone digits, email lowercased) and each contact stored as its own record. **This is find-or-create, and the response tells you which happened.** A guest already on file matching on email — then phone — AND name is returned instead of a duplicate being created. Read the `created` flag rather than inferring from the status: `201` with `created: true` means a new record was written, `200` with `created: false` means an existing guest matched. Quietly handing back an existing record as though it were new is exactly the ambiguity this flag removes. Field names are camelCase, and an unrecognised field is rejected by name rather than silently dropped. Send `Idempotency-Key` to make a retry safe.
24
+ # @param guest_create_request [GuestCreateRequest]
25
+ # @param [Hash] opts the optional parameters
26
+ # @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.
27
+ # @return [GuestCreateResponse]
28
+ def create_guest(guest_create_request, opts = {})
29
+ data, _status_code, _headers = create_guest_with_http_info(guest_create_request, opts)
30
+ data
31
+ end
32
+
33
+ # Create a guest
34
+ # Creates a guest in the workspace, with contact normalisation applied (phone digits, email lowercased) and each contact stored as its own record. **This is find-or-create, and the response tells you which happened.** A guest already on file matching on email — then phone — AND name is returned instead of a duplicate being created. Read the &#x60;created&#x60; flag rather than inferring from the status: &#x60;201&#x60; with &#x60;created: true&#x60; means a new record was written, &#x60;200&#x60; with &#x60;created: false&#x60; means an existing guest matched. Quietly handing back an existing record as though it were new is exactly the ambiguity this flag removes. Field names are camelCase, and an unrecognised field is rejected by name rather than silently dropped. Send &#x60;Idempotency-Key&#x60; to make a retry safe.
35
+ # @param guest_create_request [GuestCreateRequest]
36
+ # @param [Hash] opts the optional parameters
37
+ # @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.
38
+ # @return [Array<(GuestCreateResponse, Integer, Hash)>] GuestCreateResponse data, response status code and response headers
39
+ def create_guest_with_http_info(guest_create_request, opts = {})
40
+ if @api_client.config.debugging
41
+ @api_client.config.logger.debug 'Calling API: GuestsApi.create_guest ...'
42
+ end
43
+ # verify the required parameter 'guest_create_request' is set
44
+ if @api_client.config.client_side_validation && guest_create_request.nil?
45
+ fail ArgumentError, "Missing the required parameter 'guest_create_request' when calling GuestsApi.create_guest"
46
+ end
47
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
48
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling GuestsApi.create_guest, the character length must be smaller than or equal to 255.'
49
+ end
50
+
51
+ # resource path
52
+ local_var_path = '/v1/guests'
53
+
54
+ # query parameters
55
+ query_params = opts[:query_params] || {}
56
+
57
+ # header parameters
58
+ header_params = opts[:header_params] || {}
59
+ # HTTP header 'Accept' (if needed)
60
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
61
+ # HTTP header 'Content-Type'
62
+ content_type = @api_client.select_header_content_type(['application/json'])
63
+ if !content_type.nil?
64
+ header_params['Content-Type'] = content_type
65
+ end
66
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
67
+
68
+ # form parameters
69
+ form_params = opts[:form_params] || {}
70
+
71
+ # http body (model)
72
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(guest_create_request)
73
+
74
+ # return_type
75
+ return_type = opts[:debug_return_type] || 'GuestCreateResponse'
76
+
77
+ # auth_names
78
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
79
+
80
+ new_options = opts.merge(
81
+ :operation => :"GuestsApi.create_guest",
82
+ :header_params => header_params,
83
+ :query_params => query_params,
84
+ :form_params => form_params,
85
+ :body => post_body,
86
+ :auth_names => auth_names,
87
+ :return_type => return_type
88
+ )
89
+
90
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
91
+ if @api_client.config.debugging
92
+ @api_client.config.logger.debug "API called: GuestsApi#create_guest\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
93
+ end
94
+ return data, status_code, headers
95
+ end
96
+
22
97
  # Get guest profile
23
- # Returns the full guest profile — base list-row fields plus contacts, flags, notes, risk metadata, and reservation aggregates. Aggregates main vanio's `GuestService.getGuestProfile()` into the public Repull shape so SDK consumers don't have to learn the internal schema.
98
+ # Returns the full guest profile — base list-row fields plus contacts, flags, notes, risk metadata, and reservation aggregates. Aggregates main vanio's `GuestService.getGuestProfile()` into the public Repull shape so SDK consumers don't have to learn the internal schema. **Inactive listings:** a guest whose every reservation is on an inactive listing returns `403 listing_inactive` naming those listings (the guest is kept, so this is not a 404). Otherwise the reservation aggregates exclude reservations on inactive listings. A guest with no reservations is always readable.
24
99
  # @param id [Integer]
25
100
  # @param [Hash] opts the optional parameters
26
101
  # @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;.
@@ -31,7 +106,7 @@ module Repull
31
106
  end
32
107
 
33
108
  # Get guest profile
34
- # Returns the full guest profile — base list-row fields plus contacts, flags, notes, risk metadata, and reservation aggregates. Aggregates main vanio&#39;s &#x60;GuestService.getGuestProfile()&#x60; into the public Repull shape so SDK consumers don&#39;t have to learn the internal schema.
109
+ # Returns the full guest profile — base list-row fields plus contacts, flags, notes, risk metadata, and reservation aggregates. Aggregates main vanio&#39;s &#x60;GuestService.getGuestProfile()&#x60; into the public Repull shape so SDK consumers don&#39;t have to learn the internal schema. **Inactive listings:** a guest whose every reservation is on an inactive listing returns &#x60;403 listing_inactive&#x60; naming those listings (the guest is kept, so this is not a 404). Otherwise the reservation aggregates exclude reservations on inactive listings. A guest with no reservations is always readable.
35
110
  # @param id [Integer]
36
111
  # @param [Hash] opts the optional parameters
37
112
  # @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;.
@@ -86,11 +161,11 @@ module Repull
86
161
  end
87
162
 
88
163
  # List guests
89
- # Cursor-paginated list of guests in the workspace. Walks `guests.id ASC` keyset for constant per-page cost regardless of how many guests the customer has. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request. `?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/email/phone), `has_reservation` (`true`|`false`), `listing_id` (restrict to guests with at least one reservation on that listing).
164
+ # Cursor-paginated list of guests in the workspace. Walks `guests.id ASC` keyset for constant per-page cost regardless of how many guests the customer has. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request. `?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/email/phone), `has_reservation` (`true`|`false`), `listing_id` (restrict to guests with at least one reservation on that listing). **Inactive listings:** a guest whose every reservation is on an inactive listing is left out of the page and of `pagination.total`, and `totalReservations`, `totalRevenue`, `firstStayedAt` / `lastStayedAt`, `has_reservation` and `listing_id` only consider reservations that are not on an inactive listing. Guests with no reservations are tied to no listing and are always listed. Filtering by an inactive `listing_id` returns `403 listing_inactive`.
90
165
  # @param [Hash] opts the optional parameters
91
166
  # @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;.
92
167
  # @option opts [String] :cursor Opaque cursor returned in the previous response&#39;s &#x60;pagination.nextCursor&#x60;. Omit to fetch the first page.
93
- # @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)
168
+ # @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)
94
169
  # @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 20)
95
170
  # @option opts [String] :q Case-insensitive substring search on name, email, or phone.
96
171
  # @option opts [Boolean] :has_reservation Restrict to guests that do (&#x60;true&#x60;) or do not (&#x60;false&#x60;) have any reservation on file.
@@ -102,11 +177,11 @@ module Repull
102
177
  end
103
178
 
104
179
  # List guests
105
- # Cursor-paginated list of guests in the workspace. Walks &#x60;guests.id ASC&#x60; keyset for constant per-page cost regardless of how many guests the customer has. Use &#x60;pagination.nextCursor&#x60; from one response as the &#x60;cursor&#x60; query param of the next request. &#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/email/phone), &#x60;has_reservation&#x60; (&#x60;true&#x60;|&#x60;false&#x60;), &#x60;listing_id&#x60; (restrict to guests with at least one reservation on that listing).
180
+ # Cursor-paginated list of guests in the workspace. Walks &#x60;guests.id ASC&#x60; keyset for constant per-page cost regardless of how many guests the customer has. Use &#x60;pagination.nextCursor&#x60; from one response as the &#x60;cursor&#x60; query param of the next request. &#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/email/phone), &#x60;has_reservation&#x60; (&#x60;true&#x60;|&#x60;false&#x60;), &#x60;listing_id&#x60; (restrict to guests with at least one reservation on that listing). **Inactive listings:** a guest whose every reservation is on an inactive listing is left out of the page and of &#x60;pagination.total&#x60;, and &#x60;totalReservations&#x60;, &#x60;totalRevenue&#x60;, &#x60;firstStayedAt&#x60; / &#x60;lastStayedAt&#x60;, &#x60;has_reservation&#x60; and &#x60;listing_id&#x60; only consider reservations that are not on an inactive listing. Guests with no reservations are tied to no listing and are always listed. Filtering by an inactive &#x60;listing_id&#x60; returns &#x60;403 listing_inactive&#x60;.
106
181
  # @param [Hash] opts the optional parameters
107
182
  # @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;.
108
183
  # @option opts [String] :cursor Opaque cursor returned in the previous response&#39;s &#x60;pagination.nextCursor&#x60;. Omit to fetch the first page.
109
- # @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)
184
+ # @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)
110
185
  # @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 20)
111
186
  # @option opts [String] :q Case-insensitive substring search on name, email, or phone.
112
187
  # @option opts [Boolean] :has_reservation Restrict to guests that do (&#x60;true&#x60;) or do not (&#x60;false&#x60;) have any reservation on file.