repull 0.2.16 → 0.2.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/repull/api/airbnb_api.rb +6 -6
  3. data/lib/repull/api/booking_com_api.rb +86 -2
  4. data/lib/repull/api/conversations_api.rb +8 -8
  5. data/lib/repull/api/listings_api.rb +182 -12
  6. data/lib/repull/api/reservations_api.rb +4 -4
  7. data/lib/repull/models/airbnb_publish_result.rb +41 -2
  8. data/lib/repull/models/booking_property_action_request.rb +176 -0
  9. data/lib/repull/models/booking_property_action_response.rb +281 -0
  10. data/lib/repull/models/booking_publish_result.rb +245 -0
  11. data/lib/repull/models/booking_publish_section_error.rb +220 -0
  12. data/lib/repull/models/booking_setup_request.rb +44 -5
  13. data/lib/repull/models/booking_setup_request_legal_entity.rb +235 -0
  14. data/lib/repull/models/channel_market_state_item.rb +291 -0
  15. data/lib/repull/models/error_error.rb +11 -1
  16. data/lib/repull/models/inquiry_updated_payload.rb +1 -1
  17. data/lib/repull/models/list_inquiries200_response_data_inner.rb +1 -1
  18. data/lib/repull/models/listing_address_readiness.rb +171 -0
  19. data/lib/repull/models/listing_content_update_request_address.rb +40 -3
  20. data/lib/repull/models/listing_create_request.rb +48 -2
  21. data/lib/repull/models/listing_market_state_request.rb +149 -0
  22. data/lib/repull/models/listing_market_state_response.rb +221 -0
  23. data/lib/repull/models/listing_publish_booking_request.rb +149 -0
  24. data/lib/repull/models/{listing_publish_response.rb → listing_publish_booking_response.rb} +4 -5
  25. data/lib/repull/models/listing_publish_status_channel.rb +32 -1
  26. data/lib/repull/models/listing_publish_status_connection.rb +17 -5
  27. data/lib/repull/models/listing_publish_status_response.rb +13 -1
  28. data/lib/repull/models/reservation_request_updated_payload.rb +1 -1
  29. data/lib/repull/version.rb +1 -1
  30. data/lib/repull.rb +11 -1
  31. data/openapi/v1.json +855 -72
  32. data/scripts/regen.sh +1 -1
  33. metadata +13 -3
@@ -438,7 +438,7 @@ module Repull
438
438
  end
439
439
 
440
440
  # Per-channel publish status
441
- # Returns connection state and sync activity per channel. `channels` is sync activity (empty until first push). `connections` is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer `GET /v1/listings` and filter client-side. 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.
441
+ # Returns connection state and sync activity per channel. `channels` is sync activity (empty until first push). `connections` is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer `GET /v1/listings` and filter client-side. **When a push fails, this endpoint says why.** `channels[].pushError` carries the channel's own reason for the last failed push, verbatim — `\"Links and contact info can't be shared\"`, `\"Check-in start time must be before end time\"`, `\"property_type_group must be one of […]\"`. It is free text written by the channel, so render it next to the retry button rather than parsing it. `null` when the last push succeeded or none has run; pair it with `pushStatus` to tell those two apart. **It also says what you will not be allowed to change.** The `airbnb` entry in `connections` carries `lockedFields` — attributes Airbnb has locked on this listing. Airbnb does not refuse a write to one: it answers 200, reports the field as locked, and applies nothing, so a locked write is indistinguishable from a successful one unless you looked first. Read it before you let someone edit. Airbnb-only; no other channel has the concept, and no other entry carries the field. 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.
442
442
  # @param id [Integer]
443
443
  # @param [Hash] opts the optional parameters
444
444
  # @return [ListingPublishStatusResponse]
@@ -448,7 +448,7 @@ module Repull
448
448
  end
449
449
 
450
450
  # Per-channel publish status
451
- # Returns connection state and sync activity per channel. `channels` is sync activity (empty until first push). `connections` is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer `GET /v1/listings` and filter client-side. 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.
451
+ # Returns connection state and sync activity per channel. `channels` is sync activity (empty until first push). `connections` is connection state (populated as soon as a channel is linked). Recommended polling cadence: at most once per 30s per listing — for bulk views, prefer `GET /v1/listings` and filter client-side. **When a push fails, this endpoint says why.** `channels[].pushError` carries the channel's own reason for the last failed push, verbatim — `\"Links and contact info can't be shared\"`, `\"Check-in start time must be before end time\"`, `\"property_type_group must be one of […]\"`. It is free text written by the channel, so render it next to the retry button rather than parsing it. `null` when the last push succeeded or none has run; pair it with `pushStatus` to tell those two apart. **It also says what you will not be allowed to change.** The `airbnb` entry in `connections` carries `lockedFields` — attributes Airbnb has locked on this listing. Airbnb does not refuse a write to one: it answers 200, reports the field as locked, and applies nothing, so a locked write is indistinguishable from a successful one unless you looked first. Read it before you let someone edit. Airbnb-only; no other channel has the concept, and no other entry carries the field. 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.
452
452
  # @param id [Integer]
453
453
  # @param [Hash] opts the optional parameters
454
454
  # @return [Array<(ListingPublishStatusResponse, Integer, Hash)>] ListingPublishStatusResponse data, response status code and response headers
@@ -665,7 +665,7 @@ module Repull
665
665
  end
666
666
 
667
667
  # Publish a listing to Airbnb
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.
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.live` is a different question from `result.published`. `published` is about CONTENT — every attempted section landed. `live` is about whether the listing takes bookings: it is true only when activation was actually performed and succeeded. A create can land all eight sections and still leave the listing inactive, because activation is skipped when instant-booking cannot be confirmed to be off — so `published: true` with `live: false` is a real and common outcome, and `result.warnings` says why. `live` is ABSENT, not `false`, when activation was never part of the operation: publishing to an already-mapped listing updates content and activates nothing. Only treat a listing as not-live when `live` is present and false. `result.warnings[]` lists steps that failed WITHOUT failing the publish — optional work the push carried on past. They were previously swallowed, so the only sign of one was a listing that was somehow not quite right afterwards. A publish can be `published: true` and still carry warnings; read them before concluding nothing needs doing. `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
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 &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
@@ -677,7 +677,7 @@ module Repull
677
677
  end
