repull 0.2.28 → 0.2.29

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/repull/api/conversations_api.rb +2 -2
  3. data/lib/repull/api/guests_api.rb +83 -2
  4. data/lib/repull/api/listings_api.rb +2 -2
  5. data/lib/repull/api/reservations_api.rb +2 -2
  6. data/lib/repull/api/reviews_api.rb +2 -2
  7. data/lib/repull/models/connect_status_capabilities.rb +14 -5
  8. data/lib/repull/models/guest_create_request.rb +14 -4
  9. data/lib/repull/models/guest_create_response.rb +15 -5
  10. data/lib/repull/models/guest_create_response_pms.rb +158 -0
  11. data/lib/repull/models/guest_update_request.rb +205 -0
  12. data/lib/repull/models/guest_update_response.rb +209 -0
  13. data/lib/repull/models/{guest_create_response_contacts_inner.rb → guest_update_response_contacts_inner.rb} +3 -3
  14. data/lib/repull/models/guest_update_response_pms_inner.rb +158 -0
  15. data/lib/repull/models/listing_capabilities.rb +14 -5
  16. data/lib/repull/models/listing_content_update_response.rb +15 -5
  17. data/lib/repull/models/listing_content_update_response_pms.rb +172 -0
  18. data/lib/repull/models/listing_content_update_response_pms_errors_inner.rb +199 -0
  19. data/lib/repull/models/pms_capabilities.rb +242 -0
  20. data/lib/repull/models/pms_capabilities_calendar.rb +148 -0
  21. data/lib/repull/models/pms_capabilities_conversations.rb +167 -0
  22. data/lib/repull/models/pms_capabilities_guests.rb +158 -0
  23. data/lib/repull/models/pms_capabilities_listings.rb +238 -0
  24. data/lib/repull/models/pms_capabilities_payments.rb +148 -0
  25. data/lib/repull/models/pms_capabilities_reservations.rb +158 -0
  26. data/lib/repull/models/pms_capabilities_reviews.rb +158 -0
  27. data/lib/repull/models/pms_capabilities_tasks.rb +156 -0
  28. data/lib/repull/models/reply_to_review201_response.rb +12 -1
  29. data/lib/repull/models/review.rb +12 -1
  30. data/lib/repull/models/send_message_request.rb +2 -2
  31. data/lib/repull/version.rb +1 -1
  32. data/lib/repull.rb +16 -1
  33. data/openapi/v1.json +392 -24
  34. data/scripts/regen.sh +1 -1
  35. metadata +17 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 983a3a420ae0f025e199f4d46ceb6756d52d5ab458999db33fcc69d5879c15c5
4
- data.tar.gz: b42f6bbfca55482fd579adc0cfbe72023f93affc99b86b8763a1424c0c8ede35
3
+ metadata.gz: 4cc085c47e294ad0270e4e35077a6a18147378a97b326e7141f79dbe933a350c
4
+ data.tar.gz: ed380d1783d830313bf0c05e339072fa14565744462ca79cf16563b13275bbba
5
5
  SHA512:
6
- metadata.gz: c5c2578223f4ae8b8fe7a9b27f30839f807068f6d12b292024b12d2409650e62600e20e543c019bde6cf8db99fa44c652da60ec96b3c85783fe2b483cb01257c
7
- data.tar.gz: '024581228228769ad7533e8745d92ada228fd836a25d4825f76cf9c49b02b87de520d39f1b011fc3d775487426c7a0ab641c79d8290bb07b0c897c199b0f2e60'
6
+ metadata.gz: e638b18ecefbafa17394f3a8d81bdf2097130879a0ab86642e72674def37e7ca9bd393da6cef0435e665e7cb29d0ee6b7af28908f4e3210137d2eed5b51f3ae0
7
+ data.tar.gz: d9a8c373761fc4d21e89e6518fa1457080d9d04e8c257aa9a35264d501cf2895a907c7341ea88928e5a7aac58c2ec05456f08172439dc088446a41088d14bcc6
@@ -534,7 +534,7 @@ module Repull
534
534
  end
535
535
 
536
536
  # Pre-approve an inquiry (Airbnb, VRBO)
537
- # Pre-approve the inquiry on this conversation: the guest who asked about dates may now book them at the listed price, without waiting on you. To change the dates, guests or price, send a special offer instead (`POST /v1/conversations/{id}/special-offers`). Find inquiries that need an answer with `GET /v1/inquiries` (default `status=open`); each carries the `conversationId` to use here. One endpoint for every channel with pre-approvals: **Airbnb** (listings connected directly) and **VRBO**. A Booking.com or direct-booking conversation, or an Airbnb one relayed through a PMS (Hostaway, Guesty), returns `422 channel_not_supported` and nothing is sent — `GET /v1/conversations/{id}` → `capabilities.canPreApprove` says where it works. `blockInstantBooking` is Airbnb only (VRBO has no such switch: `422 invalid_params`). `message` is sent to the guest with a VRBO pre-approval (a friendly default otherwise). The inquiry is marked `pre_approved` everywhere, the same as pre-approving on the channel. Withdraw it with `DELETE /v1/conversations/{id}/pre-approval` (VRBO). A channel’s refusal is never reported as a success: an inquiry that already moved on is `409 inquiry_no_longer_open`, an expired one `409 inquiry_expired`, a conversation that already has a booking `409 conversation_already_booked`. Send `Idempotency-Key`: a repeat with the same key replays the first response instead of acting twice (a `409 idempotency_key_in_use` while the first is still running). A 5xx, a `429 airbnb_rate_limited` or a `403 connection_reauth_required` is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
537
+ # Pre-approve the inquiry on this conversation: the guest who asked about dates may now book them at the listed price, without waiting on you. To change the dates, guests or price, send a special offer instead (`POST /v1/conversations/{id}/special-offers`). Find inquiries that need an answer with `GET /v1/inquiries` (default `status=open`); each carries the `conversationId` to use here. One endpoint for every channel with pre-approvals: **Airbnb** (listings connected directly) and **VRBO**. A Booking.com or direct-booking conversation returns `422 channel_not_supported` and nothing is sent — `GET /v1/conversations/{id}` → `capabilities.canPreApprove` says where it works. **An inquiry relayed by a PMS** (Guesty, Hostaway, …) is pre-approved in that PMS. A PMS whose API cannot returns `422 pms_write_unsupported` naming it (Hostaway today); `GET /v1/connect/{provider}` → `capabilities.pms.reservations.preapprove` says so beforehand. The response then carries `pms`. `blockInstantBooking` is Airbnb only (VRBO has no such switch: `422 invalid_params`). `message` is sent to the guest with a VRBO pre-approval (a friendly default otherwise). The inquiry is marked `pre_approved` everywhere, the same as pre-approving on the channel. Withdraw it with `DELETE /v1/conversations/{id}/pre-approval` (VRBO). A channel’s refusal is never reported as a success: an inquiry that already moved on is `409 inquiry_no_longer_open`, an expired one `409 inquiry_expired`, a conversation that already has a booking `409 conversation_already_booked`. Send `Idempotency-Key`: a repeat with the same key replays the first response instead of acting twice (a `409 idempotency_key_in_use` while the first is still running). A 5xx, a `429 airbnb_rate_limited` or a `403 connection_reauth_required` is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
538
538
  # @param id [Integer] Repull conversation id (from `GET /v1/conversations` or `conversationId` on `GET /v1/inquiries`) — not the Airbnb thread id.
