repull 0.2.30 → 0.2.31

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/repull/api/airbnb_api.rb +2 -2
  3. data/lib/repull/api/billing_api.rb +68 -9
  4. data/lib/repull/api/connect_api.rb +139 -0
  5. data/lib/repull/api/conversations_api.rb +5 -2
  6. data/lib/repull/api/health_api.rb +2 -2
  7. data/lib/repull/api/hotels_api.rb +142 -0
  8. data/lib/repull/api/workspaces_api.rb +96 -0
  9. data/lib/repull/configuration.rb +0 -4
  10. data/lib/repull/models/availability_batch_write_request.rb +30 -1
  11. data/lib/repull/models/availability_write_request.rb +30 -1
  12. data/lib/repull/models/availability_write_settings.rb +33 -4
  13. data/lib/repull/models/connect_provider.rb +2 -2
  14. data/lib/repull/models/connect_session.rb +12 -2
  15. data/lib/repull/models/create_billing_checkout200_response.rb +156 -0
  16. data/lib/repull/models/create_billing_checkout_request.rb +2 -2
  17. data/lib/repull/models/create_connect_session_request.rb +13 -1
  18. data/lib/repull/models/create_connect_session_request_workspace.rb +1 -1
  19. data/lib/repull/models/get_billing200_response.rb +183 -0
  20. data/lib/repull/models/get_billing200_response_limits.rb +160 -0
  21. data/lib/repull/models/get_billing200_response_used.rb +156 -0
  22. data/lib/repull/models/get_channel_health200_response_vrbo.rb +11 -1
  23. data/lib/repull/models/get_hotel200_response.rb +252 -0
  24. data/lib/repull/models/get_hotel200_response_room_types_inner.rb +168 -0
  25. data/lib/repull/models/get_usage_summary200_response.rb +10 -1
  26. data/lib/repull/models/get_usage_summary200_response_credits.rb +186 -0
  27. data/lib/repull/models/list_hotels200_response.rb +158 -0
  28. data/lib/repull/models/list_hotels200_response_data_inner.rb +241 -0
  29. data/lib/repull/models/list_workspaces200_response.rb +158 -0
  30. data/lib/repull/models/listing.rb +50 -1
  31. data/lib/repull/models/listing_hotel.rb +202 -0
  32. data/lib/repull/models/record_account.rb +15 -5
  33. data/lib/repull/models/reservation_message_received_payload.rb +12 -1
  34. data/lib/repull/models/reservation_message_sent_payload.rb +12 -1
  35. data/lib/repull/models/reservation_message_updated_payload.rb +12 -1
  36. data/lib/repull/models/select_provider_response.rb +1 -1
  37. data/lib/repull/models/workspace.rb +265 -0
  38. data/lib/repull/version.rb +1 -1
  39. data/lib/repull.rb +14 -0
  40. data/openapi/v1.json +633 -18
  41. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69fa9729bf197cd3253d4f8508060d92ff8f63612f4fe819732e33791f319a29
4
- data.tar.gz: d8d971bed80c935f493fd41f62aa0bb68c3fbcc94871a6c0cebda620fa631473
3
+ metadata.gz: c3b71b0b3f2a6425621fe610515407d396ea3466f3ec39d30a77d7a2305b527d
4
+ data.tar.gz: f063363af9332fcee42f4458299b78aac800d8f1f85ed7c6556d9120e7ba8260
5
5
  SHA512:
6
- metadata.gz: b633634e3a8fa7f3e7af997bb7426504c18fd9ff16876673ae0765cc0752e43bc593a3df119c63a4fe8c1ddd2e987f4d2b86d8628004870eb81de29c5fbee44a
7
- data.tar.gz: 6ad990df1d082b04d17a090ad145922e4d40d5e7a6510de77a14fe36f8c559d3e20782fdb388ab3de287f162933c66cc3079749bca7b2c916fb38dc9fa66ee07
6
+ metadata.gz: 683a5cbcc182f873900c356f74db640f0c3bf913822e553d9804f7773eff32dea96837e73bc186f3cce0992b16852df97b5d54d31c36b59184c8835422b61498
7
+ data.tar.gz: f6b207c5ed832883d56624f4189bd9ba1e8836e0f2d370c34a56cf5161f575134cfb36797ed7401e7f3b79c4effd441b3297257468a0c37f98b4e45745386837
@@ -1197,7 +1197,7 @@ module Repull
1197
1197
  end
1198
1198
 
1199
1199
  # Get Airbnb availability