678
678
 
679
679
  # Publish a listing to Airbnb
680
- # Push a Repull listing&#39;s canonical content to Airbnb. Pass &#x60;airbnbConnectionId&#x60; to update an already-mapped Airbnb listing, or &#x60;hostId&#x60; 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. &#x60;result.published&#x60; is true only when every attempted section landed; &#x60;result.sections&#x60; lists the ones that did and &#x60;result.errors[]&#x60; carries Airbnb&#39;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. &#x60;result.lockedFields&#x60; names the fields Airbnb will not let this listing change at all. They are not retryable by anyone: Airbnb answers 200 and applies nothing. &#x60;GET /v1/channels/airbnb/listings/{id}&#x60; 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 (&#x60;PUT /v1/channels/airbnb/listings/{id}/descriptions&#x60;), guest-safety disclosures (&#x60;PUT …/safety-disclosures&#x60;), check-in method (&#x60;PUT …/details&#x60;), permits (&#x60;PUT …/permits&#x60;), and the calendar (&#x60;PUT …/availability&#x60;). &#x60;force: true&#x60; re-pushes every section, ignoring dirty-field tracking. Without it only the sections changed since the last successful publish are sent. Send &#x60;Idempotency-Key&#x60; to make a retry safe: a timeout on a publish otherwise leaves you unable to tell whether it ran. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
680
+ # Push a Repull listing&#39;s canonical content to Airbnb. Pass &#x60;airbnbConnectionId&#x60; to update an already-mapped Airbnb listing, or &#x60;hostId&#x60; 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. &#x60;result.published&#x60; is true only when every attempted section landed; &#x60;result.sections&#x60; lists the ones that did and &#x60;result.errors[]&#x60; carries Airbnb&#39;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. &#x60;result.live&#x60; is a different question from &#x60;result.published&#x60;. &#x60;published&#x60; is about CONTENT — every attempted section landed. &#x60;live&#x60; is about whether the listing takes bookings: it is true only when activation was actually performed and succeeded. A create can land all eight sections and still leave the listing inactive, because activation is skipped when instant-booking cannot be confirmed to be off — so &#x60;published: true&#x60; with &#x60;live: false&#x60; is a real and common outcome, and &#x60;result.warnings&#x60; says why. &#x60;live&#x60; is ABSENT, not &#x60;false&#x60;, when activation was never part of the operation: publishing to an already-mapped listing updates content and activates nothing. Only treat a listing as not-live when &#x60;live&#x60; is present and false. &#x60;result.warnings[]&#x60; lists steps that failed WITHOUT failing the publish — optional work the push carried on past. They were previously swallowed, so the only sign of one was a listing that was somehow not quite right afterwards. A publish can be &#x60;published: true&#x60; and still carry warnings; read them before concluding nothing needs doing. &#x60;result.lockedFields&#x60; names the fields Airbnb will not let this listing change at all. They are not retryable by anyone: Airbnb answers 200 and applies nothing. &#x60;GET /v1/channels/airbnb/listings/{id}&#x60; 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 (&#x60;PUT /v1/channels/airbnb/listings/{id}/descriptions&#x60;), guest-safety disclosures (&#x60;PUT …/safety-disclosures&#x60;), check-in method (&#x60;PUT …/details&#x60;), permits (&#x60;PUT …/permits&#x60;), and the calendar (&#x60;PUT …/availability&#x60;). &#x60;force: true&#x60; re-pushes every section, ignoring dirty-field tracking. Without it only the sections changed since the last successful publish are sent. Send &#x60;Idempotency-Key&#x60; to make a retry safe: a timeout on a publish otherwise leaves you unable to tell whether it ran. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
681
681
  # @param id [Integer]
682
682
  # @param [Hash] opts the optional parameters
683
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 &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
@@ -742,20 +742,24 @@ module Repull
742
742
  end
743
743
 
744
744
  # Publish a listing to Booking.com
745
- # Push a Repull listing to Booking.com. The listing must already be mapped to a Booking property + room (created via the Booking-claim Connect flow). 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.
746
- # @param id [Integer]
745
+ # Push a Repull listing's content to Booking.com. The listing must already be mapped to a Booking.com property + room — claim the hotel through the Connect Booking flow, then map its rooms with `POST /v1/connect/booking/map-rooms`. **Which property the content lands in.** A listing can be mapped to more than one Booking.com property; the same unit re-listed under a new property keeps its old mapping, and workspaces routinely sit on five or six. When the listing has exactly one property you need send nothing. When it has several, name one with `hotelId` in the body (or `?hotel_id=` — the same value, accepted either way, body wins if you send both). Omit it on such a listing and the push is refused with **`409 ambiguous_booking_mapping`**, listing the candidate ids: content pushed into a property chosen for you lands on the wrong listing and reports success, which is worse than a refusal. `GET /v1/channels/booking/properties` lists every property with the listings mapped under it. Naming a property this listing is not mapped to is a `404` that names the ones it is. The property that actually received the content comes back as `result.hotelId`. **A publish is not one call to Booking.com.** It is several independent Content API calls — details, description, amenities, rooms, photos, pricing — 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 Booking.com's own reason, per section, for the ones that did not. A property whose Content API credentials do not cover a section answers 403 for that section alone. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Fix the failing sections and publish again — re-publishing an unchanged section is harmless. A listing with no Booking.com property mapped at all is not an error: the call returns `result.published: false` with `result.reason` and `result.hotelId: null`, and nothing is pushed. 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.
746
+ # @param id [Integer] Repull listing id — NOT a Booking.com hotel id.
747
747
  # @param [Hash] opts the optional parameters