539
539
  # @param [Hash] opts the optional parameters
540
540
  # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged `Idempotency-Status: cached` — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → `409 idempotency_key_in_use`. - Same key with a DIFFERENT payload → `422 idempotency_key_reused`. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status >= 500, `408`, `425` and `429`, and the refusals that happen before anything is done and tell you to fix something outside the request first — `connection_reauth_required`, `listing_inactive`, and the rate/daily limits. Every other answer, including a final refusal such as `422 airbnb_rejected`, is stored and replayed.
@@ -546,7 +546,7 @@ module Repull
546
546
  end
547
547
 
548
548
  # Pre-approve an inquiry (Airbnb, VRBO)
549
- # Pre-approve the inquiry on this conversation: the guest who asked about dates may now book them at the listed price, without waiting on you. To change the dates, guests or price, send a special offer instead (`POST /v1/conversations/{id}/special-offers`). Find inquiries that need an answer with `GET /v1/inquiries` (default `status=open`); each carries the `conversationId` to use here. One endpoint for every channel with pre-approvals: **Airbnb** (listings connected directly) and **VRBO**. A Booking.com or direct-booking conversation, or an Airbnb one relayed through a PMS (Hostaway, Guesty), returns `422 channel_not_supported` and nothing is sent — `GET /v1/conversations/{id}` → `capabilities.canPreApprove` says where it works. `blockInstantBooking` is Airbnb only (VRBO has no such switch: `422 invalid_params`). `message` is sent to the guest with a VRBO pre-approval (a friendly default otherwise). The inquiry is marked `pre_approved` everywhere, the same as pre-approving on the channel. Withdraw it with `DELETE /v1/conversations/{id}/pre-approval` (VRBO). A channel’s refusal is never reported as a success: an inquiry that already moved on is `409 inquiry_no_longer_open`, an expired one `409 inquiry_expired`, a conversation that already has a booking `409 conversation_already_booked`. Send `Idempotency-Key`: a repeat with the same key replays the first response instead of acting twice (a `409 idempotency_key_in_use` while the first is still running). A 5xx, a `429 airbnb_rate_limited` or a `403 connection_reauth_required` is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
549
+ # Pre-approve the inquiry on this conversation: the guest who asked about dates may now book them at the listed price, without waiting on you. To change the dates, guests or price, send a special offer instead (`POST /v1/conversations/{id}/special-offers`). Find inquiries that need an answer with `GET /v1/inquiries` (default `status=open`); each carries the `conversationId` to use here. One endpoint for every channel with pre-approvals: **Airbnb** (listings connected directly) and **VRBO**. A Booking.com or direct-booking conversation returns `422 channel_not_supported` and nothing is sent — `GET /v1/conversations/{id}` → `capabilities.canPreApprove` says where it works. **An inquiry relayed by a PMS** (Guesty, Hostaway, …) is pre-approved in that PMS. A PMS whose API cannot returns `422 pms_write_unsupported` naming it (Hostaway today); `GET /v1/connect/{provider}` → `capabilities.pms.reservations.preapprove` says so beforehand. The response then carries `pms`. `blockInstantBooking` is Airbnb only (VRBO has no such switch: `422 invalid_params`). `message` is sent to the guest with a VRBO pre-approval (a friendly default otherwise). The inquiry is marked `pre_approved` everywhere, the same as pre-approving on the channel. Withdraw it with `DELETE /v1/conversations/{id}/pre-approval` (VRBO). A channel’s refusal is never reported as a success: an inquiry that already moved on is `409 inquiry_no_longer_open`, an expired one `409 inquiry_expired`, a conversation that already has a booking `409 conversation_already_booked`. Send `Idempotency-Key`: a repeat with the same key replays the first response instead of acting twice (a `409 idempotency_key_in_use` while the first is still running). A 5xx, a `429 airbnb_rate_limited` or a `403 connection_reauth_required` is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
550
550
  # @param id [Integer] Repull conversation id (from `GET /v1/conversations` or `conversationId` on `GET /v1/inquiries`) — not the Airbnb thread id.
551
551
  # @param [Hash] opts the optional parameters
