repull 0.2.14 → 0.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/repull/api/airbnb_api.rb +1265 -125
- data/lib/repull/api/availability_api.rb +2 -2
- data/lib/repull/api/connect_api.rb +4 -4
- data/lib/repull/api/listings_api.rb +97 -13
- data/lib/repull/models/airbnb_account_freshness.rb +239 -0
- data/lib/repull/models/airbnb_alteration.rb +46 -2
- data/lib/repull/models/airbnb_alteration_create_request.rb +264 -0
- data/lib/repull/models/airbnb_connection.rb +69 -2
- data/lib/repull/models/airbnb_connection_host.rb +1 -1
- data/lib/repull/models/airbnb_content_write_response.rb +275 -0
- data/lib/repull/models/airbnb_data_freshness.rb +22 -10
- data/lib/repull/models/{create_airbnb_alteration_request.rb → airbnb_description_write_request.rb} +44 -47
- data/lib/repull/models/airbnb_description_write_request_description.rb +365 -0
- data/lib/repull/models/airbnb_listing.rb +12 -1
- data/lib/repull/models/airbnb_listing_action200_response.rb +105 -0
- data/lib/repull/models/airbnb_listing_action200_response_one_of.rb +157 -0
- data/lib/repull/models/airbnb_listing_action200_response_one_of1.rb +175 -0
- data/lib/repull/models/airbnb_listing_action_request.rb +2 -2
- data/lib/repull/models/airbnb_listing_details_response.rb +284 -0
- data/lib/repull/models/airbnb_listing_details_write_request.rb +209 -0
- data/lib/repull/models/airbnb_listing_details_write_request_check_in_option.rb +214 -0
- data/lib/repull/models/airbnb_listing_details_write_request_quiet_hours_inner.rb +190 -0
- data/lib/repull/models/airbnb_listing_lifecycle_response.rb +196 -0
- data/lib/repull/models/airbnb_permits_response.rb +163 -0
- data/lib/repull/models/airbnb_permits_response_cached_inner.rb +200 -0
- data/lib/repull/models/airbnb_permits_write_request.rb +176 -0
- data/lib/repull/models/airbnb_permits_write_request_permits_inner.rb +228 -0
- data/lib/repull/models/airbnb_permits_write_request_permits_inner_answers_inner.rb +198 -0
- data/lib/repull/models/airbnb_photo_position.rb +159 -0
- data/lib/repull/models/airbnb_publish_result.rb +263 -0
- data/lib/repull/models/airbnb_reservation.rb +23 -1
- data/lib/repull/models/airbnb_reservation_list_response.rb +13 -4
- data/lib/repull/models/airbnb_review.rb +23 -1
- data/lib/repull/models/airbnb_review_list_response.rb +13 -4
- data/lib/repull/models/airbnb_safety_disclosure.rb +202 -0
- data/lib/repull/models/airbnb_safety_disclosures_response.rb +162 -0
- data/lib/repull/models/airbnb_safety_disclosures_write_request.rb +176 -0
- data/lib/repull/models/airbnb_thread.rb +23 -1
- data/lib/repull/models/airbnb_thread_list_response.rb +13 -4
- data/lib/repull/models/airbnb_transaction.rb +23 -1
- data/lib/repull/models/create_airbnb_listing_room_request.rb +315 -0
- data/lib/repull/models/delete_airbnb_listing_photo200_response.rb +14 -4
- data/lib/repull/models/delete_airbnb_listing_room200_response.rb +157 -0
- data/lib/repull/models/error_error.rb +31 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response.rb +190 -0
- data/lib/repull/models/get_airbnb_booking_settings200_response_data.rb +246 -0
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_advance_notice.rb +172 -0
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_booking_window.rb +160 -0
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_cancellation.rb +203 -0
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_cancellation_non_refundable.rb +218 -0
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_in.rb +159 -0
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_in_start.rb +104 -0
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_out.rb +172 -0
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_instant_book.rb +206 -0
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_preparation_time.rb +173 -0
- data/lib/repull/models/get_airbnb_listing_details200_response.rb +192 -0
- data/lib/repull/models/list_airbnb_listing_permits200_response.rb +190 -0
- data/lib/repull/models/list_airbnb_listing_safety_disclosures200_response.rb +190 -0
- data/lib/repull/models/listing.rb +2 -1
- data/lib/repull/models/listing_content.rb +13 -2
- data/lib/repull/models/listing_content_update_request.rb +21 -2
- data/lib/repull/models/listing_content_update_request_details.rb +206 -0
- data/lib/repull/models/listing_content_update_request_policies.rb +95 -5
- data/lib/repull/models/listing_content_update_response.rb +1 -1
- data/lib/repull/models/listing_publish_airbnb_response.rb +165 -0
- data/lib/repull/models/listing_pull_airbnb_request.rb +149 -0
- data/lib/repull/models/listing_pull_response.rb +231 -0
- data/lib/repull/models/publish_section_error.rb +232 -0
- data/lib/repull/models/reorder_airbnb_listing_photos200_response.rb +191 -0
- data/lib/repull/models/reorder_airbnb_listing_photos200_response_data.rb +172 -0
- data/lib/repull/models/reorder_airbnb_listing_photos_request.rb +185 -0
- data/lib/repull/models/reservation.rb +23 -1
- data/lib/repull/models/reservation_webhook_object.rb +38 -5
- data/lib/repull/models/set_airbnb_listing_cover_photo200_response.rb +191 -0
- data/lib/repull/models/set_airbnb_listing_cover_photo200_response_data.rb +171 -0
- data/lib/repull/models/set_airbnb_listing_cover_photo_request.rb +165 -0
- data/lib/repull/models/update_airbnb_booking_settings200_response.rb +164 -0
- data/lib/repull/models/update_airbnb_booking_settings200_response_data.rb +205 -0
- data/lib/repull/models/update_airbnb_booking_settings_request.rb +202 -0
- data/lib/repull/models/update_airbnb_booking_settings_request_advance_notice.rb +183 -0
- data/lib/repull/models/update_airbnb_booking_settings_request_booking_window.rb +183 -0
- data/lib/repull/models/update_airbnb_booking_settings_request_cancellation.rb +201 -0
- data/lib/repull/models/update_airbnb_booking_settings_request_cancellation_non_refundable.rb +183 -0
- data/lib/repull/models/update_airbnb_booking_settings_request_check_in.rb +159 -0
- data/lib/repull/models/update_airbnb_booking_settings_request_check_out.rb +182 -0
- data/lib/repull/models/update_airbnb_booking_settings_request_instant_book.rb +203 -0
- data/lib/repull/models/update_airbnb_booking_settings_request_preparation_time.rb +182 -0
- data/lib/repull/models/update_airbnb_listing_amenities200_response.rb +191 -0
- data/lib/repull/models/update_airbnb_listing_amenities200_response_data.rb +158 -0
- data/lib/repull/models/update_airbnb_listing_amenities_request.rb +199 -0
- data/lib/repull/models/update_airbnb_listing_amenities_request_accessibility_amenities_inner.rb +246 -0
- data/lib/repull/models/update_airbnb_listing_amenities_request_amenities_inner.rb +218 -0
- data/lib/repull/models/update_airbnb_listing_permits200_response.rb +168 -0
- data/lib/repull/models/update_airbnb_listing_photo200_response.rb +194 -0
- data/lib/repull/models/update_airbnb_listing_photo_request.rb +242 -0
- data/lib/repull/models/update_airbnb_listing_room200_response.rb +194 -0
- data/lib/repull/models/update_airbnb_listing_room_request.rb +293 -0
- data/lib/repull/models/update_airbnb_listing_room_request_beds_inner.rb +209 -0
- data/lib/repull/models/update_airbnb_listing_room_request_room_amenities_inner.rb +182 -0
- data/lib/repull/models/update_airbnb_listing_room_request_room_amenities_inner_value.rb +105 -0
- data/lib/repull/models/update_airbnb_listing_safety_disclosures200_response.rb +180 -0
- data/lib/repull/models/upload_airbnb_listing_photos_request.rb +184 -0
- data/lib/repull/models/upload_airbnb_listing_photos_request_photos_inner.rb +305 -0
- data/lib/repull/models/upload_airbnb_listing_photos_request_photos_inner_listing_id.rb +105 -0
- data/lib/repull/version.rb +1 -1
- data/lib/repull.rb +78 -1
- data/openapi/v1.json +4523 -1282
- data/scripts/regen.sh +1 -1
- metadata +80 -3
|
@@ -88,7 +88,7 @@ module Repull
|
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
# Get property availability
|
|
91
|
-
# Channel-agnostic day-by-day availability calendar for a property over a date window. Returns a thin per-date shape — `{ date, available, price, minNights }` — projected from the property calendar. The `from` and `to` query params are **required** (ISO `YYYY-MM-DD`, inclusive) — omitting or malforming either returns 422. The window is capped at 366 days; longer ranges are truncated to the first 366 days. **`days` contains only the dates we actually hold calendar data for.** Requested dates with no calendar row are listed in `coverage.missingDates` — their availability is unknown. Never treat a missing date as bookable: this endpoint deliberately does not synthesise availability, because a fabricated open date can be double-booked. A property with no calendar still returns a real 200 (`days: []`, every date in `coverage.missingDates`), never a 404 — 404 means the property id does not exist or belongs to a different workspace. This endpoint is read-only, and the projected per-date shape carries **availability, price, and min-nights only** — it does NOT expose max-stay, closed-to-arrival (CTA), closed-to-departure (CTD), or the dedicated stop-sell flag. To read or write that full restriction set on Booking.com use the channel routes: `GET`/`PUT /v1/channels/booking/availability` (with the room + rate ids from `GET /v1/channels/booking/properties/{id}/rooms`).
|
|
91
|
+
# Channel-agnostic day-by-day availability calendar for a property over a date window. Returns a thin per-date shape — `{ date, available, price, minNights }` — projected from the property calendar. The `from` and `to` query params are **required** (ISO `YYYY-MM-DD`, inclusive) — omitting or malforming either returns 422. The window is capped at 366 days; longer ranges are truncated to the first 366 days. **`days` contains only the dates we actually hold calendar data for.** Requested dates with no calendar row are listed in `coverage.missingDates` — their availability is unknown. Never treat a missing date as bookable: this endpoint deliberately does not synthesise availability, because a fabricated open date can be double-booked. A property with no calendar still returns a real 200 (`days: []`, every date in `coverage.missingDates`), never a 404 — 404 means the property id does not exist or belongs to a different workspace. This endpoint is read-only, and the projected per-date shape carries **availability, price, and min-nights only** — it does NOT expose max-stay, closed-to-arrival (CTA), closed-to-departure (CTD), or the dedicated stop-sell flag. To read or write that full restriction set on Booking.com use the channel routes: `GET`/`PUT /v1/channels/booking/availability` (with the room + rate ids from `GET /v1/channels/booking/properties/{id}/rooms`). To **write** calendar values use `PUT /v1/availability/{propertyId}` (or `PATCH /v1/availability/batch`), which updates the property calendar and pushes to its connected channels; channel-only settings stay on the channel routes. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
|
|
92
92
|
# @param property_id [Integer] Repull property id (equal to `listings.id`; the same integer used as `propertyId` on availability and `listingId` on reservations).
|
|
93
93
|
# @param from [Date] Start of the window (inclusive), ISO `YYYY-MM-DD`. Required — missing/malformed returns 422. `startDate` is accepted as an alias.
|
|
94
94
|
# @param to [Date] End of the window (inclusive), ISO `YYYY-MM-DD`. Required — missing/malformed returns 422. `endDate` is accepted as an alias.
|
|
@@ -100,7 +100,7 @@ module Repull
|
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
# Get property availability
|
|
103
|
-
# Channel-agnostic day-by-day availability calendar for a property over a date window. Returns a thin per-date shape — `{ date, available, price, minNights }` — projected from the property calendar. The `from` and `to` query params are **required** (ISO `YYYY-MM-DD`, inclusive) — omitting or malforming either returns 422. The window is capped at 366 days; longer ranges are truncated to the first 366 days. **`days` contains only the dates we actually hold calendar data for.** Requested dates with no calendar row are listed in `coverage.missingDates` — their availability is unknown. Never treat a missing date as bookable: this endpoint deliberately does not synthesise availability, because a fabricated open date can be double-booked. A property with no calendar still returns a real 200 (`days: []`, every date in `coverage.missingDates`), never a 404 — 404 means the property id does not exist or belongs to a different workspace. This endpoint is read-only, and the projected per-date shape carries **availability, price, and min-nights only** — it does NOT expose max-stay, closed-to-arrival (CTA), closed-to-departure (CTD), or the dedicated stop-sell flag. To read or write that full restriction set on Booking.com use the channel routes: `GET`/`PUT /v1/channels/booking/availability` (with the room + rate ids from `GET /v1/channels/booking/properties/{id}/rooms`).
|
|
103
|
+
# Channel-agnostic day-by-day availability calendar for a property over a date window. Returns a thin per-date shape — `{ date, available, price, minNights }` — projected from the property calendar. The `from` and `to` query params are **required** (ISO `YYYY-MM-DD`, inclusive) — omitting or malforming either returns 422. The window is capped at 366 days; longer ranges are truncated to the first 366 days. **`days` contains only the dates we actually hold calendar data for.** Requested dates with no calendar row are listed in `coverage.missingDates` — their availability is unknown. Never treat a missing date as bookable: this endpoint deliberately does not synthesise availability, because a fabricated open date can be double-booked. A property with no calendar still returns a real 200 (`days: []`, every date in `coverage.missingDates`), never a 404 — 404 means the property id does not exist or belongs to a different workspace. This endpoint is read-only, and the projected per-date shape carries **availability, price, and min-nights only** — it does NOT expose max-stay, closed-to-arrival (CTA), closed-to-departure (CTD), or the dedicated stop-sell flag. To read or write that full restriction set on Booking.com use the channel routes: `GET`/`PUT /v1/channels/booking/availability` (with the room + rate ids from `GET /v1/channels/booking/properties/{id}/rooms`). To **write** calendar values use `PUT /v1/availability/{propertyId}` (or `PATCH /v1/availability/batch`), which updates the property calendar and pushes to its connected channels; channel-only settings stay on the channel routes. 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.
|
|
104
104
|
# @param property_id [Integer] Repull property id (equal to `listings.id`; the same integer used as `propertyId` on availability and `listingId` on reservations).
|
|
105
105
|
# @param from [Date] Start of the window (inclusive), ISO `YYYY-MM-DD`. Required — missing/malformed returns 422. `startDate` is accepted as an alias.
|
|
106
106
|
# @param to [Date] End of the window (inclusive), ISO `YYYY-MM-DD`. Required — missing/malformed returns 422. `endDate` is accepted as an alias.
|
|
@@ -226,7 +226,7 @@ module Repull
|
|
|
226
226
|
end
|
|
227
227
|
|
|
228
228
|
# Disconnect provider
|
|
229
|
-
# Disconnect ONE connected account of a provider from this workspace. Supported for `airbnb` and `booking`. **Which account.** Pass `accountId` — for Airbnb the host id (`accounts[].externalAccountId` from `GET /v1/connect/airbnb`), for Booking.com the hotel id. It is optional only when the workspace has exactly one account for the provider. With several and no `accountId`, the call returns `422` with the account ids in `valid_values` instead of guessing. An `accountId` that is not connected to this workspace returns `404`. Disconnecting one account leaves the others connected. **What happens.** The account's stored authorization is removed and it stops syncing. Its listings are **deactivated**, not deleted: they stop counting toward your plan's listing limit, their data is kept, and they are returned in `listingsDeactivated`. A listing that is still connected through another account or channel stays active. Reconnect the account, then activate the listings with `POST /v1/listings/status`. The change is all or nothing. For Airbnb, the host can also revoke access on Airbnb's side (Account → Privacy & sharing → Connected apps); that alone does not update this workspace, so call this endpoint as well. Other providers return `501 not_implemented` with instructions for disconnecting on the provider's side.
|
|
229
|
+
# Disconnect ONE connected account of a provider from this workspace. Supported for `airbnb` and `booking`. **Which account.** Pass `accountId` — for Airbnb the host id (`accounts[].externalAccountId` from `GET /v1/connect/airbnb`), for Booking.com the hotel id. It is optional only when the workspace has exactly one account for the provider. With several and no `accountId`, the call returns `422` with the account ids in `valid_values` instead of guessing. An `accountId` that is not connected to this workspace returns `404`. Disconnecting one account leaves the others connected. **What happens.** The account's stored authorization is removed and it stops syncing. Its listings are **deactivated**, not deleted: they stop counting toward your plan's listing limit, their data is kept, and they are returned in `listingsDeactivated`. A listing that is still connected through another account or channel stays active. Reconnect the account, then activate the listings with `POST /v1/listings/status`. The change is all or nothing. For Airbnb, the host can also revoke access on Airbnb's side (Account → Privacy & sharing → Connected apps); that alone does not update this workspace, so call this endpoint as well. Other providers return `501 not_implemented` with instructions for disconnecting on the provider's side. That answer depends only on the provider, not on your workspace: an unsupported provider returns `501` whether or not you have a connection to it. `404 not_found` on a supported provider means this workspace has no connection to it (or, with `accountId`, that the account is not connected here).
|
|
230
230
|
# @param provider [String] PMS provider slug (e.g., hostaway, guesty, ownerrez)
|
|
231
231
|
# @param [Hash] opts the optional parameters
|
|
232
232
|
# @option opts [String] :account_id The account to disconnect: the Airbnb host id (`accounts[].externalAccountId` on `GET /v1/connect/airbnb`) or the Booking.com hotel id. Required when the workspace has more than one connected account for the provider. Not the same as the `X-Account-Id` header.
|
|
@@ -237,7 +237,7 @@ module Repull
|
|
|
237
237
|
end
|
|
238
238
|
|
|
239
239
|
# Disconnect provider
|
|
240
|
-
# Disconnect ONE connected account of a provider from this workspace. Supported for `airbnb` and `booking`. **Which account.** Pass `accountId` — for Airbnb the host id (`accounts[].externalAccountId` from `GET /v1/connect/airbnb`), for Booking.com the hotel id. It is optional only when the workspace has exactly one account for the provider. With several and no `accountId`, the call returns `422` with the account ids in `valid_values` instead of guessing. An `accountId` that is not connected to this workspace returns `404`. Disconnecting one account leaves the others connected. **What happens.** The account's stored authorization is removed and it stops syncing. Its listings are **deactivated**, not deleted: they stop counting toward your plan's listing limit, their data is kept, and they are returned in `listingsDeactivated`. A listing that is still connected through another account or channel stays active. Reconnect the account, then activate the listings with `POST /v1/listings/status`. The change is all or nothing. For Airbnb, the host can also revoke access on Airbnb's side (Account → Privacy & sharing → Connected apps); that alone does not update this workspace, so call this endpoint as well. Other providers return `501 not_implemented` with instructions for disconnecting on the provider's side.
|
|
240
|
+
# Disconnect ONE connected account of a provider from this workspace. Supported for `airbnb` and `booking`. **Which account.** Pass `accountId` — for Airbnb the host id (`accounts[].externalAccountId` from `GET /v1/connect/airbnb`), for Booking.com the hotel id. It is optional only when the workspace has exactly one account for the provider. With several and no `accountId`, the call returns `422` with the account ids in `valid_values` instead of guessing. An `accountId` that is not connected to this workspace returns `404`. Disconnecting one account leaves the others connected. **What happens.** The account's stored authorization is removed and it stops syncing. Its listings are **deactivated**, not deleted: they stop counting toward your plan's listing limit, their data is kept, and they are returned in `listingsDeactivated`. A listing that is still connected through another account or channel stays active. Reconnect the account, then activate the listings with `POST /v1/listings/status`. The change is all or nothing. For Airbnb, the host can also revoke access on Airbnb's side (Account → Privacy & sharing → Connected apps); that alone does not update this workspace, so call this endpoint as well. Other providers return `501 not_implemented` with instructions for disconnecting on the provider's side. That answer depends only on the provider, not on your workspace: an unsupported provider returns `501` whether or not you have a connection to it. `404 not_found` on a supported provider means this workspace has no connection to it (or, with `accountId`, that the account is not connected here).
|
|
241
241
|
# @param provider [String] PMS provider slug (e.g., hostaway, guesty, ownerrez)
|
|
242
242
|
# @param [Hash] opts the optional parameters
|
|
243
243
|
# @option opts [String] :account_id The account to disconnect: the Airbnb host id (`accounts[].externalAccountId` on `GET /v1/connect/airbnb`) or the Booking.com hotel id. Required when the workspace has more than one connected account for the provider. Not the same as the `X-Account-Id` header.
|
|
@@ -601,7 +601,7 @@ module Repull
|
|
|
601
601
|
end
|
|
602
602
|
|
|
603
603
|
# Bind a picker session to a provider
|
|
604
|
-
# Called by the hosted picker page once the user clicks a channel card. Validates the provider exists and is permitted by the session's `
|
|
604
|
+
# Called by the hosted picker page once the user clicks a channel card. Validates the provider exists and is permitted by the session's `allowedProviders` whitelist (if any), then returns the next-step URL the picker should navigate to. No API key required — the session ID is the capability token. The session must still be pending and unexpired.
|
|
605
605
|
# @param session_id [String] The picker session ID returned by `createConnectSession`.
|
|
606
606
|
# @param select_connect_provider_request [SelectConnectProviderRequest]
|
|
607
607
|
# @param [Hash] opts the optional parameters
|
|
@@ -612,7 +612,7 @@ module Repull
|
|
|
612
612
|
end
|
|
613
613
|
|
|
614
614
|
# Bind a picker session to a provider
|
|
615
|
-
# Called by the hosted picker page once the user clicks a channel card. Validates the provider exists and is permitted by the session's `
|
|
615
|
+
# Called by the hosted picker page once the user clicks a channel card. Validates the provider exists and is permitted by the session's `allowedProviders` whitelist (if any), then returns the next-step URL the picker should navigate to. No API key required — the session ID is the capability token. The session must still be pending and unexpired.
|
|
616
616
|
# @param session_id [String] The picker session ID returned by `createConnectSession`.
|
|
617
617
|
# @param select_connect_provider_request [SelectConnectProviderRequest]
|
|
618
618
|
# @param [Hash] opts the optional parameters
|
|
@@ -564,16 +564,16 @@ module Repull
|
|
|
564
564
|
end
|
|
565
565
|
|
|
566
566
|
# List listings
|
|
567
|
-
# Cursor-paginated list of listings owned by the authenticated workspace. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request to walk the full set. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. Filters: `q` (substring on name/street/city), `status`, `channel`. **Optional expansions:** Pass `?include=content` to enrich each row with the rich content slab (summary, description, space, house rules, etc. — sourced from `listings_descriptions` for the `en` locale). Pass `?include=details` for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.). Both default to `null` per row when the underlying `listings_descriptions` / `listings_details` row is missing — distinct from the field being absent (which signals the expansion was not requested). Combine comma-separated, e.g. `?include=content,
|
|
567
|
+
# Cursor-paginated list of listings owned by the authenticated workspace. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request to walk the full set. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. Filters: `q` (substring on name/street/city), `status`, `channel`. **Optional expansions:** Pass `?include=content` to enrich each row with the rich content slab (summary, description, space, house rules, etc. — sourced from `listings_descriptions` for the `en` locale). Pass `?include=details` for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.). Both default to `null` per row when the underlying `listings_descriptions` / `listings_details` row is missing — distinct from the field being absent (which signals the expansion was not requested). Pass `?include=thumbnail` to guarantee `thumbnailUrl` on every returned row — including the reduced inactive ones. Combine comma-separated, e.g. `?include=content,thumbnail`. The default response stays lean; consumers must opt in. **Inactive listings:** by default only active listings are returned. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated, so when `status` asks for inactive ones they carry only `id`, `name`, `status` and `channels` — enough to choose what to activate with `PATCH /v1/listings/{id}`. The `content` and `details` expansions are not applied to them. `?include=thumbnail` is the one exception: it adds `thumbnailUrl` to an inactive row so a single request can render an active/inactive selection screen with pictures, instead of one follow-up call per listing (which an inactive listing would answer with `403 listing_inactive` anyway).
|
|
568
568
|
# @param [Hash] opts the optional parameters
|
|
569
569
|
# @option opts [String] :x_schema Apply a custom or built-in schema to transform the response. Built-in: `native` (default), `calry`, `calry-v1`. Custom: any schema name created via `POST /v1/schema/custom`. Unknown / inactive schema names fall back to `native`.
|
|
570
570
|
# @option opts [String] :cursor Opaque cursor returned in the previous response's `pagination.nextCursor`. Omit to fetch the first page.
|
|
571
571
|
# @option opts [Integer] :offset First-class alias for cursor-based pagination. Mutually exclusive with `cursor` — passing both returns 422. Accepts integers in `[0, 10000]`; deeper walks must use `cursor` (constant per-page cost). The response always includes `pagination.nextCursor` so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying. (default to 0)
|
|
572
572
|
# @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 20)
|
|
573
573
|
# @option opts [String] :q Case-insensitive substring search on name, street, or city.
|
|
574
|
-
# @option opts [String] :status Filter by listing status. Defaults to `active`. Pass `inactive` to list the listings you can activate, `archived` for archived ones, or `all` for every status. Inactive listings are returned with identity fields only — `id`, `name`, `status` and `channels` — and never with `address`, `
|
|
574
|
+
# @option opts [String] :status Filter by listing status. Defaults to `active`. Pass `inactive` to list the listings you can activate, `archived` for archived ones, or `all` for every status. Inactive listings are returned with identity fields only — `id`, `name`, `status` and `channels` — and never with `address`, `content` or `details`; activate one to see the rest. The only field you can add to an inactive row is `thumbnailUrl`, via `?include=thumbnail`. (default to 'active')
|
|
575
575
|
# @option opts [String] :channel Restrict to listings published on the given channel (`airbnb`, `booking`, `vrbo`, etc.). Joins through `listing_platform_links` and matches active links only.
|
|
576
|
-
# @option opts [String] :include Comma-separated optional expansions. Currently supported: `content`, `details`. Unknown values return 422 with a `valid_values` envelope. (Note: `amenities` is not yet supported on the list endpoint — use the detail endpoint to fetch amenity rows for a single listing.)
|
|
576
|
+
# @option opts [String] :include Comma-separated optional expansions. Currently supported: `content`, `details`, `thumbnail`. `thumbnail` guarantees `thumbnailUrl` on every row and is the only expansion that applies to inactive listings. Unknown values return 422 with a `valid_values` envelope. (Note: `amenities` is not yet supported on the list endpoint — use the detail endpoint to fetch amenity rows for a single listing.)
|
|
577
577
|
# @return [ListingListResponse]
|
|
578
578
|
def list_listings(opts = {})
|
|
579
579
|
data, _status_code, _headers = list_listings_with_http_info(opts)
|
|
@@ -581,16 +581,16 @@ module Repull
|
|
|
581
581
|
end
|
|
582
582
|
|
|
583
583
|
# List listings
|
|
584
|
-
# Cursor-paginated list of listings owned by the authenticated workspace. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request to walk the full set. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. Filters: `q` (substring on name/street/city), `status`, `channel`. **Optional expansions:** Pass `?include=content` to enrich each row with the rich content slab (summary, description, space, house rules, etc. — sourced from `listings_descriptions` for the `en` locale). Pass `?include=details` for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.). Both default to `null` per row when the underlying `listings_descriptions` / `listings_details` row is missing — distinct from the field being absent (which signals the expansion was not requested). Combine comma-separated, e.g. `?include=content,
|
|
584
|
+
# Cursor-paginated list of listings owned by the authenticated workspace. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request to walk the full set. `?offset=` is also accepted as a first-class alias for shallow paging (0..10000) — see the `offset` parameter below. Mutually exclusive with `cursor`. Filters: `q` (substring on name/street/city), `status`, `channel`. **Optional expansions:** Pass `?include=content` to enrich each row with the rich content slab (summary, description, space, house rules, etc. — sourced from `listings_descriptions` for the `en` locale). Pass `?include=details` for the structural slab (bedrooms, bathrooms, person capacity, check-in window, wifi, house manual, etc.). Both default to `null` per row when the underlying `listings_descriptions` / `listings_details` row is missing — distinct from the field being absent (which signals the expansion was not requested). Pass `?include=thumbnail` to guarantee `thumbnailUrl` on every returned row — including the reduced inactive ones. Combine comma-separated, e.g. `?include=content,thumbnail`. The default response stays lean; consumers must opt in. **Inactive listings:** by default only active listings are returned. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated, so when `status` asks for inactive ones they carry only `id`, `name`, `status` and `channels` — enough to choose what to activate with `PATCH /v1/listings/{id}`. The `content` and `details` expansions are not applied to them. `?include=thumbnail` is the one exception: it adds `thumbnailUrl` to an inactive row so a single request can render an active/inactive selection screen with pictures, instead of one follow-up call per listing (which an inactive listing would answer with `403 listing_inactive` anyway).
|
|
585
585
|
# @param [Hash] opts the optional parameters
|
|
586
586
|
# @option opts [String] :x_schema Apply a custom or built-in schema to transform the response. Built-in: `native` (default), `calry`, `calry-v1`. Custom: any schema name created via `POST /v1/schema/custom`. Unknown / inactive schema names fall back to `native`.
|
|
587
587
|
# @option opts [String] :cursor Opaque cursor returned in the previous response's `pagination.nextCursor`. Omit to fetch the first page.
|
|
588
588
|
# @option opts [Integer] :offset First-class alias for cursor-based pagination. Mutually exclusive with `cursor` — passing both returns 422. Accepts integers in `[0, 10000]`; deeper walks must use `cursor` (constant per-page cost). The response always includes `pagination.nextCursor` so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying. (default to 0)
|
|
589
589
|
# @option opts [Integer] :limit Max items per page. Hard cap is 100. (default to 20)
|
|
590
590
|
# @option opts [String] :q Case-insensitive substring search on name, street, or city.
|
|
591
|
-
# @option opts [String] :status Filter by listing status. Defaults to `active`. Pass `inactive` to list the listings you can activate, `archived` for archived ones, or `all` for every status. Inactive listings are returned with identity fields only — `id`, `name`, `status` and `channels` — and never with `address`, `
|
|
591
|
+
# @option opts [String] :status Filter by listing status. Defaults to `active`. Pass `inactive` to list the listings you can activate, `archived` for archived ones, or `all` for every status. Inactive listings are returned with identity fields only — `id`, `name`, `status` and `channels` — and never with `address`, `content` or `details`; activate one to see the rest. The only field you can add to an inactive row is `thumbnailUrl`, via `?include=thumbnail`. (default to 'active')
|
|
592
592
|
# @option opts [String] :channel Restrict to listings published on the given channel (`airbnb`, `booking`, `vrbo`, etc.). Joins through `listing_platform_links` and matches active links only.
|
|
593
|
-
# @option opts [String] :include Comma-separated optional expansions. Currently supported: `content`, `details`. Unknown values return 422 with a `valid_values` envelope. (Note: `amenities` is not yet supported on the list endpoint — use the detail endpoint to fetch amenity rows for a single listing.)
|
|
593
|
+
# @option opts [String] :include Comma-separated optional expansions. Currently supported: `content`, `details`, `thumbnail`. `thumbnail` guarantees `thumbnailUrl` on every row and is the only expansion that applies to inactive listings. Unknown values return 422 with a `valid_values` envelope. (Note: `amenities` is not yet supported on the list endpoint — use the detail endpoint to fetch amenity rows for a single listing.)
|
|
594
594
|
# @return [Array<(ListingListResponse, Integer, Hash)>] ListingListResponse data, response status code and response headers
|
|
595
595
|
def list_listings_with_http_info(opts = {})
|
|
596
596
|
if @api_client.config.debugging
|
|
@@ -665,22 +665,24 @@ module Repull
|
|
|
665
665
|
end
|
|
666
666
|
|
|
667
667
|
# Publish a listing to Airbnb
|
|
668
|
-
# Push a Repull listing to Airbnb. Pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create a brand-new Airbnb listing under that host. 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.
|
|
668
|
+
# Push a Repull listing's canonical content to Airbnb. Pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create a brand-new Airbnb listing under that host. **A publish is not one call to Airbnb.** It is up to eight independent ones — details, description, amenities, rooms, policies, photos, pricing, checkout_tasks — and each can fail on its own. `result.published` is true only when every attempted section landed; `result.sections` lists the ones that did and `result.errors[]` carries Airbnb's own reason, per section, for the ones that did not. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Publish again once you have fixed the failing sections — a re-publish of an unchanged section is harmless. `result.lockedFields` names the fields Airbnb will not let this listing change at all. They are not retryable by anyone: Airbnb answers 200 and applies nothing. `GET /v1/channels/airbnb/listings/{id}` reports the same list up front. **Which fields this pushes** — title, description sections and house rules (English/primary locale), amenities, rooms and beds, photos, nightly price and fees, cancellation policy and guest controls, check-in/out times, quiet hours, property and room type, checkout tasks. **Not pushed by this endpoint:** non-primary locales (`PUT /v1/channels/airbnb/listings/{id}/descriptions`), guest-safety disclosures (`PUT …/safety-disclosures`), check-in method (`PUT …/details`), permits (`PUT …/permits`), and the calendar (`PUT …/availability`). `force: true` re-pushes every section, ignoring dirty-field tracking. Without it only the sections changed since the last successful publish are sent. Send `Idempotency-Key` to make a retry safe: a timeout on a publish otherwise leaves you unable to tell whether it ran. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
|
|
669
669
|
# @param id [Integer]
|
|
670
670
|
# @param [Hash] opts the optional parameters
|
|
671
|
+
# @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged `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. - Responses with status >= 500 are deliberately not stored, so a server error stays retryable.
|
|
671
672
|
# @option opts [ListingPublishAirbnbRequest] :listing_publish_airbnb_request
|
|
672
|
-
# @return [
|
|
673
|
+
# @return [ListingPublishAirbnbResponse]
|
|
673
674
|
def publish_listing_to_airbnb(id, opts = {})
|
|
674
675
|
data, _status_code, _headers = publish_listing_to_airbnb_with_http_info(id, opts)
|
|
675
676
|
data
|
|
676
677
|
end
|
|
677
678
|
|
|
678
679
|
# Publish a listing to Airbnb
|
|
679
|
-
# Push a Repull listing to Airbnb. Pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create a brand-new Airbnb listing under that host. 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.
|
|
680
|
+
# Push a Repull listing's canonical content to Airbnb. Pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create a brand-new Airbnb listing under that host. **A publish is not one call to Airbnb.** It is up to eight independent ones — details, description, amenities, rooms, policies, photos, pricing, checkout_tasks — and each can fail on its own. `result.published` is true only when every attempted section landed; `result.sections` lists the ones that did and `result.errors[]` carries Airbnb's own reason, per section, for the ones that did not. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Publish again once you have fixed the failing sections — a re-publish of an unchanged section is harmless. `result.lockedFields` names the fields Airbnb will not let this listing change at all. They are not retryable by anyone: Airbnb answers 200 and applies nothing. `GET /v1/channels/airbnb/listings/{id}` reports the same list up front. **Which fields this pushes** — title, description sections and house rules (English/primary locale), amenities, rooms and beds, photos, nightly price and fees, cancellation policy and guest controls, check-in/out times, quiet hours, property and room type, checkout tasks. **Not pushed by this endpoint:** non-primary locales (`PUT /v1/channels/airbnb/listings/{id}/descriptions`), guest-safety disclosures (`PUT …/safety-disclosures`), check-in method (`PUT …/details`), permits (`PUT …/permits`), and the calendar (`PUT …/availability`). `force: true` re-pushes every section, ignoring dirty-field tracking. Without it only the sections changed since the last successful publish are sent. Send `Idempotency-Key` to make a retry safe: a timeout on a publish otherwise leaves you unable to tell whether it ran. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
|
|
680
681
|
# @param id [Integer]
|
|
681
682
|
# @param [Hash] opts the optional parameters
|
|
683
|
+
# @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged `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. - Responses with status >= 500 are deliberately not stored, so a server error stays retryable.
|
|
682
684
|
# @option opts [ListingPublishAirbnbRequest] :listing_publish_airbnb_request
|
|
683
|
-
# @return [Array<(
|
|
685
|
+
# @return [Array<(ListingPublishAirbnbResponse, Integer, Hash)>] ListingPublishAirbnbResponse data, response status code and response headers
|
|
684
686
|
def publish_listing_to_airbnb_with_http_info(id, opts = {})
|
|
685
687
|
if @api_client.config.debugging
|
|
686
688
|
@api_client.config.logger.debug 'Calling API: ListingsApi.publish_listing_to_airbnb ...'
|
|
@@ -689,6 +691,10 @@ module Repull
|
|
|
689
691
|
if @api_client.config.client_side_validation && id.nil?
|
|
690
692
|
fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.publish_listing_to_airbnb"
|
|
691
693
|
end
|
|
694
|
+
if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
|
|
695
|
+
fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling ListingsApi.publish_listing_to_airbnb, the character length must be smaller than or equal to 255.'
|
|
696
|
+
end
|
|
697
|
+
|
|
692
698
|
# resource path
|
|
693
699
|
local_var_path = '/v1/listings/{id}/publish/airbnb'.sub('{id}', CGI.escape(id.to_s))
|
|
694
700
|
|
|
@@ -704,6 +710,7 @@ module Repull
|
|
|
704
710
|
if !content_type.nil?
|
|
705
711
|
header_params['Content-Type'] = content_type
|
|
706
712
|
end
|
|
713
|
+
header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
|
|
707
714
|
|
|
708
715
|
# form parameters
|
|
709
716
|
form_params = opts[:form_params] || {}
|
|
@@ -712,7 +719,7 @@ module Repull
|
|
|
712
719
|
post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'listing_publish_airbnb_request'])
|
|
713
720
|
|
|
714
721
|
# return_type
|
|
715
|
-
return_type = opts[:debug_return_type] || '
|
|
722
|
+
return_type = opts[:debug_return_type] || 'ListingPublishAirbnbResponse'
|
|
716
723
|
|
|
717
724
|
# auth_names
|
|
718
725
|
auth_names = opts[:debug_auth_names] || ['bearerAuth']
|
|
@@ -797,6 +804,76 @@ module Repull
|
|
|
797
804
|
return data, status_code, headers
|
|
798
805
|
end
|
|
799
806
|
|
|
807
|
+
# Refresh a listing from Airbnb
|
|
808
|
+
# Re-read this listing from Airbnb and update your stored copy, then report what was refreshed and when. The mirror image of `POST /v1/listings/{id}/publish/airbnb`. Every other Airbnb read on this API is served from our database. This endpoint is the one that goes and asks Airbnb — use it after a push, to see the values Airbnb actually kept, or when a host has changed something in the Airbnb app. **What it refreshes:** basic listing facts (property type, bedrooms, beds, bathrooms, capacity), descriptions, photos, rooms and beds, amenities, booking settings (check-in/check-out windows, guest controls, cancellation policy), stay rules (min/max nights, advance-booking window, turnover buffer), pricing settings and standard fees, permits, checkout tasks and the check-in guide. After it returns, those values are what `GET /v1/listings/{id}?include=content,details` and the `/v1/channels/airbnb/**` routes serve. **What it does NOT refresh:** the calendar (nightly rates and availability — see `GET /v1/channels/airbnb/listings/{id}/availability`), reservations, messages, reviews or payouts. Those arrive continuously through the channel's own sync and never need a manual pull. **Runs synchronously** — the response is the result, not a job id. Expect several seconds. **One pull per listing per 15 minutes.** A pull is roughly a dozen Airbnb calls; a second call inside the window returns `429 rate_limit_exceeded` with `Retry-After` and `nextPullAvailableAt`, and makes no Airbnb calls. Two simultaneous calls cannot both run. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
|
|
809
|
+
# @param id [Integer]
|
|
810
|
+
# @param [Hash] opts the optional parameters
|
|
811
|
+
# @option opts [ListingPullAirbnbRequest] :listing_pull_airbnb_request
|
|
812
|
+
# @return [ListingPullResponse]
|
|
813
|
+
def pull_listing_from_airbnb(id, opts = {})
|
|
814
|
+
data, _status_code, _headers = pull_listing_from_airbnb_with_http_info(id, opts)
|
|
815
|
+
data
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
# Refresh a listing from Airbnb
|
|
819
|
+
# Re-read this listing from Airbnb and update your stored copy, then report what was refreshed and when. The mirror image of `POST /v1/listings/{id}/publish/airbnb`. Every other Airbnb read on this API is served from our database. This endpoint is the one that goes and asks Airbnb — use it after a push, to see the values Airbnb actually kept, or when a host has changed something in the Airbnb app. **What it refreshes:** basic listing facts (property type, bedrooms, beds, bathrooms, capacity), descriptions, photos, rooms and beds, amenities, booking settings (check-in/check-out windows, guest controls, cancellation policy), stay rules (min/max nights, advance-booking window, turnover buffer), pricing settings and standard fees, permits, checkout tasks and the check-in guide. After it returns, those values are what `GET /v1/listings/{id}?include=content,details` and the `/v1/channels/airbnb/**` routes serve. **What it does NOT refresh:** the calendar (nightly rates and availability — see `GET /v1/channels/airbnb/listings/{id}/availability`), reservations, messages, reviews or payouts. Those arrive continuously through the channel's own sync and never need a manual pull. **Runs synchronously** — the response is the result, not a job id. Expect several seconds. **One pull per listing per 15 minutes.** A pull is roughly a dozen Airbnb calls; a second call inside the window returns `429 rate_limit_exceeded` with `Retry-After` and `nextPullAvailableAt`, and makes no Airbnb calls. Two simultaneous calls cannot both run. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
|
|
820
|
+
# @param id [Integer]
|
|
821
|
+
# @param [Hash] opts the optional parameters
|
|
822
|
+
# @option opts [ListingPullAirbnbRequest] :listing_pull_airbnb_request
|
|
823
|
+
# @return [Array<(ListingPullResponse, Integer, Hash)>] ListingPullResponse data, response status code and response headers
|
|
824
|
+
def pull_listing_from_airbnb_with_http_info(id, opts = {})
|
|
825
|
+
if @api_client.config.debugging
|
|
826
|
+
@api_client.config.logger.debug 'Calling API: ListingsApi.pull_listing_from_airbnb ...'
|
|
827
|
+
end
|
|
828
|
+
# verify the required parameter 'id' is set
|
|
829
|
+
if @api_client.config.client_side_validation && id.nil?
|
|
830
|
+
fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.pull_listing_from_airbnb"
|
|
831
|
+
end
|
|
832
|
+
# resource path
|
|
833
|
+
local_var_path = '/v1/listings/{id}/pull/airbnb'.sub('{id}', CGI.escape(id.to_s))
|
|
834
|
+
|
|
835
|
+
# query parameters
|
|
836
|
+
query_params = opts[:query_params] || {}
|
|
837
|
+
|
|
838
|
+
# header parameters
|
|
839
|
+
header_params = opts[:header_params] || {}
|
|
840
|
+
# HTTP header 'Accept' (if needed)
|
|
841
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
842
|
+
# HTTP header 'Content-Type'
|
|
843
|
+
content_type = @api_client.select_header_content_type(['application/json'])
|
|
844
|
+
if !content_type.nil?
|
|
845
|
+
header_params['Content-Type'] = content_type
|
|
846
|
+
end
|
|
847
|
+
|
|
848
|
+
# form parameters
|
|
849
|
+
form_params = opts[:form_params] || {}
|
|
850
|
+
|
|
851
|
+
# http body (model)
|
|
852
|
+
post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'listing_pull_airbnb_request'])
|
|
853
|
+
|
|
854
|
+
# return_type
|
|
855
|
+
return_type = opts[:debug_return_type] || 'ListingPullResponse'
|
|
856
|
+
|
|
857
|
+
# auth_names
|
|
858
|
+
auth_names = opts[:debug_auth_names] || ['bearerAuth']
|
|
859
|
+
|
|
860
|
+
new_options = opts.merge(
|
|
861
|
+
:operation => :"ListingsApi.pull_listing_from_airbnb",
|
|
862
|
+
:header_params => header_params,
|
|
863
|
+
:query_params => query_params,
|
|
864
|
+
:form_params => form_params,
|
|
865
|
+
:body => post_body,
|
|
866
|
+
:auth_names => auth_names,
|
|
867
|
+
:return_type => return_type
|
|
868
|
+
)
|
|
869
|
+
|
|
870
|
+
data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
|
|
871
|
+
if @api_client.config.debugging
|
|
872
|
+
@api_client.config.logger.debug "API called: ListingsApi#pull_listing_from_airbnb\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
873
|
+
end
|
|
874
|
+
return data, status_code, headers
|
|
875
|
+
end
|
|
876
|
+
|
|
800
877
|
# Activate or deactivate listings in bulk
|
|
801
878
|
# Sets up to 500 listings active or inactive in one call. Send `{ \"listingIds\": [\"4118\", \"4119\"], \"active\": false }` to deactivate them, or `\"active\": true` to activate them. An inactive listing is not counted toward your plan's listing limit or billed. It is NOT deleted and the upstream channel (Airbnb / Booking.com / your PMS) is never touched — its data keeps syncing, so it is complete the moment you activate it again. Until then it cannot be read, changed, or receive webhooks. **All or nothing.** Nothing changes unless the whole request can be applied: - If any id is not one of your listings, the call returns `404` naming those ids. - If activating would take you over your plan's listing limit, the call returns `402 listings_limit_exceeded`. Only listings that are currently inactive count toward the new total, so re-sending ids that are already active never trips the limit. Deactivating is always allowed, including when your account is already over its limit — it is how you get back under it. **Idempotent.** Ids already in the requested state are returned in `unchanged`; ids this call changed are returned in `updated`. For a single listing, `PATCH /v1/listings/{id}` does the same.
|
|
802
879
|
# @param listing_status_batch_request [ListingStatusBatchRequest]
|
|
@@ -940,10 +1017,11 @@ module Repull
|
|
|
940
1017
|
end
|
|
941
1018
|
|
|
942
1019
|
# Update canonical listing content
|
|
943
|
-
# Write your PMS's canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \"the PMS owns listing content, Repull distributes it\" enabler. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. `amenities` is a FULL replacement of the amenity set (omit to leave untouched, send `[]` to clear). **Local write only — NOT a channel publish.** This mutates Repull's own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided `photos` array is echoed back in the `deferred` field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio. 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.
|
|
1020
|
+
# Write your PMS's canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \"the PMS owns listing content, Repull distributes it\" enabler. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. `amenities` is a FULL replacement of the amenity set (omit to leave untouched, send `[]` to clear). **Multilingual:** send `locale` to say which language this copy is in (`it`, `pt-BR`, …). Canonical content is stored per locale, so each language keeps its own row instead of overwriting the English one. Omit it for English. **Local write only — NOT a channel publish.** This mutates Repull's own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided `photos` array is echoed back in the `deferred` field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
|
|
944
1021
|
# @param id [Integer] Repull listing id
|
|
945
1022
|
# @param listing_content_update_request [ListingContentUpdateRequest]
|
|
946
1023
|
# @param [Hash] opts the optional parameters
|
|
1024
|
+
# @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged `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. - Responses with status >= 500 are deliberately not stored, so a server error stays retryable.
|
|
947
1025
|
# @return [ListingContentUpdateResponse]
|
|
948
1026
|
def update_listing_content(id, listing_content_update_request, opts = {})
|
|
949
1027
|
data, _status_code, _headers = update_listing_content_with_http_info(id, listing_content_update_request, opts)
|
|
@@ -951,10 +1029,11 @@ module Repull
|
|
|
951
1029
|
end
|
|
952
1030
|
|
|
953
1031
|
# Update canonical listing content
|
|
954
|
-
# Write your PMS's canonical listing content — title, description, amenities, address, occupancy, and policies — into a Repull listing, making it the source of truth. This is the flagship \"the PMS owns listing content, Repull distributes it\" enabler. **Partial update:** every field is optional. Only the fields you send are written; absent fields are left untouched. `amenities` is a FULL replacement of the amenity set (omit to leave untouched, send `[]` to clear). **Local write only — NOT a channel publish.** This mutates Repull's own copy of the content. It does NOT push to Airbnb / Booking.com; it marks the channels dirty so a later publish knows what changed. Distribution stays a separate explicit step. **Photos are deferred:** a provided `photos` array is echoed back in the `deferred` field and NOT persisted (media ingestion is a follow-up). Cross-tenant access (a listing that belongs to a different workspace) returns 404 — never 403. This endpoint is served even when the account is over the plan-listings cap, since editing content on a listing you already own never grows the portfolio. 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.
|
|
1032
|
+
# 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.
|
|
955
1033
|
# @param id [Integer] Repull listing id
|
|
956
1034
|
# @param listing_content_update_request [ListingContentUpdateRequest]
|
|
957
1035
|
# @param [Hash] opts the optional parameters
|
|
1036
|
+
# @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged `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. - Responses with status >= 500 are deliberately not stored, so a server error stays retryable.
|
|
958
1037
|
# @return [Array<(ListingContentUpdateResponse, Integer, Hash)>] ListingContentUpdateResponse data, response status code and response headers
|
|
959
1038
|
def update_listing_content_with_http_info(id, listing_content_update_request, opts = {})
|
|
960
1039
|
if @api_client.config.debugging
|
|
@@ -968,6 +1047,10 @@ module Repull
|
|
|
968
1047
|
if @api_client.config.client_side_validation && listing_content_update_request.nil?
|
|
969
1048
|
fail ArgumentError, "Missing the required parameter 'listing_content_update_request' when calling ListingsApi.update_listing_content"
|
|
970
1049
|
end
|
|
1050
|
+
if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
|
|
1051
|
+
fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling ListingsApi.update_listing_content, the character length must be smaller than or equal to 255.'
|
|
1052
|
+
end
|
|
1053
|
+
|
|
971
1054
|
# resource path
|
|
972
1055
|
local_var_path = '/v1/listings/{id}/content'.sub('{id}', CGI.escape(id.to_s))
|
|
973
1056
|
|
|
@@ -983,6 +1066,7 @@ module Repull
|
|
|
983
1066
|
if !content_type.nil?
|
|
984
1067
|
header_params['Content-Type'] = content_type
|
|
985
1068
|
end
|
|
1069
|
+
header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
|
|
986
1070
|
|
|
987
1071
|
# form parameters
|
|
988
1072
|
form_params = opts[:form_params] || {}
|
|
@@ -0,0 +1,239 @@
|
|
|
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` | 50 | | `custom` | unlimited | When a customer's active-listing count is above their tier cap, the API returns **`402 Payment Required`** with `error.code = \"listings_limit_exceeded\"` on every route EXCEPT: - `/v1/health` — uptime probes are never gated. - `/v1/usage/*` — so dashboards can render the over-cap state. - Any `DELETE` — so the customer can trim listings to get back under the cap without paying. Unlike 429, 402 is NOT a \"wait and retry\" condition — `Retry-After` is not set. The only paths back to 200 are: 1. `DELETE` enough listings to come back under the cap, or 2. Upgrade at `https://repull.dev/dashboard/billing`. The server-side usage cache is 60s, so the first 200 after an upgrade may take up to a minute. The envelope mirrors `rate_limit_exceeded` for SDK ergonomics: `tier`, `limit`, `active_listings`, `upgrade_url`, plus the standard `code` / `message` / `fix` / `docs_url` / `request_id`.
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
Contact: ivan@vanio.ai
|
|
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
|
+
# Freshness of ONE connected Airbnb account. Freshness is a property of an account, not of a workspace: one host's token expiring says nothing about another host's data.
|
|
18
|
+
class AirbnbAccountFreshness < ApiModelBase
|
|
19
|
+
# Airbnb host id, as a string (they exceed 2^53). The same value `?account_id=` accepts and `GET /v1/connect/airbnb` returns as `accounts[].externalAccountId`.
|
|
20
|
+
attr_accessor :account_id
|
|
21
|
+
|
|
22
|
+
# Display name of the connected account.
|
|
23
|
+
attr_accessor :account_name
|
|
24
|
+
|
|
25
|
+
# When this account last COMPLETED an Airbnb import. `null` when it never has. A run that failed or was rate-limited does not move it.
|
|
26
|
+
attr_accessor :last_synced_at
|
|
27
|
+
|
|
28
|
+
# `true` when this account is disconnected, has never synced, or has not refreshed in 24h+.
|
|
29
|
+
attr_accessor :stale
|
|
30
|
+
|
|
31
|
+
# Why THIS account is stale. Omitted when it is fresh.
|
|
32
|
+
attr_accessor :reason
|
|
33
|
+
|
|
34
|
+
# Where to reconnect this account. Omitted when it is fresh.
|
|
35
|
+
attr_accessor :fix_url
|
|
36
|
+
|
|
37
|
+
# Attribute mapping from ruby-style variable name to JSON key.
|
|
38
|
+
def self.attribute_map
|
|
39
|
+
{
|
|
40
|
+
:'account_id' => :'accountId',
|
|
41
|
+
:'account_name' => :'accountName',
|
|
42
|
+
:'last_synced_at' => :'lastSyncedAt',
|
|
43
|
+
:'stale' => :'stale',
|
|
44
|
+
:'reason' => :'reason',
|
|
45
|
+
:'fix_url' => :'fixUrl'
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Returns attribute mapping this model knows about
|
|
50
|
+
def self.acceptable_attribute_map
|
|
51
|
+
attribute_map
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Returns all the JSON keys this model knows about
|
|
55
|
+
def self.acceptable_attributes
|
|
56
|
+
acceptable_attribute_map.values
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Attribute type mapping.
|
|
60
|
+
def self.openapi_types
|
|
61
|
+
{
|
|
62
|
+
:'account_id' => :'String',
|
|
63
|
+
:'account_name' => :'String',
|
|
64
|
+
:'last_synced_at' => :'Time',
|
|
65
|
+
:'stale' => :'Boolean',
|
|
66
|
+
:'reason' => :'String',
|
|
67
|
+
:'fix_url' => :'String'
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# List of attributes with nullable: true
|
|
72
|
+
def self.openapi_nullable
|
|
73
|
+
Set.new([
|
|
74
|
+
:'account_name',
|
|
75
|
+
:'last_synced_at',
|
|
76
|
+
:'reason',
|
|
77
|
+
:'fix_url'
|
|
78
|
+
])
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Initializes the object
|
|
82
|
+
# @param [Hash] attributes Model attributes in the form of hash
|
|
83
|
+
def initialize(attributes = {})
|
|
84
|
+
if (!attributes.is_a?(Hash))
|
|
85
|
+
fail ArgumentError, "The input argument (attributes) must be a hash in `Repull::AirbnbAccountFreshness` initialize method"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# check to see if the attribute exists and convert string to symbol for hash key
|
|
89
|
+
acceptable_attribute_map = self.class.acceptable_attribute_map
|
|
90
|
+
attributes = attributes.each_with_object({}) { |(k, v), h|
|
|
91
|
+
if (!acceptable_attribute_map.key?(k.to_sym))
|
|
92
|
+
fail ArgumentError, "`#{k}` is not a valid attribute in `Repull::AirbnbAccountFreshness`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
|
|
93
|
+
end
|
|
94
|
+
h[k.to_sym] = v
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if attributes.key?(:'account_id')
|
|
98
|
+
self.account_id = attributes[:'account_id']
|
|
99
|
+
else
|
|
100
|
+
self.account_id = nil
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
if attributes.key?(:'account_name')
|
|
104
|
+
self.account_name = attributes[:'account_name']
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
if attributes.key?(:'last_synced_at')
|
|
108
|
+
self.last_synced_at = attributes[:'last_synced_at']
|
|
109
|
+
else
|
|
110
|
+
self.last_synced_at = nil
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
if attributes.key?(:'stale')
|
|
114
|
+
self.stale = attributes[:'stale']
|
|
115
|
+
else
|
|
116
|
+
self.stale = nil
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
if attributes.key?(:'reason')
|
|
120
|
+
self.reason = attributes[:'reason']
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
if attributes.key?(:'fix_url')
|
|
124
|
+
self.fix_url = attributes[:'fix_url']
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Show invalid properties with the reasons. Usually used together with valid?
|
|
129
|
+
# @return Array for valid properties with the reasons
|
|
130
|
+
def list_invalid_properties
|
|
131
|
+
warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
|
|
132
|
+
invalid_properties = Array.new
|
|
133
|
+
if @account_id.nil?
|
|
134
|
+
invalid_properties.push('invalid value for "account_id", account_id cannot be nil.')
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
if @stale.nil?
|
|
138
|
+
invalid_properties.push('invalid value for "stale", stale cannot be nil.')
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
invalid_properties
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Check to see if the all the properties in the model are valid
|
|
145
|
+
# @return true if the model is valid
|
|
146
|
+
def valid?
|
|
147
|
+
warn '[DEPRECATED] the `valid?` method is obsolete'
|
|
148
|
+
return false if @account_id.nil?
|
|
149
|
+
return false if @stale.nil?
|
|
150
|
+
true
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Custom attribute writer method with validation
|
|
154
|
+
# @param [Object] account_id Value to be assigned
|
|
155
|
+
def account_id=(account_id)
|
|
156
|
+
if account_id.nil?
|
|
157
|
+
fail ArgumentError, 'account_id cannot be nil'
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
@account_id = account_id
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Custom attribute writer method with validation
|
|
164
|
+
# @param [Object] stale Value to be assigned
|
|
165
|
+
def stale=(stale)
|
|
166
|
+
if stale.nil?
|
|
167
|
+
fail ArgumentError, 'stale cannot be nil'
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
@stale = stale
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Checks equality by comparing each attribute.
|
|
174
|
+
# @param [Object] Object to be compared
|
|
175
|
+
def ==(o)
|
|
176
|
+
return true if self.equal?(o)
|
|
177
|
+
self.class == o.class &&
|
|
178
|
+
account_id == o.account_id &&
|
|
179
|
+
account_name == o.account_name &&
|
|
180
|
+
last_synced_at == o.last_synced_at &&
|
|
181
|
+
stale == o.stale &&
|
|
182
|
+
reason == o.reason &&
|
|
183
|
+
fix_url == o.fix_url
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# @see the `==` method
|
|
187
|
+
# @param [Object] Object to be compared
|
|
188
|
+
def eql?(o)
|
|
189
|
+
self == o
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Calculates hash code according to all attributes.
|
|
193
|
+
# @return [Integer] Hash code
|
|
194
|
+
def hash
|
|
195
|
+
[account_id, account_name, last_synced_at, stale, reason, fix_url].hash
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Builds the object from hash
|
|
199
|
+
# @param [Hash] attributes Model attributes in the form of hash
|
|
200
|
+
# @return [Object] Returns the model itself
|
|
201
|
+
def self.build_from_hash(attributes)
|
|
202
|
+
return nil unless attributes.is_a?(Hash)
|
|
203
|
+
attributes = attributes.transform_keys(&:to_sym)
|
|
204
|
+
transformed_hash = {}
|
|
205
|
+
openapi_types.each_pair do |key, type|
|
|
206
|
+
if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
|
|
207
|
+
transformed_hash["#{key}"] = nil
|
|
208
|
+
elsif type =~ /\AArray<(.*)>/i
|
|
209
|
+
# check to ensure the input is an array given that the attribute
|
|
210
|
+
# is documented as an array but the input is not
|
|
211
|
+
if attributes[attribute_map[key]].is_a?(Array)
|
|
212
|
+
transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
|
|
213
|
+
end
|
|
214
|
+
elsif !attributes[attribute_map[key]].nil?
|
|
215
|
+
transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
new(transformed_hash)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# Returns the object in the form of hash
|
|
222
|
+
# @return [Hash] Returns the object in the form of hash
|
|
223
|
+
def to_hash
|
|
224
|
+
hash = {}
|
|
225
|
+
self.class.attribute_map.each_pair do |attr, param|
|
|
226
|
+
value = self.send(attr)
|
|
227
|
+
if value.nil?
|
|
228
|
+
is_nullable = self.class.openapi_nullable.include?(attr)
|
|
229
|
+
next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
hash[param] = _to_hash(value)
|
|
233
|
+
end
|
|
234
|
+
hash
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
end
|