748
- # @return [ListingPublishResponse]
748
+ # @option opts [String] :hotel_id Booking.com property to publish into, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;, accepted so this route reads the same as every other Booking listing-addressed route. The body wins when both are sent.
749
+ # @option opts [ListingPublishBookingRequest] :listing_publish_booking_request
750
+ # @return [ListingPublishBookingResponse]
749
751
  def publish_listing_to_booking(id, opts = {})
750
752
  data, _status_code, _headers = publish_listing_to_booking_with_http_info(id, opts)
751
753
  data
752
754
  end
753
755
 
754
756
  # Publish a listing to Booking.com
755
- # Push a Repull listing to Booking.com. The listing must already be mapped to a Booking property + room (created via the Booking-claim Connect flow). Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
756
- # @param id [Integer]
757
+ # Push a Repull listing&#39;s content to Booking.com. The listing must already be mapped to a Booking.com property + room — claim the hotel through the Connect Booking flow, then map its rooms with &#x60;POST /v1/connect/booking/map-rooms&#x60;. **Which property the content lands in.** A listing can be mapped to more than one Booking.com property; the same unit re-listed under a new property keeps its old mapping, and workspaces routinely sit on five or six. When the listing has exactly one property you need send nothing. When it has several, name one with &#x60;hotelId&#x60; in the body (or &#x60;?hotel_id&#x3D;&#x60; — the same value, accepted either way, body wins if you send both). Omit it on such a listing and the push is refused with **&#x60;409 ambiguous_booking_mapping&#x60;**, listing the candidate ids: content pushed into a property chosen for you lands on the wrong listing and reports success, which is worse than a refusal. &#x60;GET /v1/channels/booking/properties&#x60; lists every property with the listings mapped under it. Naming a property this listing is not mapped to is a &#x60;404&#x60; that names the ones it is. The property that actually received the content comes back as &#x60;result.hotelId&#x60;. **A publish is not one call to Booking.com.** It is several independent Content API calls — details, description, amenities, rooms, photos, pricing — and each can fail on its own. &#x60;result.published&#x60; is true only when every attempted section landed; &#x60;result.sections&#x60; lists the ones that did and &#x60;result.errors[]&#x60; carries Booking.com&#39;s own reason, per section, for the ones that did not. A property whose Content API credentials do not cover a section answers 403 for that section alone. **A partial publish is normal and is not rolled back**: what succeeded stays applied. Fix the failing sections and publish again — re-publishing an unchanged section is harmless. A listing with no Booking.com property mapped at all is not an error: the call returns &#x60;result.published: false&#x60; with &#x60;result.reason&#x60; and &#x60;result.hotelId: null&#x60;, and nothing is pushed. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
758
+ # @param id [Integer] Repull listing id — NOT a Booking.com hotel id.
757
759
  # @param [Hash] opts the optional parameters
758
- # @return [Array<(ListingPublishResponse, Integer, Hash)>] ListingPublishResponse data, response status code and response headers
760
+ # @option opts [String] :hotel_id Booking.com property to publish into, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;, accepted so this route reads the same as every other Booking listing-addressed route. The body wins when both are sent.
761
+ # @option opts [ListingPublishBookingRequest] :listing_publish_booking_request
762
+ # @return [Array<(ListingPublishBookingResponse, Integer, Hash)>] ListingPublishBookingResponse data, response status code and response headers
759
763
  def publish_listing_to_booking_with_http_info(id, opts = {})
760
764
  if @api_client.config.debugging
761
765
  @api_client.config.logger.debug 'Calling API: ListingsApi.publish_listing_to_booking ...'
@@ -769,20 +773,26 @@ module Repull
769
773
 
770
774
  # query parameters
771
775
  query_params = opts[:query_params] || {}
776
+ query_params[:'hotel_id'] = opts[:'hotel_id'] if !opts[:'hotel_id'].nil?
772
777
 
773
778
  # header parameters
774
779
  header_params = opts[:header_params] || {}
775
780
  # HTTP header 'Accept' (if needed)
776
781
  header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
782
+ # HTTP header 'Content-Type'
783
+ content_type = @api_client.select_header_content_type(['application/json'])
784
+ if !content_type.nil?
785
+ header_params['Content-Type'] = content_type
786
+ end
777
787
 
778
788
  # form parameters
779
789
  form_params = opts[:form_params] || {}
780
790
 
781
791
  # http body (model)
782
- post_body = opts[:debug_body]
792
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'listing_publish_booking_request'])
783
793
 
784
794
  # return_type
785
- return_type = opts[:debug_return_type] || 'ListingPublishResponse'
795
+ return_type = opts[:debug_return_type] || 'ListingPublishBookingResponse'
786
796
 
787
797
  # auth_names
788
798
  auth_names = opts[:debug_auth_names] || ['bearerAuth']
@@ -942,6 +952,166 @@ module Repull
942
952
  return data, status_code, headers
943
953
  end
944
954
 