552
552
  # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged `Idempotency-Status: cached` — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → `409 idempotency_key_in_use`. - Same key with a DIFFERENT payload → `422 idempotency_key_reused`. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status >= 500, `408`, `425` and `429`, and the refusals that happen before anything is done and tell you to fix something outside the request first — `connection_reauth_required`, `listing_inactive`, and the rate/daily limits. Every other answer, including a final refusal such as `422 airbnb_rejected`, is stored and replayed.
@@ -20,7 +20,7 @@ module Repull
20
20
  @api_client = api_client
21
21
  end
22
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.
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. **Creating the guest in a connected PMS too:** send `provider` (e.g. `guesty`). The guest is created in the PMS first and its id there comes back as `pms.externalId`; a PMS whose API cannot create guest profiles returns `422 pms_write_unsupported` naming it (Hostaway today) and nothing is created. `GET /v1/connect/{provider}` → `capabilities.pms.guests.create` says so beforehand. Send `Idempotency-Key` to make a retry safe.
24
24
  # @param guest_create_request [GuestCreateRequest]
25
25
  # @param [Hash] opts the optional parameters
26
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 `Idempotency-Status: cached` — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → `409 idempotency_key_in_use`. - Same key with a DIFFERENT payload → `422 idempotency_key_reused`. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status >= 500, `408`, `425` and `429`, and the refusals that happen before anything is done and tell you to fix something outside the request first — `connection_reauth_required`, `listing_inactive`, and the rate/daily limits. Every other answer, including a final refusal such as `422 airbnb_rejected`, is stored and replayed.
@@ -31,7 +31,7 @@ module Repull
31
31
  end
32
32
 
33
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 `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.
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 `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. **Creating the guest in a connected PMS too:** send `provider` (e.g. `guesty`). The guest is created in the PMS first and its id there comes back as `pms.externalId`; a PMS whose API cannot create guest profiles returns `422 pms_write_unsupported` naming it (Hostaway today) and nothing is created. `GET /v1/connect/{provider}` → `capabilities.pms.guests.create` says so beforehand. Send `Idempotency-Key` to make a retry safe.
35
35
  # @param guest_create_request [GuestCreateRequest]
36
36
  # @param [Hash] opts the optional parameters
37
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 `Idempotency-Status: cached` — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → `409 idempotency_key_in_use`. - Same key with a DIFFERENT payload → `422 idempotency_key_reused`. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status >= 500, `408`, `425` and `429`, and the refusals that happen before anything is done and tell you to fix something outside the request first — `connection_reauth_required`, `listing_inactive`, and the rate/daily limits. Every other answer, including a final refusal such as `422 airbnb_rejected`, is stored and replayed.
@@ -253,5 +253,86 @@ module Repull
253
253
  end
254
254
  return data, status_code, headers
255
255
  end
256
+
257
+ # Update a guest
258
+ # Change a guest's name, email, phone or language. Email and phone are added as the guest's newest contact; earlier ones are kept. **Guests linked to a connected PMS** (created with `provider`, or imported from one) are changed in that PMS first. A PMS whose API cannot change guest profiles returns `422 pms_write_unsupported` naming it (Hostaway today) and nothing is written; `GET /v1/connect/{provider}` → `capabilities.pms.guests.update` says so beforehand. A revoked PMS connection is `403 connection_reauth_required`. Send `Idempotency-Key` to make a retry safe.
259
+ # @param id [Integer]
260
+ # @param guest_update_request [GuestUpdateRequest]
261
+ # @param [Hash] opts the optional parameters
262
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged `Idempotency-Status: cached` — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → `409 idempotency_key_in_use`. - Same key with a DIFFERENT payload → `422 idempotency_key_reused`. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status >= 500, `408`, `425` and `429`, and the refusals that happen before anything is done and tell you to fix something outside the request first — `connection_reauth_required`, `listing_inactive`, and the rate/daily limits. Every other answer, including a final refusal such as `422 airbnb_rejected`, is stored and replayed.
263
+ # @return [GuestUpdateResponse]
264
+ def update_guest(id, guest_update_request, opts = {})
265
+ data, _status_code, _headers = update_guest_with_http_info(id, guest_update_request, opts)
266
+ data
267
+ end
268
+
269
+ # Update a guest
270
+ # Change a guest's name, email, phone or language. Email and phone are added as the guest's newest contact; earlier ones are kept. **Guests linked to a connected PMS** (created with `provider`, or imported from one) are changed in that PMS first. A PMS whose API cannot change guest profiles returns `422 pms_write_unsupported` naming it (Hostaway today) and nothing is written; `GET /v1/connect/{provider}` → `capabilities.pms.guests.update` says so beforehand. A revoked PMS connection is `403 connection_reauth_required`. Send `Idempotency-Key` to make a retry safe.
271
+ # @param id [Integer]
272
+ # @param guest_update_request [GuestUpdateRequest]
273
+ # @param [Hash] opts the optional parameters
274
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged `Idempotency-Status: cached` — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → `409 idempotency_key_in_use`. - Same key with a DIFFERENT payload → `422 idempotency_key_reused`. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status >= 500, `408`, `425` and `429`, and the refusals that happen before anything is done and tell you to fix something outside the request first — `connection_reauth_required`, `listing_inactive`, and the rate/daily limits. Every other answer, including a final refusal such as `422 airbnb_rejected`, is stored and replayed.
275
+ # @return [Array<(GuestUpdateResponse, Integer, Hash)>] GuestUpdateResponse data, response status code and response headers
276
+ def update_guest_with_http_info(id, guest_update_request, opts = {})
277
+ if @api_client.config.debugging
278
+ @api_client.config.logger.debug 'Calling API: GuestsApi.update_guest ...'
279
+ end
280
+ # verify the required parameter 'id' is set
281
+ if @api_client.config.client_side_validation && id.nil?
282
+ fail ArgumentError, "Missing the required parameter 'id' when calling GuestsApi.update_guest"
283
+ end
284
+ # verify the required parameter 'guest_update_request' is set
285
+ if @api_client.config.client_side_validation && guest_update_request.nil?
286
+ fail ArgumentError, "Missing the required parameter 'guest_update_request' when calling GuestsApi.update_guest"
287
+ end
288
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
289
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling GuestsApi.update_guest, the character length must be smaller than or equal to 255.'
290
+ end
291
+
292
+ # resource path
293
+ local_var_path = '/v1/guests/{id}'.sub('{id}', CGI.escape(id.to_s))
294
+
295
+ # query parameters
296
+ query_params = opts[:query_params] || {}
297
+
298
+ # header parameters
299
+ header_params = opts[:header_params] || {}
300
+ # HTTP header 'Accept' (if needed)
301
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
302
+ # HTTP header 'Content-Type'
303
+ content_type = @api_client.select_header_content_type(['application/json'])
304
+ if !content_type.nil?
305
+ header_params['Content-Type'] = content_type
306
+ end
307
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
308
+
309
+ # form parameters
310
+ form_params = opts[:form_params] || {}
311
+
312
+ # http body (model)
313
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(guest_update_request)
314
+
315
+ # return_type
316
+ return_type = opts[:debug_return_type] || 'GuestUpdateResponse'
317
+
318
+ # auth_names
319
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
320
+
321
+ new_options = opts.merge(
322
+ :operation => :"GuestsApi.update_guest",
323
+ :header_params => header_params,
324
+ :query_params => query_params,
325
+ :form_params => form_params,
326
+ :body => post_body,
327
+ :auth_names => auth_names,
328
+ :return_type => return_type
329
+ )
330
+
331
+ data, status_code, headers = @api_client.call_api(:PATCH, local_var_path, new_options)
332
+ if @api_client.config.debugging
333
+ @api_client.config.logger.debug "API called: GuestsApi#update_guest\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
334
+ end
335
+ return data, status_code, headers
336
+ end
256
337
  end