1200
- # Read the per-day availability calendar for an Airbnb listing. Returns one row per day including price overrides, min-stay, and blocked status. 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.
1200
+ # Read the per-day availability calendar for an Airbnb listing. Returns one row per day including price overrides, min-stay, and blocked status. The calendar is served from Repull's stored copy, refreshed by the periodic sync. A successful calendar write through `PUT .../availability` or `PUT .../pricing` (`type: \"calendar\"`) updates the stored days immediately, so reading back right after a write returns the values you published. Changes made directly on Airbnb appear after the next sync (`dataFreshness.lastSyncedAt`). **Coverage:** with `start_date` + `end_date`, `data.coverage` gives `{ from, to }`, the first and last stored date for the listing (the sync keeps about 12 months ahead). A date outside that window is not stored, so a missing date there means \"not covered\", not \"nothing set\". Request it again once `coverage.to` reaches it. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1201
1201
  # @param id [String]
1202
1202
  # @param [Hash] opts the optional parameters
1203
1203
  # @return [nil]
@@ -1207,7 +1207,7 @@ module Repull
1207
1207
  end
1208
1208
 
1209
1209
  # Get Airbnb availability
1210
- # Read the per-day availability calendar for an Airbnb listing. Returns one row per day including price overrides, min-stay, and blocked status. 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.
1210
+ # Read the per-day availability calendar for an Airbnb listing. Returns one row per day including price overrides, min-stay, and blocked status. The calendar is served from Repull's stored copy, refreshed by the periodic sync. A successful calendar write through `PUT .../availability` or `PUT .../pricing` (`type: \"calendar\"`) updates the stored days immediately, so reading back right after a write returns the values you published. Changes made directly on Airbnb appear after the next sync (`dataFreshness.lastSyncedAt`). **Coverage:** with `start_date` + `end_date`, `data.coverage` gives `{ from, to }`, the first and last stored date for the listing (the sync keeps about 12 months ahead). A date outside that window is not stored, so a missing date there means \"not covered\", not \"nothing set\". Request it again once `coverage.to` reaches it. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1211
1211
  # @param id [String]
1212
1212
  # @param [Hash] opts the optional parameters
1213
1213
  # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
@@ -19,21 +19,21 @@ module Repull
19
19
  def initialize(api_client = ApiClient.default)
20
20
  @api_client = api_client
21
21
  end
22
- # Create checkout session
23
- # Redirect user to Stripe checkout.
22
+ # Start an upgrade
23
+ # Returns the URL where the workspace owner upgrades to Starter. Plans above Starter are set up with the Repull team and return `422 billing_error` with the next step.
24
24
  # @param [Hash] opts the optional parameters
25
25
  # @option opts [CreateBillingCheckoutRequest] :create_billing_checkout_request
26
- # @return [nil]
26
+ # @return [CreateBillingCheckout200Response]
27
27
  def create_billing_checkout(opts = {})
28
- create_billing_checkout_with_http_info(opts)
29
- nil
28
+ data, _status_code, _headers = create_billing_checkout_with_http_info(opts)
29
+ data
30
30
  end
31
31
 
32
- # Create checkout session
33
- # Redirect user to Stripe checkout.
32
+ # Start an upgrade
33
+ # Returns the URL where the workspace owner upgrades to Starter. Plans above Starter are set up with the Repull team and return &#x60;422 billing_error&#x60; with the next step.
34
34
  # @param [Hash] opts the optional parameters
35
35
  # @option opts [CreateBillingCheckoutRequest] :create_billing_checkout_request
36
- # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
36
+ # @return [Array<(CreateBillingCheckout200Response, Integer, Hash)>] CreateBillingCheckout200Response data, response status code and response headers
37
37
  def create_billing_checkout_with_http_info(opts = {})
38
38
  if @api_client.config.debugging
39
39
  @api_client.config.logger.debug 'Calling API: BillingApi.create_billing_checkout ...'
@@ -46,6 +46,8 @@ module Repull
46
46
 
47
47
  # header parameters
48
48
  header_params = opts[:header_params] || {}
49
+ # HTTP header 'Accept' (if needed)
50
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
49
51
  # HTTP header 'Content-Type'
50
52
  content_type = @api_client.select_header_content_type(['application/json'])
51
53
  if !content_type.nil?
@@ -59,7 +61,7 @@ module Repull
59
61
  post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'create_billing_checkout_request'])
60
62
 
61
63
  # return_type
62
- return_type = opts[:debug_return_type]
64
+ return_type = opts[:debug_return_type] || 'CreateBillingCheckout200Response'
63
65
 
64
66
  # auth_names
65
67
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -81,6 +83,63 @@ module Repull
81
83
  return data, status_code, headers
82
84
  end
83
85
 