955
+ # Take a listing off the market
956
+ # Stop this listing being sold, on every channel it is connected to, in one call. What that means differs per channel and you do not have to know which is which. On **Airbnb** the live listing is deactivated with a valid deactivation reason and then READ BACK — Airbnb accepts some deactivations and leaves the listing up, so \"we sent the request\" is never reported as success. On **Booking.com** there is no unlist at all; the equivalent is closing the room's availability across the whole forward window, which is what happens. **This is not the same as deactivating the listing in Repull.** The two get confused because both sound like removal, and they have opposite consequences: | | Take offline (this endpoint) | Deactivate in Repull (`PATCH /v1/listings/{id}` `{\"active\": false}`) | |---|---|---| | The guest-facing listing | **Stops taking bookings** | Stays live and keeps taking bookings | | Billing and plan limits | Unchanged | No longer billed, no longer counts toward the cap | | API access to the listing | Unchanged — you can still read and write it | `403 listing_inactive` until reactivated | | Reverse it with | `POST /v1/listings/{id}/online` | `PATCH /v1/listings/{id}` `{\"active\": true}` | | Data kept | Yes | Yes, and it keeps syncing | Neither one deletes anything, on either side. **The answer is per channel item.** A listing can sit on several Airbnb connections and a Booking.com property at once; they fail independently and a partial result is the ordinary outcome, so every item reports its own `state`, `code` and `message` and there is no top-level success flag to mislead you. Nothing is rolled back — re-send the same request to retry the items that did not land. **Booking.com ambiguity is reported, not fanned out.** A listing mapped to more than one active Booking.com property comes back with that item refused (`ambiguous_booking_mapping`) while the Airbnb items still run: closing the wrong property's availability takes real inventory off sale, and taking a listing off Airbnb is not less urgent because its Booking.com mapping is untidy. Name the property with `hotelId` and send it again. 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.
957
+ # @param id [Integer] Repull listing id.
958
+ # @param [Hash] opts the optional parameters
959
+ # @option opts [String] :hotel_id Booking.com property to act on, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;; the body wins when both are sent.
960
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
961
+ # @option opts [ListingMarketStateRequest] :listing_market_state_request
962
+ # @return [ListingMarketStateResponse]
963
+ def take_listing_offline(id, opts = {})
964
+ data, _status_code, _headers = take_listing_offline_with_http_info(id, opts)
965
+ data
966
+ end
967
+
968
+ # Take a listing off the market
969
+ # Stop this listing being sold, on every channel it is connected to, in one call. What that means differs per channel and you do not have to know which is which. On **Airbnb** the live listing is deactivated with a valid deactivation reason and then READ BACK — Airbnb accepts some deactivations and leaves the listing up, so \&quot;we sent the request\&quot; is never reported as success. On **Booking.com** there is no unlist at all; the equivalent is closing the room&#39;s availability across the whole forward window, which is what happens. **This is not the same as deactivating the listing in Repull.** The two get confused because both sound like removal, and they have opposite consequences: | | Take offline (this endpoint) | Deactivate in Repull (&#x60;PATCH /v1/listings/{id}&#x60; &#x60;{\&quot;active\&quot;: false}&#x60;) | |---|---|---| | The guest-facing listing | **Stops taking bookings** | Stays live and keeps taking bookings | | Billing and plan limits | Unchanged | No longer billed, no longer counts toward the cap | | API access to the listing | Unchanged — you can still read and write it | &#x60;403 listing_inactive&#x60; until reactivated | | Reverse it with | &#x60;POST /v1/listings/{id}/online&#x60; | &#x60;PATCH /v1/listings/{id}&#x60; &#x60;{\&quot;active\&quot;: true}&#x60; | | Data kept | Yes | Yes, and it keeps syncing | Neither one deletes anything, on either side. **The answer is per channel item.** A listing can sit on several Airbnb connections and a Booking.com property at once; they fail independently and a partial result is the ordinary outcome, so every item reports its own &#x60;state&#x60;, &#x60;code&#x60; and &#x60;message&#x60; and there is no top-level success flag to mislead you. Nothing is rolled back — re-send the same request to retry the items that did not land. **Booking.com ambiguity is reported, not fanned out.** A listing mapped to more than one active Booking.com property comes back with that item refused (&#x60;ambiguous_booking_mapping&#x60;) while the Airbnb items still run: closing the wrong property&#39;s availability takes real inventory off sale, and taking a listing off Airbnb is not less urgent because its Booking.com mapping is untidy. Name the property with &#x60;hotelId&#x60; and send it again. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
970
+ # @param id [Integer] Repull listing id.
971
+ # @param [Hash] opts the optional parameters
972
+ # @option opts [String] :hotel_id Booking.com property to act on, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;; the body wins when both are sent.
973
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
974
+ # @option opts [ListingMarketStateRequest] :listing_market_state_request
975
+ # @return [Array<(ListingMarketStateResponse, Integer, Hash)>] ListingMarketStateResponse data, response status code and response headers
976
+ def take_listing_offline_with_http_info(id, opts = {})
977
+ if @api_client.config.debugging
978
+ @api_client.config.logger.debug 'Calling API: ListingsApi.take_listing_offline ...'
979
+ end
980
+ # verify the required parameter 'id' is set
981
+ if @api_client.config.client_side_validation && id.nil?
982
+ fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.take_listing_offline"
983
+ end
984
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
985
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling ListingsApi.take_listing_offline, the character length must be smaller than or equal to 255.'
986
+ end
987
+
988
+ # resource path
989
+ local_var_path = '/v1/listings/{id}/offline'.sub('{id}', CGI.escape(id.to_s))
990
+
991
+ # query parameters
992
+ query_params = opts[:query_params] || {}
993
+ query_params[:'hotel_id'] = opts[:'hotel_id'] if !opts[:'hotel_id'].nil?
994
+
995
+ # header parameters
996
+ header_params = opts[:header_params] || {}
997
+ # HTTP header 'Accept' (if needed)
998
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
999
+ # HTTP header 'Content-Type'
1000
+ content_type = @api_client.select_header_content_type(['application/json'])
1001
+ if !content_type.nil?
1002
+ header_params['Content-Type'] = content_type
1003
+ end
1004
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
1005
+
1006
+ # form parameters
1007
+ form_params = opts[:form_params] || {}
1008
+
1009
+ # http body (model)
1010
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'listing_market_state_request'])
1011
+
1012
+ # return_type
1013
+ return_type = opts[:debug_return_type] || 'ListingMarketStateResponse'
1014
+
1015
+ # auth_names
1016
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
1017
+
1018
+ new_options = opts.merge(
1019
+ :operation => :"ListingsApi.take_listing_offline",
1020
+ :header_params => header_params,
1021
+ :query_params => query_params,
1022
+ :form_params => form_params,
1023
+ :body => post_body,
1024
+ :auth_names => auth_names,
1025
+ :return_type => return_type
1026
+ )
1027
+
1028
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
1029
+ if @api_client.config.debugging
1030
+ @api_client.config.logger.debug "API called: ListingsApi#take_listing_offline\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
1031
+ end
1032
+ return data, status_code, headers
1033
+ end
1034
+
1035
+ # Put a listing back on the market
1036
+ # Put this listing back on sale, on every channel it is connected to. The counterpart of `POST /v1/listings/{id}/offline`, which documents the per-item response and the difference between this and deactivating a listing in Repull. **It does not push content.** On **Airbnb** it re-enables sync and makes the listing available again; anything that changed while the listing was down is still unpublished, so follow with `POST /v1/listings/{id}/publish/airbnb` if the content moved. On **Booking.com** it re-syncs the true calendar rather than opening everything: dates that are genuinely blocked — a reservation, an owner stay — stay blocked, and only the closure `offline` wrote lifts. The two directions are not mirror images, and that is deliberate. **One asymmetry worth planning for.** Taking a listing down passes no billing gate; putting it back up goes through the channel-publish gate. So on a workspace whose subscription has lapsed, `offline` still works and this endpoint answers `402 payment_required` — a listing can be left off the market until billing is sorted out. That refusal is reported as a billing refusal with the action that fixes it, never as a channel error: retrying, or reconnecting the channel, does nothing for it. Returns `403 listing_inactive` when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1037
+ # @param id [Integer] Repull listing id.
1038
+ # @param [Hash] opts the optional parameters
1039
+ # @option opts [String] :hotel_id Booking.com property to act on, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;; the body wins when both are sent.
1040
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
1041
+ # @option opts [ListingMarketStateRequest] :listing_market_state_request
1042
+ # @return [ListingMarketStateResponse]
1043
+ def take_listing_online(id, opts = {})
1044
+ data, _status_code, _headers = take_listing_online_with_http_info(id, opts)
1045
+ data
1046
+ end
1047
+
1048
+ # Put a listing back on the market
1049
+ # Put this listing back on sale, on every channel it is connected to. The counterpart of &#x60;POST /v1/listings/{id}/offline&#x60;, which documents the per-item response and the difference between this and deactivating a listing in Repull. **It does not push content.** On **Airbnb** it re-enables sync and makes the listing available again; anything that changed while the listing was down is still unpublished, so follow with &#x60;POST /v1/listings/{id}/publish/airbnb&#x60; if the content moved. On **Booking.com** it re-syncs the true calendar rather than opening everything: dates that are genuinely blocked — a reservation, an owner stay — stay blocked, and only the closure &#x60;offline&#x60; wrote lifts. The two directions are not mirror images, and that is deliberate. **One asymmetry worth planning for.** Taking a listing down passes no billing gate; putting it back up goes through the channel-publish gate. So on a workspace whose subscription has lapsed, &#x60;offline&#x60; still works and this endpoint answers &#x60;402 payment_required&#x60; — a listing can be left off the market until billing is sorted out. That refusal is reported as a billing refusal with the action that fixes it, never as a channel error: retrying, or reconnecting the channel, does nothing for it. Returns &#x60;403 listing_inactive&#x60; when the listing is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.
1050
+ # @param id [Integer] Repull listing id.
1051
+ # @param [Hash] opts the optional parameters
1052
+ # @option opts [String] :hotel_id Booking.com property to act on, for a listing mapped to more than one. The query-string spelling of the body&#39;s &#x60;hotelId&#x60;; the body wins when both are sent.
1053
+ # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
1054
+ # @option opts [ListingMarketStateRequest] :listing_market_state_request
1055
+ # @return [Array<(ListingMarketStateResponse, Integer, Hash)>] ListingMarketStateResponse data, response status code and response headers
1056
+ def take_listing_online_with_http_info(id, opts = {})
1057
+ if @api_client.config.debugging
1058
+ @api_client.config.logger.debug 'Calling API: ListingsApi.take_listing_online ...'
1059
+ end
1060
+ # verify the required parameter 'id' is set
1061
+ if @api_client.config.client_side_validation && id.nil?
1062
+ fail ArgumentError, "Missing the required parameter 'id' when calling ListingsApi.take_listing_online"
1063
+ end
1064
+ if @api_client.config.client_side_validation && !opts[:'idempotency_key'].nil? && opts[:'idempotency_key'].to_s.length > 255
1065
+ fail ArgumentError, 'invalid value for "opts[:"idempotency_key"]" when calling ListingsApi.take_listing_online, the character length must be smaller than or equal to 255.'
1066
+ end
1067
+
1068
+ # resource path
1069
+ local_var_path = '/v1/listings/{id}/online'.sub('{id}', CGI.escape(id.to_s))
1070
+
1071
+ # query parameters
1072
+ query_params = opts[:query_params] || {}
1073
+ query_params[:'hotel_id'] = opts[:'hotel_id'] if !opts[:'hotel_id'].nil?
1074
+
1075
+ # header parameters
1076
+ header_params = opts[:header_params] || {}
1077
+ # HTTP header 'Accept' (if needed)
1078
+ header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
1079
+ # HTTP header 'Content-Type'
1080
+ content_type = @api_client.select_header_content_type(['application/json'])
1081
+ if !content_type.nil?
1082
+ header_params['Content-Type'] = content_type
1083
+ end
1084
+ header_params[:'Idempotency-Key'] = opts[:'idempotency_key'] if !opts[:'idempotency_key'].nil?
1085
+
1086
+ # form parameters
1087
+ form_params = opts[:form_params] || {}
1088
+
1089
+ # http body (model)
1090
+ post_body = opts[:debug_body] || @api_client.object_to_http_body(opts[:'listing_market_state_request'])
1091
+
1092
+ # return_type
1093
+ return_type = opts[:debug_return_type] || 'ListingMarketStateResponse'
1094
+
1095
+ # auth_names
1096
+ auth_names = opts[:debug_auth_names] || ['bearerAuth']
1097
+
1098
+ new_options = opts.merge(
1099
+ :operation => :"ListingsApi.take_listing_online",
1100
+ :header_params => header_params,
1101
+ :query_params => query_params,
1102
+ :form_params => form_params,
1103
+ :body => post_body,
1104
+ :auth_names => auth_names,
1105
+ :return_type => return_type
1106
+ )
1107
+
1108
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
1109
+ if @api_client.config.debugging
1110
+ @api_client.config.logger.debug "API called: ListingsApi#take_listing_online\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
1111
+ end
1112
+ return data, status_code, headers
1113
+ end
1114
+
945
1115
  # Deactivate or reactivate a listing