257
338
  end
@@ -1450,7 +1450,7 @@ module Repull
1450
1450
  end
1451
1451
 
1452
1452
  # Update canonical listing content
1453
- # Write your PMS's canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \"the PMS owns listing content, Repull distributes it\" enabler. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. `amenities` is a FULL replacement of the amenity set (omit to leave untouched, send `[]` to clear). **Multilingual:** send `locale` to say which language this copy is in (`it`, `pt-BR`, …). Canonical content is stored per locale, so each language keeps its own row instead of overwriting the English one. Omit it for English. **Local write only — NOT a channel publish.** This mutates Repull's own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided `photos` array is echoed back in the `deferred` field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1453
+ # Write your PMS's canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \"the PMS owns listing content, Repull distributes it\" enabler. **Listings managed in a connected PMS** (Guesty, Hostaway, …): the PMS owns their content, so title, descriptions, check-in/out times, capacity, amenities, house rules, address and added photos are written to the PMS first; Repull keeps only what it accepted (refused sections are in `deferred`, its per-section outcome in `pms`). A section that PMS cannot write returns `422 pms_write_unsupported` naming it when nothing was applied (or is listed in `deferred` when other sections were); `GET /v1/listings/{id}` → `capabilities.pms.listings` says which sections it takes. A PMS whose connector writes no listing content at all (Mews, Cloudbeds, Lodgify, …) keeps today's behaviour: the content is written to Repull only. Send photos with `photosMode: \"append\"` — replacing a PMS listing's photo set needs the PMS's own photo ids. A revoked PMS connection is `403 connection_reauth_required`. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. `amenities` is a FULL replacement of the amenity set (omit to leave untouched, send `[]` to clear). **Multilingual:** send `locale` to say which language this copy is in (`it`, `pt-BR`, …). Canonical content is stored per locale, so each language keeps its own row instead of overwriting the English one. Omit it for English. **Local write only — NOT a channel publish.** This mutates Repull's own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided `photos` array is echoed back in the `deferred` field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1454
1454
  # @param id [Integer] Repull listing id
1455
1455
  # @param listing_content_update_request [ListingContentUpdateRequest]
1456
1456
  # @param [Hash] opts the optional parameters
@@ -1462,7 +1462,7 @@ module Repull
1462
1462
  end
1463
1463
 
1464
1464
  # Update canonical listing content
1465
- # Write your PMS&#39;s canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \&quot;the PMS owns listing content, Repull distributes it\&quot; enabler. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. &#x60;amenities&#x60; is a FULL replacement of the amenity set (omit to leave untouched, send &#x60;[]&#x60; to clear). **Multilingual:** send &#x60;locale&#x60; to say which language this copy is in (&#x60;it&#x60;, &#x60;pt-BR&#x60;, …). Canonical content is stored per locale, so each language keeps its own row instead of overwriting the English one. Omit it for English. **Local write only — NOT a channel publish.** This mutates Repull&#39;s own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided &#x60;photos&#x60; array is echoed back in the &#x60;deferred&#x60; field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1465
+ # Write your PMS&#39;s canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \&quot;the PMS owns listing content, Repull distributes it\&quot; enabler. **Listings managed in a connected PMS** (Guesty, Hostaway, …): the PMS owns their content, so title, descriptions, check-in/out times, capacity, amenities, house rules, address and added photos are written to the PMS first; Repull keeps only what it accepted (refused sections are in &#x60;deferred&#x60;, its per-section outcome in &#x60;pms&#x60;). A section that PMS cannot write returns &#x60;422 pms_write_unsupported&#x60; naming it when nothing was applied (or is listed in &#x60;deferred&#x60; when other sections were); &#x60;GET /v1/listings/{id}&#x60; → &#x60;capabilities.pms.listings&#x60; says which sections it takes. A PMS whose connector writes no listing content at all (Mews, Cloudbeds, Lodgify, …) keeps today&#39;s behaviour: the content is written to Repull only. Send photos with &#x60;photosMode: \&quot;append\&quot;&#x60; — replacing a PMS listing&#39;s photo set needs the PMS&#39;s own photo ids. A revoked PMS connection is &#x60;403 connection_reauth_required&#x60;. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. &#x60;amenities&#x60; is a FULL replacement of the amenity set (omit to leave untouched, send &#x60;[]&#x60; to clear). **Multilingual:** send &#x60;locale&#x60; to say which language this copy is in (&#x60;it&#x60;, &#x60;pt-BR&#x60;, …). Canonical content is stored per locale, so each language keeps its own row instead of overwriting the English one. Omit it for English. **Local write only — NOT a channel publish.** This mutates Repull&#39;s own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided &#x60;photos&#x60; array is echoed back in the &#x60;deferred&#x60; field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1466
1466
  # @param id [Integer] Repull listing id