86
+ # Get plan and usage
87
+ # The workspace's plan, its request limits, usage this period, and where the owner manages the plan. Same numbers as `GET /v1/usage/tier`.
88
+ # @param [Hash] opts the optional parameters
89
+ # @return [GetBilling200Response]
90
+ def get_billing(opts = {})
91
+ data, _status_code, _headers = get_billing_with_http_info(opts)
92
+ data
93
+ end
94
+
95
+ # Get plan and usage
96
+ # The workspace&#39;s plan, its request limits, usage this period, and where the owner manages the plan. Same numbers as &#x60;GET /v1/usage/tier&#x60;.
97
+ # @param [Hash] opts the optional parameters
98
+ # @return [Array<(GetBilling200Response, Integer, Hash)>] GetBilling200Response data, response status code and response headers
99
+ def get_billing_with_http_info(opts = {})
100
+ if @api_client.config.debugging
101
+ @api_client.config.logger.debug 'Calling API: BillingApi.get_billing ...'
102
+ end
103
+ # resource path
104
+ local_var_path = '/v1/billing'
105
+
106
+ # query parameters
107
+ query_params = opts[:query_params] || {}
108
+
109
+ # header parameters
110
+ header_params = opts[:header_params] || {}
111
+ # HTTP header 'Accept' (if needed)
112
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
113
+
114
+ # form parameters
115
+ form_params = opts[:form_params] || {}
116
+
117
+ # http body (model)
118
+ post_body = opts[:debug_body]
119
+
120
+ # return_type
121
+ return_type = opts[:debug_return_type] || 'GetBilling200Response'
122
+
123
+ # auth_names
124
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
125
+
126
+ new_options = opts.merge(
127
+ :operation => :"BillingApi.get_billing",
128
+ :header_params => header_params,
129
+ :query_params => query_params,
130
+ :form_params => form_params,
131
+ :body => post_body,
132
+ :auth_names => auth_names,
133
+ :return_type => return_type
134
+ )
135
+
136
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
137
+ if @api_client.config.debugging
138
+ @api_client.config.logger.debug "API called: BillingApi#get_billing\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
139
+ end
140
+ return data, status_code, headers
141
+ end
142
+
84
143
  # List API request logs
85
144
  # Cursor-paginated raw API request log for the authenticated workspace, newest first. Filter by time `range`, `operation` id(s), status class, or free-text `q`. Walk pages with `cursor` from `pagination.nextCursor` until `pagination.hasMore` is `false`; `offset` is accepted as a shallow alias (deep walks must use `cursor`).
86
145
  # @param [Hash] opts the optional parameters
@@ -751,6 +751,7 @@ module Repull
751
751
  # List Connect channels
752
752
  # Returns the public registry of every channel the picker supports. No customer-specific data — display metadata only. Cached for 5 minutes at the edge.
753
753
  # @param [Hash] opts the optional parameters
754
+ # @option opts [Boolean] :include_request_only Also return the PMSes Repull doesn&#39;t connect yet (&#x60;status: request-only&#x60;), for a picker you render yourself for a session created with &#x60;includeRequestOnly&#x60;. (default to false)
754
755
  # @return [ConnectProviderListResponse]
755
756
  def list_connect_providers(opts = {})
756
757
  data, _status_code, _headers = list_connect_providers_with_http_info(opts)
@@ -760,6 +761,7 @@ module Repull
760
761
  # List Connect channels
761
762
  # Returns the public registry of every channel the picker supports. No customer-specific data — display metadata only. Cached for 5 minutes at the edge.
762
763
  # @param [Hash] opts the optional parameters
764
+ # @option opts [Boolean] :include_request_only Also return the PMSes Repull doesn&#39;t connect yet (&#x60;status: request-only&#x60;), for a picker you render yourself for a session created with &#x60;includeRequestOnly&#x60;. (default to false)
763
765
  # @return [Array<(ConnectProviderListResponse, Integer, Hash)>] ConnectProviderListResponse data, response status code and response headers
764
766
  def list_connect_providers_with_http_info(opts = {})
765
767
  if @api_client.config.debugging
@@ -770,6 +772,7 @@ module Repull
770
772
 
771
773
  # query parameters
772
774
  query_params = opts[:query_params] || {}
775
+ query_params[:'includeRequestOnly'] = opts[:'include_request_only'] if !opts[:'include_request_only'].nil?
773
776
 
774
777
  # header parameters
775
778
  header_params = opts[:header_params] || {}
@@ -998,6 +1001,74 @@ module Repull
998
1001
  return data, status_code, headers
999
1002
  end
1000
1003
 