946
1116
  # Toggle a listing's active state. Send `{ \"active\": false }` to **deactivate** (exclude the listing from Repull) or `{ \"active\": true }` to **reactivate** it. \"Deactivate\" keeps the listing row — it is NOT a hard delete, and it NEVER touches the upstream channel (Airbnb / Hospitable / Booking.com). Repull only mutates its own copy of the inventory. Deactivating is the self-serve way to get back under the plan-listings cap without paying. Reactivation respects the plan-listings cap: if activating this listing would push you over the cap for your tier, the call returns `402 listings_limit_exceeded` and the listing stays inactive. Deactivate another listing or upgrade first. Idempotent: setting a listing to the state it's already in returns 200. To change many listings at once, all or nothing, use `POST /v1/listings/status`.
947
1117
  # @param id [Integer] Repull listing id
@@ -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. Runs the same action as the Vanio dashboard’s Accept button. Airbnb confirms asynchronously: the reservation’s status moves to confirmed, and a `reservation.updated` webhook fires, when Airbnb’s notification lands (usually within seconds). The response reports what Airbnb was asked to do. **Airbnb only**, and only for listings connected to Airbnb directly: other channels have no request step (`422 channel_not_supported`). A reservation that is not pending is refused before Airbnb is contacted (`409 reservation_not_pending`); one Airbnb says already moved on is `409 request_no_longer_pending`. Neither is worth retrying. Takes no body. Send `Idempotency-Key`: a repeat with the same key replays the first response instead of acting twice (a `409 idempotency_key_in_use` while the first is still running). A 5xx, a `429 airbnb_rate_limited` or a `403 connection_reauth_required` is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
23
+ # Accept a pending Airbnb booking request — a reservation with status `pending`, made on a listing without Instant Book. Find them with `GET /v1/reservations?status=pending`. Airbnb expires a request the host has not answered within 24 hours. Airbnb confirms asynchronously: the reservation’s status moves to confirmed, and a `reservation.updated` webhook fires, when Airbnb’s notification lands (usually within seconds). The response reports what Airbnb was asked to do. **Airbnb only**, and only for listings connected to Airbnb directly: other channels have no request step (`422 channel_not_supported`). A reservation that is not pending is refused before Airbnb is contacted (`409 reservation_not_pending`); one Airbnb says already moved on is `409 request_no_longer_pending`. Neither is worth retrying. Takes no body. Send `Idempotency-Key`: a repeat with the same key replays the first response instead of acting twice (a `409 idempotency_key_in_use` while the first is still running). A 5xx, a `429 airbnb_rate_limited` or a `403 connection_reauth_required` is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
24
24
  # @param id [Integer] Repull reservation id (from &#x60;GET /v1/reservations?status&#x3D;pending&#x60;) — not the Airbnb confirmation code.