1467
1467
  # @param listing_content_update_request [ListingContentUpdateRequest]
1468
1468
  # @param [Hash] opts the optional parameters
@@ -20,7 +20,7 @@ module Repull
20
20
  @api_client = api_client
21
21
  end
22
22
  # Accept a booking request
23
- # Accept a pending Airbnb booking request — a reservation with status `pending`, made on a listing without Instant Book. Find them with `GET /v1/reservations?status=pending`. Airbnb expires a request the host has not answered within 24 hours. Airbnb confirms asynchronously: the reservation’s status moves to confirmed, and a `reservation.updated` webhook fires, when Airbnb’s notification lands (usually within seconds). The response reports what Airbnb was asked to do. **Airbnb only**, and only for listings connected to Airbnb directly: other channels have no request step (`422 channel_not_supported`). A reservation that is not pending is refused before Airbnb is contacted (`409 reservation_not_pending`); one Airbnb says already moved on is `409 request_no_longer_pending`. Neither is worth retrying. Takes no body. Send `Idempotency-Key`: a repeat with the same key replays the first response instead of acting twice (a `409 idempotency_key_in_use` while the first is still running). A 5xx, a `429 airbnb_rate_limited` or a `403 connection_reauth_required` is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
23
+ # Accept a pending Airbnb booking request — a reservation with status `pending`, made on a listing without Instant Book. Find them with `GET /v1/reservations?status=pending`. Airbnb expires a request the host has not answered within 24 hours. Airbnb confirms asynchronously: the reservation’s status moves to confirmed, and a `reservation.updated` webhook fires, when Airbnb’s notification lands (usually within seconds). The response reports what Airbnb was asked to do. **Airbnb**, for listings connected to Airbnb directly; other channels have no request step (`422 channel_not_supported`). **A request relayed by a PMS** (Guesty, Hostaway, …) is answered in that PMS, whatever channel it came from; a PMS whose API cannot answer requests returns `422 pms_write_unsupported` naming it (Hostaway today), and `GET /v1/connect/{provider}` → `capabilities.pms.reservations.respond` says so beforehand. The response then carries `pms`. A reservation that is not pending is refused before Airbnb is contacted (`409 reservation_not_pending`); one Airbnb says already moved on is `409 request_no_longer_pending`. Neither is worth retrying. Takes no body. Send `Idempotency-Key`: a repeat with the same key replays the first response instead of acting twice (a `409 idempotency_key_in_use` while the first is still running). A 5xx, a `429 airbnb_rate_limited` or a `403 connection_reauth_required` is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
24
24
  # @param id [Integer] Repull reservation id (from &#x60;GET /v1/reservations?status&#x3D;pending&#x60;) — not the Airbnb confirmation code.
25
25
  # @param [Hash] opts the optional parameters
26
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. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
@@ -31,7 +31,7 @@ module Repull
31
31
  end
32
32
 
33
33
  # Accept a booking request
34
- # Accept a pending Airbnb booking request — a reservation with status &#x60;pending&#x60;, made on a listing without Instant Book. Find them with &#x60;GET /v1/reservations?status&#x3D;pending&#x60;. Airbnb expires a request the host has not answered within 24 hours. Airbnb confirms asynchronously: the reservation’s status moves to confirmed, and a &#x60;reservation.updated&#x60; webhook fires, when Airbnb’s notification lands (usually within seconds). The response reports what Airbnb was asked to do. **Airbnb only**, and only for listings connected to Airbnb directly: other channels have no request step (&#x60;422 channel_not_supported&#x60;). A reservation that is not pending is refused before Airbnb is contacted (&#x60;409 reservation_not_pending&#x60;); one Airbnb says already moved on is &#x60;409 request_no_longer_pending&#x60;. Neither is worth retrying. Takes no body. Send &#x60;Idempotency-Key&#x60;: a repeat with the same key replays the first response instead of acting twice (a &#x60;409 idempotency_key_in_use&#x60; while the first is still running). A 5xx, a &#x60;429 airbnb_rate_limited&#x60; or a &#x60;403 connection_reauth_required&#x60; is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
34
+ # Accept a pending Airbnb booking request — a reservation with status &#x60;pending&#x60;, made on a listing without Instant Book. Find them with &#x60;GET /v1/reservations?status&#x3D;pending&#x60;. Airbnb expires a request the host has not answered within 24 hours. Airbnb confirms asynchronously: the reservation’s status moves to confirmed, and a &#x60;reservation.updated&#x60; webhook fires, when Airbnb’s notification lands (usually within seconds). The response reports what Airbnb was asked to do. **Airbnb**, for listings connected to Airbnb directly; other channels have no request step (&#x60;422 channel_not_supported&#x60;). **A request relayed by a PMS** (Guesty, Hostaway, …) is answered in that PMS, whatever channel it came from; a PMS whose API cannot answer requests returns &#x60;422 pms_write_unsupported&#x60; naming it (Hostaway today), and &#x60;GET /v1/connect/{provider}&#x60; → &#x60;capabilities.pms.reservations.respond&#x60; says so beforehand. The response then carries &#x60;pms&#x60;. A reservation that is not pending is refused before Airbnb is contacted (&#x60;409 reservation_not_pending&#x60;); one Airbnb says already moved on is &#x60;409 request_no_longer_pending&#x60;. Neither is worth retrying. Takes no body. Send &#x60;Idempotency-Key&#x60;: a repeat with the same key replays the first response instead of acting twice (a &#x60;409 idempotency_key_in_use&#x60; while the first is still running). A 5xx, a &#x60;429 airbnb_rate_limited&#x60; or a &#x60;403 connection_reauth_required&#x60; is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
35
35
  # @param id [Integer] Repull reservation id (from &#x60;GET /v1/reservations?status&#x3D;pending&#x60;) — not the Airbnb confirmation code.