1004
+ # RentalReady OAuth callback
1005
+ # RentalReady's OAuth redirect after the host allows or denies access on RentalReady's consent screen. It finishes the Connect session and redirects the host to the hosted Connect page. Called by the host's browser, not by integrators.
1006
+ # @param state [String] The signed Connect state Repull sent to RentalReady.
1007
+ # @param [Hash] opts the optional parameters
1008
+ # @option opts [String] :code Authorization code from RentalReady.
1009
+ # @option opts [String] :error Set by RentalReady when the host denied access (&#x60;access_denied&#x60;).
1010
+ # @return [nil]
1011
+ def rental_ready_connect_callback(state, opts = {})
1012
+ rental_ready_connect_callback_with_http_info(state, opts)
1013
+ nil
1014
+ end
1015
+
1016
+ # RentalReady OAuth callback
1017
+ # RentalReady&#39;s OAuth redirect after the host allows or denies access on RentalReady&#39;s consent screen. It finishes the Connect session and redirects the host to the hosted Connect page. Called by the host&#39;s browser, not by integrators.
1018
+ # @param state [String] The signed Connect state Repull sent to RentalReady.
1019
+ # @param [Hash] opts the optional parameters
1020
+ # @option opts [String] :code Authorization code from RentalReady.
1021
+ # @option opts [String] :error Set by RentalReady when the host denied access (&#x60;access_denied&#x60;).
1022
+ # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
1023
+ def rental_ready_connect_callback_with_http_info(state, opts = {})
1024
+ if @api_client.config.debugging
1025
+ @api_client.config.logger.debug 'Calling API: ConnectApi.rental_ready_connect_callback ...'
1026
+ end
1027
+ # verify the required parameter 'state' is set
1028
+ if @api_client.config.client_side_validation && state.nil?
1029
+ fail ArgumentError, "Missing the required parameter 'state' when calling ConnectApi.rental_ready_connect_callback"
1030
+ end
1031
+ # resource path
1032
+ local_var_path = '/v1/connect/rentalready/callback'
1033
+
1034
+ # query parameters
1035
+ query_params = opts[:query_params] || {}
1036
+ query_params[:'state'] = state
1037
+ query_params[:'code'] = opts[:'code'] if !opts[:'code'].nil?
1038
+ query_params[:'error'] = opts[:'error'] if !opts[:'error'].nil?
1039
+
1040
+ # header parameters
1041
+ header_params = opts[:header_params] || {}
1042
+
1043
+ # form parameters
1044
+ form_params = opts[:form_params] || {}
1045
+
1046
+ # http body (model)
1047
+ post_body = opts[:debug_body]
1048
+
1049
+ # return_type
1050
+ return_type = opts[:debug_return_type]
1051
+
1052
+ # auth_names
1053
+ auth_names = opts[:debug_auth_names] || []
1054
+
1055
+ new_options = opts.merge(
1056
+ :operation => :"ConnectApi.rental_ready_connect_callback",
1057
+ :header_params => header_params,
1058
+ :query_params => query_params,
1059
+ :form_params => form_params,
1060
+ :body => post_body,
1061
+ :auth_names => auth_names,
1062
+ :return_type => return_type
1063
+ )
1064
+
1065
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
1066
+ if @api_client.config.debugging
1067
+ @api_client.config.logger.debug "API called: ConnectApi#rental_ready_connect_callback\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
1068
+ end
1069
+ return data, status_code, headers
1070
+ end
1071
+
1001
1072
  # Open a connection's fix link
1002
1073
  # The target of a connection's `fixUrl`. Open it in the host's browser to send them back into Connect for an EXISTING connection — for example to grant the Booking.com extranet user full access after a `needs_permissions` state, or to reconnect a Smoobu account that still uses a legacy single API key with an API key + secret. Each open starts a fresh, short-lived Connect session bound to that connection and redirects (302) to the hosted Connect page, which shows the connection's current state. The link itself does not expire on its own schedule — store `fixUrl` and open it whenever the connection needs attention. No API key — the signed `t` token is the capability. Supported for Booking.com extranet login and Smoobu connections.
1003
1074
  # @param t [String] The signed resume token, exactly as it appears in the connection&#39;s &#x60;fixUrl&#x60;.
@@ -2374,5 +2445,73 @@ module Repull
2374
2445
  end
2375
2446
  return data, status_code, headers
2376
2447
  end
