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.
- checksums.yaml +4 -4
- data/lib/repull/api/conversations_api.rb +2 -2
- data/lib/repull/api/guests_api.rb +83 -2
- data/lib/repull/api/listings_api.rb +2 -2
- data/lib/repull/api/reservations_api.rb +2 -2
- data/lib/repull/api/reviews_api.rb +2 -2
- data/lib/repull/models/connect_status_capabilities.rb +14 -5
- data/lib/repull/models/guest_create_request.rb +14 -4
- data/lib/repull/models/guest_create_response.rb +15 -5
- data/lib/repull/models/guest_create_response_pms.rb +158 -0
- data/lib/repull/models/guest_update_request.rb +205 -0
- data/lib/repull/models/guest_update_response.rb +209 -0
- data/lib/repull/models/{guest_create_response_contacts_inner.rb → guest_update_response_contacts_inner.rb} +3 -3
- data/lib/repull/models/guest_update_response_pms_inner.rb +158 -0
- data/lib/repull/models/listing_capabilities.rb +14 -5
- data/lib/repull/models/listing_content_update_response.rb +15 -5
- data/lib/repull/models/listing_content_update_response_pms.rb +172 -0
- data/lib/repull/models/listing_content_update_response_pms_errors_inner.rb +199 -0
- data/lib/repull/models/pms_capabilities.rb +242 -0
- data/lib/repull/models/pms_capabilities_calendar.rb +148 -0
- data/lib/repull/models/pms_capabilities_conversations.rb +167 -0
- data/lib/repull/models/pms_capabilities_guests.rb +158 -0
- data/lib/repull/models/pms_capabilities_listings.rb +238 -0
- data/lib/repull/models/pms_capabilities_payments.rb +148 -0
- data/lib/repull/models/pms_capabilities_reservations.rb +158 -0
- data/lib/repull/models/pms_capabilities_reviews.rb +158 -0
- data/lib/repull/models/pms_capabilities_tasks.rb +156 -0
- data/lib/repull/models/reply_to_review201_response.rb +12 -1
- data/lib/repull/models/review.rb +12 -1
- data/lib/repull/models/send_message_request.rb +2 -2
- data/lib/repull/version.rb +1 -1
- data/lib/repull.rb +16 -1
- data/openapi/v1.json +392 -24
- data/scripts/regen.sh +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4cc085c47e294ad0270e4e35077a6a18147378a97b326e7141f79dbe933a350c
|
|
4
|
+
data.tar.gz: ed380d1783d830313bf0c05e339072fa14565744462ca79cf16563b13275bbba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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
|
|
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'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.
|
|
1465
|
+
# 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.
|
|
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
|
|
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 `GET /v1/reservations?status=pending`) — 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 `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
|
# Accept a booking request
|
|
34
|
-
# 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
|
|
34
|
+
# 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.
|
|
35
35
|
# @param id [Integer] Repull reservation id (from `GET /v1/reservations?status=pending`) — 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 `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.
|
|
@@ -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 `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.
|
|
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 `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.
|
|
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<
|
|
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
|