36
36
  # @param [Hash] opts the optional parameters
37
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. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
@@ -220,7 +220,7 @@ module Repull
220
220
  end
221
221
 
222
222
  # Reply to a review on any channel
223
- # Resolves the review, reads its channel and dispatches the reply. Channel-neutral: you do not need to know where the review came from. Replies work on Airbnb, Booking.com and VRBO. Each channel accepts one reply per review (VRBO: a second is `409 already_replied`; a review VRBO no longer takes a response to is `409 reply_not_allowed`). On VRBO the response is signed with a name — the connected account's host name, or `name` if you send it. A review from a channel without a reply API returns `422 unsupported_channel` naming the channels that do work. To review a guest (Airbnb only), use `POST /v1/reviews/{id}/guest-review`. **Inactive listings:** a review of an inactive listing returns `403 listing_inactive` and no reply reaches the channel. Activate the listing first.
223
+ # Resolves the review, reads its channel and dispatches the reply. Channel-neutral: you do not need to know where the review came from. Replies work on Airbnb, Booking.com and VRBO. Each channel accepts one reply per review (VRBO: a second is `409 already_replied`; a review VRBO no longer takes a response to is `409 reply_not_allowed`). On VRBO the response is signed with a name — the connected account's host name, or `name` if you send it. A review from a channel without a reply API returns `422 unsupported_channel` naming the channels that do work. **Reviews read from a PMS** (`pms` set on the review — Guesty, Hostaway, …) are answered through that PMS. A PMS whose API has no reply returns `422 pms_write_unsupported` naming it (Hostaway today); `GET /v1/connect/{provider}` → `capabilities.pms.reviews.reply` says so beforehand. A revoked PMS connection is `403 connection_reauth_required`. To review a guest (Airbnb only), use `POST /v1/reviews/{id}/guest-review`. **Inactive listings:** a review of an inactive listing returns `403 listing_inactive` and no reply reaches the channel. Activate the listing first.
224
224
  # @param id [Integer] Internal Repull review id.
225
225
  # @param reply_to_review_request [ReplyToReviewRequest]
226
226
  # @param [Hash] opts the optional parameters
@@ -231,7 +231,7 @@ module Repull
231
231
  end
232
232
 
233
233
  # Reply to a review on any channel
234
- # Resolves the review, reads its channel and dispatches the reply. Channel-neutral: you do not need to know where the review came from. Replies work on Airbnb, Booking.com and VRBO. Each channel accepts one reply per review (VRBO: a second is &#x60;409 already_replied&#x60;; a review VRBO no longer takes a response to is &#x60;409 reply_not_allowed&#x60;). On VRBO the response is signed with a name — the connected account&#39;s host name, or &#x60;name&#x60; if you send it. A review from a channel without a reply API returns &#x60;422 unsupported_channel&#x60; naming the channels that do work. To review a guest (Airbnb only), use &#x60;POST /v1/reviews/{id}/guest-review&#x60;. **Inactive listings:** a review of an inactive listing returns &#x60;403 listing_inactive&#x60; and no reply reaches the channel. Activate the listing first.
234
+ # Resolves the review, reads its channel and dispatches the reply. Channel-neutral: you do not need to know where the review came from. Replies work on Airbnb, Booking.com and VRBO. Each channel accepts one reply per review (VRBO: a second is &#x60;409 already_replied&#x60;; a review VRBO no longer takes a response to is &#x60;409 reply_not_allowed&#x60;). On VRBO the response is signed with a name — the connected account&#39;s host name, or &#x60;name&#x60; if you send it. A review from a channel without a reply API returns &#x60;422 unsupported_channel&#x60; naming the channels that do work. **Reviews read from a PMS** (&#x60;pms&#x60; set on the review — Guesty, Hostaway, …) are answered through that PMS. A PMS whose API has no reply returns &#x60;422 pms_write_unsupported&#x60; naming it (Hostaway today); &#x60;GET /v1/connect/{provider}&#x60; → &#x60;capabilities.pms.reviews.reply&#x60; says so beforehand. A revoked PMS connection is &#x60;403 connection_reauth_required&#x60;. To review a guest (Airbnb only), use &#x60;POST /v1/reviews/{id}/guest-review&#x60;. **Inactive listings:** a review of an inactive listing returns &#x60;403 listing_inactive&#x60; and no reply reaches the channel. Activate the listing first.
235
235
  # @param id [Integer] Internal Repull review id.
236
236
  # @param reply_to_review_request [ReplyToReviewRequest]
237
237
  # @param [Hash] opts the optional parameters
@@ -14,14 +14,17 @@ require 'date'
14
14
  require 'time'
15
15
 
16
16
  module Repull
17
- # PMS providers only. `reservations`: which reservation writes the API performs on this connection's listings — the connector's support combined with `writePolicy`. When `connected` is false, what the connector supports once connected.
17
+ # PMS providers only. `reservations`: which reservation writes the API performs on this connection's listings — the connector's support combined with `writePolicy`. `pms`: everything else the API does through this PMS (review replies, request answers, listing content, guests, message channel/attachments, calendar). When `connected` is false, what the connector supports once connected.
18
18
  class ConnectStatusCapabilities < ApiModelBase