2448
+
2449
+ # Zeevou OAuth callback
2450
+ # Zeevou's OAuth redirect after the host allows or denies access on Zeevou's consent screen. It finishes the Connect session and redirects the host to the hosted Connect page. Called by the host's browser, not by integrators.
2451
+ # @param state [String] The signed Connect state Repull sent to Zeevou.
2452
+ # @param [Hash] opts the optional parameters
2453
+ # @option opts [String] :code Authorization code from Zeevou.
2454
+ # @option opts [String] :error Set by Zeevou when the host denied access (&#x60;access_denied&#x60;).
2455
+ # @return [nil]
2456
+ def zeevou_connect_callback(state, opts = {})
2457
+ zeevou_connect_callback_with_http_info(state, opts)
2458
+ nil
2459
+ end
2460
+
2461
+ # Zeevou OAuth callback
2462
+ # Zeevou&#39;s OAuth redirect after the host allows or denies access on Zeevou&#39;s consent screen. It finishes the Connect session and redirects the host to the hosted Connect page. Called by the host&#39;s browser, not by integrators.
2463
+ # @param state [String] The signed Connect state Repull sent to Zeevou.
2464
+ # @param [Hash] opts the optional parameters
2465
+ # @option opts [String] :code Authorization code from Zeevou.
2466
+ # @option opts [String] :error Set by Zeevou when the host denied access (&#x60;access_denied&#x60;).
2467
+ # @return [Array<(nil, Integer, Hash)>] nil, response status code and response headers
2468
+ def zeevou_connect_callback_with_http_info(state, opts = {})
2469
+ if @api_client.config.debugging
2470
+ @api_client.config.logger.debug 'Calling API: ConnectApi.zeevou_connect_callback ...'
2471
+ end
2472
+ # verify the required parameter 'state' is set
2473
+ if @api_client.config.client_side_validation && state.nil?
2474
+ fail ArgumentError, "Missing the required parameter 'state' when calling ConnectApi.zeevou_connect_callback"
2475
+ end
2476
+ # resource path
2477
+ local_var_path = '/v1/connect/zeevou/callback'
2478
+
2479
+ # query parameters
2480
+ query_params = opts[:query_params] || {}
2481
+ query_params[:'state'] = state
2482
+ query_params[:'code'] = opts[:'code'] if !opts[:'code'].nil?
2483
+ query_params[:'error'] = opts[:'error'] if !opts[:'error'].nil?
2484
+
2485
+ # header parameters
2486
+ header_params = opts[:header_params] || {}
2487
+
2488
+ # form parameters
2489
+ form_params = opts[:form_params] || {}
2490
+
2491
+ # http body (model)
2492
+ post_body = opts[:debug_body]
2493
+
2494
+ # return_type
2495
+ return_type = opts[:debug_return_type]
2496
+
2497
+ # auth_names
2498
+ auth_names = opts[:debug_auth_names] || []
2499
+
2500
+ new_options = opts.merge(
2501
+ :operation => :"ConnectApi.zeevou_connect_callback",
2502
+ :header_params => header_params,
2503
+ :query_params => query_params,
2504
+ :form_params => form_params,
2505
+ :body => post_body,
2506
+ :auth_names => auth_names,
2507
+ :return_type => return_type
2508
+ )
2509
+
2510
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
2511
+ if @api_client.config.debugging
2512
+ @api_client.config.logger.debug "API called: ConnectApi#zeevou_connect_callback\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
2513
+ end
2514
+ return data, status_code, headers
2515
+ end
2377
2516
  end
2378
2517
  end
@@ -334,7 +334,7 @@ module Repull
334
334
  end
335
335
 
336
336
  # List conversations
337
- # Cursor-paginated list of message threads owned by the workspace. 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.
337
+ # Cursor-paginated list of message threads owned by the workspace. 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. **Order:** newest conversation first (by when the conversation started), unless you pass `updated_since`. **Incremental sync (`?updated_since=<ISO8601>`):** only conversations with activity (a new message or another change) at or after that instant, ordered oldest change first (`updatedAt ASC`). Walk every page with `cursor`, keeping `updated_since` on each request; the last row's `updatedAt` is your next watermark. A cursor from one kind of walk is refused on the other.
338
338
  # @param [Hash] opts the optional parameters
339
339
  # @option opts [String] :account Only the records of one connected account, as &#x60;provider:externalAccountId&#x60; — the pair from a webhook &#x60;account&#x60; block, &#x60;connect.session.completed&#x60;, or &#x60;GET /v1/connect/{provider}&#x60; → &#x60;accounts&#x60;. A record belongs to an account when it is on that account&#39;s listings and on its channel (a PMS account: came in through that PMS). An account with no listings returns an empty page.
340
340
  # @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;.
@@ -342,6 +342,7 @@ module Repull
342
342
  # @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)
343
343
  # @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 20)
344
344
  # @option opts [String] :platform Restrict to threads on a single channel.
345
+ # @option opts [Time] :updated_since ISO 8601 instant. Only conversations with activity at or after it, oldest change first. Keep it on every page of the walk; use the last row&#39;s &#x60;updatedAt&#x60; as the next value.
345
346
  # @option opts [String] :status Filter by archive status. &#x60;archived&#x60; currently always returns an empty page — kept for forward-compat.