25
25
  # @param [Hash] opts the optional parameters
26
26
  # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
@@ -31,7 +31,7 @@ module Repull
31
31
  end
32
32
 
33
33
  # Accept a booking request
34
- # Accept a pending Airbnb booking request — a reservation with status &#x60;pending&#x60;, made on a listing without Instant Book. Find them with &#x60;GET /v1/reservations?status&#x3D;pending&#x60;. Airbnb expires a request the host has not answered within 24 hours. Runs the same action as the Vanio dashboard’s Accept button. Airbnb confirms asynchronously: the reservation’s status moves to confirmed, and a &#x60;reservation.updated&#x60; webhook fires, when Airbnb’s notification lands (usually within seconds). The response reports what Airbnb was asked to do. **Airbnb only**, and only for listings connected to Airbnb directly: other channels have no request step (&#x60;422 channel_not_supported&#x60;). A reservation that is not pending is refused before Airbnb is contacted (&#x60;409 reservation_not_pending&#x60;); one Airbnb says already moved on is &#x60;409 request_no_longer_pending&#x60;. Neither is worth retrying. Takes no body. Send &#x60;Idempotency-Key&#x60;: a repeat with the same key replays the first response instead of acting twice (a &#x60;409 idempotency_key_in_use&#x60; while the first is still running). A 5xx, a &#x60;429 airbnb_rate_limited&#x60; or a &#x60;403 connection_reauth_required&#x60; is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
34
+ # Accept a pending Airbnb booking request — a reservation with status &#x60;pending&#x60;, made on a listing without Instant Book. Find them with &#x60;GET /v1/reservations?status&#x3D;pending&#x60;. Airbnb expires a request the host has not answered within 24 hours. Airbnb confirms asynchronously: the reservation’s status moves to confirmed, and a &#x60;reservation.updated&#x60; webhook fires, when Airbnb’s notification lands (usually within seconds). The response reports what Airbnb was asked to do. **Airbnb only**, and only for listings connected to Airbnb directly: other channels have no request step (&#x60;422 channel_not_supported&#x60;). A reservation that is not pending is refused before Airbnb is contacted (&#x60;409 reservation_not_pending&#x60;); one Airbnb says already moved on is &#x60;409 request_no_longer_pending&#x60;. Neither is worth retrying. Takes no body. Send &#x60;Idempotency-Key&#x60;: a repeat with the same key replays the first response instead of acting twice (a &#x60;409 idempotency_key_in_use&#x60; while the first is still running). A 5xx, a &#x60;429 airbnb_rate_limited&#x60; or a &#x60;403 connection_reauth_required&#x60; is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
35
35
  # @param id [Integer] Repull reservation id (from &#x60;GET /v1/reservations?status&#x3D;pending&#x60;) — not the Airbnb confirmation code.