19
19
  attr_accessor :reservations
20
20
 
21
+ attr_accessor :pms
22
+
21
23
  # Attribute mapping from ruby-style variable name to JSON key.
22
24
  def self.attribute_map
23
25
  {
24
- :'reservations' => :'reservations'
26
+ :'reservations' => :'reservations',
27
+ :'pms' => :'pms'
25
28
  }
26
29
  end
27
30
 
@@ -38,7 +41,8 @@ module Repull
38
41
  # Attribute type mapping.
39
42
  def self.openapi_types
40
43
  {
41
- :'reservations' => :'ReservationCapabilities'
44
+ :'reservations' => :'ReservationCapabilities',
45
+ :'pms' => :'PmsCapabilities'
42
46
  }
43
47
  end
44
48
 
@@ -67,6 +71,10 @@ module Repull
67
71
  if attributes.key?(:'reservations')
68
72
  self.reservations = attributes[:'reservations']
69
73
  end
74
+
75
+ if attributes.key?(:'pms')
76
+ self.pms = attributes[:'pms']
77
+ end
70
78
  end
71
79
 
72
80
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -89,7 +97,8 @@ module Repull
89
97
  def ==(o)
90
98
  return true if self.equal?(o)
91
99
  self.class == o.class &&
92
- reservations == o.reservations
100
+ reservations == o.reservations &&
101
+ pms == o.pms
93
102
  end
94
103
 
95
104
  # @see the `==` method
@@ -101,7 +110,7 @@ module Repull
101
110
  # Calculates hash code according to all attributes.
102
111
  # @return [Integer] Hash code
103
112
  def hash
104
- [reservations].hash
113
+ [reservations, pms].hash
105
114
  end
106
115
 
107
116
  # Builds the object from hash
@@ -31,6 +31,9 @@ module Repull
31
31
 
32
32
  attr_accessor :is_business_traveler
33
33
 
34
+ # A connected PMS to create the guest in as well. The guest is created there FIRST; a PMS that cannot create guest profiles returns `422 pms_write_unsupported` and nothing is created. The PMS's guest id comes back as `pms.externalId`, and later `PATCH /v1/guests/{id}` changes reach it.
35
+ attr_accessor :provider
36
+
34
37
  # Attribute mapping from ruby-style variable name to JSON key.
35
38
  def self.attribute_map
36
39
  {
@@ -40,7 +43,8 @@ module Repull
40
43
  :'phone' => :'phone',
41
44
  :'language' => :'language',
42
45
  :'currency' => :'currency',
43
- :'is_business_traveler' => :'isBusinessTraveler'
46
+ :'is_business_traveler' => :'isBusinessTraveler',
47
+ :'provider' => :'provider'
44
48
  }
45
49
  end
46
50
 
@@ -63,7 +67,8 @@ module Repull
63
67
  :'phone' => :'String',
64
68
  :'language' => :'String',
65
69
  :'currency' => :'String',
66
- :'is_business_traveler' => :'Boolean'
70
+ :'is_business_traveler' => :'Boolean',
71
+ :'provider' => :'String'
67
72
  }
68
73
  end
69
74
 
@@ -120,6 +125,10 @@ module Repull
120
125
  else
121
126
  self.is_business_traveler = false
122
127
  end
128
+
129
+ if attributes.key?(:'provider')
130
+ self.provider = attributes[:'provider']
131
+ end
123
132
  end
124
133
 
125
134
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -191,7 +200,8 @@ module Repull
191
200
  phone == o.phone &&
192
201
  language == o.language &&
193
202
  currency == o.currency &&
194
- is_business_traveler == o.is_business_traveler
203
+ is_business_traveler == o.is_business_traveler &&
204
+ provider == o.provider
195
205
  end
196
206
 
197
207
  # @see the `==` method
@@ -203,7 +213,7 @@ module Repull
203
213
  # Calculates hash code according to all attributes.
204
214
  # @return [Integer] Hash code
205
215
  def hash
206
- [first_name, last_name, email, phone, language, currency, is_business_traveler].hash
216
+ [first_name, last_name, email, phone, language, currency, is_business_traveler, provider].hash
207
217
  end
208
218
 
209
219
  # Builds the object from hash
@@ -36,6 +36,8 @@ module Repull
36
36
 
37
37
  attr_accessor :created_at
38
38
 
39
+ attr_accessor :pms
40
+
39
41
  # Attribute mapping from ruby-style variable name to JSON key.
40
42
  def self.attribute_map
41
43
  {
@@ -47,7 +49,8 @@ module Repull
47
49
  :'currency' => :'currency',
48
50
  :'is_business_traveler' => :'isBusinessTraveler',
49
51
  :'contacts' => :'contacts',
50
- :'created_at' => :'createdAt'
52
+ :'created_at' => :'createdAt',
53
+ :'pms' => :'pms'
51
54
  }
52
55
  end
53
56
 
@@ -71,8 +74,9 @@ module Repull
71
74
  :'language' => :'String',
72
75
  :'currency' => :'String',
73
76
  :'is_business_traveler' => :'Boolean',
74
- :'contacts' => :'Array<GuestCreateResponseContactsInner>',
75
- :'created_at' => :'Time'
77
+ :'contacts' => :'Array<GuestUpdateResponseContactsInner>',
78
+ :'created_at' => :'Time',
79
+ :'pms' => :'GuestCreateResponsePms'
76
80
  }
77
81
  end
78
82
 
@@ -82,6 +86,7 @@ module Repull
82
86
  :'last_name',
83
87
  :'language',
84
88
  :'currency',
89
+ :'pms'
85
90
  ])
86
91
  end
87
92
 
@@ -138,6 +143,10 @@ module Repull
138
143
  if attributes.key?(:'created_at')