346
347
  # @return [ConversationListResponse]
347
348
  def list_conversations(opts = {})
@@ -350,7 +351,7 @@ module Repull
350
351
  end
351
352
 
352
353
  # List conversations
353
- # Cursor-paginated list of message threads owned by the workspace. 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.
354
+ # Cursor-paginated list of message threads owned by the workspace. 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. **Order:** newest conversation first (by when the conversation started), unless you pass &#x60;updated_since&#x60;. **Incremental sync (&#x60;?updated_since&#x3D;&lt;ISO8601&gt;&#x60;):** only conversations with activity (a new message or another change) at or after that instant, ordered oldest change first (&#x60;updatedAt ASC&#x60;). Walk every page with &#x60;cursor&#x60;, keeping &#x60;updated_since&#x60; on each request; the last row&#39;s &#x60;updatedAt&#x60; is your next watermark. A cursor from one kind of walk is refused on the other.
354
355
  # @param [Hash] opts the optional parameters
355
356
  # @option opts [String] :account Only the records of one connected account, as &#x60;provider:externalAccountId&#x60; — the pair from a webhook &#x60;account&#x60; block, &#x60;connect.session.completed&#x60;, or &#x60;GET /v1/connect/{provider}&#x60; → &#x60;accounts&#x60;. A record belongs to an account when it is on that account&#39;s listings and on its channel (a PMS account: came in through that PMS). An account with no listings returns an empty page.
356
357
  # @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;.
@@ -358,6 +359,7 @@ module Repull
358
359
  # @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)
359
360
  # @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 20)
360
361
  # @option opts [String] :platform Restrict to threads on a single channel.
362
+ # @option opts [Time] :updated_since ISO 8601 instant. Only conversations with activity at or after it, oldest change first. Keep it on every page of the walk; use the last row&#39;s &#x60;updatedAt&#x60; as the next value.
361
363
  # @option opts [String] :status Filter by archive status. &#x60;archived&#x60; currently always returns an empty page — kept for forward-compat.
362
364
  # @return [Array<(ConversationListResponse, Integer, Hash)>] ConversationListResponse data, response status code and response headers
363
365
  def list_conversations_with_http_info(opts = {})
@@ -398,6 +400,7 @@ module Repull
398
400
  query_params[:'offset'] = opts[:'offset'] if !opts[:'offset'].nil?
399
401
  query_params[:'limit'] = opts[:'limit'] if !opts[:'limit'].nil?
400
402
  query_params[:'platform'] = opts[:'platform'] if !opts[:'platform'].nil?
403
+ query_params[:'updated_since'] = opts[:'updated_since'] if !opts[:'updated_since'].nil?
401
404
  query_params[:'status'] = opts[:'status'] if !opts[:'status'].nil?
402
405
 
403
406
  # header parameters
@@ -77,7 +77,7 @@ module Repull
77
77
  end
78
78
 
79
79
  # Per-channel connectivity health
80
- # Reports reachability and auth state for one channel (`airbnb`, `booking`, `vrbo`, `plumguide`). Use it to tell \"the channel is down\" apart from \"this workspace's connection expired\". `200` when `status` is `ok`, `503` when `degraded` or `down` (the body's `status` and `message` say which and why). **`vrbo`** reports the connector's own signals in a `vrbo` block: connected accounts, accounts VRBO signed out (their bookings, messages and calendar stop until reconnected — `down`), accounts whose inbox sync is late (`degraded`), and the calendar push queue backlog and its oldest wait (`degraded` past 3 hours). Its rate is failed calendar pushes over finished ones in the last 3 hours (`vrbo.window_hours`; `refresh_attempts_24h` / `refresh_rejections_24h` count that window for VRBO), judged only once at least 50 pushes finished and at least 5 failed — VRBO pushes run in bursts, so a day-long window would keep reporting a problem already fixed.
80
+ # Reports reachability and auth state for one channel (`airbnb`, `booking`, `vrbo`, `plumguide`). Use it to tell \"the channel is down\" apart from \"this workspace's connection expired\". `200` when `status` is `ok`, `503` when `degraded` or `down` (the body's `status` and `message` say which and why). **`vrbo`** reports the connector's own signals in a `vrbo` block: connected accounts, accounts VRBO signed out (their bookings, messages and calendar stop until reconnected — `down`), accounts whose inbox sync is late (`degraded`), and the calendar push queue backlog and its oldest wait (`degraded` past 3 hours). Its rate is calendar pushes VRBO refused over finished ones in the last 3 hours; failures inside Repull's own connector are reported apart as `vrbo.connector_errors` and do not count (`vrbo.window_hours`; `refresh_attempts_24h` / `refresh_rejections_24h` count that window for VRBO), judged only once at least 50 pushes finished and at least 5 failed — VRBO pushes run in bursts, so a day-long window would keep reporting a problem already fixed.
81
81
  # @param channel [String]