36
36
  # @param [Hash] opts the optional parameters
37
37
  # @option opts [String] :idempotency_key Makes a retry of this request safe. Send a unique string (a UUID generated at the point you build the request) and the response is stored for 24 hours: a repeat with the SAME key replays that stored response — tagged &#x60;Idempotency-Status: cached&#x60; — without running the operation again, so no duplicate reservation, guest or guest message is created. - Same key while the first request is still in flight → &#x60;409 idempotency_key_in_use&#x60;. - Same key with a DIFFERENT payload → &#x60;422 idempotency_key_reused&#x60;. Generate a new key per distinct request; reuse one only when retrying that exact request. - Retryable outcomes are deliberately not stored, so a retry with the same key runs for real: any status &gt;&#x3D; 500, &#x60;408&#x60;, &#x60;425&#x60; and &#x60;429&#x60;, and the refusals that happen before anything is done and tell you to fix something outside the request first — &#x60;connection_reauth_required&#x60;, &#x60;listing_inactive&#x60;, and the rate/daily limits. Every other answer, including a final refusal such as &#x60;422 airbnb_rejected&#x60;, is stored and replayed.
@@ -165,7 +165,7 @@ module Repull
165
165
  end
166
166
 
167
167
  # Decline a booking request
168
- # Decline a pending Airbnb booking request (a reservation with status `pending`; find them with `GET /v1/reservations?status=pending`). `reason` must be one of Airbnb’s own decline reasons. `message` is required: Airbnb sends it to the guest with the decline (at most 500 characters). It is not defaulted — a canned message would put words in your mouth. Runs the same action as the Vanio dashboard’s Decline button. Airbnb confirms asynchronously; the reservation’s status moves, and `reservation.updated` fires, when its notification lands. Same channel and status rules as `POST /v1/reservations/{id}/accept`. 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.
168
+ # Decline a pending Airbnb booking request (a reservation with status `pending`; find them with `GET /v1/reservations?status=pending`). `reason` must be one of Airbnb’s own decline reasons. `message` is required: Airbnb sends it to the guest with the decline (at most 500 characters). It is not defaulted — a canned message would put words in your mouth. Airbnb confirms asynchronously; the reservation’s status moves, and `reservation.updated` fires, when its notification lands. Same channel and status rules as `POST /v1/reservations/{id}/accept`. 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.
169
169
  # @param id [Integer] Repull reservation id (from &#x60;GET /v1/reservations?status&#x3D;pending&#x60;) — not the Airbnb confirmation code.
170
170
  # @param decline_reservation_request_request [DeclineReservationRequestRequest]
171
171
  # @param [Hash] opts the optional parameters
@@ -177,7 +177,7 @@ module Repull
177
177
  end
178
178
 
179
179
  # Decline a booking request
180
- # Decline a pending Airbnb booking request (a reservation with status &#x60;pending&#x60;; find them with &#x60;GET /v1/reservations?status&#x3D;pending&#x60;). &#x60;reason&#x60; must be one of Airbnb’s own decline reasons. &#x60;message&#x60; is required: Airbnb sends it to the guest with the decline (at most 500 characters). It is not defaulted — a canned message would put words in your mouth. Runs the same action as the Vanio dashboard’s Decline button. Airbnb confirms asynchronously; the reservation’s status moves, and &#x60;reservation.updated&#x60; fires, when its notification lands. Same channel and status rules as &#x60;POST /v1/reservations/{id}/accept&#x60;. Send &#x60;Idempotency-Key&#x60;: a repeat with the same key replays the first response instead of acting twice (a &#x60;409 idempotency_key_in_use&#x60; while the first is still running). A 5xx, a &#x60;429 airbnb_rate_limited&#x60; or a &#x60;403 connection_reauth_required&#x60; is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
180
+ # Decline a pending Airbnb booking request (a reservation with status &#x60;pending&#x60;; find them with &#x60;GET /v1/reservations?status&#x3D;pending&#x60;). &#x60;reason&#x60; must be one of Airbnb’s own decline reasons. &#x60;message&#x60; is required: Airbnb sends it to the guest with the decline (at most 500 characters). It is not defaulted — a canned message would put words in your mouth. Airbnb confirms asynchronously; the reservation’s status moves, and &#x60;reservation.updated&#x60; fires, when its notification lands. Same channel and status rules as &#x60;POST /v1/reservations/{id}/accept&#x60;. Send &#x60;Idempotency-Key&#x60;: a repeat with the same key replays the first response instead of acting twice (a &#x60;409 idempotency_key_in_use&#x60; while the first is still running). A 5xx, a &#x60;429 airbnb_rate_limited&#x60; or a &#x60;403 connection_reauth_required&#x60; is not stored — nothing was done — so retrying with the same key reaches Airbnb again.
181
181
  # @param id [Integer] Repull reservation id (from &#x60;GET /v1/reservations?status&#x3D;pending&#x60;) — not the Airbnb confirmation code.
182
182
  # @param decline_reservation_request_request [DeclineReservationRequestRequest]
183
183
  # @param [Hash] opts the optional parameters
@@ -14,17 +14,23 @@ require 'date'
14
14
  require 'time'
15
15
 
16
16
  module Repull