139
144
  self.created_at = attributes[:'created_at']
140
145
  end
146
+
147
+ if attributes.key?(:'pms')
148
+ self.pms = attributes[:'pms']
149
+ end
141
150
  end
142
151
 
143
152
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -168,7 +177,8 @@ module Repull
168
177
  currency == o.currency &&
169
178
  is_business_traveler == o.is_business_traveler &&
170
179
  contacts == o.contacts &&
171
- created_at == o.created_at
180
+ created_at == o.created_at &&
181
+ pms == o.pms
172
182
  end
173
183
 
174
184
  # @see the `==` method
@@ -180,7 +190,7 @@ module Repull
180
190
  # Calculates hash code according to all attributes.
181
191
  # @return [Integer] Hash code
182
192
  def hash
183
- [id, created, first_name, last_name, language, currency, is_business_traveler, contacts, created_at].hash
193
+ [id, created, first_name, last_name, language, currency, is_business_traveler, contacts, created_at, pms].hash
184
194
  end
185
195
 
186
196
  # Builds the object from hash
@@ -0,0 +1,158 @@
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 'date'
14
+ require 'time'
15
+
16
+ module Repull
17
+ # Set when `provider` was sent: the PMS the guest was also created in, and its id there.
18
+ class GuestCreateResponsePms < ApiModelBase
19
+ attr_accessor :provider
20
+
21
+ attr_accessor :external_id
22
+
23
+ # Attribute mapping from ruby-style variable name to JSON key.
24
+ def self.attribute_map
25
+ {
26
+ :'provider' => :'provider',
27
+ :'external_id' => :'externalId'
28
+ }
29
+ end
30
+
31
+ # Returns attribute mapping this model knows about
32
+ def self.acceptable_attribute_map
33
+ attribute_map
34
+ end
35
+
36
+ # Returns all the JSON keys this model knows about
37
+ def self.acceptable_attributes
38
+ acceptable_attribute_map.values
39
+ end
40
+
41
+ # Attribute type mapping.
42
+ def self.openapi_types
43
+ {
44
+ :'provider' => :'String',
45
+ :'external_id' => :'String'
46
+ }
47
+ end
48
+
49
+ # List of attributes with nullable: true
50
+ def self.openapi_nullable
51
+ Set.new([
52
+ :'external_id'
53
+ ])
54
+ end
55
+
56
+ # Initializes the object
57
+ # @param [Hash] attributes Model attributes in the form of hash
58
+ def initialize(attributes = {})
59
+ if (!attributes.is_a?(Hash))
60
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Repull::GuestCreateResponsePms` initialize method"
61
+ end
62
+
63
+ # check to see if the attribute exists and convert string to symbol for hash key
64
+ acceptable_attribute_map = self.class.acceptable_attribute_map
65
+ attributes = attributes.each_with_object({}) { |(k, v), h|
66
+ if (!acceptable_attribute_map.key?(k.to_sym))
67
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Repull::GuestCreateResponsePms`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
68
+ end
69
+ h[k.to_sym] = v
70
+ }
71
+
72
+ if attributes.key?(:'provider')
73
+ self.provider = attributes[:'provider']
74
+ end
75
+
76
+ if attributes.key?(:'external_id')
77
+ self.external_id = attributes[:'external_id']
78
+ end
79
+ end
80
+
81
+ # Show invalid properties with the reasons. Usually used together with valid?
82
+ # @return Array for valid properties with the reasons
83
+ def list_invalid_properties
84
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
85
+ invalid_properties = Array.new
86
+ invalid_properties
87
+ end
88
+
89
+ # Check to see if the all the properties in the model are valid
90
+ # @return true if the model is valid
91
+ def valid?
92
+ warn '[DEPRECATED] the `valid?` method is obsolete'
93
+ true
94
+ end
95
+
96
+ # Checks equality by comparing each attribute.
97
+ # @param [Object] Object to be compared
98
+ def ==(o)
99
+ return true if self.equal?(o)
100
+ self.class == o.class &&
101
+ provider == o.provider &&
102
+ external_id == o.external_id
103
+ end
104
+
105
+ # @see the `==` method
106
+ # @param [Object] Object to be compared
107
+ def eql?(o)
108
+ self == o
109
+ end
110
+
111
+ # Calculates hash code according to all attributes.
112
+ # @return [Integer] Hash code
113
+ def hash
114
+ [provider, external_id].hash
115
+ end
116
+
117
+ # Builds the object from hash
118
+ # @param [Hash] attributes Model attributes in the form of hash
119
+ # @return [Object] Returns the model itself
120
+ def self.build_from_hash(attributes)
121
+ return nil unless attributes.is_a?(Hash)
122
+ attributes = attributes.transform_keys(&:to_sym)
123
+ transformed_hash = {}
124
+ openapi_types.each_pair do |key, type|
125
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
126
+ transformed_hash["#{key}"] = nil
127
+ elsif type =~ /\AArray<(.*)>/i
128
+ # check to ensure the input is an array given that the attribute
129
+ # is documented as an array but the input is not
130
+ if attributes[attribute_map[key]].is_a?(Array)
131
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
132
+ end
133
+ elsif !attributes[attribute_map[key]].nil?
134
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
135
+ end
136
+ end
137
+ new(transformed_hash)
138
+ end
139
+
140
+ # Returns the object in the form of hash
141
+ # @return [Hash] Returns the object in the form of hash
142
+ def to_hash
143
+ hash = {}
144
+ self.class.attribute_map.each_pair do |attr, param|
145
+ value = self.send(attr)
146
+ if value.nil?
147
+ is_nullable = self.class.openapi_nullable.include?(attr)
148
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
149
+ end
150
+
151
+ hash[param] = _to_hash(value)
152
+ end
153
+ hash
154
+ end
155
+
156
+ end
157
+
158
+ end