82
82
  # @param [Hash] opts the optional parameters
83
83
  # @return [GetChannelHealth200Response]
@@ -87,7 +87,7 @@ module Repull
87
87
  end
88
88
 
89
89
  # Per-channel connectivity health
90
- # Reports reachability and auth state for one channel (&#x60;airbnb&#x60;, &#x60;booking&#x60;, &#x60;vrbo&#x60;, &#x60;plumguide&#x60;). Use it to tell \&quot;the channel is down\&quot; apart from \&quot;this workspace&#39;s connection expired\&quot;. &#x60;200&#x60; when &#x60;status&#x60; is &#x60;ok&#x60;, &#x60;503&#x60; when &#x60;degraded&#x60; or &#x60;down&#x60; (the body&#39;s &#x60;status&#x60; and &#x60;message&#x60; say which and why). **&#x60;vrbo&#x60;** reports the connector&#39;s own signals in a &#x60;vrbo&#x60; block: connected accounts, accounts VRBO signed out (their bookings, messages and calendar stop until reconnected — &#x60;down&#x60;), accounts whose inbox sync is late (&#x60;degraded&#x60;), and the calendar push queue backlog and its oldest wait (&#x60;degraded&#x60; past 3 hours). Its rate is failed calendar pushes over finished ones in the last 3 hours (&#x60;vrbo.window_hours&#x60;; &#x60;refresh_attempts_24h&#x60; / &#x60;refresh_rejections_24h&#x60; count that window for VRBO), judged only once at least 50 pushes finished and at least 5 failed — VRBO pushes run in bursts, so a day-long window would keep reporting a problem already fixed.
90
+ # Reports reachability and auth state for one channel (&#x60;airbnb&#x60;, &#x60;booking&#x60;, &#x60;vrbo&#x60;, &#x60;plumguide&#x60;). Use it to tell \&quot;the channel is down\&quot; apart from \&quot;this workspace&#39;s connection expired\&quot;. &#x60;200&#x60; when &#x60;status&#x60; is &#x60;ok&#x60;, &#x60;503&#x60; when &#x60;degraded&#x60; or &#x60;down&#x60; (the body&#39;s &#x60;status&#x60; and &#x60;message&#x60; say which and why). **&#x60;vrbo&#x60;** reports the connector&#39;s own signals in a &#x60;vrbo&#x60; block: connected accounts, accounts VRBO signed out (their bookings, messages and calendar stop until reconnected — &#x60;down&#x60;), accounts whose inbox sync is late (&#x60;degraded&#x60;), and the calendar push queue backlog and its oldest wait (&#x60;degraded&#x60; past 3 hours). Its rate is calendar pushes VRBO refused over finished ones in the last 3 hours; failures inside Repull&#39;s own connector are reported apart as &#x60;vrbo.connector_errors&#x60; and do not count (&#x60;vrbo.window_hours&#x60;; &#x60;refresh_attempts_24h&#x60; / &#x60;refresh_rejections_24h&#x60; count that window for VRBO), judged only once at least 50 pushes finished and at least 5 failed — VRBO pushes run in bursts, so a day-long window would keep reporting a problem already fixed.
91
91
  # @param channel [String]
92
92
  # @param [Hash] opts the optional parameters
93
93
  # @return [Array<(GetChannelHealth200Response, Integer, Hash)>] GetChannelHealth200Response data, response status code and response headers