17
- # A publish is not one call to Airbnb: it is up to eight independent ones (details, description, amenities, rooms, policies, photos, pricing, checkout_tasks), each of which can fail on its own. A PARTIAL publish is normal — what succeeded stays applied; there is no rollback.
17
+ # A publish is not one call to Airbnb: it is up to eight independent ones (details, description, amenities, rooms, policies, photos, pricing, checkout_tasks), each of which can fail on its own. A PARTIAL publish is normal — what succeeded stays applied; there is no rollback. **Content landing and the listing being live are two different answers.** `published` is about content; `live` is about whether the listing takes bookings. Read both.
18
18
  class AirbnbPublishResult < ApiModelBase
19
19
  # True only when EVERY attempted section reached Airbnb.
20
20
  attr_accessor :published
21
21
 
22
+ # Whether the listing is active and bookable on Airbnb — that is, whether activation was actually performed and succeeded. `published: true` with `live: false` is a real and common outcome: every content section landed, but the listing was never activated, because activation is skipped when instant-booking cannot be confirmed to be off. `warnings` says why. **Absent is not `false`.** The field is omitted entirely when activation was never part of the operation — publishing to an already-mapped Airbnb listing updates content and activates nothing, so there is nothing to report. Only treat the listing as not-live when `live` is present and false.
23
+ attr_accessor :live
24
+
22
25
  # Sections that landed on Airbnb.
23
26
  attr_accessor :sections
24
27
 
25
28
  # Per-section failures. Empty when `published` is true.
26
29
  attr_accessor :errors
27
30
 
31
+ # Steps that failed WITHOUT failing the publish — optional work the push carried on past, each in the push's own words. These used to be swallowed silently, so the only sign of one was a listing that was somehow not quite right afterwards. A publish can be `published: true` and still carry warnings; read them before concluding nothing needs doing.
32
+ attr_accessor :warnings
33
+
28
34
  # Set when the publish never started at all (no connection, address missing, subscription gate).
29
35
  attr_accessor :reason
30
36
 
@@ -35,8 +41,10 @@ module Repull
35
41
  def self.attribute_map
36
42
  {
37
43
  :'published' => :'published',
44
+ :'live' => :'live',
38
45
  :'sections' => :'sections',
39
46
  :'errors' => :'errors',
47
+ :'warnings' => :'warnings',
40
48
  :'reason' => :'reason',
41
49
  :'locked_fields' => :'lockedFields'
42
50
  }
@@ -56,8 +64,10 @@ module Repull
56
64
  def self.openapi_types
57
65
  {
58
66
  :'published' => :'Boolean',
67
+ :'live' => :'Boolean',
59
68
  :'sections' => :'Array<String>',
60
69
  :'errors' => :'Array<PublishSectionError>',
70
+ :'warnings' => :'Array<String>',
61
71
  :'reason' => :'String',
62
72
  :'locked_fields' => :'Array<String>'
63
73
  }
@@ -91,6 +101,10 @@ module Repull
91
101
  self.published = nil
92
102
  end
93
103
 
104
+ if attributes.key?(:'live')
105
+ self.live = attributes[:'live']
106
+ end
107
+
94
108
  if attributes.key?(:'sections')
95
109
  if (value = attributes[:'sections']).is_a?(Array)
96
110
  self.sections = value
@@ -107,6 +121,14 @@ module Repull
107
121
  self.errors = nil
108
122
  end
109
123
 
124
+ if attributes.key?(:'warnings')
125
+ if (value = attributes[:'warnings']).is_a?(Array)
126
+ self.warnings = value
127
+ end
128
+ else
129
+ self.warnings = nil
130
+ end
131
+
110
132
  if attributes.key?(:'reason')
111
133
  self.reason = attributes[:'reason']
112
134
  end
@@ -137,6 +159,10 @@ module Repull
137
159
  invalid_properties.push('invalid value for "errors", errors cannot be nil.')
138
160
  end
139
161
 
162
+ if @warnings.nil?
163
+ invalid_properties.push('invalid value for "warnings", warnings cannot be nil.')
164
+ end
165
+
140
166
  if @locked_fields.nil?
141
167
  invalid_properties.push('invalid value for "locked_fields", locked_fields cannot be nil.')
142
168
  end
@@ -151,6 +177,7 @@ module Repull
151
177
  return false if @published.nil?
152
178
  return false if @sections.nil?
153
179
  return false if @errors.nil?
180
+ return false if @warnings.nil?
154
181
  return false if @locked_fields.nil?
155
182
  true
156
183
  end
@@ -185,6 +212,16 @@ module Repull
185
212
  @errors = errors
186
213
  end
187
214
 
215
+ # Custom attribute writer method with validation
216
+ # @param [Object] warnings Value to be assigned
217
+ def warnings=(warnings)
218
+ if warnings.nil?
219
+ fail ArgumentError, 'warnings cannot be nil'
220
+ end
221
+
222
+ @warnings = warnings
223
+ end
224
+
188
225
  # Custom attribute writer method with validation
189
226
  # @param [Object] locked_fields Value to be assigned
190
227
  def locked_fields=(locked_fields)
@@ -201,8 +238,10 @@ module Repull
201
238
  return true if self.equal?(o)
202
239
  self.class == o.class &&
203
240
  published == o.published &&
241
+ live == o.live &&
204
242
  sections == o.sections &&
205
243
  errors == o.errors &&
244
+ warnings == o.warnings &&
206
245
  reason == o.reason &&
207
246
  locked_fields == o.locked_fields
208
247
  end
@@ -216,7 +255,7 @@ module Repull
216
255
  # Calculates hash code according to all attributes.
217
256
  # @return [Integer] Hash code
218
257
  def hash
219
- [published, sections, errors, reason, locked_fields].hash
258
+ [published, live, sections, errors, warnings, reason, locked_fields].hash
220
259
  end
221
260
 
222
261
  # Builds the object from hash