@@ -0,0 +1,142 @@
1
+ =begin
2
+ #Repull API
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_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` | unlimited (10 included, then billed per listing) | | `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
+
6
+ The version of the OpenAPI document: 1.0.0
7
+
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.22.0
10
+
11
+ =end
12
+
13
+ require 'cgi'
14
+
15
+ module Repull
16
+ class HotelsApi
17
+ attr_accessor :api_client
18
+
19
+ def initialize(api_client = ApiClient.default)
20
+ @api_client = api_client
21
+ end
22
+ # Get a hotel
23
+ # One hotel with its room types. `id` is from `GET /v1/hotels`, or a listing's `hotel.id`.
24
+ # @param id [String]
25
+ # @param [Hash] opts the optional parameters
26
+ # @return [GetHotel200Response]
27
+ def get_hotel(id, opts = {})
28
+ data, _status_code, _headers = get_hotel_with_http_info(id, opts)
29
+ data
30
+ end
31
+
32
+ # Get a hotel
33
+ # One hotel with its room types. &#x60;id&#x60; is from &#x60;GET /v1/hotels&#x60;, or a listing&#39;s &#x60;hotel.id&#x60;.
34
+ # @param id [String]
35
+ # @param [Hash] opts the optional parameters
36
+ # @return [Array<(GetHotel200Response, Integer, Hash)>] GetHotel200Response data, response status code and response headers
37
+ def get_hotel_with_http_info(id, opts = {})
38
+ if @api_client.config.debugging
39
+ @api_client.config.logger.debug 'Calling API: HotelsApi.get_hotel ...'
40
+ end
41
+ # verify the required parameter 'id' is set
42
+ if @api_client.config.client_side_validation && id.nil?
43
+ fail ArgumentError, "Missing the required parameter 'id' when calling HotelsApi.get_hotel"
44
+ end
45
+ # resource path
46
+ local_var_path = '/v1/hotels/{id}'.sub('{id}', CGI.escape(id.to_s))
47
+
48
+ # query parameters
49
+ query_params = opts[:query_params] || {}
50
+
51
+ # header parameters
52
+ header_params = opts[:header_params] || {}
53
+ # HTTP header 'Accept' (if needed)
54
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
55
+
56
+ # form parameters
57
+ form_params = opts[:form_params] || {}
58
+
59
+ # http body (model)
60
+ post_body = opts[:debug_body]
61
+
62
+ # return_type
63
+ return_type = opts[:debug_return_type] || 'GetHotel200Response'
64
+
65
+ # auth_names
66
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
67
+
68
+ new_options = opts.merge(
69
+ :operation => :"HotelsApi.get_hotel",
70
+ :header_params => header_params,
71
+ :query_params => query_params,
72
+ :form_params => form_params,
73
+ :body => post_body,
74
+ :auth_names => auth_names,
75
+ :return_type => return_type
76
+ )
77
+
78
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
79
+ if @api_client.config.debugging
80
+ @api_client.config.logger.debug "API called: HotelsApi#get_hotel\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
81
+ end
82
+ return data, status_code, headers
83
+ end
84
+
85
+ # List hotels
86
+ # Your workspace's hotels: hotels from a hotel PMS (Cloudbeds, Mews) and Booking.com properties with several room types or rooms. Each room type is a listing — `GET /v1/hotels/{id}` lists them with their room counts. A hotel itself is never booked: availability, prices and reservations live on its room types. See the Hotels & multi-unit guide.
87
+ # @param [Hash] opts the optional parameters
88
+ # @return [ListHotels200Response]
89
+ def list_hotels(opts = {})
90
+ data, _status_code, _headers = list_hotels_with_http_info(opts)
91
+ data
92
+ end
93
+
94
+ # List hotels
95
+ # Your workspace&#39;s hotels: hotels from a hotel PMS (Cloudbeds, Mews) and Booking.com properties with several room types or rooms. Each room type is a listing — &#x60;GET /v1/hotels/{id}&#x60; lists them with their room counts. A hotel itself is never booked: availability, prices and reservations live on its room types. See the Hotels &amp; multi-unit guide.
96
+ # @param [Hash] opts the optional parameters
97
+ # @return [Array<(ListHotels200Response, Integer, Hash)>] ListHotels200Response data, response status code and response headers
98
+ def list_hotels_with_http_info(opts = {})
99
+ if @api_client.config.debugging
100
+ @api_client.config.logger.debug 'Calling API: HotelsApi.list_hotels ...'
101
+ end
102
+ # resource path
103
+ local_var_path = '/v1/hotels'
104
+
105
+ # query parameters
106
+ query_params = opts[:query_params] || {}
107
+
108
+ # header parameters
109
+ header_params = opts[:header_params] || {}
110
+ # HTTP header 'Accept' (if needed)
111
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
112
+
113
+ # form parameters
114
+ form_params = opts[:form_params] || {}
115
+
116
+ # http body (model)
117
+ post_body = opts[:debug_body]
118
+
119
+ # return_type
120
+ return_type = opts[:debug_return_type] || 'ListHotels200Response'
121
+
122
+ # auth_names
123
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
124
+
125
+ new_options = opts.merge(
126
+ :operation => :"HotelsApi.list_hotels",
127
+ :header_params => header_params,
128
+ :query_params => query_params,
129
+ :form_params => form_params,
130
+ :body => post_body,
131
+ :auth_names => auth_names,
132
+ :return_type => return_type
133
+ )
134
+
135
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
136
+ if @api_client.config.debugging
137
+ @api_client.config.logger.debug "API called: HotelsApi#list_hotels\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
138
+ end
139
+ return data, status_code, headers
140
+ end
141
+ end
142
+ end