repull 0.2.20 → 0.2.22
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 +54 -15
- data/lib/repull/api/atlas_api.rb +1 -1
- data/lib/repull/api/availability_api.rb +3 -3
- data/lib/repull/api/billing_api.rb +1 -1
- data/lib/repull/api/booking_com_api.rb +5 -5
- data/lib/repull/api/connect_api.rb +137 -1
- data/lib/repull/api/conversations_api.rb +3 -3
- data/lib/repull/api/guests_api.rb +3 -3
- data/lib/repull/api/health_api.rb +1 -1
- data/lib/repull/api/kv_api.rb +1 -1
- data/lib/repull/api/listings_api.rb +207 -7
- data/lib/repull/api/markets_api.rb +1 -1
- data/lib/repull/api/migrate_api.rb +1 -1
- data/lib/repull/api/plumguide_api.rb +1 -1
- data/lib/repull/api/pricing_api.rb +1 -1
- data/lib/repull/api/properties_api.rb +9 -9
- data/lib/repull/api/quotes_api.rb +1 -1
- data/lib/repull/api/reservations_api.rb +71 -1
- data/lib/repull/api/reviews_api.rb +3 -3
- data/lib/repull/api/schema_api.rb +1 -1
- data/lib/repull/api/system_api.rb +1 -1
- data/lib/repull/api/vrbo_api.rb +1 -1
- data/lib/repull/api/webhooks_api.rb +1 -1
- data/lib/repull/api_client.rb +1 -1
- data/lib/repull/api_error.rb +1 -1
- data/lib/repull/api_model_base.rb +1 -1
- data/lib/repull/configuration.rb +1 -1
- data/lib/repull/models/accept_reservation_request200_response.rb +1 -1
- data/lib/repull/models/account_created_event.rb +1 -1
- data/lib/repull/models/account_created_payload.rb +1 -1
- data/lib/repull/models/account_disconnected_event.rb +1 -1
- data/lib/repull/models/account_disconnected_payload.rb +1 -1
- data/lib/repull/models/acknowledge_booking_reservations_request.rb +1 -1
- data/lib/repull/models/ai_operation.rb +1 -1
- data/lib/repull/models/ai_operation_completed_event.rb +1 -1
- data/lib/repull/models/ai_operation_completed_payload.rb +1 -1
- data/lib/repull/models/ai_operation_failed_event.rb +1 -1
- data/lib/repull/models/ai_operation_failed_payload.rb +1 -1
- data/lib/repull/models/ai_operation_failed_payload_error.rb +1 -1
- data/lib/repull/models/airbnb_account_freshness.rb +1 -1
- data/lib/repull/models/airbnb_alteration.rb +1 -1
- data/lib/repull/models/airbnb_alteration_create_request.rb +1 -1
- data/lib/repull/models/airbnb_amenity.rb +1 -1
- data/lib/repull/models/airbnb_availability_write_request.rb +1 -1
- data/lib/repull/models/airbnb_calendar_operation.rb +1 -1
- data/lib/repull/models/airbnb_connection.rb +3 -3
- data/lib/repull/models/airbnb_connection_accessibility_amenities_inner.rb +1 -1
- data/lib/repull/models/airbnb_connection_amenities_inner.rb +1 -1
- data/lib/repull/models/airbnb_connection_host.rb +1 -1
- data/lib/repull/models/airbnb_connection_response.rb +1 -1
- data/lib/repull/models/airbnb_connection_summary.rb +1 -1
- data/lib/repull/models/airbnb_content_write_response.rb +1 -1
- data/lib/repull/models/airbnb_data_freshness.rb +1 -1
- data/lib/repull/models/airbnb_description_write_request.rb +1 -1
- data/lib/repull/models/airbnb_description_write_request_description.rb +1 -1
- data/lib/repull/models/airbnb_listing.rb +4 -4
- data/lib/repull/models/airbnb_listing_action200_response.rb +1 -1
- data/lib/repull/models/airbnb_listing_action200_response_one_of.rb +1 -1
- data/lib/repull/models/airbnb_listing_action200_response_one_of1.rb +1 -1
- data/lib/repull/models/airbnb_listing_action_request.rb +1 -1
- data/lib/repull/models/airbnb_listing_details_response.rb +1 -1
- data/lib/repull/models/airbnb_listing_details_write_request.rb +1 -1
- data/lib/repull/models/airbnb_listing_details_write_request_check_in_option.rb +1 -1
- data/lib/repull/models/airbnb_listing_details_write_request_quiet_hours_inner.rb +1 -1
- data/lib/repull/models/airbnb_listing_lifecycle_response.rb +2 -2
- data/lib/repull/models/airbnb_listing_list_response.rb +1 -1
- data/lib/repull/models/airbnb_permits_response.rb +1 -1
- data/lib/repull/models/airbnb_permits_response_cached_inner.rb +1 -1
- data/lib/repull/models/airbnb_permits_write_request.rb +1 -1
- data/lib/repull/models/airbnb_permits_write_request_permits_inner.rb +1 -1
- data/lib/repull/models/airbnb_permits_write_request_permits_inner_answers_value.rb +1 -1
- data/lib/repull/models/airbnb_photo_position.rb +1 -1
- data/lib/repull/models/airbnb_pricing_write_request.rb +1 -1
- data/lib/repull/models/airbnb_pricing_write_request_records_inner.rb +1 -1
- data/lib/repull/models/airbnb_publish_result.rb +1 -1
- data/lib/repull/models/airbnb_reservation.rb +1 -1
- data/lib/repull/models/airbnb_reservation_action200_response.rb +1 -1
- data/lib/repull/models/airbnb_reservation_action_request.rb +1 -1
- data/lib/repull/models/airbnb_reservation_list_response.rb +1 -1
- data/lib/repull/models/airbnb_review.rb +1 -1
- data/lib/repull/models/airbnb_review_list_response.rb +1 -1
- data/lib/repull/models/airbnb_safety_disclosure.rb +1 -1
- data/lib/repull/models/airbnb_safety_disclosures_response.rb +1 -1
- data/lib/repull/models/airbnb_safety_disclosures_write_request.rb +1 -1
- data/lib/repull/models/airbnb_thread.rb +1 -1
- data/lib/repull/models/airbnb_thread_list_response.rb +1 -1
- data/lib/repull/models/airbnb_transaction.rb +216 -217
- data/lib/repull/models/airbnb_transaction_fees.rb +164 -0
- data/lib/repull/models/airbnb_transaction_payout.rb +47 -6
- data/lib/repull/models/alteration_change.rb +1 -1
- data/lib/repull/models/alteration_webhook_object.rb +1 -1
- data/lib/repull/models/availability_batch_write_request.rb +1 -1
- data/lib/repull/models/availability_write_request.rb +1 -1
- data/lib/repull/models/availability_write_result.rb +1 -1
- data/lib/repull/models/availability_write_result_synced.rb +1 -1
- data/lib/repull/models/availability_write_settings.rb +1 -1
- data/lib/repull/models/booking_availability_state_response.rb +1 -1
- data/lib/repull/models/booking_availability_update.rb +1 -1
- data/lib/repull/models/booking_availability_update_date_range.rb +1 -1
- data/lib/repull/models/booking_availability_update_request.rb +1 -1
- data/lib/repull/models/booking_availability_update_request_property_id.rb +1 -1
- data/lib/repull/models/booking_availability_update_request_updates_inner.rb +1 -1
- data/lib/repull/models/booking_connect_listing_option.rb +1 -1
- data/lib/repull/models/booking_connect_room.rb +1 -1
- data/lib/repull/models/booking_connect_rooms_response.rb +1 -1
- data/lib/repull/models/booking_conversation.rb +1 -1
- data/lib/repull/models/booking_pricing_rate_update.rb +1 -1
- data/lib/repull/models/booking_pricing_rate_update_date_range.rb +1 -1
- data/lib/repull/models/booking_pricing_rate_update_restrictions.rb +1 -1
- data/lib/repull/models/booking_pricing_response.rb +1 -1
- data/lib/repull/models/booking_pricing_update_request.rb +1 -1
- data/lib/repull/models/booking_pricing_update_response.rb +1 -1
- data/lib/repull/models/booking_property.rb +2 -1
- data/lib/repull/models/booking_property_action_request.rb +1 -1
- data/lib/repull/models/booking_property_action_response.rb +1 -1
- data/lib/repull/models/booking_property_listings_inner.rb +1 -1
- data/lib/repull/models/booking_publish_result.rb +1 -1
- data/lib/repull/models/booking_publish_section_error.rb +1 -1
- data/lib/repull/models/booking_rate_write_occupancy.rb +1 -1
- data/lib/repull/models/booking_rate_write_price_half.rb +1 -1
- data/lib/repull/models/booking_rate_write_restriction_half.rb +1 -1
- data/lib/repull/models/booking_rate_write_verification.rb +1 -1
- data/lib/repull/models/booking_rate_write_verification_row.rb +1 -1
- data/lib/repull/models/booking_reservation.rb +1 -1
- data/lib/repull/models/booking_reservation_room.rb +1 -1
- data/lib/repull/models/booking_restriction_request_row.rb +1 -1
- data/lib/repull/models/booking_restriction_verification.rb +1 -1
- data/lib/repull/models/booking_restriction_verification_row.rb +1 -1
- data/lib/repull/models/booking_restriction_verification_row_booking_value.rb +1 -1
- data/lib/repull/models/booking_restriction_verification_row_expected.rb +1 -1
- data/lib/repull/models/booking_room_mapping.rb +1 -1
- data/lib/repull/models/booking_rooms_rates_response.rb +1 -1
- data/lib/repull/models/booking_rooms_rates_response_rooms_inner.rb +1 -1
- data/lib/repull/models/booking_rooms_rates_response_rooms_inner_rates_inner.rb +1 -1
- data/lib/repull/models/booking_setup_request.rb +1 -1
- data/lib/repull/models/booking_setup_request_legal_entity.rb +1 -1
- data/lib/repull/models/booking_upstream_failure.rb +1 -1
- data/lib/repull/models/booking_verify_hotel_request.rb +1 -1
- data/lib/repull/models/booking_verify_hotel_response.rb +1 -1
- data/lib/repull/models/bulk_pricing_failure.rb +1 -1
- data/lib/repull/models/bulk_pricing_item.rb +1 -1
- data/lib/repull/models/bulk_pricing_request.rb +1 -1
- data/lib/repull/models/bulk_pricing_response.rb +1 -1
- data/lib/repull/models/calendar_day.rb +1 -1
- data/lib/repull/models/calendar_response.rb +1 -1
- data/lib/repull/models/calendar_updated_event.rb +1 -1
- data/lib/repull/models/calendar_updated_payload.rb +1 -1
- data/lib/repull/models/calendar_updated_payload_range.rb +1 -1
- data/lib/repull/models/cancel_reservation200_response.rb +259 -0
- data/lib/repull/models/{airbnb_transaction_guest_breakdown.rb → cancel_reservation200_response_pms.rb} +28 -29
- data/lib/repull/models/cancel_reservation200_response_pms_errors_inner.rb +165 -0
- data/lib/repull/models/cancel_reservation_request.rb +148 -0
- data/lib/repull/models/channel_market_state_item.rb +2 -2
- data/lib/repull/models/check_migration_cutover200_response.rb +1 -1
- data/lib/repull/models/check_migration_cutover_request.rb +1 -1
- data/lib/repull/models/check_migration_cutover_request_reservations_inner.rb +1 -1
- data/lib/repull/models/clear_kv200_response.rb +1 -1
- data/lib/repull/models/connect_host.rb +1 -1
- data/lib/repull/models/connect_provider.rb +1 -1
- data/lib/repull/models/connect_provider_list_response.rb +1 -1
- data/lib/repull/models/connect_session.rb +1 -1
- data/lib/repull/models/connect_status.rb +1 -1
- data/lib/repull/models/connect_status_accounts_inner.rb +1 -1
- data/lib/repull/models/connection.rb +1 -1
- data/lib/repull/models/connection_list_response.rb +11 -2
- data/lib/repull/models/conversation.rb +1 -1
- data/lib/repull/models/conversation_detail.rb +1 -1
- data/lib/repull/models/conversation_guest.rb +1 -1
- data/lib/repull/models/conversation_guest_contact.rb +1 -1
- data/lib/repull/models/conversation_host.rb +1 -1
- data/lib/repull/models/conversation_list_response.rb +1 -1
- data/lib/repull/models/conversation_message_attachment.rb +1 -1
- data/lib/repull/models/create_airbnb_listing_room_request.rb +1 -1
- data/lib/repull/models/create_airbnb_offer_request.rb +1 -1
- data/lib/repull/models/create_airbnb_offer_request_guest_details.rb +1 -1
- data/lib/repull/models/create_billing_checkout_request.rb +1 -1
- data/lib/repull/models/create_booking_webhook_request.rb +1 -1
- data/lib/repull/models/create_connect_session_request.rb +1 -1
- data/lib/repull/models/create_connect_session_request_copy.rb +1 -1
- data/lib/repull/models/create_connect_session_request_workspace.rb +1 -1
- data/lib/repull/models/create_connection_request.rb +1 -1
- data/lib/repull/models/create_conversation_special_offer201_response.rb +1 -1
- data/lib/repull/models/create_conversation_special_offer201_response_guests.rb +1 -1
- data/lib/repull/models/create_conversation_special_offer_request.rb +1 -1
- data/lib/repull/models/create_conversation_special_offer_request_guests.rb +1 -1
- data/lib/repull/models/create_webhook_request.rb +1 -1
- data/lib/repull/models/custom_schema.rb +1 -1
- data/lib/repull/models/custom_schema_create.rb +1 -1
- data/lib/repull/models/custom_schema_create_response.rb +1 -1
- data/lib/repull/models/custom_schema_delete_response.rb +1 -1
- data/lib/repull/models/custom_schema_list_response.rb +1 -1
- data/lib/repull/models/custom_schema_summary.rb +1 -1
- data/lib/repull/models/custom_schema_update.rb +1 -1
- data/lib/repull/models/decline_reservation_request_request.rb +1 -1
- data/lib/repull/models/delete_airbnb_listing_photo200_response.rb +1 -1
- data/lib/repull/models/delete_airbnb_listing_room200_response.rb +1 -1
- data/lib/repull/models/delete_connection200_response.rb +1 -1
- data/lib/repull/models/delete_kv200_response.rb +1 -1
- data/lib/repull/models/delete_migration200_response.rb +1 -1
- data/lib/repull/models/delete_migration200_response_data.rb +1 -1
- data/lib/repull/models/error.rb +1 -1
- data/lib/repull/models/error_error.rb +1 -1
- data/lib/repull/models/error_error_support.rb +1 -1
- data/lib/repull/models/get_airbnb_alteration200_response.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response_data.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_advance_notice.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_booking_window.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_cancellation.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_cancellation_non_refundable.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_in.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_in_start.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_check_out.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_instant_book.rb +1 -1
- data/lib/repull/models/get_airbnb_booking_settings200_response_data_preparation_time.rb +1 -1
- data/lib/repull/models/get_airbnb_checkin_guide200_response.rb +1 -1
- data/lib/repull/models/get_airbnb_listing_details200_response.rb +1 -1
- data/lib/repull/models/get_airbnb_listing_quality200_response.rb +1 -1
- data/lib/repull/models/get_airbnb_listing_settings200_response.rb +1 -1
- data/lib/repull/models/get_airbnb_offer200_response.rb +1 -1
- data/lib/repull/models/get_airbnb_thread200_response.rb +1 -1
- data/lib/repull/models/get_health200_response.rb +1 -1
- data/lib/repull/models/get_listing_markups200_response.rb +170 -0
- data/lib/repull/models/get_listing_markups200_response_airbnb_inner.rb +159 -0
- data/lib/repull/models/get_listing_markups200_response_booking_inner.rb +171 -0
- data/lib/repull/models/get_migration200_response.rb +1 -1
- data/lib/repull/models/get_migration_channel_map200_response.rb +1 -1
- data/lib/repull/models/get_migration_report200_response.rb +1 -1
- data/lib/repull/models/get_usage_logs200_response.rb +1 -1
- data/lib/repull/models/get_usage_logs200_response_data_inner.rb +1 -1
- data/lib/repull/models/get_usage_logs200_response_pagination.rb +1 -1
- data/lib/repull/models/get_usage_summary200_response.rb +14 -5
- data/lib/repull/models/get_usage_summary200_response_breakdown_inner.rb +1 -1
- data/lib/repull/models/get_usage_summary200_response_limits.rb +1 -1
- data/lib/repull/models/get_usage_summary200_response_remaining.rb +1 -1
- data/lib/repull/models/get_usage_summary200_response_status_distribution.rb +1 -1
- data/lib/repull/models/get_usage_summary200_response_timeline_inner.rb +1 -1
- data/lib/repull/models/get_usage_summary200_response_totals.rb +1 -1
- data/lib/repull/models/get_usage_summary200_response_used.rb +1 -1
- data/lib/repull/models/get_usage_tier200_response.rb +1 -1
- data/lib/repull/models/get_usage_tier200_response_limits.rb +1 -1
- data/lib/repull/models/get_usage_tier200_response_remaining.rb +1 -1
- data/lib/repull/models/get_usage_tier200_response_used.rb +1 -1
- data/lib/repull/models/guest.rb +1 -1
- data/lib/repull/models/guest_contact.rb +1 -1
- data/lib/repull/models/guest_create_request.rb +1 -1
- data/lib/repull/models/guest_create_response.rb +1 -1
- data/lib/repull/models/guest_create_response_contacts_inner.rb +1 -1
- data/lib/repull/models/guest_flag.rb +2 -2
- data/lib/repull/models/guest_list_response.rb +1 -1
- data/lib/repull/models/guest_note.rb +1 -1
- data/lib/repull/models/guest_profile.rb +2 -2
- data/lib/repull/models/guest_reservations_summary.rb +1 -1
- data/lib/repull/models/inquiry_created_event.rb +1 -1
- data/lib/repull/models/inquiry_created_payload.rb +1 -1
- data/lib/repull/models/inquiry_updated_event.rb +1 -1
- data/lib/repull/models/inquiry_updated_payload.rb +1 -1
- data/lib/repull/models/inquiry_webhook_object.rb +1 -1
- data/lib/repull/models/inquiry_webhook_object_expected_payout.rb +1 -1
- data/lib/repull/models/inquiry_webhook_object_guests.rb +1 -1
- data/lib/repull/models/list_airbnb_alterations200_response.rb +1 -1
- data/lib/repull/models/list_airbnb_listing_amenities200_response.rb +1 -1
- data/lib/repull/models/list_airbnb_listing_amenities200_response_data.rb +1 -1
- data/lib/repull/models/list_airbnb_listing_permits200_response.rb +1 -1
- data/lib/repull/models/list_airbnb_listing_safety_disclosures200_response.rb +1 -1
- data/lib/repull/models/list_airbnb_thread_messages200_response.rb +1 -1
- data/lib/repull/models/list_airbnb_thread_messages200_response_data_inner.rb +1 -1
- data/lib/repull/models/list_airbnb_thread_messages200_response_pagination.rb +1 -1
- data/lib/repull/models/list_airbnb_transactions200_response.rb +28 -2
- data/lib/repull/models/list_booking_reservations200_response.rb +1 -1
- data/lib/repull/models/list_inquiries200_response.rb +1 -1
- data/lib/repull/models/list_inquiries200_response_data_inner.rb +1 -1
- data/lib/repull/models/list_inquiries200_response_data_inner_expected_payout.rb +1 -1
- data/lib/repull/models/list_inquiries200_response_data_inner_guests.rb +1 -1
- data/lib/repull/models/list_kv200_response.rb +1 -1
- data/lib/repull/models/list_kv200_response_data_inner.rb +1 -1
- data/lib/repull/models/list_kv200_response_pagination.rb +1 -1
- data/lib/repull/models/list_listing_units200_response.rb +167 -0
- data/lib/repull/models/list_listing_units200_response_data_inner.rb +207 -0
- data/lib/repull/models/list_migrations200_response.rb +1 -1
- data/lib/repull/models/listing.rb +14 -2
- data/lib/repull/models/listing_active_request.rb +1 -1
- data/lib/repull/models/listing_active_response.rb +1 -1
- data/lib/repull/models/listing_address.rb +1 -1
- data/lib/repull/models/listing_address_readiness.rb +1 -1
- data/lib/repull/models/listing_amenity.rb +1 -1
- data/lib/repull/models/listing_channel.rb +1 -1
- data/lib/repull/models/listing_comp.rb +1 -1
- data/lib/repull/models/listing_comp_nightly.rb +1 -1
- data/lib/repull/models/listing_comp_ratings.rb +1 -1
- data/lib/repull/models/listing_comps_response.rb +1 -1
- data/lib/repull/models/listing_content.rb +1 -1
- data/lib/repull/models/listing_content_update_request.rb +1 -1
- data/lib/repull/models/listing_content_update_request_address.rb +1 -1
- data/lib/repull/models/listing_content_update_request_amenities.rb +1 -1
- data/lib/repull/models/listing_content_update_request_amenities_one_of_inner.rb +1 -1
- data/lib/repull/models/listing_content_update_request_checkout_tasks_inner.rb +1 -1
- data/lib/repull/models/listing_content_update_request_details.rb +1 -1
- data/lib/repull/models/listing_content_update_request_occupancy.rb +1 -1
- data/lib/repull/models/listing_content_update_request_photos_inner.rb +1 -1
- data/lib/repull/models/listing_content_update_request_photos_inner_one_of.rb +1 -1
- data/lib/repull/models/listing_content_update_request_policies.rb +1 -1
- data/lib/repull/models/listing_content_update_request_pricing.rb +1 -1
- data/lib/repull/models/listing_content_update_request_rooms_inner.rb +1 -1
- data/lib/repull/models/listing_content_update_request_rooms_inner_beds_inner.rb +1 -1
- data/lib/repull/models/listing_content_update_response.rb +1 -1
- data/lib/repull/models/listing_create_request.rb +1 -1
- data/lib/repull/models/listing_create_response.rb +1 -1
- data/lib/repull/models/listing_created_event.rb +1 -1
- data/lib/repull/models/listing_created_payload.rb +1 -1
- data/lib/repull/models/listing_created_payload_address.rb +1 -1
- data/lib/repull/models/listing_deleted_event.rb +1 -1
- data/lib/repull/models/listing_deleted_payload.rb +1 -1
- data/lib/repull/models/listing_details.rb +1 -1
- data/lib/repull/models/listing_generate_content_request.rb +1 -1
- data/lib/repull/models/listing_generate_content_response.rb +1 -1
- data/lib/repull/models/listing_list_response.rb +11 -2
- data/lib/repull/models/listing_market_state_request.rb +1 -1
- data/lib/repull/models/listing_market_state_response.rb +1 -1
- data/lib/repull/models/listing_photo.rb +1 -1
- data/lib/repull/models/listing_photo_delete_request.rb +1 -1
- data/lib/repull/models/listing_photo_delete_response.rb +1 -1
- data/lib/repull/models/listing_photo_upload_url_request.rb +19 -3
- data/lib/repull/models/listing_photo_upload_url_response.rb +16 -6
- data/lib/repull/models/listing_photos_response.rb +1 -1
- data/lib/repull/models/listing_pricing_apply_request.rb +1 -1
- data/lib/repull/models/listing_pricing_apply_response.rb +1 -1
- data/lib/repull/models/listing_pricing_history_entry.rb +1 -1
- data/lib/repull/models/listing_pricing_history_response.rb +1 -1
- data/lib/repull/models/listing_pricing_recommendation.rb +2 -2
- data/lib/repull/models/listing_pricing_response.rb +1 -1
- data/lib/repull/models/listing_pricing_response_comp_summary.rb +1 -1
- data/lib/repull/models/listing_pricing_response_date_range.rb +1 -1
- data/lib/repull/models/listing_pricing_response_listing.rb +1 -1
- data/lib/repull/models/listing_pricing_strategy.rb +1 -1
- data/lib/repull/models/listing_pricing_strategy_input.rb +1 -1
- data/lib/repull/models/listing_publish_airbnb_request.rb +1 -1
- data/lib/repull/models/listing_publish_airbnb_response.rb +1 -1
- data/lib/repull/models/listing_publish_booking_request.rb +1 -1
- data/lib/repull/models/listing_publish_booking_response.rb +1 -1
- data/lib/repull/models/listing_publish_status_channel.rb +1 -1
- data/lib/repull/models/listing_publish_status_connection.rb +1 -1
- data/lib/repull/models/listing_publish_status_response.rb +1 -1
- data/lib/repull/models/listing_pull_airbnb_request.rb +1 -1
- data/lib/repull/models/listing_pull_response.rb +1 -1
- data/lib/repull/models/listing_quality_tier.rb +1 -1
- data/lib/repull/models/listing_reactivated_event.rb +1 -1
- data/lib/repull/models/listing_segment.rb +1 -1
- data/lib/repull/models/listing_segment_recommendation.rb +1 -1
- data/lib/repull/models/listing_segments_response.rb +1 -1
- data/lib/repull/models/listing_segments_response_scope.rb +1 -1
- data/lib/repull/models/listing_status_batch_request.rb +1 -1
- data/lib/repull/models/listing_status_batch_response.rb +1 -1
- data/lib/repull/models/listing_suspended_event.rb +1 -1
- data/lib/repull/models/listing_suspension_payload.rb +1 -1
- data/lib/repull/models/listing_units_inner.rb +204 -0
- data/lib/repull/models/listing_updated_event.rb +1 -1
- data/lib/repull/models/listing_updated_payload.rb +1 -1
- data/lib/repull/models/listing_webhook_object.rb +1 -1
- data/lib/repull/models/listing_webhook_object_address.rb +1 -1
- data/lib/repull/models/listing_webhook_object_channels_inner.rb +1 -1
- data/lib/repull/models/map_airbnb_listing_request.rb +1 -1
- data/lib/repull/models/map_airbnb_listing_response.rb +1 -1
- data/lib/repull/models/map_booking_room_request.rb +1 -1
- data/lib/repull/models/map_booking_room_response.rb +17 -6
- data/lib/repull/models/map_connect_booking_rooms_request.rb +1 -1
- data/lib/repull/models/map_connect_booking_rooms_response.rb +29 -8
- data/lib/repull/models/market_browse_category.rb +1 -1
- data/lib/repull/models/market_browse_entry.rb +1 -1
- data/lib/repull/models/market_browse_featured.rb +1 -1
- data/lib/repull/models/market_browse_response.rb +1 -1
- data/lib/repull/models/market_calendar_day.rb +1 -1
- data/lib/repull/models/market_calendar_day_events_inner.rb +1 -1
- data/lib/repull/models/market_calendar_response.rb +1 -1
- data/lib/repull/models/market_detail_response.rb +1 -1
- data/lib/repull/models/market_detail_response_price_distribution_inner.rb +1 -1
- data/lib/repull/models/market_detail_response_property_type_mix_inner.rb +1 -1
- data/lib/repull/models/market_detail_response_supply_trend_inner.rb +1 -1
- data/lib/repull/models/market_detail_response_top_comps.rb +1 -1
- data/lib/repull/models/market_event.rb +1 -1
- data/lib/repull/models/market_my_listing.rb +1 -1
- data/lib/repull/models/market_summary.rb +1 -1
- data/lib/repull/models/market_top_comp.rb +1 -1
- data/lib/repull/models/markets_overview_response.rb +1 -1
- data/lib/repull/models/markets_overview_response_browse.rb +1 -1
- data/lib/repull/models/markets_overview_response_subscriptions.rb +1 -1
- data/lib/repull/models/markets_overview_response_totals.rb +1 -1
- data/lib/repull/models/message.rb +3 -3
- data/lib/repull/models/message_list_response.rb +1 -1
- data/lib/repull/models/migration.rb +1 -1
- data/lib/repull/models/migration_channel_map.rb +1 -1
- data/lib/repull/models/migration_channel_map_listings_inner.rb +1 -1
- data/lib/repull/models/migration_channel_map_listings_inner_airbnb.rb +1 -1
- data/lib/repull/models/migration_channel_map_listings_inner_booking.rb +1 -1
- data/lib/repull/models/migration_channel_map_sources_inner.rb +1 -1
- data/lib/repull/models/migration_completed_event.rb +1 -1
- data/lib/repull/models/migration_connections_inner.rb +1 -1
- data/lib/repull/models/migration_counts.rb +1 -1
- data/lib/repull/models/migration_cutover_check.rb +1 -1
- data/lib/repull/models/migration_cutover_check_mismatched_inner.rb +1 -1
- data/lib/repull/models/migration_failed_event.rb +1 -1
- data/lib/repull/models/migration_import_payload.rb +1 -1
- data/lib/repull/models/migration_import_payload_results_inner.rb +1 -1
- data/lib/repull/models/migration_import_run.rb +1 -1
- data/lib/repull/models/migration_import_run_results_inner.rb +1 -1
- data/lib/repull/models/migration_report.rb +1 -1
- data/lib/repull/models/migration_report_issues_inner.rb +1 -1
- data/lib/repull/models/migration_reservation_ref.rb +1 -1
- data/lib/repull/models/pagination.rb +1 -1
- data/lib/repull/models/payment_completed_event.rb +1 -1
- data/lib/repull/models/payment_completed_payload.rb +1 -1
- data/lib/repull/models/payment_refunded_event.rb +1 -1
- data/lib/repull/models/payment_refunded_payload.rb +1 -1
- data/lib/repull/models/payment_webhook_object.rb +1 -1
- data/lib/repull/models/payout_completed_event.rb +281 -0
- data/lib/repull/models/payout_completed_payload.rb +257 -0
- data/lib/repull/models/plan_notice.rb +283 -0
- data/lib/repull/models/plumguide_listing.rb +1 -1
- data/lib/repull/models/plumguide_listing_list_response.rb +1 -1
- data/lib/repull/models/preapprove_conversation201_response.rb +1 -1
- data/lib/repull/models/preapprove_conversation_request.rb +1 -1
- data/lib/repull/models/property.rb +1 -1
- data/lib/repull/models/property_availability.rb +1 -1
- data/lib/repull/models/property_availability_coverage.rb +1 -1
- data/lib/repull/models/property_availability_day.rb +41 -5
- data/lib/repull/models/property_list_response.rb +11 -2
- data/lib/repull/models/publish_section_error.rb +1 -1
- data/lib/repull/models/quote.rb +1 -1
- data/lib/repull/models/quote_pricing.rb +1 -1
- data/lib/repull/models/reorder_airbnb_listing_photos200_response.rb +1 -1
- data/lib/repull/models/reorder_airbnb_listing_photos200_response_data.rb +1 -1
- data/lib/repull/models/reorder_airbnb_listing_photos_request.rb +1 -1
- data/lib/repull/models/replay_webhook_delivery_request.rb +1 -1
- data/lib/repull/models/reply_booking_review200_response.rb +1 -1
- data/lib/repull/models/reply_booking_review_request.rb +1 -1
- data/lib/repull/models/reply_to_review201_response.rb +1 -1
- data/lib/repull/models/reply_to_review_request.rb +1 -1
- data/lib/repull/models/repull_ping_event.rb +1 -1
- data/lib/repull/models/repull_ping_payload.rb +1 -1
- data/lib/repull/models/reservation.rb +12 -2
- data/lib/repull/models/reservation_alteration_created_event.rb +1 -1
- data/lib/repull/models/reservation_alteration_created_payload.rb +1 -1
- data/lib/repull/models/reservation_alteration_responded_event.rb +1 -1
- data/lib/repull/models/reservation_alteration_responded_payload.rb +1 -1
- data/lib/repull/models/reservation_cancelled_event.rb +1 -1
- data/lib/repull/models/reservation_cancelled_payload.rb +1 -1
- data/lib/repull/models/reservation_create_request.rb +1 -1
- data/lib/repull/models/reservation_create_response.rb +27 -7
- data/lib/repull/models/reservation_create_response_pms.rb +180 -0
- data/lib/repull/models/reservation_create_response_unit.rb +158 -0
- data/lib/repull/models/reservation_created_event.rb +1 -1
- data/lib/repull/models/reservation_created_payload.rb +1 -1
- data/lib/repull/models/reservation_financials.rb +1 -1
- data/lib/repull/models/reservation_guest_financials.rb +1 -1
- data/lib/repull/models/reservation_guest_input.rb +1 -1
- data/lib/repull/models/reservation_host_financials.rb +1 -1
- data/lib/repull/models/reservation_list_response.rb +1 -1
- data/lib/repull/models/reservation_message_received_event.rb +1 -1
- data/lib/repull/models/reservation_message_received_payload.rb +1 -1
- data/lib/repull/models/reservation_message_received_payload_from.rb +1 -1
- data/lib/repull/models/reservation_message_sent_event.rb +281 -0
- data/lib/repull/models/reservation_message_sent_payload.rb +263 -0
- data/lib/repull/models/reservation_message_sent_payload_from.rb +158 -0
- data/lib/repull/models/{airbnb_transaction_host_breakdown.rb → reservation_message_updated_event.rb} +128 -93
- data/lib/repull/models/reservation_message_updated_payload.rb +244 -0
- data/lib/repull/models/reservation_message_updated_payload_from.rb +157 -0
- data/lib/repull/models/reservation_money_line.rb +1 -1
- data/lib/repull/models/reservation_occupancy.rb +1 -1
- data/lib/repull/models/reservation_primary_guest.rb +1 -1
- data/lib/repull/models/reservation_request_created_event.rb +1 -1
- data/lib/repull/models/reservation_request_created_payload.rb +1 -1
- data/lib/repull/models/reservation_request_updated_event.rb +1 -1
- data/lib/repull/models/reservation_request_updated_payload.rb +1 -1
- data/lib/repull/models/reservation_unit.rb +159 -0
- data/lib/repull/models/reservation_update_request.rb +1 -1
- data/lib/repull/models/reservation_update_response.rb +1 -1
- data/lib/repull/models/reservation_updated_event.rb +1 -1
- data/lib/repull/models/reservation_updated_payload.rb +1 -1
- data/lib/repull/models/reservation_webhook_object.rb +1 -1
- data/lib/repull/models/respond_airbnb_review_request.rb +1 -1
- data/lib/repull/models/review.rb +2 -2
- data/lib/repull/models/review_category.rb +1 -1
- data/lib/repull/models/review_created_event.rb +1 -1
- data/lib/repull/models/review_created_payload.rb +1 -1
- data/lib/repull/models/review_list_response.rb +1 -1
- data/lib/repull/models/review_responded_event.rb +1 -1
- data/lib/repull/models/review_responded_payload.rb +1 -1
- data/lib/repull/models/review_response.rb +1 -1
- data/lib/repull/models/review_webhook_object.rb +1 -1
- data/lib/repull/models/rotate_webhook_secret200_response.rb +1 -1
- data/lib/repull/models/run_migration_import202_response.rb +1 -1
- data/lib/repull/models/run_migration_import202_response_data.rb +1 -1
- data/lib/repull/models/run_migration_import202_response_data_queued_inner.rb +1 -1
- data/lib/repull/models/run_migration_import_request.rb +1 -1
- data/lib/repull/models/select_connect_provider_request.rb +1 -1
- data/lib/repull/models/select_provider_response.rb +1 -1
- data/lib/repull/models/send_airbnb_message201_response.rb +1 -1
- data/lib/repull/models/send_airbnb_message_request.rb +1 -1
- data/lib/repull/models/send_booking_message_request.rb +1 -1
- data/lib/repull/models/send_message_attachment.rb +1 -1
- data/lib/repull/models/send_message_part.rb +1 -1
- data/lib/repull/models/send_message_request.rb +1 -1
- data/lib/repull/models/send_message_response.rb +1 -1
- data/lib/repull/models/sent_attachment.rb +1 -1
- data/lib/repull/models/set_airbnb_listing_cover_photo200_response.rb +1 -1
- data/lib/repull/models/set_airbnb_listing_cover_photo200_response_data.rb +1 -1
- data/lib/repull/models/set_airbnb_listing_cover_photo_request.rb +1 -1
- data/lib/repull/models/set_kv_request.rb +1 -1
- data/lib/repull/models/set_listing_markup_request.rb +235 -0
- data/lib/repull/models/submit_beds24_credentials200_response.rb +1 -1
- data/lib/repull/models/submit_beds24_credentials_request.rb +1 -1
- data/lib/repull/models/submit_bookingsync_credentials_request.rb +1 -1
- data/lib/repull/models/submit_cloudbeds_credentials200_response.rb +204 -0
- data/lib/repull/models/submit_cloudbeds_credentials200_response_account_info.rb +170 -0
- data/lib/repull/models/submit_cloudbeds_credentials200_response_webhooks.rb +158 -0
- data/lib/repull/models/submit_cloudbeds_credentials_request.rb +174 -0
- data/lib/repull/models/submit_cloudbeds_credentials_request_credentials.rb +178 -0
- data/lib/repull/models/submit_guesty_credentials_request.rb +1 -1
- data/lib/repull/models/submit_hospitable_credentials_request.rb +1 -1
- data/lib/repull/models/submit_hostaway_credentials_request.rb +1 -1
- data/lib/repull/models/submit_igms_credentials_request.rb +1 -1
- data/lib/repull/models/submit_lodgify_credentials_request.rb +1 -1
- data/lib/repull/models/submit_mews_credentials200_response.rb +204 -0
- data/lib/repull/models/submit_mews_credentials200_response_account_info.rb +170 -0
- data/lib/repull/models/submit_mews_credentials_request.rb +174 -0
- data/lib/repull/models/submit_mews_credentials_request_credentials.rb +212 -0
- data/lib/repull/models/submit_ownerrez_credentials_request.rb +1 -1
- data/lib/repull/models/submit_smoobu_credentials_request.rb +1 -1
- data/lib/repull/models/submit_vrbo_credentials_request.rb +1 -1
- data/lib/repull/models/sync_airbnb_transactions200_response.rb +34 -6
- data/lib/repull/models/sync_airbnb_transactions200_response_accounts_inner.rb +254 -0
- data/lib/repull/models/sync_airbnb_transactions200_response_accounts_inner_error.rb +191 -0
- data/lib/repull/models/sync_airbnb_transactions_request.rb +4 -3
- data/lib/repull/models/test_webhook_request.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings200_response.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings200_response_data.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings_request.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings_request_advance_notice.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings_request_booking_window.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings_request_cancellation.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings_request_cancellation_non_refundable.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings_request_check_in.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings_request_check_out.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings_request_instant_book.rb +1 -1
- data/lib/repull/models/update_airbnb_booking_settings_request_preparation_time.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_amenities200_response.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_amenities200_response_data.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_amenities_request.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_amenities_request_accessibility_amenities_inner.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_amenities_request_amenities_inner.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_permits200_response.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_photo200_response.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_photo_request.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_room200_response.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_room_request.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_room_request_beds_inner.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_room_request_room_amenities_inner.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_room_request_room_amenities_inner_value.rb +1 -1
- data/lib/repull/models/update_airbnb_listing_safety_disclosures200_response.rb +1 -1
- data/lib/repull/models/update_airbnb_message_request.rb +1 -1
- data/lib/repull/models/update_booking_charges_request.rb +1 -1
- data/lib/repull/models/update_booking_content_request.rb +1 -1
- data/lib/repull/models/update_booking_content_request_content_data_inner.rb +1 -1
- data/lib/repull/models/update_booking_content_request_photos_inner.rb +1 -1
- data/lib/repull/models/update_listing_pricing_strategy200_response.rb +1 -1
- data/lib/repull/models/update_webhook_request.rb +1 -1
- data/lib/repull/models/upload_airbnb_listing_photos_request.rb +1 -1
- data/lib/repull/models/upload_airbnb_listing_photos_request_photos_inner.rb +1 -1
- data/lib/repull/models/upload_airbnb_listing_photos_request_photos_inner_listing_id.rb +1 -1
- data/lib/repull/models/usage_quota_warning_event.rb +1 -1
- data/lib/repull/models/usage_quota_warning_payload.rb +1 -1
- data/lib/repull/models/usage_quota_warning_payload_top_operation.rb +1 -1
- data/lib/repull/models/vrbo_listing.rb +1 -1
- data/lib/repull/models/vrbo_reservation.rb +1 -1
- data/lib/repull/models/vrbo_reservation_list_response.rb +1 -1
- data/lib/repull/models/webhook_delivery.rb +1 -1
- data/lib/repull/models/webhook_delivery_detail.rb +1 -1
- data/lib/repull/models/webhook_delivery_list_response.rb +1 -1
- data/lib/repull/models/webhook_event.rb +7 -1
- data/lib/repull/models/webhook_event_account.rb +1 -1
- data/lib/repull/models/webhook_event_catalog.rb +1 -1
- data/lib/repull/models/webhook_event_catalog_domains_inner.rb +1 -1
- data/lib/repull/models/webhook_event_catalog_entry.rb +1 -1
- data/lib/repull/models/webhook_event_type.rb +5 -2
- data/lib/repull/models/webhook_list_response.rb +1 -1
- data/lib/repull/models/webhook_subscription.rb +1 -1
- data/lib/repull/models/withdraw_conversation_special_offer200_response.rb +1 -1
- data/lib/repull/version.rb +2 -2
- data/lib/repull.rb +36 -3
- data/openapi/v1.json +1672 -270
- metadata +37 -4
data/openapi/v1.json
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
"version": "1.0.0",
|
|
6
6
|
"description": "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.\n\n## Designed for AI agents\nEvery 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:\n- `error.code` \u2014 stable string identifier (e.g. `invalid_params`, `rate_limit_exceeded`)\n- `error.message` \u2014 human-readable cause\n- `error.fix` \u2014 exact recovery steps (e.g. \"Pass `check_in_after` as ISO 8601: `?check_in_after=2026-01-15`\")\n- `error.docs_url` \u2014 link to the canonical write-up at `https://repull.dev/docs/errors/{code}`\n- `error.request_id` \u2014 id to correlate with server-side logs\n- `error.field` / `error.value_received` / `error.valid_values` / `error.did_you_mean` \u2014 when the error is parameter-specific\n- `error.retry_after` \u2014 seconds to wait before retrying (rate-limit + transient upstream)\n\n`Access-Control-Expose-Headers` lists `x-request-id` and the `X-RateLimit-*` family so browsers can read them on cross-origin responses.\n\n## Quick Start\n1. Get an API key at https://repull.dev/dashboard\n2. Connect a PMS: `POST /v1/connect/{provider}`\n3. List properties: `GET /v1/properties`\n4. Get reservations: `GET /v1/reservations`\n\n## Authentication\nAll requests require a Bearer token:\n```\nAuthorization: Bearer sk_live_YOUR_API_KEY\n```\n\n## Request Correlation (X-Request-ID)\nEvery response carries an `X-Request-ID` header, e.g. `X-Request-ID: req_01HXY...`. Include this id in support tickets and bug reports \u2014 we can trace the full request lifecycle (auth, rate limit, handler, downstream calls, log row) from a single id.\n\nYou 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}$`.\n\nThe 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.\n\n## Rate Limits\nThe public API enforces a per-API-key sliding-window rate limit on top of the per-tier monthly + daily-AI quotas.\n\n**Default policy:** 600 requests per 60 seconds, per API key. Sliding window \u2014 there is no fixed-minute boundary you can burst across.\n\nEvery response includes:\n\n| Header | Meaning |\n|---|---|\n| `X-RateLimit-Limit` | Requests permitted in the current window. |\n| `X-RateLimit-Remaining` | Requests left in the current window after this call. |\n| `X-RateLimit-Reset` | Unix epoch (seconds) when the next slot opens. |\n| `X-RateLimit-Policy` | Machine-readable policy descriptor, e.g. `600;w=60`. |\n| `Retry-After` | Seconds to wait before retrying. **Only present on 429 responses.** |\n\n**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 \u2014 never a tight loop.\n\nRecommended backoff:\n```\nsleep_ms = (Retry-After * 1000) + random(0..250)\n```\n\nMonthly + daily-AI tier quotas (`free`, `starter`, `custom`) are enforced separately and also surface as 429s; they include `tier`, `scope`, and `resetsAt` fields.\n\n## Plan Limits (402 \u2014 `listings_limit_exceeded`)\nThe Repull API also enforces a per-tier cap on **active listings**:\n\n| Tier | Active listings cap |\n|---|---|\n| `free` | 3 |\n| `starter` | 50 |\n| `custom` | unlimited |\n\nWhen 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:\n\n- `/v1/health` \u2014 uptime probes are never gated.\n- `/v1/usage/*` \u2014 so dashboards can render the over-cap state.\n- Any `DELETE` \u2014 so the customer can trim listings to get back under the cap without paying.\n\nUnlike 429, 402 is NOT a \"wait and retry\" condition \u2014 `Retry-After` is not set. The only paths back to 200 are:\n 1. `DELETE` enough listings to come back under the cap, or\n 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.\n\nThe envelope mirrors `rate_limit_exceeded` for SDK ergonomics: `tier`, `limit`, `active_listings`, `upgrade_url`, plus the standard `code` / `message` / `fix` / `docs_url` / `request_id`.",
|
|
7
7
|
"contact": {
|
|
8
|
-
"email": "ivan@vanio.ai",
|
|
9
8
|
"url": "https://repull.dev"
|
|
10
9
|
},
|
|
11
10
|
"license": {
|
|
@@ -117,7 +116,7 @@
|
|
|
117
116
|
},
|
|
118
117
|
{
|
|
119
118
|
"name": "Markets",
|
|
120
|
-
"description": "Atlas market intelligence \u2014 per-city KPIs, comp distributions, calendar-level demand, and events. Sourced from Atlas
|
|
119
|
+
"description": "Atlas market intelligence \u2014 per-city KPIs, comp distributions, calendar-level demand, and events. Sourced from Atlas market data merged with the customer's own listing data."
|
|
121
120
|
},
|
|
122
121
|
{
|
|
123
122
|
"name": "Atlas",
|
|
@@ -237,7 +236,8 @@
|
|
|
237
236
|
"date",
|
|
238
237
|
"available",
|
|
239
238
|
"price",
|
|
240
|
-
"minNights"
|
|
239
|
+
"minNights",
|
|
240
|
+
"availableUnits"
|
|
241
241
|
],
|
|
242
242
|
"properties": {
|
|
243
243
|
"date": {
|
|
@@ -259,6 +259,12 @@
|
|
|
259
259
|
"type": "integer",
|
|
260
260
|
"description": "Minimum-stay requirement for a stay starting on this date. Falls back to the listing-level default min-nights when the calendar row carries none.",
|
|
261
261
|
"example": 2
|
|
262
|
+
},
|
|
263
|
+
"availableUnits": {
|
|
264
|
+
"type": "integer",
|
|
265
|
+
"minimum": 0,
|
|
266
|
+
"description": "Units still sellable that night. 1 or 0 for a single home. For a hotel-model listing (a Mews or Cloudbeds room type) the rooms of that type left, e.g. 3 of 5 \u2014 see `GET /v1/listings/{id}/units`. `available` is false whenever this is 0.",
|
|
267
|
+
"example": 1
|
|
262
268
|
}
|
|
263
269
|
}
|
|
264
270
|
},
|
|
@@ -605,6 +611,22 @@
|
|
|
605
611
|
"description": "Channel-side confirmation code (Airbnb HMxxx, Booking.com numeric, etc.).",
|
|
606
612
|
"example": "HMXYZ123"
|
|
607
613
|
},
|
|
614
|
+
"unit": {
|
|
615
|
+
"type": "object",
|
|
616
|
+
"nullable": true,
|
|
617
|
+
"description": "The physical room the stay was assigned, for a hotel-model PMS (Mews, Cloudbeds) where the listing is a room type. `null` when no room is assigned yet, and for every listing that is a single home.",
|
|
618
|
+
"properties": {
|
|
619
|
+
"id": {
|
|
620
|
+
"type": "string",
|
|
621
|
+
"description": "The room id, as listed by `GET /v1/listings/{id}/units`."
|
|
622
|
+
},
|
|
623
|
+
"name": {
|
|
624
|
+
"type": "string",
|
|
625
|
+
"nullable": true,
|
|
626
|
+
"example": "101"
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
},
|
|
608
630
|
"primaryGuest": {
|
|
609
631
|
"allOf": [
|
|
610
632
|
{
|
|
@@ -776,7 +798,7 @@
|
|
|
776
798
|
},
|
|
777
799
|
"GuestFlag": {
|
|
778
800
|
"type": "object",
|
|
779
|
-
"description": "A risk/operational flag attached to a guest profile (e.g. blacklist, do-not-host, VIP).
|
|
801
|
+
"description": "A risk/operational flag attached to a guest profile (e.g. blacklist, do-not-host, VIP).",
|
|
780
802
|
"properties": {
|
|
781
803
|
"type": {
|
|
782
804
|
"type": "string",
|
|
@@ -896,7 +918,7 @@
|
|
|
896
918
|
"riskLevel": {
|
|
897
919
|
"type": "string",
|
|
898
920
|
"nullable": true,
|
|
899
|
-
"description": "
|
|
921
|
+
"description": "Risk score (e.g. `low`, `medium`, `high`)."
|
|
900
922
|
},
|
|
901
923
|
"verificationLevel": {
|
|
902
924
|
"type": "string",
|
|
@@ -1195,11 +1217,11 @@
|
|
|
1195
1217
|
},
|
|
1196
1218
|
"isAutomated": {
|
|
1197
1219
|
"type": "boolean",
|
|
1198
|
-
"description": "`true` when the message was sent by
|
|
1220
|
+
"description": "`true` when the message was sent by an automation (template, schedule, etc.)."
|
|
1199
1221
|
},
|
|
1200
1222
|
"aiGenerated": {
|
|
1201
1223
|
"type": "boolean",
|
|
1202
|
-
"description": "`true` when the body was
|
|
1224
|
+
"description": "`true` when the body was written by AI (autopilot, draft)."
|
|
1203
1225
|
},
|
|
1204
1226
|
"sentAt": {
|
|
1205
1227
|
"type": "string",
|
|
@@ -1251,7 +1273,7 @@
|
|
|
1251
1273
|
},
|
|
1252
1274
|
"Review": {
|
|
1253
1275
|
"type": "object",
|
|
1254
|
-
"description": "A guest or host review unified across channels. Returned by `GET /v1/reviews` and `GET /v1/reviews/{id}`.
|
|
1276
|
+
"description": "A guest or host review unified across channels. Returned by `GET /v1/reviews` and `GET /v1/reviews/{id}`. Includes every channel's reviews once they have been imported.",
|
|
1255
1277
|
"properties": {
|
|
1256
1278
|
"id": {
|
|
1257
1279
|
"type": "string",
|
|
@@ -1947,7 +1969,7 @@
|
|
|
1947
1969
|
"type": "string",
|
|
1948
1970
|
"nullable": true,
|
|
1949
1971
|
"description": "Provider-side account ID (e.g. the Airbnb host ID).",
|
|
1950
|
-
"example": "
|
|
1972
|
+
"example": "10000001"
|
|
1951
1973
|
},
|
|
1952
1974
|
"createdAt": {
|
|
1953
1975
|
"type": "string",
|
|
@@ -2255,6 +2277,8 @@
|
|
|
2255
2277
|
"reservation.updated",
|
|
2256
2278
|
"reservation.cancelled",
|
|
2257
2279
|
"reservation.message.received",
|
|
2280
|
+
"reservation.message.sent",
|
|
2281
|
+
"reservation.message.updated",
|
|
2258
2282
|
"reservation.alteration.created",
|
|
2259
2283
|
"reservation.alteration.responded",
|
|
2260
2284
|
"reservation.request.created",
|
|
@@ -2275,6 +2299,7 @@
|
|
|
2275
2299
|
"ai.operation.failed",
|
|
2276
2300
|
"payment.completed",
|
|
2277
2301
|
"payment.refunded",
|
|
2302
|
+
"payout.completed",
|
|
2278
2303
|
"migration.completed",
|
|
2279
2304
|
"migration.failed",
|
|
2280
2305
|
"repull.ping",
|
|
@@ -2464,6 +2489,138 @@
|
|
|
2464
2489
|
}
|
|
2465
2490
|
}
|
|
2466
2491
|
},
|
|
2492
|
+
"ReservationMessageSentPayload": {
|
|
2493
|
+
"type": "object",
|
|
2494
|
+
"description": "Payload for `reservation.message.sent`: a host-side message was sent on a reservation thread. Same fields as `reservation.message.received`, plus `source`.",
|
|
2495
|
+
"properties": {
|
|
2496
|
+
"reservationId": {
|
|
2497
|
+
"type": "integer",
|
|
2498
|
+
"nullable": true,
|
|
2499
|
+
"example": 235970
|
|
2500
|
+
},
|
|
2501
|
+
"threadId": {
|
|
2502
|
+
"type": "string",
|
|
2503
|
+
"example": "161347"
|
|
2504
|
+
},
|
|
2505
|
+
"messageId": {
|
|
2506
|
+
"type": "string",
|
|
2507
|
+
"description": "Repull message id, as `GET /v1/conversations/{id}/messages` returns it.",
|
|
2508
|
+
"example": "1854462"
|
|
2509
|
+
},
|
|
2510
|
+
"externalMessageId": {
|
|
2511
|
+
"type": "string",
|
|
2512
|
+
"nullable": true,
|
|
2513
|
+
"description": "The channel's own message id. Dedupe on it.",
|
|
2514
|
+
"example": "32877308873"
|
|
2515
|
+
},
|
|
2516
|
+
"channel": {
|
|
2517
|
+
"type": "string",
|
|
2518
|
+
"example": "airbnb"
|
|
2519
|
+
},
|
|
2520
|
+
"source": {
|
|
2521
|
+
"type": "string",
|
|
2522
|
+
"description": "`channel`: sent in the channel's own app (e.g. the Airbnb app). `repull`: sent through Repull \u2014 the API, the dashboard, an automation or AI."
|
|
2523
|
+
},
|
|
2524
|
+
"from": {
|
|
2525
|
+
"type": "object",
|
|
2526
|
+
"properties": {
|
|
2527
|
+
"type": {
|
|
2528
|
+
"type": "string",
|
|
2529
|
+
"example": "host",
|
|
2530
|
+
"description": "`host` or `co-host`."
|
|
2531
|
+
},
|
|
2532
|
+
"name": {
|
|
2533
|
+
"type": "string",
|
|
2534
|
+
"nullable": true
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
},
|
|
2538
|
+
"body": {
|
|
2539
|
+
"type": "string"
|
|
2540
|
+
},
|
|
2541
|
+
"sentAt": {
|
|
2542
|
+
"type": "string",
|
|
2543
|
+
"format": "date-time"
|
|
2544
|
+
},
|
|
2545
|
+
"direction": {
|
|
2546
|
+
"type": "string"
|
|
2547
|
+
},
|
|
2548
|
+
"isAutomated": {
|
|
2549
|
+
"type": "boolean"
|
|
2550
|
+
},
|
|
2551
|
+
"aiGenerated": {
|
|
2552
|
+
"type": "boolean"
|
|
2553
|
+
},
|
|
2554
|
+
"attachments": {
|
|
2555
|
+
"type": "array",
|
|
2556
|
+
"items": {
|
|
2557
|
+
"$ref": "#/components/schemas/ConversationMessageAttachment"
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
},
|
|
2562
|
+
"ReservationMessageUpdatedPayload": {
|
|
2563
|
+
"type": "object",
|
|
2564
|
+
"description": "Payload for `reservation.message.updated`: a message was edited on the channel. `body` is the new text; `previousBody` what it replaced. Read receipts and reactions do not fire it.",
|
|
2565
|
+
"properties": {
|
|
2566
|
+
"reservationId": {
|
|
2567
|
+
"type": "integer",
|
|
2568
|
+
"nullable": true,
|
|
2569
|
+
"example": 235970
|
|
2570
|
+
},
|
|
2571
|
+
"threadId": {
|
|
2572
|
+
"type": "string",
|
|
2573
|
+
"example": "161347"
|
|
2574
|
+
},
|
|
2575
|
+
"messageId": {
|
|
2576
|
+
"type": "string",
|
|
2577
|
+
"example": "1854462"
|
|
2578
|
+
},
|
|
2579
|
+
"externalMessageId": {
|
|
2580
|
+
"type": "string",
|
|
2581
|
+
"nullable": true,
|
|
2582
|
+
"example": "32877308873"
|
|
2583
|
+
},
|
|
2584
|
+
"channel": {
|
|
2585
|
+
"type": "string",
|
|
2586
|
+
"example": "airbnb"
|
|
2587
|
+
},
|
|
2588
|
+
"from": {
|
|
2589
|
+
"type": "object",
|
|
2590
|
+
"properties": {
|
|
2591
|
+
"type": {
|
|
2592
|
+
"type": "string",
|
|
2593
|
+
"example": "host"
|
|
2594
|
+
},
|
|
2595
|
+
"name": {
|
|
2596
|
+
"type": "string",
|
|
2597
|
+
"nullable": true
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
},
|
|
2601
|
+
"body": {
|
|
2602
|
+
"type": "string",
|
|
2603
|
+
"description": "The text after the edit."
|
|
2604
|
+
},
|
|
2605
|
+
"previousBody": {
|
|
2606
|
+
"type": "string",
|
|
2607
|
+
"description": "The text before the edit."
|
|
2608
|
+
},
|
|
2609
|
+
"editedAt": {
|
|
2610
|
+
"type": "string",
|
|
2611
|
+
"format": "date-time",
|
|
2612
|
+
"description": "When the edit was made, as the channel reports it. Also the event's `revision`."
|
|
2613
|
+
},
|
|
2614
|
+
"sentAt": {
|
|
2615
|
+
"type": "string",
|
|
2616
|
+
"format": "date-time",
|
|
2617
|
+
"description": "When the message was first sent."
|
|
2618
|
+
},
|
|
2619
|
+
"direction": {
|
|
2620
|
+
"type": "string"
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
},
|
|
2467
2624
|
"AlterationWebhookObject": {
|
|
2468
2625
|
"type": "object",
|
|
2469
2626
|
"description": "Lightweight alteration snapshot delivered as `data.object` on `reservation.alteration.*` events. Currently Airbnb only. Fetch full state (original vs new dates/guests/price) via `GET /v1/channels/airbnb/alterations` filtered by `reservation_code`.",
|
|
@@ -3430,6 +3587,40 @@
|
|
|
3430
3587
|
}
|
|
3431
3588
|
}
|
|
3432
3589
|
},
|
|
3590
|
+
"PayoutCompletedPayload": {
|
|
3591
|
+
"type": "object",
|
|
3592
|
+
"description": "Payload for `payout.completed`: one Airbnb payout and every line it paid. `payout` and each of `lines` are `AirbnbTransaction` objects, identical \u2014 ids included \u2014 to what `GET /v1/channels/airbnb/transactions?payout_id=` returns, so you can deduplicate on `transactionId` across webhooks and reads. The lines' signed `amount`s sum to `payout.payout.paidOutAmount`.",
|
|
3593
|
+
"required": [
|
|
3594
|
+
"channel",
|
|
3595
|
+
"accountId",
|
|
3596
|
+
"payout",
|
|
3597
|
+
"lines"
|
|
3598
|
+
],
|
|
3599
|
+
"properties": {
|
|
3600
|
+
"channel": {
|
|
3601
|
+
"type": "string"
|
|
3602
|
+
},
|
|
3603
|
+
"accountId": {
|
|
3604
|
+
"type": "string",
|
|
3605
|
+
"description": "The Airbnb account (host id) that was paid.",
|
|
3606
|
+
"example": "10000001"
|
|
3607
|
+
},
|
|
3608
|
+
"accountName": {
|
|
3609
|
+
"type": "string",
|
|
3610
|
+
"nullable": true
|
|
3611
|
+
},
|
|
3612
|
+
"payout": {
|
|
3613
|
+
"$ref": "#/components/schemas/AirbnbTransaction"
|
|
3614
|
+
},
|
|
3615
|
+
"lines": {
|
|
3616
|
+
"type": "array",
|
|
3617
|
+
"items": {
|
|
3618
|
+
"$ref": "#/components/schemas/AirbnbTransaction"
|
|
3619
|
+
},
|
|
3620
|
+
"description": "In payout order (`payout.lineIndex`)."
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
},
|
|
3433
3624
|
"RepullPingPayload": {
|
|
3434
3625
|
"type": "object",
|
|
3435
3626
|
"description": "Payload for `repull.ping`. A diagnostic delivery used by the dashboard to verify endpoint reachability.",
|
|
@@ -3669,6 +3860,78 @@
|
|
|
3669
3860
|
}
|
|
3670
3861
|
}
|
|
3671
3862
|
},
|
|
3863
|
+
"ReservationMessageSentEvent": {
|
|
3864
|
+
"type": "object",
|
|
3865
|
+
"required": [
|
|
3866
|
+
"event",
|
|
3867
|
+
"eventId",
|
|
3868
|
+
"apiVersion",
|
|
3869
|
+
"timestamp",
|
|
3870
|
+
"data"
|
|
3871
|
+
],
|
|
3872
|
+
"properties": {
|
|
3873
|
+
"event": {
|
|
3874
|
+
"type": "string",
|
|
3875
|
+
"description": "The event name. This field is `event`, not `type`."
|
|
3876
|
+
},
|
|
3877
|
+
"eventId": {
|
|
3878
|
+
"type": "string",
|
|
3879
|
+
"format": "uuid",
|
|
3880
|
+
"description": "Stable across every delivery and replay of this logical event \u2014 dedupe on it."
|
|
3881
|
+
},
|
|
3882
|
+
"apiVersion": {
|
|
3883
|
+
"type": "string",
|
|
3884
|
+
"example": "2026-04"
|
|
3885
|
+
},
|
|
3886
|
+
"timestamp": {
|
|
3887
|
+
"type": "string",
|
|
3888
|
+
"format": "date-time",
|
|
3889
|
+
"description": "When this delivery was built."
|
|
3890
|
+
},
|
|
3891
|
+
"account": {
|
|
3892
|
+
"$ref": "#/components/schemas/WebhookEventAccount"
|
|
3893
|
+
},
|
|
3894
|
+
"data": {
|
|
3895
|
+
"$ref": "#/components/schemas/ReservationMessageSentPayload"
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
3898
|
+
},
|
|
3899
|
+
"ReservationMessageUpdatedEvent": {
|
|
3900
|
+
"type": "object",
|
|
3901
|
+
"required": [
|
|
3902
|
+
"event",
|
|
3903
|
+
"eventId",
|
|
3904
|
+
"apiVersion",
|
|
3905
|
+
"timestamp",
|
|
3906
|
+
"data"
|
|
3907
|
+
],
|
|
3908
|
+
"properties": {
|
|
3909
|
+
"event": {
|
|
3910
|
+
"type": "string",
|
|
3911
|
+
"description": "The event name. This field is `event`, not `type`."
|
|
3912
|
+
},
|
|
3913
|
+
"eventId": {
|
|
3914
|
+
"type": "string",
|
|
3915
|
+
"format": "uuid",
|
|
3916
|
+
"description": "Stable across every delivery and replay of this logical event \u2014 dedupe on it."
|
|
3917
|
+
},
|
|
3918
|
+
"apiVersion": {
|
|
3919
|
+
"type": "string",
|
|
3920
|
+
"example": "2026-04"
|
|
3921
|
+
},
|
|
3922
|
+
"timestamp": {
|
|
3923
|
+
"type": "string",
|
|
3924
|
+
"format": "date-time",
|
|
3925
|
+
"description": "When this delivery was built."
|
|
3926
|
+
},
|
|
3927
|
+
"account": {
|
|
3928
|
+
"$ref": "#/components/schemas/WebhookEventAccount"
|
|
3929
|
+
},
|
|
3930
|
+
"data": {
|
|
3931
|
+
"$ref": "#/components/schemas/ReservationMessageUpdatedPayload"
|
|
3932
|
+
}
|
|
3933
|
+
}
|
|
3934
|
+
},
|
|
3672
3935
|
"ReservationAlterationCreatedEvent": {
|
|
3673
3936
|
"type": "object",
|
|
3674
3937
|
"required": [
|
|
@@ -4353,6 +4616,42 @@
|
|
|
4353
4616
|
}
|
|
4354
4617
|
}
|
|
4355
4618
|
},
|
|
4619
|
+
"PayoutCompletedEvent": {
|
|
4620
|
+
"type": "object",
|
|
4621
|
+
"required": [
|
|
4622
|
+
"event",
|
|
4623
|
+
"eventId",
|
|
4624
|
+
"apiVersion",
|
|
4625
|
+
"timestamp",
|
|
4626
|
+
"data"
|
|
4627
|
+
],
|
|
4628
|
+
"properties": {
|
|
4629
|
+
"event": {
|
|
4630
|
+
"type": "string",
|
|
4631
|
+
"description": "The event name. This field is `event`, not `type`."
|
|
4632
|
+
},
|
|
4633
|
+
"eventId": {
|
|
4634
|
+
"type": "string",
|
|
4635
|
+
"format": "uuid",
|
|
4636
|
+
"description": "Stable across every delivery and replay of this logical event \u2014 dedupe on it."
|
|
4637
|
+
},
|
|
4638
|
+
"apiVersion": {
|
|
4639
|
+
"type": "string",
|
|
4640
|
+
"example": "2026-04"
|
|
4641
|
+
},
|
|
4642
|
+
"timestamp": {
|
|
4643
|
+
"type": "string",
|
|
4644
|
+
"format": "date-time",
|
|
4645
|
+
"description": "When this delivery was built."
|
|
4646
|
+
},
|
|
4647
|
+
"account": {
|
|
4648
|
+
"$ref": "#/components/schemas/WebhookEventAccount"
|
|
4649
|
+
},
|
|
4650
|
+
"data": {
|
|
4651
|
+
"$ref": "#/components/schemas/PayoutCompletedPayload"
|
|
4652
|
+
}
|
|
4653
|
+
}
|
|
4654
|
+
},
|
|
4356
4655
|
"PaymentRefundedEvent": {
|
|
4357
4656
|
"type": "object",
|
|
4358
4657
|
"required": [
|
|
@@ -4613,6 +4912,12 @@
|
|
|
4613
4912
|
{
|
|
4614
4913
|
"$ref": "#/components/schemas/ReservationMessageReceivedEvent"
|
|
4615
4914
|
},
|
|
4915
|
+
{
|
|
4916
|
+
"$ref": "#/components/schemas/ReservationMessageSentEvent"
|
|
4917
|
+
},
|
|
4918
|
+
{
|
|
4919
|
+
"$ref": "#/components/schemas/ReservationMessageUpdatedEvent"
|
|
4920
|
+
},
|
|
4616
4921
|
{
|
|
4617
4922
|
"$ref": "#/components/schemas/ReservationAlterationCreatedEvent"
|
|
4618
4923
|
},
|
|
@@ -4674,7 +4979,10 @@
|
|
|
4674
4979
|
"$ref": "#/components/schemas/PaymentRefundedEvent"
|
|
4675
4980
|
},
|
|
4676
4981
|
{
|
|
4677
|
-
"$ref": "#/components/schemas/
|
|
4982
|
+
"$ref": "#/components/schemas/PayoutCompletedEvent"
|
|
4983
|
+
},
|
|
4984
|
+
{
|
|
4985
|
+
"$ref": "#/components/schemas/RepullPingEvent"
|
|
4678
4986
|
},
|
|
4679
4987
|
{
|
|
4680
4988
|
"$ref": "#/components/schemas/UsageQuotaWarningEvent"
|
|
@@ -4693,6 +5001,8 @@
|
|
|
4693
5001
|
"reservation.updated": "#/components/schemas/ReservationUpdatedEvent",
|
|
4694
5002
|
"reservation.cancelled": "#/components/schemas/ReservationCancelledEvent",
|
|
4695
5003
|
"reservation.message.received": "#/components/schemas/ReservationMessageReceivedEvent",
|
|
5004
|
+
"reservation.message.sent": "#/components/schemas/ReservationMessageSentEvent",
|
|
5005
|
+
"reservation.message.updated": "#/components/schemas/ReservationMessageUpdatedEvent",
|
|
4696
5006
|
"reservation.alteration.created": "#/components/schemas/ReservationAlterationCreatedEvent",
|
|
4697
5007
|
"reservation.alteration.responded": "#/components/schemas/ReservationAlterationRespondedEvent",
|
|
4698
5008
|
"reservation.request.created": "#/components/schemas/ReservationRequestCreatedEvent",
|
|
@@ -4713,6 +5023,7 @@
|
|
|
4713
5023
|
"ai.operation.failed": "#/components/schemas/AiOperationFailedEvent",
|
|
4714
5024
|
"payment.completed": "#/components/schemas/PaymentCompletedEvent",
|
|
4715
5025
|
"payment.refunded": "#/components/schemas/PaymentRefundedEvent",
|
|
5026
|
+
"payout.completed": "#/components/schemas/PayoutCompletedEvent",
|
|
4716
5027
|
"repull.ping": "#/components/schemas/RepullPingEvent",
|
|
4717
5028
|
"usage.quota.warning": "#/components/schemas/UsageQuotaWarningEvent",
|
|
4718
5029
|
"migration.completed": "#/components/schemas/MigrationCompletedEvent",
|
|
@@ -4723,11 +5034,11 @@
|
|
|
4723
5034
|
},
|
|
4724
5035
|
"AirbnbListing": {
|
|
4725
5036
|
"type": "object",
|
|
4726
|
-
"description": "A
|
|
5037
|
+
"description": "A listing paired with its Airbnb connections. The list endpoint groups every Airbnb connection of the same `listingId` under a single `connections[]` array.",
|
|
4727
5038
|
"properties": {
|
|
4728
5039
|
"listingId": {
|
|
4729
5040
|
"type": "string",
|
|
4730
|
-
"description": "
|
|
5041
|
+
"description": "Repull listing id",
|
|
4731
5042
|
"example": "6248"
|
|
4732
5043
|
},
|
|
4733
5044
|
"name": {
|
|
@@ -4744,7 +5055,7 @@
|
|
|
4744
5055
|
"type": "string",
|
|
4745
5056
|
"format": "uri",
|
|
4746
5057
|
"nullable": true,
|
|
4747
|
-
"description": "Cover photo URL for the
|
|
5058
|
+
"description": "Cover photo URL for the listing. **Only present when the caller passes `?include=thumbnail`.** `null` when the listing has no cover photo stored \u2014 the listing is still returned."
|
|
4748
5059
|
},
|
|
4749
5060
|
"connections": {
|
|
4750
5061
|
"type": "array",
|
|
@@ -4756,7 +5067,7 @@
|
|
|
4756
5067
|
},
|
|
4757
5068
|
"AirbnbConnection": {
|
|
4758
5069
|
"type": "object",
|
|
4759
|
-
"description": "An Airbnb-side connection record for a
|
|
5070
|
+
"description": "An Airbnb-side connection record for a listing. The same property may appear under multiple connections if it has been linked from multiple Airbnb host accounts.",
|
|
4760
5071
|
"properties": {
|
|
4761
5072
|
"id": {
|
|
4762
5073
|
"type": "string",
|
|
@@ -4765,7 +5076,7 @@
|
|
|
4765
5076
|
"airbnbId": {
|
|
4766
5077
|
"type": "string",
|
|
4767
5078
|
"description": "Airbnb-side listing id",
|
|
4768
|
-
"example": "
|
|
5079
|
+
"example": "1234567890123456789"
|
|
4769
5080
|
},
|
|
4770
5081
|
"accountId": {
|
|
4771
5082
|
"type": "string",
|
|
@@ -4777,7 +5088,7 @@
|
|
|
4777
5088
|
"type": "string",
|
|
4778
5089
|
"nullable": true,
|
|
4779
5090
|
"description": "Display name of that connected Airbnb account.",
|
|
4780
|
-
"example": "
|
|
5091
|
+
"example": "Seaside Stays"
|
|
4781
5092
|
},
|
|
4782
5093
|
"hostId": {
|
|
4783
5094
|
"type": "string",
|
|
@@ -4801,7 +5112,7 @@
|
|
|
4801
5112
|
"markup": {
|
|
4802
5113
|
"type": "string",
|
|
4803
5114
|
"nullable": true,
|
|
4804
|
-
"description": "
|
|
5115
|
+
"description": "The Airbnb markup as a fraction: \"0.35\" = +35% on the listing's own price. Read or set it as a percentage with `/v1/listings/{id}/markups`."
|
|
4805
5116
|
},
|
|
4806
5117
|
"syncCategory": {
|
|
4807
5118
|
"type": "string",
|
|
@@ -4899,7 +5210,8 @@
|
|
|
4899
5210
|
},
|
|
4900
5211
|
"markup": {
|
|
4901
5212
|
"type": "string",
|
|
4902
|
-
"nullable": true
|
|
5213
|
+
"nullable": true,
|
|
5214
|
+
"description": "The Booking.com markup on this property, as a fraction: \"0.18\" = +18%, shared by every listing on the property. Read or set it as a percentage with `/v1/listings/{id}/markups`."
|
|
4903
5215
|
},
|
|
4904
5216
|
"syncCategory": {
|
|
4905
5217
|
"type": "string",
|
|
@@ -5021,7 +5333,7 @@
|
|
|
5021
5333
|
"type": "string",
|
|
5022
5334
|
"nullable": true,
|
|
5023
5335
|
"description": "Display name of that connected Airbnb account.",
|
|
5024
|
-
"example": "
|
|
5336
|
+
"example": "Seaside Stays"
|
|
5025
5337
|
},
|
|
5026
5338
|
"status": {
|
|
5027
5339
|
"type": "string",
|
|
@@ -5098,7 +5410,7 @@
|
|
|
5098
5410
|
"type": "string",
|
|
5099
5411
|
"nullable": true,
|
|
5100
5412
|
"description": "Display name of that connected Airbnb account.",
|
|
5101
|
-
"example": "
|
|
5413
|
+
"example": "Seaside Stays"
|
|
5102
5414
|
},
|
|
5103
5415
|
"guestName": {
|
|
5104
5416
|
"type": "string",
|
|
@@ -5192,7 +5504,7 @@
|
|
|
5192
5504
|
"type": "string",
|
|
5193
5505
|
"nullable": true,
|
|
5194
5506
|
"description": "Display name of that connected Airbnb account.",
|
|
5195
|
-
"example": "
|
|
5507
|
+
"example": "Seaside Stays"
|
|
5196
5508
|
},
|
|
5197
5509
|
"platform": {
|
|
5198
5510
|
"type": "string",
|
|
@@ -5345,7 +5657,7 @@
|
|
|
5345
5657
|
"type": "string",
|
|
5346
5658
|
"nullable": true,
|
|
5347
5659
|
"description": "Display name of that connected Airbnb account.",
|
|
5348
|
-
"example": "
|
|
5660
|
+
"example": "Seaside Stays"
|
|
5349
5661
|
},
|
|
5350
5662
|
"rating": {
|
|
5351
5663
|
"type": "integer",
|
|
@@ -5899,6 +6211,9 @@
|
|
|
5899
6211
|
"PropertyListResponse": {
|
|
5900
6212
|
"type": "object",
|
|
5901
6213
|
"properties": {
|
|
6214
|
+
"planNotice": {
|
|
6215
|
+
"$ref": "#/components/schemas/PlanNotice"
|
|
6216
|
+
},
|
|
5902
6217
|
"data": {
|
|
5903
6218
|
"type": "array",
|
|
5904
6219
|
"items": {
|
|
@@ -5988,6 +6303,9 @@
|
|
|
5988
6303
|
"ConnectionListResponse": {
|
|
5989
6304
|
"type": "object",
|
|
5990
6305
|
"properties": {
|
|
6306
|
+
"planNotice": {
|
|
6307
|
+
"$ref": "#/components/schemas/PlanNotice"
|
|
6308
|
+
},
|
|
5991
6309
|
"data": {
|
|
5992
6310
|
"type": "array",
|
|
5993
6311
|
"items": {
|
|
@@ -6042,7 +6360,7 @@
|
|
|
6042
6360
|
"type": "string",
|
|
6043
6361
|
"nullable": true,
|
|
6044
6362
|
"description": "Display name of the connected account.",
|
|
6045
|
-
"example": "
|
|
6363
|
+
"example": "Seaside Stays"
|
|
6046
6364
|
},
|
|
6047
6365
|
"lastSyncedAt": {
|
|
6048
6366
|
"type": "string",
|
|
@@ -6129,234 +6447,183 @@
|
|
|
6129
6447
|
},
|
|
6130
6448
|
"AirbnbTransaction": {
|
|
6131
6449
|
"type": "object",
|
|
6132
|
-
"description": "One Airbnb
|
|
6450
|
+
"description": "One line of the Airbnb settlement ledger: a Payout row (`isPayout: true`) or a line it paid. Money is in the payout currency; `amount` is signed (negative = taken back, e.g. an adjustment offset against this payout). A payout's lines sum to its `payout.paidOutAmount`.",
|
|
6133
6451
|
"required": [
|
|
6134
|
-
"
|
|
6135
|
-
"
|
|
6136
|
-
"
|
|
6452
|
+
"transactionId",
|
|
6453
|
+
"status",
|
|
6454
|
+
"type",
|
|
6455
|
+
"isPayout",
|
|
6456
|
+
"fees",
|
|
6137
6457
|
"payout",
|
|
6138
|
-
"
|
|
6458
|
+
"onInactiveListing",
|
|
6459
|
+
"unavailableFields"
|
|
6139
6460
|
],
|
|
6140
6461
|
"properties": {
|
|
6141
|
-
"
|
|
6462
|
+
"transactionId": {
|
|
6142
6463
|
"type": "string",
|
|
6143
|
-
"description": "
|
|
6464
|
+
"description": "Stable id. A Payout row: Airbnb's payout id. A settled line: `<payoutId>:<type>:<confirmationCode>:<n>`. An upcoming line: `upcoming:<accountId>:<type>:<confirmationCode>:<date>:<n>`. Identical on every refresh; upsert on it.",
|
|
6465
|
+
"example": "M-HQLLNSWKUWK7R:reservation:HMRQ8FC4YN:1"
|
|
6144
6466
|
},
|
|
6145
|
-
"
|
|
6467
|
+
"accountId": {
|
|
6146
6468
|
"type": "string",
|
|
6147
6469
|
"nullable": true,
|
|
6148
|
-
"description": "
|
|
6470
|
+
"description": "The connected Airbnb account (host id, as a string \u2014 they exceed 2^53).",
|
|
6471
|
+
"example": "10000001"
|
|
6149
6472
|
},
|
|
6150
|
-
"
|
|
6473
|
+
"accountName": {
|
|
6151
6474
|
"type": "string",
|
|
6152
|
-
"nullable": true
|
|
6475
|
+
"nullable": true,
|
|
6476
|
+
"example": "Seaside Stays"
|
|
6153
6477
|
},
|
|
6154
|
-
"
|
|
6478
|
+
"status": {
|
|
6155
6479
|
"type": "string",
|
|
6156
|
-
"
|
|
6157
|
-
"nullable": true,
|
|
6158
|
-
"description": "Transaction date."
|
|
6480
|
+
"description": "`COMPLETED`: settled in a payout. `UPCOMING`: expected, not paid out yet."
|
|
6159
6481
|
},
|
|
6160
|
-
"
|
|
6482
|
+
"type": {
|
|
6161
6483
|
"type": "string",
|
|
6162
|
-
"
|
|
6163
|
-
"
|
|
6484
|
+
"description": "Airbnb's line type, verbatim: `Payout`, `Reservation`, `Adjustment`, `Resolution Payout`, `Resolution Adjustment`, `Cancellation Fee`, `Pass Through Tot`, \u2026",
|
|
6485
|
+
"example": "Reservation"
|
|
6164
6486
|
},
|
|
6165
|
-
"
|
|
6166
|
-
"type": "
|
|
6167
|
-
"
|
|
6168
|
-
"description": "Resolved Vanio reservation id when the confirmation code matched a reservation in this workspace; null otherwise."
|
|
6487
|
+
"isPayout": {
|
|
6488
|
+
"type": "boolean",
|
|
6489
|
+
"description": "`true` on the Payout row itself."
|
|
6169
6490
|
},
|
|
6170
|
-
"
|
|
6491
|
+
"date": {
|
|
6171
6492
|
"type": "string",
|
|
6493
|
+
"format": "date",
|
|
6172
6494
|
"nullable": true,
|
|
6173
|
-
"description": "
|
|
6174
|
-
"example": "1772489413932732258"
|
|
6495
|
+
"description": "The line's date as Airbnb reports it. Can be the day before its payout's date."
|
|
6175
6496
|
},
|
|
6176
|
-
"
|
|
6497
|
+
"currency": {
|
|
6177
6498
|
"type": "string",
|
|
6178
6499
|
"nullable": true,
|
|
6179
|
-
"
|
|
6180
|
-
"example": "Pomello"
|
|
6500
|
+
"example": "USD"
|
|
6181
6501
|
},
|
|
6182
|
-
"
|
|
6183
|
-
"type": "
|
|
6502
|
+
"amount": {
|
|
6503
|
+
"type": "number",
|
|
6184
6504
|
"nullable": true,
|
|
6185
|
-
"description": "Airbnb
|
|
6186
|
-
|
|
6187
|
-
"thread_id": {
|
|
6188
|
-
"type": "string",
|
|
6189
|
-
"nullable": true
|
|
6190
|
-
},
|
|
6191
|
-
"nights": {
|
|
6192
|
-
"type": "integer",
|
|
6193
|
-
"nullable": true
|
|
6194
|
-
},
|
|
6195
|
-
"reservation_start_date": {
|
|
6196
|
-
"type": "string",
|
|
6197
|
-
"format": "date",
|
|
6198
|
-
"nullable": true
|
|
6199
|
-
},
|
|
6200
|
-
"booked_at": {
|
|
6201
|
-
"type": "string",
|
|
6202
|
-
"format": "date-time",
|
|
6203
|
-
"nullable": true
|
|
6204
|
-
},
|
|
6205
|
-
"check_in": {
|
|
6206
|
-
"type": "string",
|
|
6207
|
-
"format": "date-time",
|
|
6208
|
-
"nullable": true
|
|
6209
|
-
},
|
|
6210
|
-
"check_out": {
|
|
6211
|
-
"type": "string",
|
|
6212
|
-
"format": "date-time",
|
|
6213
|
-
"nullable": true
|
|
6214
|
-
},
|
|
6215
|
-
"time_zone": {
|
|
6216
|
-
"type": "string",
|
|
6217
|
-
"nullable": true
|
|
6218
|
-
},
|
|
6219
|
-
"guest_name": {
|
|
6220
|
-
"type": "string",
|
|
6221
|
-
"nullable": true
|
|
6505
|
+
"description": "Signed amount this line contributes to its payout, after Airbnb's host service fee. On a Payout row, the amount paid out.",
|
|
6506
|
+
"example": 40.6
|
|
6222
6507
|
},
|
|
6223
|
-
"
|
|
6224
|
-
"type": "
|
|
6508
|
+
"grossAmount": {
|
|
6509
|
+
"type": "number",
|
|
6225
6510
|
"nullable": true,
|
|
6226
|
-
"description": "
|
|
6511
|
+
"description": "Before Airbnb's host service fee: `amount - fees.hostServiceFee`.",
|
|
6512
|
+
"example": 48.05
|
|
6227
6513
|
},
|
|
6228
|
-
"
|
|
6229
|
-
"type": "string",
|
|
6230
|
-
"nullable": true
|
|
6231
|
-
},
|
|
6232
|
-
"payout": {
|
|
6514
|
+
"fees": {
|
|
6233
6515
|
"type": "object",
|
|
6234
6516
|
"required": [
|
|
6235
|
-
"
|
|
6236
|
-
"
|
|
6237
|
-
"paid_out_amount"
|
|
6517
|
+
"hostServiceFee",
|
|
6518
|
+
"cleaningFee"
|
|
6238
6519
|
],
|
|
6239
6520
|
"properties": {
|
|
6240
|
-
"
|
|
6241
|
-
"type": "
|
|
6242
|
-
"nullable": true
|
|
6243
|
-
},
|
|
6244
|
-
"payout_date": {
|
|
6245
|
-
"type": "string",
|
|
6246
|
-
"format": "date",
|
|
6521
|
+
"hostServiceFee": {
|
|
6522
|
+
"type": "number",
|
|
6247
6523
|
"nullable": true,
|
|
6248
|
-
"description": "
|
|
6524
|
+
"description": "Airbnb's host service fee on this line, as a deduction (negative). Already taken out of `amount`.",
|
|
6525
|
+
"example": -7.45
|
|
6249
6526
|
},
|
|
6250
|
-
"
|
|
6527
|
+
"cleaningFee": {
|
|
6251
6528
|
"type": "number",
|
|
6252
|
-
"nullable": true
|
|
6529
|
+
"nullable": true,
|
|
6530
|
+
"description": "Cleaning fee included in this line's gross.",
|
|
6531
|
+
"example": 40.57
|
|
6253
6532
|
}
|
|
6254
6533
|
}
|
|
6255
6534
|
},
|
|
6256
|
-
"
|
|
6257
|
-
"type": "string",
|
|
6258
|
-
"nullable": true
|
|
6259
|
-
},
|
|
6260
|
-
"host_currency": {
|
|
6261
|
-
"type": "string",
|
|
6262
|
-
"nullable": true
|
|
6263
|
-
},
|
|
6264
|
-
"amount": {
|
|
6265
|
-
"type": "number",
|
|
6266
|
-
"nullable": true,
|
|
6267
|
-
"description": "Top-level transaction amount."
|
|
6268
|
-
},
|
|
6269
|
-
"host_breakdown": {
|
|
6535
|
+
"payout": {
|
|
6270
6536
|
"type": "object",
|
|
6271
|
-
"description": "Host-side breakdown (all host currency).",
|
|
6272
6537
|
"required": [
|
|
6273
|
-
"
|
|
6538
|
+
"payoutId",
|
|
6539
|
+
"payoutIdSynthetic",
|
|
6540
|
+
"payoutDate",
|
|
6541
|
+
"lineIndex",
|
|
6542
|
+
"paidOutAmount"
|
|
6274
6543
|
],
|
|
6275
6544
|
"properties": {
|
|
6276
|
-
"
|
|
6277
|
-
"type": "
|
|
6278
|
-
"nullable": true,
|
|
6279
|
-
"description": "Nightly rate \u00d7 nights, net of stay-level discounts already applied by Airbnb."
|
|
6280
|
-
},
|
|
6281
|
-
"cleaning_fee": {
|
|
6282
|
-
"type": "number",
|
|
6283
|
-
"nullable": true
|
|
6284
|
-
},
|
|
6285
|
-
"host_service_fee_base": {
|
|
6286
|
-
"type": "number",
|
|
6287
|
-
"nullable": true,
|
|
6288
|
-
"description": "Airbnb host service fee, base component (negative = deduction)."
|
|
6289
|
-
},
|
|
6290
|
-
"host_service_fee_vat": {
|
|
6291
|
-
"type": "number",
|
|
6292
|
-
"nullable": true,
|
|
6293
|
-
"description": "Airbnb host service fee, VAT component (negative = deduction)."
|
|
6294
|
-
},
|
|
6295
|
-
"host_service_fee_total": {
|
|
6296
|
-
"type": "number",
|
|
6545
|
+
"payoutId": {
|
|
6546
|
+
"type": "string",
|
|
6297
6547
|
"nullable": true,
|
|
6298
|
-
"description": "
|
|
6548
|
+
"description": "The payout this line was settled in (its own id on a Payout row). `null` on an UPCOMING line.",
|
|
6549
|
+
"example": "M-HQLLNSWKUWK7R"
|
|
6299
6550
|
},
|
|
6300
|
-
"
|
|
6301
|
-
"type": "
|
|
6302
|
-
"
|
|
6303
|
-
},
|
|
6304
|
-
"pass_through_tax": {
|
|
6305
|
-
"type": "number",
|
|
6306
|
-
"nullable": true
|
|
6551
|
+
"payoutIdSynthetic": {
|
|
6552
|
+
"type": "boolean",
|
|
6553
|
+
"description": "`true` when Airbnb sent no payout id (a payout netting to $0.00) and Repull derived a stable one."
|
|
6307
6554
|
},
|
|
6308
|
-
"
|
|
6309
|
-
"type": "
|
|
6555
|
+
"payoutDate": {
|
|
6556
|
+
"type": "string",
|
|
6557
|
+
"format": "date",
|
|
6310
6558
|
"nullable": true
|
|
6311
6559
|
},
|
|
6312
|
-
"
|
|
6313
|
-
"type": "
|
|
6314
|
-
"nullable": true
|
|
6560
|
+
"lineIndex": {
|
|
6561
|
+
"type": "integer",
|
|
6562
|
+
"nullable": true,
|
|
6563
|
+
"description": "Position within the payout, from 1. `null` on the Payout row and on UPCOMING lines."
|
|
6315
6564
|
},
|
|
6316
|
-
"
|
|
6565
|
+
"paidOutAmount": {
|
|
6317
6566
|
"type": "number",
|
|
6318
6567
|
"nullable": true,
|
|
6319
|
-
"description": "
|
|
6568
|
+
"description": "On the Payout row only: the amount paid out. Its lines sum to it."
|
|
6320
6569
|
}
|
|
6321
6570
|
}
|
|
6322
6571
|
},
|
|
6323
|
-
"
|
|
6324
|
-
"type": "
|
|
6325
|
-
"
|
|
6326
|
-
"
|
|
6327
|
-
"total_paid"
|
|
6328
|
-
],
|
|
6329
|
-
"properties": {
|
|
6330
|
-
"total_paid": {
|
|
6331
|
-
"type": "number",
|
|
6332
|
-
"nullable": true
|
|
6333
|
-
},
|
|
6334
|
-
"service_fee_base": {
|
|
6335
|
-
"type": "number",
|
|
6336
|
-
"nullable": true
|
|
6337
|
-
},
|
|
6338
|
-
"service_fee_vat": {
|
|
6339
|
-
"type": "number",
|
|
6340
|
-
"nullable": true
|
|
6341
|
-
}
|
|
6342
|
-
}
|
|
6572
|
+
"confirmationCode": {
|
|
6573
|
+
"type": "string",
|
|
6574
|
+
"nullable": true,
|
|
6575
|
+
"example": "HMRQ8FC4YN"
|
|
6343
6576
|
},
|
|
6344
|
-
"
|
|
6345
|
-
"type": "
|
|
6346
|
-
"
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6577
|
+
"reservationId": {
|
|
6578
|
+
"type": "string",
|
|
6579
|
+
"nullable": true,
|
|
6580
|
+
"description": "Repull reservation id when the confirmation code matches a reservation in this workspace; `null` when it does not (explicitly unlinked)."
|
|
6581
|
+
},
|
|
6582
|
+
"listingId": {
|
|
6583
|
+
"type": "string",
|
|
6584
|
+
"nullable": true,
|
|
6585
|
+
"description": "Airbnb listing id."
|
|
6586
|
+
},
|
|
6587
|
+
"listingName": {
|
|
6588
|
+
"type": "string",
|
|
6589
|
+
"nullable": true
|
|
6590
|
+
},
|
|
6591
|
+
"onInactiveListing": {
|
|
6592
|
+
"type": "boolean",
|
|
6593
|
+
"description": "`true` when the line is on a listing that is inactive in Repull. Still returned, so the payout reconciles."
|
|
6350
6594
|
},
|
|
6351
|
-
"
|
|
6595
|
+
"guestName": {
|
|
6596
|
+
"type": "string",
|
|
6597
|
+
"nullable": true
|
|
6598
|
+
},
|
|
6599
|
+
"nights": {
|
|
6600
|
+
"type": "integer",
|
|
6601
|
+
"nullable": true
|
|
6602
|
+
},
|
|
6603
|
+
"reservationStartDate": {
|
|
6604
|
+
"type": "string",
|
|
6605
|
+
"format": "date",
|
|
6606
|
+
"nullable": true
|
|
6607
|
+
},
|
|
6608
|
+
"description": {
|
|
6609
|
+
"type": "string",
|
|
6352
6610
|
"nullable": true,
|
|
6353
|
-
"description": "
|
|
6611
|
+
"description": "Airbnb's description: the stay dates, the resolution, or on a Payout row the payout method."
|
|
6354
6612
|
},
|
|
6355
|
-
"
|
|
6613
|
+
"reference": {
|
|
6614
|
+
"type": "string",
|
|
6356
6615
|
"nullable": true,
|
|
6357
|
-
"description": "
|
|
6616
|
+
"description": "The resolution id on resolution payouts and adjustments; else `null`.",
|
|
6617
|
+
"example": "CLSF-06472635"
|
|
6358
6618
|
},
|
|
6359
|
-
"
|
|
6619
|
+
"unavailableFields": {
|
|
6620
|
+
"type": "array",
|
|
6621
|
+
"items": {
|
|
6622
|
+
"type": "string"
|
|
6623
|
+
},
|
|
6624
|
+
"description": "What Airbnb's transaction history does not carry, so it is never filled in: `taxes` (those Airbnb remits itself; pass-through tax paid to the host arrives as `Pass Through Tot` lines), `guest_paid_total`, `original_transaction_id`, `currency_conversion`, `management_fee`."
|
|
6625
|
+
},
|
|
6626
|
+
"syncedAt": {
|
|
6360
6627
|
"type": "string",
|
|
6361
6628
|
"format": "date-time",
|
|
6362
6629
|
"nullable": true
|
|
@@ -7482,11 +7749,52 @@
|
|
|
7482
7749
|
}
|
|
7483
7750
|
}
|
|
7484
7751
|
},
|
|
7752
|
+
"PlanNotice": {
|
|
7753
|
+
"type": "object",
|
|
7754
|
+
"description": "Added to the body of EVERY JSON response (success or error, except bare arrays and 5xx) while the workspace is connected to more listings than its plan lets it use \u2014 so a developer reading any payload, or an AI assistant relaying it, sees it. Connect keeps every listing it finds, but on a capped plan only as many as the plan allows are active; the rest are held back inactive and keep syncing. The same responses also carry the `X-Repull-Listings-Held-Back` and `X-Repull-Active-Listing-Limit` headers. Using a held-back listing answers `403 listing_inactive` with `reason: \"plan_limit\"`. Tell the user: they can see the held-back listings with `GET /v1/listings?status=all`, choose which are active with `POST /v1/listings/status`, or upgrade.",
|
|
7755
|
+
"required": [
|
|
7756
|
+
"code",
|
|
7757
|
+
"listingsHeldBack",
|
|
7758
|
+
"activeListingLimit",
|
|
7759
|
+
"message",
|
|
7760
|
+
"fix",
|
|
7761
|
+
"billingUrl"
|
|
7762
|
+
],
|
|
7763
|
+
"properties": {
|
|
7764
|
+
"code": {
|
|
7765
|
+
"type": "string"
|
|
7766
|
+
},
|
|
7767
|
+
"listingsHeldBack": {
|
|
7768
|
+
"type": "integer",
|
|
7769
|
+
"description": "Connected listings kept inactive because of the plan.",
|
|
7770
|
+
"example": 40
|
|
7771
|
+
},
|
|
7772
|
+
"activeListingLimit": {
|
|
7773
|
+
"type": "integer",
|
|
7774
|
+
"nullable": true,
|
|
7775
|
+
"description": "The plan's cap on active listings.",
|
|
7776
|
+
"example": 3
|
|
7777
|
+
},
|
|
7778
|
+
"message": {
|
|
7779
|
+
"type": "string",
|
|
7780
|
+
"example": "40 more connected listings are held inactive because your plan allows 3 active listings. They stay connected and keep syncing."
|
|
7781
|
+
},
|
|
7782
|
+
"fix": {
|
|
7783
|
+
"type": "string"
|
|
7784
|
+
},
|
|
7785
|
+
"billingUrl": {
|
|
7786
|
+
"type": "string",
|
|
7787
|
+
"format": "uri",
|
|
7788
|
+
"example": "https://repull.dev/dashboard/billing"
|
|
7789
|
+
}
|
|
7790
|
+
}
|
|
7791
|
+
},
|
|
7485
7792
|
"ListingPhotoUploadUrlRequest": {
|
|
7486
7793
|
"type": "object",
|
|
7487
7794
|
"required": [
|
|
7488
7795
|
"fileName",
|
|
7489
|
-
"fileType"
|
|
7796
|
+
"fileType",
|
|
7797
|
+
"fileSize"
|
|
7490
7798
|
],
|
|
7491
7799
|
"properties": {
|
|
7492
7800
|
"fileName": {
|
|
@@ -7501,8 +7809,8 @@
|
|
|
7501
7809
|
},
|
|
7502
7810
|
"fileSize": {
|
|
7503
7811
|
"type": "integer",
|
|
7504
|
-
"
|
|
7505
|
-
"
|
|
7812
|
+
"description": "File size in bytes. Required: the signed upload is issued for this size.",
|
|
7813
|
+
"example": 453631
|
|
7506
7814
|
}
|
|
7507
7815
|
}
|
|
7508
7816
|
},
|
|
@@ -7516,7 +7824,7 @@
|
|
|
7516
7824
|
"uploadUrl": {
|
|
7517
7825
|
"type": "string",
|
|
7518
7826
|
"format": "uri",
|
|
7519
|
-
"description": "PUT the raw file bytes here directly from the client. Not a Repull
|
|
7827
|
+
"description": "PUT the raw file bytes here directly from the client. Not a Repull API endpoint \u2014 a signed storage URL."
|
|
7520
7828
|
},
|
|
7521
7829
|
"token": {
|
|
7522
7830
|
"type": "string",
|
|
@@ -7534,6 +7842,10 @@
|
|
|
7534
7842
|
"expiresIn": {
|
|
7535
7843
|
"type": "integer",
|
|
7536
7844
|
"description": "Seconds until `uploadUrl` expires. Mint a new one via a fresh POST if the upload did not happen in time."
|
|
7845
|
+
},
|
|
7846
|
+
"nextStep": {
|
|
7847
|
+
"type": "string",
|
|
7848
|
+
"description": "What to do after uploading. Uploading does NOT attach the photo to the listing: send `publicUrl` in `photos` on `PUT /v1/listings/{id}/content` (with `photosMode: \"append\"` to keep existing photos)."
|
|
7537
7849
|
}
|
|
7538
7850
|
}
|
|
7539
7851
|
},
|
|
@@ -7885,6 +8197,39 @@
|
|
|
7885
8197
|
"type": "object",
|
|
7886
8198
|
"description": "A vacation rental listing in your Repull workspace.\n\nAn **inactive** listing appears only in `GET /v1/listings`, and only when `?status=` asks for it. Such a row carries identity fields only \u2014 `id`, `name`, `status`, `channels` \u2014 so `address`, `content`, `details`, `createdAt` and `updatedAt` are absent until the listing is activated. `GET /v1/listings/{id}` and every other listing endpoint answer `403 listing_inactive` for it. The one field you can add back is `thumbnailUrl`, by passing `?include=thumbnail` \u2014 enough to render an activate/deactivate picker with pictures from a single request.",
|
|
7887
8199
|
"properties": {
|
|
8200
|
+
"units": {
|
|
8201
|
+
"type": "array",
|
|
8202
|
+
"description": "`GET /v1/listings/{id}` only. The physical rooms under a hotel-model listing (a Mews or Cloudbeds room type); empty for a single home. Same items as `GET /v1/listings/{id}/units`.",
|
|
8203
|
+
"items": {
|
|
8204
|
+
"type": "object",
|
|
8205
|
+
"properties": {
|
|
8206
|
+
"id": {
|
|
8207
|
+
"type": "string"
|
|
8208
|
+
},
|
|
8209
|
+
"name": {
|
|
8210
|
+
"type": "string"
|
|
8211
|
+
},
|
|
8212
|
+
"active": {
|
|
8213
|
+
"type": "boolean"
|
|
8214
|
+
},
|
|
8215
|
+
"parentId": {
|
|
8216
|
+
"type": "string",
|
|
8217
|
+
"nullable": true
|
|
8218
|
+
},
|
|
8219
|
+
"housekeepingStatus": {
|
|
8220
|
+
"type": "string",
|
|
8221
|
+
"nullable": true
|
|
8222
|
+
},
|
|
8223
|
+
"floor": {
|
|
8224
|
+
"type": "string",
|
|
8225
|
+
"nullable": true
|
|
8226
|
+
},
|
|
8227
|
+
"source": {
|
|
8228
|
+
"type": "string"
|
|
8229
|
+
}
|
|
8230
|
+
}
|
|
8231
|
+
}
|
|
8232
|
+
},
|
|
7888
8233
|
"id": {
|
|
7889
8234
|
"type": "string",
|
|
7890
8235
|
"description": "Repull listing id"
|
|
@@ -7963,6 +8308,9 @@
|
|
|
7963
8308
|
"ListingListResponse": {
|
|
7964
8309
|
"type": "object",
|
|
7965
8310
|
"properties": {
|
|
8311
|
+
"planNotice": {
|
|
8312
|
+
"$ref": "#/components/schemas/PlanNotice"
|
|
8313
|
+
},
|
|
7966
8314
|
"data": {
|
|
7967
8315
|
"type": "array",
|
|
7968
8316
|
"items": {
|
|
@@ -7986,7 +8334,7 @@
|
|
|
7986
8334
|
"currentPrice": {
|
|
7987
8335
|
"type": "number",
|
|
7988
8336
|
"nullable": true,
|
|
7989
|
-
"description": "Current calendar price
|
|
8337
|
+
"description": "Current calendar price before applying the recommendation."
|
|
7990
8338
|
},
|
|
7991
8339
|
"recommendedPrice": {
|
|
7992
8340
|
"type": "number",
|
|
@@ -10347,7 +10695,8 @@
|
|
|
10347
10695
|
},
|
|
10348
10696
|
"status": {
|
|
10349
10697
|
"type": "string",
|
|
10350
|
-
"
|
|
10698
|
+
"description": "Same vocabulary as `GET /v1/reservations/{id}`.",
|
|
10699
|
+
"example": "confirmed"
|
|
10351
10700
|
},
|
|
10352
10701
|
"checkIn": {
|
|
10353
10702
|
"type": "string",
|
|
@@ -10364,28 +10713,79 @@
|
|
|
10364
10713
|
"totalPrice": {
|
|
10365
10714
|
"type": "number",
|
|
10366
10715
|
"nullable": true,
|
|
10367
|
-
"description": "The price the pricing engine derived for the stay. Reservations created through this endpoint are NOT priced from the request \u2014 see the operation description."
|
|
10716
|
+
"description": "The price the pricing engine derived for the stay. Reservations created through this endpoint are NOT priced from the request \u2014 see the operation description. On a Mews or Cloudbeds listing, the PMS prices it from its own rate."
|
|
10368
10717
|
},
|
|
10369
10718
|
"currency": {
|
|
10370
10719
|
"type": "string",
|
|
10371
10720
|
"nullable": true
|
|
10372
|
-
}
|
|
10373
|
-
}
|
|
10374
|
-
},
|
|
10375
|
-
"ReservationUpdateRequest": {
|
|
10376
|
-
"type": "object",
|
|
10377
|
-
"minProperties": 1,
|
|
10378
|
-
"description": "At least one field is required. Guest identity, pricing, `status`, `platform` and notes are rejected by name \u2014 see the operation description for why each is excluded.",
|
|
10379
|
-
"properties": {
|
|
10380
|
-
"checkIn": {
|
|
10381
|
-
"type": "string",
|
|
10382
|
-
"format": "date",
|
|
10383
|
-
"example": "2026-10-02"
|
|
10384
10721
|
},
|
|
10385
|
-
"
|
|
10386
|
-
"type": "
|
|
10387
|
-
"
|
|
10388
|
-
"
|
|
10722
|
+
"unit": {
|
|
10723
|
+
"type": "object",
|
|
10724
|
+
"nullable": true,
|
|
10725
|
+
"description": "Mews or Cloudbeds listings only: the room the PMS assigned. Absent for every other listing.",
|
|
10726
|
+
"properties": {
|
|
10727
|
+
"id": {
|
|
10728
|
+
"type": "string"
|
|
10729
|
+
},
|
|
10730
|
+
"name": {
|
|
10731
|
+
"type": "string",
|
|
10732
|
+
"nullable": true
|
|
10733
|
+
}
|
|
10734
|
+
}
|
|
10735
|
+
},
|
|
10736
|
+
"pms": {
|
|
10737
|
+
"type": "object",
|
|
10738
|
+
"description": "Mews or Cloudbeds listings only: the booking was made in the PMS first, and this is what it applied.",
|
|
10739
|
+
"properties": {
|
|
10740
|
+
"provider": {
|
|
10741
|
+
"type": "string",
|
|
10742
|
+
"example": "mews"
|
|
10743
|
+
},
|
|
10744
|
+
"reservationId": {
|
|
10745
|
+
"type": "string",
|
|
10746
|
+
"description": "The PMS's own id for the booking."
|
|
10747
|
+
},
|
|
10748
|
+
"applied": {
|
|
10749
|
+
"type": "array",
|
|
10750
|
+
"items": {
|
|
10751
|
+
"type": "string"
|
|
10752
|
+
}
|
|
10753
|
+
},
|
|
10754
|
+
"errors": {
|
|
10755
|
+
"type": "array",
|
|
10756
|
+
"items": {
|
|
10757
|
+
"type": "object",
|
|
10758
|
+
"properties": {
|
|
10759
|
+
"section": {
|
|
10760
|
+
"type": "string"
|
|
10761
|
+
},
|
|
10762
|
+
"message": {
|
|
10763
|
+
"type": "string"
|
|
10764
|
+
},
|
|
10765
|
+
"code": {
|
|
10766
|
+
"type": "string"
|
|
10767
|
+
}
|
|
10768
|
+
}
|
|
10769
|
+
}
|
|
10770
|
+
}
|
|
10771
|
+
}
|
|
10772
|
+
}
|
|
10773
|
+
}
|
|
10774
|
+
},
|
|
10775
|
+
"ReservationUpdateRequest": {
|
|
10776
|
+
"type": "object",
|
|
10777
|
+
"minProperties": 1,
|
|
10778
|
+
"description": "At least one field is required. Guest identity, pricing, `status`, `platform` and notes are rejected by name \u2014 see the operation description for why each is excluded.",
|
|
10779
|
+
"properties": {
|
|
10780
|
+
"checkIn": {
|
|
10781
|
+
"type": "string",
|
|
10782
|
+
"format": "date",
|
|
10783
|
+
"example": "2026-10-02"
|
|
10784
|
+
},
|
|
10785
|
+
"checkOut": {
|
|
10786
|
+
"type": "string",
|
|
10787
|
+
"format": "date",
|
|
10788
|
+
"example": "2026-10-07"
|
|
10389
10789
|
},
|
|
10390
10790
|
"checkInTime": {
|
|
10391
10791
|
"type": "string",
|
|
@@ -11137,7 +11537,11 @@
|
|
|
11137
11537
|
},
|
|
11138
11538
|
"mapped": {
|
|
11139
11539
|
"type": "integer",
|
|
11140
|
-
"description": "
|
|
11540
|
+
"description": "Rooms now linked to a listing."
|
|
11541
|
+
},
|
|
11542
|
+
"unmapped": {
|
|
11543
|
+
"type": "integer",
|
|
11544
|
+
"description": "Rooms submitted with `listingId: null` (\"don't map\"), which are left without a listing."
|
|
11141
11545
|
},
|
|
11142
11546
|
"sessionId": {
|
|
11143
11547
|
"type": "string"
|
|
@@ -11148,7 +11552,12 @@
|
|
|
11148
11552
|
"reservationsImported": {
|
|
11149
11553
|
"type": "integer",
|
|
11150
11554
|
"nullable": true,
|
|
11151
|
-
"description": "Reservations pulled from Booking.com once the rooms were mapped. Mapping triggers the same full property sync the dashboard's Sync button runs, because a reservation can only be resolved to a listing through a mapped room. `null` means the sync could not be run \u2014 the connection and mapping are still good, and the property can be synced from the dashboard."
|
|
11555
|
+
"description": "Reservations pulled from Booking.com once the rooms were mapped. Mapping triggers the same full property sync the dashboard's Sync button runs, because a reservation can only be resolved to a listing through a mapped room. `0` without a sync when no room was mapped. `null` means the sync could not be run \u2014 the connection and mapping are still good, and the property can be synced from the dashboard."
|
|
11556
|
+
},
|
|
11557
|
+
"reservationsFound": {
|
|
11558
|
+
"type": "integer",
|
|
11559
|
+
"nullable": true,
|
|
11560
|
+
"description": "How many reservations Booking.com returned for the property. Equal to `reservationsImported` unless some could not be attached to a listing \u2014 so `0` here means Booking.com had none. `null` when the sync could not run."
|
|
11152
11561
|
}
|
|
11153
11562
|
},
|
|
11154
11563
|
"required": [
|
|
@@ -11313,6 +11722,11 @@
|
|
|
11313
11722
|
"type": "integer",
|
|
11314
11723
|
"nullable": true,
|
|
11315
11724
|
"description": "Reservations Booking.com returned for the property and ran through the import after the room was mapped \u2014 the property's active bookings, which would otherwise never reach the listing. A reservation already present is left as it is, so this counts what was processed, not what was new, and re-sending never duplicates. Runs on every successful map, including a re-map to the same listing, so re-sending retries an import that did not run. `null` means the mapping succeeded but the import could not run; the room is still mapped. Absent after an unmap, when there is nothing to pull."
|
|
11725
|
+
},
|
|
11726
|
+
"reservationsFound": {
|
|
11727
|
+
"type": "integer",
|
|
11728
|
+
"nullable": true,
|
|
11729
|
+
"description": "How many reservations Booking.com returned for the property. Equal to `reservationsImported` unless some could not be attached \u2014 so `0` here means Booking.com had none. Same `null` / absent rules as `reservationsImported`."
|
|
11316
11730
|
}
|
|
11317
11731
|
}
|
|
11318
11732
|
},
|
|
@@ -11365,7 +11779,7 @@
|
|
|
11365
11779
|
},
|
|
11366
11780
|
"verified": {
|
|
11367
11781
|
"type": "boolean",
|
|
11368
|
-
"description": "True when the result was confirmed by reading the listing back from Airbnb
|
|
11782
|
+
"description": "True when the result was confirmed by reading the listing back from Airbnb, on `unlist` and `relist` alike: Airbnb accepting the call is not proof the listing came down or went live. `false` means the read-back could not run \u2014 an unknown, not a success. A read-back that shows the wrong state is returned as an error, not as `verified: false`."
|
|
11369
11783
|
}
|
|
11370
11784
|
}
|
|
11371
11785
|
},
|
|
@@ -11615,7 +12029,7 @@
|
|
|
11615
12029
|
},
|
|
11616
12030
|
"verified": {
|
|
11617
12031
|
"type": "boolean",
|
|
11618
|
-
"description": "Airbnb only
|
|
12032
|
+
"description": "Airbnb only: the listing was READ BACK afterwards and is in the state asked for \u2014 down after `offline`, live after `online`. Airbnb can accept a deactivation and leave a listing live, or accept an activation and keep it offline; either is returned as a failure, never as success. `false` means the read-back could not run \u2014 an unknown, not a success."
|
|
11619
12033
|
}
|
|
11620
12034
|
}
|
|
11621
12035
|
},
|
|
@@ -12329,7 +12743,7 @@
|
|
|
12329
12743
|
"$ref": "#/components/schemas/Error"
|
|
12330
12744
|
},
|
|
12331
12745
|
"examples": {
|
|
12332
|
-
"
|
|
12746
|
+
"onInactiveListing": {
|
|
12333
12747
|
"summary": "The listing is inactive",
|
|
12334
12748
|
"value": {
|
|
12335
12749
|
"error": {
|
|
@@ -12524,7 +12938,7 @@
|
|
|
12524
12938
|
}
|
|
12525
12939
|
}
|
|
12526
12940
|
},
|
|
12527
|
-
"
|
|
12941
|
+
"onInactiveListing": {
|
|
12528
12942
|
"summary": "The listing is inactive",
|
|
12529
12943
|
"value": {
|
|
12530
12944
|
"error": {
|
|
@@ -12828,8 +13242,8 @@
|
|
|
12828
13242
|
"/v1/properties": {
|
|
12829
13243
|
"get": {
|
|
12830
13244
|
"operationId": "list_properties",
|
|
12831
|
-
"summary": "List properties",
|
|
12832
|
-
"description": "
|
|
13245
|
+
"summary": "List properties (older name for /v1/listings)",
|
|
13246
|
+
"description": "**`/v1/properties` is the older name for `/v1/listings`** \u2014 the same listings, the same ids. It stays for existing integrations; new code should use `/v1/listings`, which is where create, content, publishing and markups live.\n\nCursor-paginated list of properties for the authenticated workspace. Walk pages with `?cursor=<pagination.nextCursor>`; stop when `pagination.hasMore` is `false`. Cursor is opaque base64 \u2014 do not parse it.\n\n`?offset=` is also accepted as a first-class alias for shallow paging (0..10000) \u2014 see the `offset` parameter below. Mutually exclusive with `cursor`.\n\nFilters: `q` (substring on name/street/city), `status` (active|inactive|all), `lifecycle_status` (exact match on the listing's lifecycle state). Other unknown params (e.g. `?search=` or `?propertyId=`) are rejected with 422 \u2014 no silent unfiltered results.\n\n**Incremental sync (only changes since last poll):** pass `?updated_since=<ISO8601>` to receive only properties changed at or after that instant. Each property carries `updatedAt` \u2014 the last row of the final page is your next watermark. `updated_since` changes the page ordering to `updatedAt ASC, id ASC` (and the cursor with it); see the parameter description. `GET /v1/listings` does NOT yet accept `updated_since` \u2014 use this endpoint for property-side incremental sync.\n\n**Inactive properties:** an inactive property keeps syncing, but cannot be read or changed through the API until it is activated. They are only listed when `status` asks for them, and then with `id`, `name`, `status`, `lifecycleStatus`, `channels` and `updatedAt` only \u2014 enough to choose what to activate with `PATCH /v1/listings/{id}`.",
|
|
12833
13247
|
"tags": [
|
|
12834
13248
|
"Properties"
|
|
12835
13249
|
],
|
|
@@ -12931,8 +13345,8 @@
|
|
|
12931
13345
|
"/v1/properties/{id}": {
|
|
12932
13346
|
"get": {
|
|
12933
13347
|
"operationId": "get_property",
|
|
12934
|
-
"description": "
|
|
12935
|
-
"summary": "Get property details",
|
|
13348
|
+
"description": "**`/v1/properties` is the older name for `/v1/listings`** \u2014 the same listings, the same ids. It stays for existing integrations; new code should use `/v1/listings`, which is where create, content, publishing and markups live.\n\nFetch a single property by Repull id. Property ids are workspace-scoped \u2014 an id from one workspace is not valid in another. 404 means the id does not exist OR belongs to a different workspace.\n\n**Optional expansions:** Pass `?include=amenities` to enrich the response with the property's amenities (sourced from the unified `listings_amenities` table). Returns `[]` when the property has no amenity rows. The default response stays lean; consumers must opt in.\n\nReturns `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.",
|
|
13349
|
+
"summary": "Get property details (older name for /v1/listings/{id})",
|
|
12936
13350
|
"tags": [
|
|
12937
13351
|
"Properties"
|
|
12938
13352
|
],
|
|
@@ -12985,7 +13399,7 @@
|
|
|
12985
13399
|
"get": {
|
|
12986
13400
|
"operationId": "get_availability",
|
|
12987
13401
|
"summary": "Get property availability",
|
|
12988
|
-
"description": "Channel-agnostic day-by-day availability calendar for a property over a date window. Returns a thin per-date shape \u2014 `{ date, available, price, minNights }` \u2014 projected from the property calendar.\n\nThe `from` and `to` query params are **required** (ISO `YYYY-MM-DD`, inclusive) \u2014 omitting or malforming either returns 422. The window is capped at 366 days; longer ranges are truncated to the first 366 days.\n\n**`days` contains only the dates we actually hold calendar data for.** Requested dates with no calendar row are listed in `coverage.missingDates` \u2014 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 \u2014 404 means the property id does not exist or belongs to a different workspace.\n\nThis endpoint is read-only, and the projected per-date shape carries **availability, price, and min-nights only** \u2014 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.\n\nReturns `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.",
|
|
13402
|
+
"description": "Channel-agnostic day-by-day availability calendar for a property over a date window. Returns a thin per-date shape \u2014 `{ date, available, price, minNights, availableUnits }` \u2014 projected from the property calendar. `availableUnits` is 1 or 0 for a single home, and the rooms of the type left for a hotel-model listing (a Mews or Cloudbeds room type).\n\nThe `from` and `to` query params are **required** (ISO `YYYY-MM-DD`, inclusive) \u2014 omitting or malforming either returns 422. The window is capped at 366 days; longer ranges are truncated to the first 366 days.\n\n**`days` contains only the dates we actually hold calendar data for.** Requested dates with no calendar row are listed in `coverage.missingDates` \u2014 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 \u2014 404 means the property id does not exist or belongs to a different workspace.\n\nThis endpoint is read-only, and the projected per-date shape carries **availability, units left, price, and min-nights only** \u2014 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.\n\nReturns `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.",
|
|
12989
13403
|
"tags": [
|
|
12990
13404
|
"Availability"
|
|
12991
13405
|
],
|
|
@@ -13636,7 +14050,7 @@
|
|
|
13636
14050
|
"get": {
|
|
13637
14051
|
"operationId": "getGuest",
|
|
13638
14052
|
"summary": "Get guest profile",
|
|
13639
|
-
"description": "Returns the full guest profile \u2014 base list-row fields plus contacts, flags, notes, risk metadata, and reservation aggregates
|
|
14053
|
+
"description": "Returns the full guest profile \u2014 base list-row fields plus contacts, flags, notes, risk metadata, and reservation aggregates.\n\n**Inactive listings:** a guest whose every reservation is on an inactive listing returns `403 listing_inactive` naming those listings (the guest is kept, so this is not a 404). Otherwise the reservation aggregates exclude reservations on inactive listings. A guest with no reservations is always readable.",
|
|
13640
14054
|
"tags": [
|
|
13641
14055
|
"Guests"
|
|
13642
14056
|
],
|
|
@@ -13710,7 +14124,7 @@
|
|
|
13710
14124
|
"get": {
|
|
13711
14125
|
"operationId": "listConversations",
|
|
13712
14126
|
"summary": "List conversations",
|
|
13713
|
-
"description": "Cursor-paginated list of message threads owned by the workspace.
|
|
14127
|
+
"description": "Cursor-paginated list of message threads owned by the workspace. Use `pagination.nextCursor` from one response as the `cursor` query param of the next request.\n\n`?offset=` is also accepted as a first-class alias for shallow paging (0..10000) \u2014 see the `offset` parameter below. Mutually exclusive with `cursor`.\n\nFilters: `platform` (`airbnb`|`booking`|`vrbo`|`website`|`email`), `status` (`open`|`archived` \u2014 `archived` is a stable no-op until the bit lands on `message_threads`).\n\n**Inactive listings:** conversations that belong to an inactive listing (by the thread's listing or its reservation's listing) are left out of the page and of `pagination.total`. Inactive listings keep syncing; activate the listing to use it here.",
|
|
13714
14128
|
"tags": [
|
|
13715
14129
|
"Conversations"
|
|
13716
14130
|
],
|
|
@@ -14348,7 +14762,7 @@
|
|
|
14348
14762
|
"get": {
|
|
14349
14763
|
"operationId": "listReviews",
|
|
14350
14764
|
"summary": "List reviews",
|
|
14351
|
-
"description": "Cursor-paginated guest + host review stream for the workspace.
|
|
14765
|
+
"description": "Cursor-paginated guest + host review stream for the workspace. This surface returns the complete cross-channel history \u2014 separate from `/v1/channels/airbnb/reviews` which hits Airbnb live.\n\n`?offset=` is also accepted as a first-class alias for shallow paging (0..10000) \u2014 see the `offset` parameter below. Mutually exclusive with `cursor`.\n\nFilters: `platform` (`airbnb`|`booking`|`vrbo`), `listing_id` (internal Repull listing id), `rating_min` / `rating_max` (inclusive bounds, 0..5), `status` (`responded`|`unanswered`|`all`), `reviewer_role` (`guest` (default) | `host` | `all`).\n\n**Inactive listings:** reviews of inactive listings are left out of the page and of `pagination.total`. Filtering by an inactive `listing_id` returns `403 listing_inactive`. Inactive listings keep syncing; activate the listing to use it here.",
|
|
14352
14766
|
"tags": [
|
|
14353
14767
|
"Reviews"
|
|
14354
14768
|
],
|
|
@@ -16876,7 +17290,7 @@
|
|
|
16876
17290
|
"get": {
|
|
16877
17291
|
"operationId": "get_airbnb_listing",
|
|
16878
17292
|
"summary": "Get Airbnb listing",
|
|
16879
|
-
"description": "Fetch all Airbnb connection rows for a single
|
|
17293
|
+
"description": "Fetch all Airbnb connection rows for a single Repull listing id. A property may be linked from multiple Airbnb hosts \u2014 every match is returned. Pass `?include=amenities` to enrich each row with its current Airbnb amenities.\n\nEach row carries `syncCategory` \u2014 Airbnb's own per-listing API sync decision (`sync_all`, `sync_rates_and_availability`, or `none`) \u2014 and `writable`, which is `false` exactly when that category is `none`, meaning Airbnb refuses every write to the listing and Repull returns `403 listing_not_api_connected` without sending anything. `GET /v1/channels/airbnb/listings` reports both fields for the whole portfolio in one call.\n\nReturns `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.",
|
|
16880
17294
|
"tags": [
|
|
16881
17295
|
"Airbnb"
|
|
16882
17296
|
],
|
|
@@ -16918,7 +17332,7 @@
|
|
|
16918
17332
|
"post": {
|
|
16919
17333
|
"operationId": "airbnb_listing_action",
|
|
16920
17334
|
"summary": "Listing action (delete/push/publish/unlist/relist)",
|
|
16921
|
-
"description": "Apply a state action to a listing by id. The path `id` is the canonical Repull listing id.\n\n**`delete` here never touches Airbnb. Read this before you call it.**\n\n| | `action: \"delete\"` (this endpoint) | `action: \"unlist\"` (this endpoint) |\n|---|---|---|\n| What it changes | The Repull record | The live Airbnb listing |\n| Calls Airbnb | **No. Never.** | Yes |\n| The guest-facing listing | Stays live and keeps taking bookings | **Goes down** and stops taking bookings |\n| Billing and plan limits | No longer billed, no longer counts toward the cap | Unchanged |\n| API access to the listing | `403 listing_inactive` until reactivated | Unchanged \u2014 you can still read and write it |\n| Reverse it with | `PATCH /v1/listings/{id}` `{ \"active\": true }` | `action: \"relist\"` |\n| Data kept | Yes, and it keeps syncing | Yes |\n\nNeither one deletes anything on Airbnb. **There is no endpoint on this API that deletes an Airbnb listing** \u2014 the word `delete` on this route means \"deactivate the Repull record\" and nothing else
|
|
17335
|
+
"description": "Apply a state action to a listing by id. The path `id` is the canonical Repull listing id.\n\n**`delete` here never touches Airbnb. Read this before you call it.**\n\n| | `action: \"delete\"` (this endpoint) | `action: \"unlist\"` (this endpoint) |\n|---|---|---|\n| What it changes | The Repull record | The live Airbnb listing |\n| Calls Airbnb | **No. Never.** | Yes |\n| The guest-facing listing | Stays live and keeps taking bookings | **Goes down** and stops taking bookings |\n| Billing and plan limits | No longer billed, no longer counts toward the cap | Unchanged |\n| API access to the listing | `403 listing_inactive` until reactivated | Unchanged \u2014 you can still read and write it |\n| Reverse it with | `PATCH /v1/listings/{id}` `{ \"active\": true }` | `action: \"relist\"` |\n| Data kept | Yes, and it keeps syncing | Yes |\n\nNeither one deletes anything on Airbnb. **There is no endpoint on this API that deletes an Airbnb listing** \u2014 the word `delete` on this route means \"deactivate the Repull record\" and nothing else.\n\n`delete` is idempotent. To take a listing off the market on every channel at once \u2014 Airbnb and Booking.com together \u2014 use `POST /v1/listings/{id}/offline`.\n\n`unlist` calls Airbnb and **takes the live listing down**: it is deactivated with a valid deactivation reason and then READ BACK, so \"Airbnb accepted the call but the listing is still live\" is reported as a failure rather than a success. Requires `airbnbConnectionId` \u2014 a listing can be connected to more than one Airbnb listing, and taking down the wrong one is not undoable through this API. `relist` puts it back up (re-enables sync and makes the listing available again); it does not push content.\n\n`relist` goes through the channel-publish billing gate and `unlist` does not, so on a workspace whose subscription has lapsed a listing can be taken down and not put back until billing is sorted out. That refusal comes back as `402` with the action that fixes it \u2014 never as an Airbnb error, because retrying and reconnecting Airbnb do nothing for it.\n\n`push` / `publish` push the listing's content to Airbnb via the same host-side sync orchestrator as `POST /v1/listings/{id}/publish/airbnb` \u2014 pass `airbnbConnectionId` to update an already-mapped Airbnb listing, or `hostId` to create + publish a new one under that host. `force` re-pushes every field, ignoring dirty-field tracking. The result is per-section: see `AirbnbPublishResult`.\n\nAny other action (e.g. `pull`) returns a structured 422 naming the supported actions.\n\nReturns `403 listing_inactive` for `push`/`publish`/`unlist`/`relist` when the listing is inactive. `delete` (deactivation) is always accepted.",
|
|
16922
17336
|
"tags": [
|
|
16923
17337
|
"Airbnb"
|
|
16924
17338
|
],
|
|
@@ -18038,13 +18452,26 @@
|
|
|
18038
18452
|
"$ref": "#/components/responses/Unauthorized"
|
|
18039
18453
|
},
|
|
18040
18454
|
"403": {
|
|
18041
|
-
"description": "`connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired
|
|
18455
|
+
"description": "`insufficient_access` \u2014 the Airbnb account is connected with read-only or messaging access; this action needs full access (Airbnb's `property_management` permission). Nothing was sent to Airbnb; reconnect with `accessType: full_access`. `connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired or revoked). Reconnect; retrying cannot succeed. `listing_inactive` \u2014 the listing is inactive.",
|
|
18042
18456
|
"content": {
|
|
18043
18457
|
"application/json": {
|
|
18044
18458
|
"schema": {
|
|
18045
18459
|
"$ref": "#/components/schemas/Error"
|
|
18046
18460
|
},
|
|
18047
18461
|
"examples": {
|
|
18462
|
+
"insufficientAccess": {
|
|
18463
|
+
"summary": "The Airbnb account is not connected with full access",
|
|
18464
|
+
"value": {
|
|
18465
|
+
"error": {
|
|
18466
|
+
"code": "insufficient_access",
|
|
18467
|
+
"message": "This Airbnb account is connected with messaging access, which cannot accept or decline booking requests. It needs full access.",
|
|
18468
|
+
"fix": "Reconnect this Airbnb account with full access \u2014 `POST /v1/connect/airbnb` with `\"accessType\": \"full_access\"` \u2014 then retry.",
|
|
18469
|
+
"docs_url": "https://repull.dev/docs/errors/insufficient_access",
|
|
18470
|
+
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
|
|
18471
|
+
"accessType": "messaging"
|
|
18472
|
+
}
|
|
18473
|
+
}
|
|
18474
|
+
},
|
|
18048
18475
|
"reauth": {
|
|
18049
18476
|
"summary": "The Airbnb connection no longer allows this",
|
|
18050
18477
|
"value": {
|
|
@@ -18743,25 +19170,105 @@
|
|
|
18743
19170
|
"/v1/channels/airbnb/transactions": {
|
|
18744
19171
|
"get": {
|
|
18745
19172
|
"operationId": "list_airbnb_transactions",
|
|
18746
|
-
"summary": "List Airbnb transactions",
|
|
18747
|
-
"description": "
|
|
19173
|
+
"summary": "List Airbnb transactions (settlement ledger)",
|
|
19174
|
+
"description": "The Airbnb settlement ledger for this workspace: every payout Airbnb sent to the host, each followed by the lines it paid \u2014 reservations and their installments, adjustments, resolution payouts and adjustments, cancellation fees. A payout's lines' signed `amount`s sum to its `payout.paidOutAmount` exactly, negative lines included (an adjustment offset against a later payout appears under that payout). `status: UPCOMING` lines are expected earnings not paid out yet; they belong to no payout.\n\n**Ids are stable.** Airbnb sends no line id and no payout id on lines, so Repull derives them deterministically: a Payout row's id is Airbnb's payout id; a line's is `<payoutId>:<type>:<confirmationCode>:<n>`. The same line has the same id on every refresh and every page, so you can upsert on `transactionId`. A payout that nets to $0.00 has no Airbnb id; it gets a derived `Z-<date>-<hash>` id with `payout.payoutIdSynthetic: true`.\n\n**Order:** newest first by the payout's date; each Payout row is followed by its lines in Airbnb's order (`payout.lineIndex`).\n\n**Dates:** `start_date` / `end_date` match the payout's date for settled lines (a line can be dated the day before its payout, and is still returned with it) and the line's own date for UPCOMING lines.\n\n**Pure DB read** \u2014 never calls Airbnb. Refresh with `POST` on this path. `dataFreshness` reports when each account's ledger was last refreshed.\n\nLines on listings that are inactive in Repull are included and flagged `onInactiveListing: true`, so every payout reconciles. Lines Repull cannot match to a reservation keep `reservationId: null`.\n\n**Not in Airbnb's transaction history** (listed in `unavailableFields`): taxes Airbnb collects and remits itself, and the guest-paid total (see the reservation's financial breakdown); pass-through occupancy tax paid to the host does appear, as its own `Pass Through Tot` lines, the original line a refund or reversal reverses (it names the stay and the resolution), and currency-conversion amounts (only the payout currency is reported).",
|
|
18748
19175
|
"tags": [
|
|
18749
19176
|
"Airbnb"
|
|
18750
19177
|
],
|
|
18751
19178
|
"parameters": [
|
|
18752
19179
|
{
|
|
18753
19180
|
"$ref": "#/components/parameters/AirbnbAccountId"
|
|
19181
|
+
},
|
|
19182
|
+
{
|
|
19183
|
+
"name": "start_date",
|
|
19184
|
+
"in": "query",
|
|
19185
|
+
"required": false,
|
|
19186
|
+
"description": "Inclusive lower bound on the payout's date (the line's own date for UPCOMING lines). YYYY-MM-DD.",
|
|
19187
|
+
"schema": {
|
|
19188
|
+
"type": "string",
|
|
19189
|
+
"format": "date"
|
|
19190
|
+
}
|
|
19191
|
+
},
|
|
19192
|
+
{
|
|
19193
|
+
"name": "end_date",
|
|
19194
|
+
"in": "query",
|
|
19195
|
+
"required": false,
|
|
19196
|
+
"description": "Inclusive upper bound, as `start_date`.",
|
|
19197
|
+
"schema": {
|
|
19198
|
+
"type": "string",
|
|
19199
|
+
"format": "date"
|
|
19200
|
+
}
|
|
19201
|
+
},
|
|
19202
|
+
{
|
|
19203
|
+
"name": "status",
|
|
19204
|
+
"in": "query",
|
|
19205
|
+
"required": false,
|
|
19206
|
+
"description": "`COMPLETED` (settled) or `UPCOMING` (expected).",
|
|
19207
|
+
"schema": {
|
|
19208
|
+
"type": "string",
|
|
19209
|
+
"enum": [
|
|
19210
|
+
"COMPLETED",
|
|
19211
|
+
"UPCOMING"
|
|
19212
|
+
]
|
|
19213
|
+
}
|
|
19214
|
+
},
|
|
19215
|
+
{
|
|
19216
|
+
"name": "type",
|
|
19217
|
+
"in": "query",
|
|
19218
|
+
"required": false,
|
|
19219
|
+
"description": "Airbnb's line type, exact match ignoring case \u2014 e.g. `Payout`, `Reservation`, `Adjustment`, `Resolution Payout`.",
|
|
19220
|
+
"schema": {
|
|
19221
|
+
"type": "string"
|
|
19222
|
+
}
|
|
19223
|
+
},
|
|
19224
|
+
{
|
|
19225
|
+
"name": "payout_id",
|
|
19226
|
+
"in": "query",
|
|
19227
|
+
"required": false,
|
|
19228
|
+
"description": "One payout: its Payout row and all its lines.",
|
|
19229
|
+
"schema": {
|
|
19230
|
+
"type": "string"
|
|
19231
|
+
}
|
|
19232
|
+
},
|
|
19233
|
+
{
|
|
19234
|
+
"name": "confirmation_code",
|
|
19235
|
+
"in": "query",
|
|
19236
|
+
"required": false,
|
|
19237
|
+
"description": "Every line for one reservation \u2014 each installment, adjustment and resolution.",
|
|
19238
|
+
"schema": {
|
|
19239
|
+
"type": "string"
|
|
19240
|
+
}
|
|
19241
|
+
},
|
|
19242
|
+
{
|
|
19243
|
+
"name": "limit",
|
|
19244
|
+
"in": "query",
|
|
19245
|
+
"schema": {
|
|
19246
|
+
"type": "integer",
|
|
19247
|
+
"default": 100,
|
|
19248
|
+
"minimum": 1,
|
|
19249
|
+
"maximum": 500
|
|
19250
|
+
},
|
|
19251
|
+
"description": "Lines per page. Hard cap is 500."
|
|
19252
|
+
},
|
|
19253
|
+
{
|
|
19254
|
+
"name": "cursor",
|
|
19255
|
+
"in": "query",
|
|
19256
|
+
"schema": {
|
|
19257
|
+
"type": "string"
|
|
19258
|
+
},
|
|
19259
|
+
"description": "Opaque cursor returned by the previous response's `pagination.nextCursor`. Omit to fetch the first page."
|
|
18754
19260
|
}
|
|
18755
19261
|
],
|
|
18756
19262
|
"responses": {
|
|
18757
19263
|
"200": {
|
|
18758
|
-
"description": "
|
|
19264
|
+
"description": "Ledger lines",
|
|
18759
19265
|
"content": {
|
|
18760
19266
|
"application/json": {
|
|
18761
19267
|
"schema": {
|
|
18762
19268
|
"type": "object",
|
|
18763
19269
|
"required": [
|
|
18764
19270
|
"data",
|
|
19271
|
+
"pagination",
|
|
18765
19272
|
"dataFreshness"
|
|
18766
19273
|
],
|
|
18767
19274
|
"properties": {
|
|
@@ -18771,6 +19278,9 @@
|
|
|
18771
19278
|
"$ref": "#/components/schemas/AirbnbTransaction"
|
|
18772
19279
|
}
|
|
18773
19280
|
},
|
|
19281
|
+
"pagination": {
|
|
19282
|
+
"$ref": "#/components/schemas/Pagination"
|
|
19283
|
+
},
|
|
18774
19284
|
"dataFreshness": {
|
|
18775
19285
|
"$ref": "#/components/schemas/AirbnbDataFreshness"
|
|
18776
19286
|
}
|
|
@@ -18785,6 +19295,16 @@
|
|
|
18785
19295
|
"404": {
|
|
18786
19296
|
"$ref": "#/components/responses/AirbnbAccountNotFound"
|
|
18787
19297
|
},
|
|
19298
|
+
"422": {
|
|
19299
|
+
"description": "A filter or body field is malformed (dates are YYYY-MM-DD; status is COMPLETED or UPCOMING).",
|
|
19300
|
+
"content": {
|
|
19301
|
+
"application/json": {
|
|
19302
|
+
"schema": {
|
|
19303
|
+
"$ref": "#/components/schemas/Error"
|
|
19304
|
+
}
|
|
19305
|
+
}
|
|
19306
|
+
}
|
|
19307
|
+
},
|
|
18788
19308
|
"500": {
|
|
18789
19309
|
"$ref": "#/components/responses/InternalError"
|
|
18790
19310
|
}
|
|
@@ -18792,11 +19312,16 @@
|
|
|
18792
19312
|
},
|
|
18793
19313
|
"post": {
|
|
18794
19314
|
"operationId": "sync_airbnb_transactions",
|
|
18795
|
-
"summary": "
|
|
18796
|
-
"description": "
|
|
19315
|
+
"summary": "Refresh Airbnb transactions",
|
|
19316
|
+
"description": "Pull the transaction history from Airbnb into the ledger `GET` serves. Every connected Airbnb account is refreshed, or only `?account_id=`. Without dates: settled lines from the last 12 months and the forecast for the next 12. Safe to repeat: settled lines are upserted on their stable ids, never duplicated or removed; the UPCOMING forecast inside the fetched window is replaced, so a line that has since been paid out moves to its payout. Each account reports its own outcome in `accounts[]`: one account Airbnb refuses (a revoked host, a listing Airbnb no longer serves) is reported there with Airbnb's reason and does not stop the others. When every account fails, the response is Airbnb's answer with its usual code.",
|
|
18797
19317
|
"tags": [
|
|
18798
19318
|
"Airbnb"
|
|
18799
19319
|
],
|
|
19320
|
+
"parameters": [
|
|
19321
|
+
{
|
|
19322
|
+
"$ref": "#/components/parameters/AirbnbAccountId"
|
|
19323
|
+
}
|
|
19324
|
+
],
|
|
18800
19325
|
"requestBody": {
|
|
18801
19326
|
"required": false,
|
|
18802
19327
|
"content": {
|
|
@@ -18807,19 +19332,20 @@
|
|
|
18807
19332
|
"start_date": {
|
|
18808
19333
|
"type": "string",
|
|
18809
19334
|
"format": "date",
|
|
18810
|
-
"description": "Inclusive lower bound
|
|
19335
|
+
"description": "Inclusive lower bound (YYYY-MM-DD)."
|
|
18811
19336
|
},
|
|
18812
19337
|
"end_date": {
|
|
18813
19338
|
"type": "string",
|
|
18814
19339
|
"format": "date",
|
|
18815
|
-
"description": "Inclusive upper bound
|
|
19340
|
+
"description": "Inclusive upper bound (YYYY-MM-DD)."
|
|
18816
19341
|
},
|
|
18817
19342
|
"transaction_type": {
|
|
18818
19343
|
"type": "string",
|
|
18819
19344
|
"enum": [
|
|
18820
19345
|
"COMPLETED",
|
|
18821
19346
|
"UPCOMING"
|
|
18822
|
-
]
|
|
19347
|
+
],
|
|
19348
|
+
"description": "Refresh only settled or only upcoming lines. Both when omitted."
|
|
18823
19349
|
}
|
|
18824
19350
|
}
|
|
18825
19351
|
}
|
|
@@ -18828,14 +19354,15 @@
|
|
|
18828
19354
|
},
|
|
18829
19355
|
"responses": {
|
|
18830
19356
|
"200": {
|
|
18831
|
-
"description": "
|
|
19357
|
+
"description": "Refresh result",
|
|
18832
19358
|
"content": {
|
|
18833
19359
|
"application/json": {
|
|
18834
19360
|
"schema": {
|
|
18835
19361
|
"type": "object",
|
|
18836
19362
|
"required": [
|
|
18837
19363
|
"synced",
|
|
18838
|
-
"count"
|
|
19364
|
+
"count",
|
|
19365
|
+
"accounts"
|
|
18839
19366
|
],
|
|
18840
19367
|
"properties": {
|
|
18841
19368
|
"synced": {
|
|
@@ -18843,7 +19370,52 @@
|
|
|
18843
19370
|
},
|
|
18844
19371
|
"count": {
|
|
18845
19372
|
"type": "integer",
|
|
18846
|
-
"description": "
|
|
19373
|
+
"description": "Ledger lines written, Payout rows included."
|
|
19374
|
+
},
|
|
19375
|
+
"accounts": {
|
|
19376
|
+
"type": "array",
|
|
19377
|
+
"items": {
|
|
19378
|
+
"type": "object",
|
|
19379
|
+
"required": [
|
|
19380
|
+
"accountId",
|
|
19381
|
+
"count",
|
|
19382
|
+
"payouts",
|
|
19383
|
+
"upcomingRemoved"
|
|
19384
|
+
],
|
|
19385
|
+
"properties": {
|
|
19386
|
+
"accountId": {
|
|
19387
|
+
"type": "string",
|
|
19388
|
+
"description": "Airbnb host id."
|
|
19389
|
+
},
|
|
19390
|
+
"count": {
|
|
19391
|
+
"type": "integer"
|
|
19392
|
+
},
|
|
19393
|
+
"payouts": {
|
|
19394
|
+
"type": "integer",
|
|
19395
|
+
"description": "Payouts in the refreshed window."
|
|
19396
|
+
},
|
|
19397
|
+
"upcomingRemoved": {
|
|
19398
|
+
"type": "integer",
|
|
19399
|
+
"description": "UPCOMING lines Airbnb no longer lists (paid out or cancelled) and were removed."
|
|
19400
|
+
},
|
|
19401
|
+
"error": {
|
|
19402
|
+
"type": "object",
|
|
19403
|
+
"required": [
|
|
19404
|
+
"code",
|
|
19405
|
+
"message"
|
|
19406
|
+
],
|
|
19407
|
+
"description": "Present only when this account was not refreshed. `code` is `connection_reauth_required`, `airbnb_rejected`, `airbnb_rate_limited`, `airbnb_error`, or `time_budget` (the request ran out of time before reaching it: refresh it alone with `?account_id=`).",
|
|
19408
|
+
"properties": {
|
|
19409
|
+
"code": {
|
|
19410
|
+
"type": "string"
|
|
19411
|
+
},
|
|
19412
|
+
"message": {
|
|
19413
|
+
"type": "string"
|
|
19414
|
+
}
|
|
19415
|
+
}
|
|
19416
|
+
}
|
|
19417
|
+
}
|
|
19418
|
+
}
|
|
18847
19419
|
}
|
|
18848
19420
|
}
|
|
18849
19421
|
}
|
|
@@ -18853,6 +19425,19 @@
|
|
|
18853
19425
|
"401": {
|
|
18854
19426
|
"$ref": "#/components/responses/Unauthorized"
|
|
18855
19427
|
},
|
|
19428
|
+
"403": {
|
|
19429
|
+
"description": "`connection_reauth_required`: Airbnb no longer accepts this account's connection. Reconnect it.",
|
|
19430
|
+
"content": {
|
|
19431
|
+
"application/json": {
|
|
19432
|
+
"schema": {
|
|
19433
|
+
"$ref": "#/components/schemas/Error"
|
|
19434
|
+
}
|
|
19435
|
+
}
|
|
19436
|
+
}
|
|
19437
|
+
},
|
|
19438
|
+
"404": {
|
|
19439
|
+
"$ref": "#/components/responses/AirbnbAccountNotFound"
|
|
19440
|
+
},
|
|
18856
19441
|
"409": {
|
|
18857
19442
|
"description": "No connected Airbnb account for this workspace.",
|
|
18858
19443
|
"content": {
|
|
@@ -18863,8 +19448,38 @@
|
|
|
18863
19448
|
}
|
|
18864
19449
|
}
|
|
18865
19450
|
},
|
|
19451
|
+
"422": {
|
|
19452
|
+
"description": "A body field is malformed, or `airbnb_rejected`: Airbnb refused the request for every account.",
|
|
19453
|
+
"content": {
|
|
19454
|
+
"application/json": {
|
|
19455
|
+
"schema": {
|
|
19456
|
+
"$ref": "#/components/schemas/Error"
|
|
19457
|
+
}
|
|
19458
|
+
}
|
|
19459
|
+
}
|
|
19460
|
+
},
|
|
19461
|
+
"429": {
|
|
19462
|
+
"description": "`airbnb_rate_limited`: Airbnb is throttling this account. Retry after `retry_after` seconds.",
|
|
19463
|
+
"content": {
|
|
19464
|
+
"application/json": {
|
|
19465
|
+
"schema": {
|
|
19466
|
+
"$ref": "#/components/schemas/Error"
|
|
19467
|
+
}
|
|
19468
|
+
}
|
|
19469
|
+
}
|
|
19470
|
+
},
|
|
18866
19471
|
"500": {
|
|
18867
19472
|
"$ref": "#/components/responses/InternalError"
|
|
19473
|
+
},
|
|
19474
|
+
"502": {
|
|
19475
|
+
"description": "`airbnb_error`: Airbnb did not complete the request. Retry with backoff.",
|
|
19476
|
+
"content": {
|
|
19477
|
+
"application/json": {
|
|
19478
|
+
"schema": {
|
|
19479
|
+
"$ref": "#/components/schemas/Error"
|
|
19480
|
+
}
|
|
19481
|
+
}
|
|
19482
|
+
}
|
|
18868
19483
|
}
|
|
18869
19484
|
}
|
|
18870
19485
|
}
|
|
@@ -20273,13 +20888,26 @@
|
|
|
20273
20888
|
"$ref": "#/components/responses/Unauthorized"
|
|
20274
20889
|
},
|
|
20275
20890
|
"403": {
|
|
20276
|
-
"description": "`connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired
|
|
20891
|
+
"description": "`insufficient_access` \u2014 the Airbnb account is connected with read-only or messaging access; this action needs full access (Airbnb's `property_management` permission). Nothing was sent to Airbnb; reconnect with `accessType: full_access`. `connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired or revoked). Reconnect; retrying cannot succeed. `listing_inactive` \u2014 the listing is inactive.",
|
|
20277
20892
|
"content": {
|
|
20278
20893
|
"application/json": {
|
|
20279
20894
|
"schema": {
|
|
20280
20895
|
"$ref": "#/components/schemas/Error"
|
|
20281
20896
|
},
|
|
20282
20897
|
"examples": {
|
|
20898
|
+
"insufficientAccess": {
|
|
20899
|
+
"summary": "The Airbnb account is not connected with full access",
|
|
20900
|
+
"value": {
|
|
20901
|
+
"error": {
|
|
20902
|
+
"code": "insufficient_access",
|
|
20903
|
+
"message": "This Airbnb account is connected with messaging access, which cannot accept or decline booking requests. It needs full access.",
|
|
20904
|
+
"fix": "Reconnect this Airbnb account with full access \u2014 `POST /v1/connect/airbnb` with `\"accessType\": \"full_access\"` \u2014 then retry.",
|
|
20905
|
+
"docs_url": "https://repull.dev/docs/errors/insufficient_access",
|
|
20906
|
+
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
|
|
20907
|
+
"accessType": "messaging"
|
|
20908
|
+
}
|
|
20909
|
+
}
|
|
20910
|
+
},
|
|
20283
20911
|
"reauth": {
|
|
20284
20912
|
"summary": "The Airbnb connection no longer allows this",
|
|
20285
20913
|
"value": {
|
|
@@ -20413,7 +21041,7 @@
|
|
|
20413
21041
|
"post": {
|
|
20414
21042
|
"operationId": "create_airbnb_offer",
|
|
20415
21043
|
"summary": "Create Airbnb special offer or pre-approval",
|
|
20416
|
-
"description": "Create a pre-approval or a special offer on an Airbnb thread, addressed by **Airbnb** ids. **Write-side** \u2014 calls Airbnb upstream. The Repull-id equivalents, which also update the inquiry in
|
|
21044
|
+
"description": "Create a pre-approval or a special offer on an Airbnb thread, addressed by **Airbnb** ids. **Write-side** \u2014 calls Airbnb upstream. The Repull-id equivalents, which also update the inquiry in Repull, are `POST /v1/conversations/{id}/pre-approval` and `POST /v1/conversations/{id}/special-offers` \u2014 prefer those unless you only hold Airbnb ids.\n\n- `type: \"preapproval\"` \u2014 let the guest book the dates and price they asked about. Requires `thread_id`; optional `block_instant_booking`.\n- `type: \"offer\"` \u2014 your own terms. Requires `thread_id`, `listing_id` (the **Airbnb** listing id, as a string), `start_date`, `nights`, `total_price` (whole stay, listing currency) and `guest_details` with `number_of_guests` (or `number_of_adults`; Airbnb counts adults + children).\n\nThe body is validated before anything reaches Airbnb (a `422 invalid_params` names the field), and unknown fields are refused. The legacy spellings `threadId` and `blockInstantBooking` still work. The request is sent as the Airbnb account that owns the thread or listing.\n\nAirbnb refusals are mapped rather than returned as a 500: `409 inquiry_no_longer_open` / `inquiry_expired` when the inquiry moved on, `422 airbnb_rejected` with Airbnb\u2019s reason otherwise, `403 connection_reauth_required` when the grant does not allow it.\n\nReturns `403 listing_inactive` when the listing this resolves to is inactive. An inactive listing keeps syncing, but cannot be read or changed through the API until it is activated.\n\nSend `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 \u2014 nothing was done \u2014 so retrying with the same key reaches Airbnb again.",
|
|
20417
21045
|
"tags": [
|
|
20418
21046
|
"Airbnb"
|
|
20419
21047
|
],
|
|
@@ -20605,13 +21233,26 @@
|
|
|
20605
21233
|
"$ref": "#/components/responses/Unauthorized"
|
|
20606
21234
|
},
|
|
20607
21235
|
"403": {
|
|
20608
|
-
"description": "`connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired
|
|
21236
|
+
"description": "`insufficient_access` \u2014 the Airbnb account is connected with read-only or messaging access; this action needs full access (Airbnb's `property_management` permission). Nothing was sent to Airbnb; reconnect with `accessType: full_access`. `connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired or revoked). Reconnect; retrying cannot succeed. `listing_inactive` \u2014 the listing is inactive.",
|
|
20609
21237
|
"content": {
|
|
20610
21238
|
"application/json": {
|
|
20611
21239
|
"schema": {
|
|
20612
21240
|
"$ref": "#/components/schemas/Error"
|
|
20613
21241
|
},
|
|
20614
21242
|
"examples": {
|
|
21243
|
+
"insufficientAccess": {
|
|
21244
|
+
"summary": "The Airbnb account is not connected with full access",
|
|
21245
|
+
"value": {
|
|
21246
|
+
"error": {
|
|
21247
|
+
"code": "insufficient_access",
|
|
21248
|
+
"message": "This Airbnb account is connected with messaging access, which cannot accept or decline booking requests. It needs full access.",
|
|
21249
|
+
"fix": "Reconnect this Airbnb account with full access \u2014 `POST /v1/connect/airbnb` with `\"accessType\": \"full_access\"` \u2014 then retry.",
|
|
21250
|
+
"docs_url": "https://repull.dev/docs/errors/insufficient_access",
|
|
21251
|
+
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
|
|
21252
|
+
"accessType": "messaging"
|
|
21253
|
+
}
|
|
21254
|
+
}
|
|
21255
|
+
},
|
|
20615
21256
|
"reauth": {
|
|
20616
21257
|
"summary": "The Airbnb connection no longer allows this",
|
|
20617
21258
|
"value": {
|
|
@@ -20878,13 +21519,26 @@
|
|
|
20878
21519
|
"$ref": "#/components/responses/Unauthorized"
|
|
20879
21520
|
},
|
|
20880
21521
|
"403": {
|
|
20881
|
-
"description": "`connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired
|
|
21522
|
+
"description": "`insufficient_access` \u2014 the Airbnb account is connected with read-only or messaging access; this action needs full access (Airbnb's `property_management` permission). Nothing was sent to Airbnb; reconnect with `accessType: full_access`. `connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired or revoked). Reconnect; retrying cannot succeed. `listing_inactive` \u2014 the listing is inactive.",
|
|
20882
21523
|
"content": {
|
|
20883
21524
|
"application/json": {
|
|
20884
21525
|
"schema": {
|
|
20885
21526
|
"$ref": "#/components/schemas/Error"
|
|
20886
21527
|
},
|
|
20887
21528
|
"examples": {
|
|
21529
|
+
"insufficientAccess": {
|
|
21530
|
+
"summary": "The Airbnb account is not connected with full access",
|
|
21531
|
+
"value": {
|
|
21532
|
+
"error": {
|
|
21533
|
+
"code": "insufficient_access",
|
|
21534
|
+
"message": "This Airbnb account is connected with messaging access, which cannot accept or decline booking requests. It needs full access.",
|
|
21535
|
+
"fix": "Reconnect this Airbnb account with full access \u2014 `POST /v1/connect/airbnb` with `\"accessType\": \"full_access\"` \u2014 then retry.",
|
|
21536
|
+
"docs_url": "https://repull.dev/docs/errors/insufficient_access",
|
|
21537
|
+
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
|
|
21538
|
+
"accessType": "messaging"
|
|
21539
|
+
}
|
|
21540
|
+
}
|
|
21541
|
+
},
|
|
20888
21542
|
"reauth": {
|
|
20889
21543
|
"summary": "The Airbnb connection no longer allows this",
|
|
20890
21544
|
"value": {
|
|
@@ -21139,7 +21793,7 @@
|
|
|
21139
21793
|
"post": {
|
|
21140
21794
|
"operationId": "createListing",
|
|
21141
21795
|
"summary": "Create a Repull listing",
|
|
21142
|
-
"description": "Create a new vacation-rental listing under the authenticated workspace. The listing is stored
|
|
21796
|
+
"description": "Create a new vacation-rental listing under the authenticated workspace. The listing is stored as a canonical Repull listing and can be published to multiple channels (Airbnb, Booking.com) via the publish endpoints.",
|
|
21143
21797
|
"tags": [
|
|
21144
21798
|
"Listings"
|
|
21145
21799
|
],
|
|
@@ -21483,7 +22137,24 @@
|
|
|
21483
22137
|
"$ref": "#/components/responses/ListingInactive"
|
|
21484
22138
|
},
|
|
21485
22139
|
"404": {
|
|
21486
|
-
"
|
|
22140
|
+
"description": "`not_found`: the listing does not exist in this workspace. `no_connection`: no Airbnb account is connected \u2014 connect one with `POST /v1/connect/airbnb`, then send its `hostId`.",
|
|
22141
|
+
"content": {
|
|
22142
|
+
"application/json": {
|
|
22143
|
+
"schema": {
|
|
22144
|
+
"$ref": "#/components/schemas/Error"
|
|
22145
|
+
}
|
|
22146
|
+
}
|
|
22147
|
+
}
|
|
22148
|
+
},
|
|
22149
|
+
"422": {
|
|
22150
|
+
"description": "`invalid_params`: neither `airbnbConnectionId` nor `hostId` was sent. The error names the values that work for this listing \u2014 its existing Airbnb connection ids, or the connected accounts' `hostId`s \u2014 in `valid_values`.",
|
|
22151
|
+
"content": {
|
|
22152
|
+
"application/json": {
|
|
22153
|
+
"schema": {
|
|
22154
|
+
"$ref": "#/components/schemas/Error"
|
|
22155
|
+
}
|
|
22156
|
+
}
|
|
22157
|
+
}
|
|
21487
22158
|
}
|
|
21488
22159
|
}
|
|
21489
22160
|
}
|
|
@@ -21492,7 +22163,7 @@
|
|
|
21492
22163
|
"post": {
|
|
21493
22164
|
"operationId": "publishListingToBooking",
|
|
21494
22165
|
"summary": "Publish a listing to Booking.com",
|
|
21495
|
-
"description": "Push a Repull listing's content to Booking.com. The listing must already be mapped to a Booking.com property + room \u2014 claim the hotel through the Connect Booking flow, then map its rooms with `POST /v1/connect/booking/map-rooms`.\n\n**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=` \u2014 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.\n\nThe property that actually received the content comes back as `result.hotelId`.\n\n**A publish is not one call to Booking.com.** It is several independent Content API calls \u2014 details, description, amenities, rooms, photos, pricing \u2014 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 \u2014 re-publishing an unchanged section is harmless.\n\nA 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.\n\nReturns `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.",
|
|
22166
|
+
"description": "Push a Repull listing's content to Booking.com. The listing must already be mapped to a Booking.com property + room \u2014 claim the hotel through the Connect Booking flow, then map its rooms with `POST /v1/connect/booking/map-rooms`.\n\n**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=` \u2014 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.\n\nThe property that actually received the content comes back as `result.hotelId`.\n\n**A publish is not one call to Booking.com.** It is several independent Content API calls \u2014 details, description, amenities, rooms, photos, pricing \u2014 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 \u2014 re-publishing an unchanged section is harmless.\n\nA 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.\n\nReturns `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.\n\nA listing with no Booking.com room linked is refused with `409 listing_not_on_booking` and the next step, rather than answered with `published: false`.",
|
|
21496
22167
|
"tags": [
|
|
21497
22168
|
"Listings"
|
|
21498
22169
|
],
|
|
@@ -21550,8 +22221,15 @@
|
|
|
21550
22221
|
"$ref": "#/components/responses/NotFound"
|
|
21551
22222
|
},
|
|
21552
22223
|
"409": {
|
|
21553
|
-
"
|
|
21554
|
-
|
|
22224
|
+
"description": "`listing_not_on_booking`: no Booking.com room is linked to this listing. `fix` names the next step for this workspace \u2014 link a room (`POST /v1/channels/booking/listings/map`) or create a property (`POST /v1/channels/booking/setup`, `create-property`). Also `ambiguous_booking_mapping` when the listing is on several properties and no `hotelId` was sent.",
|
|
22225
|
+
"content": {
|
|
22226
|
+
"application/json": {
|
|
22227
|
+
"schema": {
|
|
22228
|
+
"$ref": "#/components/schemas/Error"
|
|
22229
|
+
}
|
|
22230
|
+
}
|
|
22231
|
+
}
|
|
22232
|
+
}
|
|
21555
22233
|
}
|
|
21556
22234
|
}
|
|
21557
22235
|
},
|
|
@@ -21600,7 +22278,7 @@
|
|
|
21600
22278
|
"post": {
|
|
21601
22279
|
"operationId": "createListingPhotoUploadUrl",
|
|
21602
22280
|
"summary": "Mint a direct-to-storage photo upload URL",
|
|
21603
|
-
"description": "Mints a short-lived signed upload URL + token for a listing photo. **The client PUTs the raw file bytes directly to the returned `uploadUrl` \u2014 the file bytes never pass through the Repull API
|
|
22281
|
+
"description": "Mints a short-lived signed upload URL + token for a listing photo. **The client PUTs the raw file bytes directly to the returned `uploadUrl` \u2014 the file bytes never pass through the Repull API.** This endpoint only mints the URL; do not POST the file itself here, it will not be accepted.\n\nFlow: (1) POST here with `fileName`, `fileType` and `fileSize` (bytes) to get `{ uploadUrl, token, path, publicUrl, expiresIn }`; (2) PUT the raw file bytes to `uploadUrl` from the client; (3) **attach it** \u2014 uploading does not put the photo on the listing: send `publicUrl` in `photos` on `PUT /v1/listings/{id}/content` (with `photosMode: \"append\"` to keep existing photos). The response's `nextStep` says the same.\n\nReturns `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.",
|
|
21604
22282
|
"tags": [
|
|
21605
22283
|
"Listings"
|
|
21606
22284
|
],
|
|
@@ -21821,7 +22499,7 @@
|
|
|
21821
22499
|
"schema": {
|
|
21822
22500
|
"type": "boolean"
|
|
21823
22501
|
},
|
|
21824
|
-
"description": "Defaults to `true`: availability per room, which is how Booking.com keeps inventory
|
|
22502
|
+
"description": "Defaults to `true`: availability per room, which is how Booking.com keeps inventory. Send `false` for the per-rate read \u2014 its `roomsToSell` is often 0 for rooms that are on sale."
|
|
21825
22503
|
}
|
|
21826
22504
|
],
|
|
21827
22505
|
"responses": {
|
|
@@ -22384,7 +23062,7 @@
|
|
|
22384
23062
|
"schema": {
|
|
22385
23063
|
"type": "boolean"
|
|
22386
23064
|
},
|
|
22387
|
-
"description": "Defaults to `true`: availability per room, which is how Booking.com keeps inventory
|
|
23065
|
+
"description": "Defaults to `true`: availability per room, which is how Booking.com keeps inventory. Send `false` for the per-rate read \u2014 its `roomsToSell` is often 0 for rooms that are on sale."
|
|
22388
23066
|
},
|
|
22389
23067
|
{
|
|
22390
23068
|
"name": "hotel_id",
|
|
@@ -23500,7 +24178,7 @@
|
|
|
23500
24178
|
"$ref": "#/components/responses/ListingInactive"
|
|
23501
24179
|
},
|
|
23502
24180
|
"502": {
|
|
23503
|
-
"description": "Upstream
|
|
24181
|
+
"description": "Upstream market-data failure"
|
|
23504
24182
|
}
|
|
23505
24183
|
}
|
|
23506
24184
|
},
|
|
@@ -23679,7 +24357,7 @@
|
|
|
23679
24357
|
"$ref": "#/components/responses/UnprocessableEntity"
|
|
23680
24358
|
},
|
|
23681
24359
|
"502": {
|
|
23682
|
-
"description": "Upstream
|
|
24360
|
+
"description": "Upstream market-data failure",
|
|
23683
24361
|
"content": {
|
|
23684
24362
|
"application/json": {
|
|
23685
24363
|
"schema": {
|
|
@@ -23779,7 +24457,7 @@
|
|
|
23779
24457
|
"$ref": "#/components/responses/UnprocessableEntity"
|
|
23780
24458
|
},
|
|
23781
24459
|
"502": {
|
|
23782
|
-
"description": "Upstream
|
|
24460
|
+
"description": "Upstream market-data failure",
|
|
23783
24461
|
"content": {
|
|
23784
24462
|
"application/json": {
|
|
23785
24463
|
"schema": {
|
|
@@ -23877,7 +24555,7 @@
|
|
|
23877
24555
|
"$ref": "#/components/responses/NotFound"
|
|
23878
24556
|
},
|
|
23879
24557
|
"502": {
|
|
23880
|
-
"description": "Upstream
|
|
24558
|
+
"description": "Upstream market-data failure",
|
|
23881
24559
|
"content": {
|
|
23882
24560
|
"application/json": {
|
|
23883
24561
|
"schema": {
|
|
@@ -23957,7 +24635,7 @@
|
|
|
23957
24635
|
"$ref": "#/components/responses/NotFound"
|
|
23958
24636
|
},
|
|
23959
24637
|
"502": {
|
|
23960
|
-
"description": "Upstream
|
|
24638
|
+
"description": "Upstream market-data failure",
|
|
23961
24639
|
"content": {
|
|
23962
24640
|
"application/json": {
|
|
23963
24641
|
"schema": {
|
|
@@ -23992,7 +24670,7 @@
|
|
|
23992
24670
|
"$ref": "#/components/responses/Unauthorized"
|
|
23993
24671
|
},
|
|
23994
24672
|
"502": {
|
|
23995
|
-
"description": "Upstream
|
|
24673
|
+
"description": "Upstream market-data failure"
|
|
23996
24674
|
}
|
|
23997
24675
|
}
|
|
23998
24676
|
}
|
|
@@ -24089,7 +24767,7 @@
|
|
|
24089
24767
|
"$ref": "#/components/responses/Unauthorized"
|
|
24090
24768
|
},
|
|
24091
24769
|
"502": {
|
|
24092
|
-
"description": "Upstream
|
|
24770
|
+
"description": "Upstream market-data failure",
|
|
24093
24771
|
"content": {
|
|
24094
24772
|
"application/json": {
|
|
24095
24773
|
"schema": {
|
|
@@ -24603,6 +25281,9 @@
|
|
|
24603
25281
|
},
|
|
24604
25282
|
"range": {
|
|
24605
25283
|
"type": "string"
|
|
25284
|
+
},
|
|
25285
|
+
"planNotice": {
|
|
25286
|
+
"$ref": "#/components/schemas/PlanNotice"
|
|
24606
25287
|
}
|
|
24607
25288
|
}
|
|
24608
25289
|
}
|
|
@@ -26861,13 +27542,26 @@
|
|
|
26861
27542
|
"$ref": "#/components/responses/Unauthorized"
|
|
26862
27543
|
},
|
|
26863
27544
|
"403": {
|
|
26864
|
-
"description": "`connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired
|
|
27545
|
+
"description": "`insufficient_access` \u2014 the Airbnb account is connected with read-only or messaging access; this action needs full access (Airbnb's `property_management` permission). Nothing was sent to Airbnb; reconnect with `accessType: full_access`. `connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired or revoked). Reconnect; retrying cannot succeed. `listing_inactive` \u2014 the listing is inactive.",
|
|
26865
27546
|
"content": {
|
|
26866
27547
|
"application/json": {
|
|
26867
27548
|
"schema": {
|
|
26868
27549
|
"$ref": "#/components/schemas/Error"
|
|
26869
27550
|
},
|
|
26870
27551
|
"examples": {
|
|
27552
|
+
"insufficientAccess": {
|
|
27553
|
+
"summary": "The Airbnb account is not connected with full access",
|
|
27554
|
+
"value": {
|
|
27555
|
+
"error": {
|
|
27556
|
+
"code": "insufficient_access",
|
|
27557
|
+
"message": "This Airbnb account is connected with messaging access, which cannot accept or decline booking requests. It needs full access.",
|
|
27558
|
+
"fix": "Reconnect this Airbnb account with full access \u2014 `POST /v1/connect/airbnb` with `\"accessType\": \"full_access\"` \u2014 then retry.",
|
|
27559
|
+
"docs_url": "https://repull.dev/docs/errors/insufficient_access",
|
|
27560
|
+
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
|
|
27561
|
+
"accessType": "messaging"
|
|
27562
|
+
}
|
|
27563
|
+
}
|
|
27564
|
+
},
|
|
26871
27565
|
"reauth": {
|
|
26872
27566
|
"summary": "The Airbnb connection no longer allows this",
|
|
26873
27567
|
"value": {
|
|
@@ -27352,13 +28046,26 @@
|
|
|
27352
28046
|
"$ref": "#/components/responses/Unauthorized"
|
|
27353
28047
|
},
|
|
27354
28048
|
"403": {
|
|
27355
|
-
"description": "`connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired
|
|
28049
|
+
"description": "`insufficient_access` \u2014 the Airbnb account is connected with read-only or messaging access; this action needs full access (Airbnb's `property_management` permission). Nothing was sent to Airbnb; reconnect with `accessType: full_access`. `connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired or revoked). Reconnect; retrying cannot succeed. `listing_inactive` \u2014 the listing is inactive.",
|
|
27356
28050
|
"content": {
|
|
27357
28051
|
"application/json": {
|
|
27358
28052
|
"schema": {
|
|
27359
28053
|
"$ref": "#/components/schemas/Error"
|
|
27360
28054
|
},
|
|
27361
28055
|
"examples": {
|
|
28056
|
+
"insufficientAccess": {
|
|
28057
|
+
"summary": "The Airbnb account is not connected with full access",
|
|
28058
|
+
"value": {
|
|
28059
|
+
"error": {
|
|
28060
|
+
"code": "insufficient_access",
|
|
28061
|
+
"message": "This Airbnb account is connected with messaging access, which cannot accept or decline booking requests. It needs full access.",
|
|
28062
|
+
"fix": "Reconnect this Airbnb account with full access \u2014 `POST /v1/connect/airbnb` with `\"accessType\": \"full_access\"` \u2014 then retry.",
|
|
28063
|
+
"docs_url": "https://repull.dev/docs/errors/insufficient_access",
|
|
28064
|
+
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
|
|
28065
|
+
"accessType": "messaging"
|
|
28066
|
+
}
|
|
28067
|
+
}
|
|
28068
|
+
},
|
|
27362
28069
|
"reauth": {
|
|
27363
28070
|
"summary": "The Airbnb connection no longer allows this",
|
|
27364
28071
|
"value": {
|
|
@@ -27764,13 +28471,26 @@
|
|
|
27764
28471
|
"$ref": "#/components/responses/Unauthorized"
|
|
27765
28472
|
},
|
|
27766
28473
|
"403": {
|
|
27767
|
-
"description": "`connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired
|
|
28474
|
+
"description": "`insufficient_access` \u2014 the Airbnb account is connected with read-only or messaging access; this action needs full access (Airbnb's `property_management` permission). Nothing was sent to Airbnb; reconnect with `accessType: full_access`. `connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired or revoked). Reconnect; retrying cannot succeed. `listing_inactive` \u2014 the listing is inactive.",
|
|
27768
28475
|
"content": {
|
|
27769
28476
|
"application/json": {
|
|
27770
28477
|
"schema": {
|
|
27771
28478
|
"$ref": "#/components/schemas/Error"
|
|
27772
28479
|
},
|
|
27773
28480
|
"examples": {
|
|
28481
|
+
"insufficientAccess": {
|
|
28482
|
+
"summary": "The Airbnb account is not connected with full access",
|
|
28483
|
+
"value": {
|
|
28484
|
+
"error": {
|
|
28485
|
+
"code": "insufficient_access",
|
|
28486
|
+
"message": "This Airbnb account is connected with messaging access, which cannot accept or decline booking requests. It needs full access.",
|
|
28487
|
+
"fix": "Reconnect this Airbnb account with full access \u2014 `POST /v1/connect/airbnb` with `\"accessType\": \"full_access\"` \u2014 then retry.",
|
|
28488
|
+
"docs_url": "https://repull.dev/docs/errors/insufficient_access",
|
|
28489
|
+
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
|
|
28490
|
+
"accessType": "messaging"
|
|
28491
|
+
}
|
|
28492
|
+
}
|
|
28493
|
+
},
|
|
27774
28494
|
"reauth": {
|
|
27775
28495
|
"summary": "The Airbnb connection no longer allows this",
|
|
27776
28496
|
"value": {
|
|
@@ -28003,13 +28723,26 @@
|
|
|
28003
28723
|
"$ref": "#/components/responses/Unauthorized"
|
|
28004
28724
|
},
|
|
28005
28725
|
"403": {
|
|
28006
|
-
"description": "`connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired
|
|
28726
|
+
"description": "`insufficient_access` \u2014 the Airbnb account is connected with read-only or messaging access; this action needs full access (Airbnb's `property_management` permission). Nothing was sent to Airbnb; reconnect with `accessType: full_access`. `connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired or revoked). Reconnect; retrying cannot succeed. `listing_inactive` \u2014 the listing is inactive.",
|
|
28007
28727
|
"content": {
|
|
28008
28728
|
"application/json": {
|
|
28009
28729
|
"schema": {
|
|
28010
28730
|
"$ref": "#/components/schemas/Error"
|
|
28011
28731
|
},
|
|
28012
28732
|
"examples": {
|
|
28733
|
+
"insufficientAccess": {
|
|
28734
|
+
"summary": "The Airbnb account is not connected with full access",
|
|
28735
|
+
"value": {
|
|
28736
|
+
"error": {
|
|
28737
|
+
"code": "insufficient_access",
|
|
28738
|
+
"message": "This Airbnb account is connected with messaging access, which cannot accept or decline booking requests. It needs full access.",
|
|
28739
|
+
"fix": "Reconnect this Airbnb account with full access \u2014 `POST /v1/connect/airbnb` with `\"accessType\": \"full_access\"` \u2014 then retry.",
|
|
28740
|
+
"docs_url": "https://repull.dev/docs/errors/insufficient_access",
|
|
28741
|
+
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
|
|
28742
|
+
"accessType": "messaging"
|
|
28743
|
+
}
|
|
28744
|
+
}
|
|
28745
|
+
},
|
|
28013
28746
|
"reauth": {
|
|
28014
28747
|
"summary": "The Airbnb connection no longer allows this",
|
|
28015
28748
|
"value": {
|
|
@@ -28548,13 +29281,26 @@
|
|
|
28548
29281
|
"$ref": "#/components/responses/Unauthorized"
|
|
28549
29282
|
},
|
|
28550
29283
|
"403": {
|
|
28551
|
-
"description": "`connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired
|
|
29284
|
+
"description": "`insufficient_access` \u2014 the Airbnb account is connected with read-only or messaging access; this action needs full access (Airbnb's `property_management` permission). Nothing was sent to Airbnb; reconnect with `accessType: full_access`. `connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired or revoked). Reconnect; retrying cannot succeed. `listing_inactive` \u2014 the listing is inactive.",
|
|
28552
29285
|
"content": {
|
|
28553
29286
|
"application/json": {
|
|
28554
29287
|
"schema": {
|
|
28555
29288
|
"$ref": "#/components/schemas/Error"
|
|
28556
29289
|
},
|
|
28557
29290
|
"examples": {
|
|
29291
|
+
"insufficientAccess": {
|
|
29292
|
+
"summary": "The Airbnb account is not connected with full access",
|
|
29293
|
+
"value": {
|
|
29294
|
+
"error": {
|
|
29295
|
+
"code": "insufficient_access",
|
|
29296
|
+
"message": "This Airbnb account is connected with messaging access, which cannot accept or decline booking requests. It needs full access.",
|
|
29297
|
+
"fix": "Reconnect this Airbnb account with full access \u2014 `POST /v1/connect/airbnb` with `\"accessType\": \"full_access\"` \u2014 then retry.",
|
|
29298
|
+
"docs_url": "https://repull.dev/docs/errors/insufficient_access",
|
|
29299
|
+
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
|
|
29300
|
+
"accessType": "messaging"
|
|
29301
|
+
}
|
|
29302
|
+
}
|
|
29303
|
+
},
|
|
28558
29304
|
"reauth": {
|
|
28559
29305
|
"summary": "The Airbnb connection no longer allows this",
|
|
28560
29306
|
"value": {
|
|
@@ -28936,13 +29682,26 @@
|
|
|
28936
29682
|
"$ref": "#/components/responses/Unauthorized"
|
|
28937
29683
|
},
|
|
28938
29684
|
"403": {
|
|
28939
|
-
"description": "`connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired
|
|
29685
|
+
"description": "`insufficient_access` \u2014 the Airbnb account is connected with read-only or messaging access; this action needs full access (Airbnb's `property_management` permission). Nothing was sent to Airbnb; reconnect with `accessType: full_access`. `connection_reauth_required` \u2014 Airbnb no longer accepts the connection for this action (expired or revoked). Reconnect; retrying cannot succeed. `listing_inactive` \u2014 the listing is inactive.",
|
|
28940
29686
|
"content": {
|
|
28941
29687
|
"application/json": {
|
|
28942
29688
|
"schema": {
|
|
28943
29689
|
"$ref": "#/components/schemas/Error"
|
|
28944
29690
|
},
|
|
28945
29691
|
"examples": {
|
|
29692
|
+
"insufficientAccess": {
|
|
29693
|
+
"summary": "The Airbnb account is not connected with full access",
|
|
29694
|
+
"value": {
|
|
29695
|
+
"error": {
|
|
29696
|
+
"code": "insufficient_access",
|
|
29697
|
+
"message": "This Airbnb account is connected with messaging access, which cannot accept or decline booking requests. It needs full access.",
|
|
29698
|
+
"fix": "Reconnect this Airbnb account with full access \u2014 `POST /v1/connect/airbnb` with `\"accessType\": \"full_access\"` \u2014 then retry.",
|
|
29699
|
+
"docs_url": "https://repull.dev/docs/errors/insufficient_access",
|
|
29700
|
+
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
|
|
29701
|
+
"accessType": "messaging"
|
|
29702
|
+
}
|
|
29703
|
+
}
|
|
29704
|
+
},
|
|
28946
29705
|
"reauth": {
|
|
28947
29706
|
"summary": "The Airbnb connection no longer allows this",
|
|
28948
29707
|
"value": {
|
|
@@ -29912,6 +30671,649 @@
|
|
|
29912
30671
|
}
|
|
29913
30672
|
}
|
|
29914
30673
|
}
|
|
30674
|
+
},
|
|
30675
|
+
"/v1/listings/{id}/markups": {
|
|
30676
|
+
"get": {
|
|
30677
|
+
"operationId": "get_listing_markups",
|
|
30678
|
+
"summary": "Get a listing's channel markups",
|
|
30679
|
+
"description": "The markup each channel adds to this listing's price.\n\nA listing's price on a channel is its own nightly price plus the channel's markup: a $200 night with a 35% Airbnb markup is sent to Airbnb as $270. The calendar keeps the listing's own price (`GET /v1/availability/{propertyId}` returns it); the markup is added only when a price is sent to the channel.\n\n- **Airbnb** \u2014 one markup per listing.\n- **Booking.com** \u2014 one markup per **property**, shared by every listing priced through it (`listingIds` names them).\n\nReturns `404 not_found` for a listing that does not exist or is not in this workspace, and `403 listing_inactive` for an inactive one.",
|
|
30680
|
+
"tags": [
|
|
30681
|
+
"Listings"
|
|
30682
|
+
],
|
|
30683
|
+
"parameters": [
|
|
30684
|
+
{
|
|
30685
|
+
"name": "id",
|
|
30686
|
+
"in": "path",
|
|
30687
|
+
"required": true,
|
|
30688
|
+
"schema": {
|
|
30689
|
+
"type": "string"
|
|
30690
|
+
},
|
|
30691
|
+
"description": "Repull listing id."
|
|
30692
|
+
}
|
|
30693
|
+
],
|
|
30694
|
+
"responses": {
|
|
30695
|
+
"200": {
|
|
30696
|
+
"description": "Markups per channel.",
|
|
30697
|
+
"content": {
|
|
30698
|
+
"application/json": {
|
|
30699
|
+
"schema": {
|
|
30700
|
+
"type": "object",
|
|
30701
|
+
"properties": {
|
|
30702
|
+
"id": {
|
|
30703
|
+
"type": "string",
|
|
30704
|
+
"description": "Repull listing id."
|
|
30705
|
+
},
|
|
30706
|
+
"airbnb": {
|
|
30707
|
+
"type": "array",
|
|
30708
|
+
"items": {
|
|
30709
|
+
"type": "object",
|
|
30710
|
+
"properties": {
|
|
30711
|
+
"airbnbId": {
|
|
30712
|
+
"type": "string",
|
|
30713
|
+
"description": "Airbnb listing id."
|
|
30714
|
+
},
|
|
30715
|
+
"markupPercent": {
|
|
30716
|
+
"type": "number",
|
|
30717
|
+
"nullable": true,
|
|
30718
|
+
"description": "Percent added to the listing's price on Airbnb. 35 = +35%. `null` = none.",
|
|
30719
|
+
"example": 35
|
|
30720
|
+
}
|
|
30721
|
+
}
|
|
30722
|
+
}
|
|
30723
|
+
},
|
|
30724
|
+
"booking": {
|
|
30725
|
+
"type": "array",
|
|
30726
|
+
"items": {
|
|
30727
|
+
"type": "object",
|
|
30728
|
+
"properties": {
|
|
30729
|
+
"hotelId": {
|
|
30730
|
+
"type": "string",
|
|
30731
|
+
"description": "Booking.com property id."
|
|
30732
|
+
},
|
|
30733
|
+
"markupPercent": {
|
|
30734
|
+
"type": "number",
|
|
30735
|
+
"nullable": true,
|
|
30736
|
+
"description": "Percent added on Booking.com, for every listing on this property.",
|
|
30737
|
+
"example": 18
|
|
30738
|
+
},
|
|
30739
|
+
"listingIds": {
|
|
30740
|
+
"type": "array",
|
|
30741
|
+
"items": {
|
|
30742
|
+
"type": "string"
|
|
30743
|
+
},
|
|
30744
|
+
"description": "Listings in this workspace priced through this property \u2014 all share this markup."
|
|
30745
|
+
}
|
|
30746
|
+
}
|
|
30747
|
+
}
|
|
30748
|
+
}
|
|
30749
|
+
}
|
|
30750
|
+
}
|
|
30751
|
+
}
|
|
30752
|
+
}
|
|
30753
|
+
},
|
|
30754
|
+
"401": {
|
|
30755
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
30756
|
+
},
|
|
30757
|
+
"403": {
|
|
30758
|
+
"$ref": "#/components/responses/ListingInactive"
|
|
30759
|
+
},
|
|
30760
|
+
"404": {
|
|
30761
|
+
"$ref": "#/components/responses/NotFound"
|
|
30762
|
+
}
|
|
30763
|
+
}
|
|
30764
|
+
},
|
|
30765
|
+
"put": {
|
|
30766
|
+
"operationId": "set_listing_markup",
|
|
30767
|
+
"summary": "Set a listing's markup on a channel",
|
|
30768
|
+
"description": "Set the markup one channel adds to this listing's price. When the value changes, the affected listings' prices are re-sent to that channel straight away (`pricesResent`); nothing else is sent.\n\nA listing's price on a channel is its own nightly price plus the channel's markup: a $200 night with a 35% Airbnb markup is sent to Airbnb as $270. The calendar keeps the listing's own price (`GET /v1/availability/{propertyId}` returns it); the markup is added only when a price is sent to the channel.\n\n- **Airbnb** \u2014 one markup per listing.\n- **Booking.com** \u2014 one markup per **property**, shared by every listing priced through it (`listingIds` names them).\n\nReturns `404 not_found` for a listing that does not exist or is not in this workspace, and `403 listing_inactive` for an inactive one.\n\nOn Booking.com the markup belongs to the property, so setting it reprices every listing on that property (`affectedListingIds`). A listing on more than one property must name one with `hotelId`; without it the request is refused with `409 ambiguous_booking_mapping` listing the candidates, rather than repricing a property it guessed.\n\n`markupPercent` is a percentage \u2014 `15` for 15%. A value between 0 and 1 is refused as a probable fraction, with the number to send instead.",
|
|
30769
|
+
"tags": [
|
|
30770
|
+
"Listings"
|
|
30771
|
+
],
|
|
30772
|
+
"parameters": [
|
|
30773
|
+
{
|
|
30774
|
+
"name": "id",
|
|
30775
|
+
"in": "path",
|
|
30776
|
+
"required": true,
|
|
30777
|
+
"schema": {
|
|
30778
|
+
"type": "string"
|
|
30779
|
+
},
|
|
30780
|
+
"description": "Repull listing id."
|
|
30781
|
+
}
|
|
30782
|
+
],
|
|
30783
|
+
"requestBody": {
|
|
30784
|
+
"required": true,
|
|
30785
|
+
"content": {
|
|
30786
|
+
"application/json": {
|
|
30787
|
+
"schema": {
|
|
30788
|
+
"type": "object",
|
|
30789
|
+
"required": [
|
|
30790
|
+
"channel",
|
|
30791
|
+
"markupPercent"
|
|
30792
|
+
],
|
|
30793
|
+
"properties": {
|
|
30794
|
+
"channel": {
|
|
30795
|
+
"type": "string",
|
|
30796
|
+
"enum": [
|
|
30797
|
+
"airbnb",
|
|
30798
|
+
"booking"
|
|
30799
|
+
]
|
|
30800
|
+
},
|
|
30801
|
+
"markupPercent": {
|
|
30802
|
+
"type": "number",
|
|
30803
|
+
"nullable": true,
|
|
30804
|
+
"minimum": 0,
|
|
30805
|
+
"maximum": 100,
|
|
30806
|
+
"exclusiveMaximum": true,
|
|
30807
|
+
"description": "15 = +15%. `null` removes the markup."
|
|
30808
|
+
},
|
|
30809
|
+
"hotelId": {
|
|
30810
|
+
"type": "string",
|
|
30811
|
+
"description": "Booking.com property \u2014 required when the listing is on more than one."
|
|
30812
|
+
}
|
|
30813
|
+
}
|
|
30814
|
+
},
|
|
30815
|
+
"example": {
|
|
30816
|
+
"channel": "booking",
|
|
30817
|
+
"markupPercent": 18
|
|
30818
|
+
}
|
|
30819
|
+
}
|
|
30820
|
+
}
|
|
30821
|
+
},
|
|
30822
|
+
"responses": {
|
|
30823
|
+
"200": {
|
|
30824
|
+
"description": "Saved. `{ id, channel, markupPercent, changed, hotelId?, affectedListingIds, pricesResent }`."
|
|
30825
|
+
},
|
|
30826
|
+
"401": {
|
|
30827
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
30828
|
+
},
|
|
30829
|
+
"403": {
|
|
30830
|
+
"$ref": "#/components/responses/ListingInactive"
|
|
30831
|
+
},
|
|
30832
|
+
"404": {
|
|
30833
|
+
"$ref": "#/components/responses/NotFound"
|
|
30834
|
+
},
|
|
30835
|
+
"409": {
|
|
30836
|
+
"description": "`ambiguous_booking_mapping` \u2014 the listing is on several Booking.com properties; `valid_values` lists them."
|
|
30837
|
+
},
|
|
30838
|
+
"422": {
|
|
30839
|
+
"$ref": "#/components/responses/UnprocessableEntity"
|
|
30840
|
+
}
|
|
30841
|
+
}
|
|
30842
|
+
}
|
|
30843
|
+
},
|
|
30844
|
+
"/v1/connect/cloudbeds/credentials": {
|
|
30845
|
+
"post": {
|
|
30846
|
+
"operationId": "submitCloudbedsCredentials",
|
|
30847
|
+
"summary": "Submit Cloudbeds credentials for a Connect session",
|
|
30848
|
+
"description": "Completes a credentials-pattern connection for Cloudbeds with a property (or organization) API key, created in Cloudbeds under Apps & Marketplace \u2192 API Credentials.\n\nIn Cloudbeds a listing is a room type and its rooms are units. A booking with several rooms becomes one reservation per room.\n\nThe key is validated and the properties it can see are read before anything is stored. On success Repull subscribes to the property's Cloudbeds webhooks (reservations, guests, room blocks) and queues the first sync.\n\nCloudbeds keys expire if unused for 30 days; the connection's regular sync keeps them alive.\n\nNo API key required when called with a `sessionId` \u2014 the session is the capability token.",
|
|
30849
|
+
"tags": [
|
|
30850
|
+
"Connect"
|
|
30851
|
+
],
|
|
30852
|
+
"requestBody": {
|
|
30853
|
+
"required": true,
|
|
30854
|
+
"content": {
|
|
30855
|
+
"application/json": {
|
|
30856
|
+
"schema": {
|
|
30857
|
+
"type": "object",
|
|
30858
|
+
"properties": {
|
|
30859
|
+
"sessionId": {
|
|
30860
|
+
"type": "string",
|
|
30861
|
+
"description": "Connect session id from `POST /v1/connect/cloudbeds`. Omit when calling with your API key."
|
|
30862
|
+
},
|
|
30863
|
+
"credentials": {
|
|
30864
|
+
"type": "object",
|
|
30865
|
+
"properties": {
|
|
30866
|
+
"apiKey": {
|
|
30867
|
+
"type": "string",
|
|
30868
|
+
"description": "Cloudbeds API key."
|
|
30869
|
+
},
|
|
30870
|
+
"propertyIds": {
|
|
30871
|
+
"type": "array",
|
|
30872
|
+
"items": {
|
|
30873
|
+
"type": "string"
|
|
30874
|
+
},
|
|
30875
|
+
"description": "Organization keys only: limit the connection to these properties. Omit to use every property the key can see."
|
|
30876
|
+
}
|
|
30877
|
+
},
|
|
30878
|
+
"required": [
|
|
30879
|
+
"apiKey"
|
|
30880
|
+
],
|
|
30881
|
+
"description": "A Cloudbeds API key (starts with `cbat_`)."
|
|
30882
|
+
}
|
|
30883
|
+
},
|
|
30884
|
+
"required": [
|
|
30885
|
+
"credentials"
|
|
30886
|
+
]
|
|
30887
|
+
}
|
|
30888
|
+
}
|
|
30889
|
+
}
|
|
30890
|
+
},
|
|
30891
|
+
"responses": {
|
|
30892
|
+
"200": {
|
|
30893
|
+
"description": "Credentials accepted, the connection stored and its first sync queued",
|
|
30894
|
+
"content": {
|
|
30895
|
+
"application/json": {
|
|
30896
|
+
"schema": {
|
|
30897
|
+
"type": "object",
|
|
30898
|
+
"properties": {
|
|
30899
|
+
"provider": {
|
|
30900
|
+
"type": "string",
|
|
30901
|
+
"example": "cloudbeds"
|
|
30902
|
+
},
|
|
30903
|
+
"connected": {
|
|
30904
|
+
"type": "boolean"
|
|
30905
|
+
},
|
|
30906
|
+
"pmsConnectionId": {
|
|
30907
|
+
"type": "string",
|
|
30908
|
+
"description": "Id of the stored connection."
|
|
30909
|
+
},
|
|
30910
|
+
"created": {
|
|
30911
|
+
"type": "boolean",
|
|
30912
|
+
"description": "False when an existing connection was updated."
|
|
30913
|
+
},
|
|
30914
|
+
"sessionId": {
|
|
30915
|
+
"type": "string",
|
|
30916
|
+
"nullable": true
|
|
30917
|
+
},
|
|
30918
|
+
"accountInfo": {
|
|
30919
|
+
"type": "object",
|
|
30920
|
+
"properties": {
|
|
30921
|
+
"externalAccountId": {
|
|
30922
|
+
"type": "string",
|
|
30923
|
+
"description": "The Cloudbeds property id these credentials belong to."
|
|
30924
|
+
},
|
|
30925
|
+
"accountName": {
|
|
30926
|
+
"type": "string",
|
|
30927
|
+
"nullable": true
|
|
30928
|
+
},
|
|
30929
|
+
"propertyIds": {
|
|
30930
|
+
"type": "array",
|
|
30931
|
+
"items": {
|
|
30932
|
+
"type": "string"
|
|
30933
|
+
},
|
|
30934
|
+
"description": "Every property the credentials cover."
|
|
30935
|
+
}
|
|
30936
|
+
}
|
|
30937
|
+
},
|
|
30938
|
+
"webhooks": {
|
|
30939
|
+
"type": "object",
|
|
30940
|
+
"properties": {
|
|
30941
|
+
"registered": {
|
|
30942
|
+
"type": "integer",
|
|
30943
|
+
"description": "Webhook subscriptions created at the PMS (Cloudbeds). Mews webhooks are enabled once per integration by Mews, so this is 0 there."
|
|
30944
|
+
},
|
|
30945
|
+
"error": {
|
|
30946
|
+
"type": "string",
|
|
30947
|
+
"description": "Why subscribing failed, if it did. The connection still syncs by polling."
|
|
30948
|
+
}
|
|
30949
|
+
}
|
|
30950
|
+
}
|
|
30951
|
+
}
|
|
30952
|
+
}
|
|
30953
|
+
}
|
|
30954
|
+
}
|
|
30955
|
+
},
|
|
30956
|
+
"400": {
|
|
30957
|
+
"$ref": "#/components/responses/BadRequest"
|
|
30958
|
+
},
|
|
30959
|
+
"401": {
|
|
30960
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
30961
|
+
},
|
|
30962
|
+
"404": {
|
|
30963
|
+
"$ref": "#/components/responses/NotFound"
|
|
30964
|
+
},
|
|
30965
|
+
"422": {
|
|
30966
|
+
"$ref": "#/components/responses/UnprocessableEntity"
|
|
30967
|
+
}
|
|
30968
|
+
}
|
|
30969
|
+
}
|
|
30970
|
+
},
|
|
30971
|
+
"/v1/connect/mews/credentials": {
|
|
30972
|
+
"post": {
|
|
30973
|
+
"operationId": "submitMewsCredentials",
|
|
30974
|
+
"summary": "Submit Mews credentials for a Connect session",
|
|
30975
|
+
"description": "Completes a credentials-pattern connection for Mews. The property enables Repull in Mews and shares its Connector API access token.\n\nIn Mews a listing is a room type and its rooms are units: rates, restrictions and availability live on the room type, and each reservation names the room it was assigned.\n\nThe token is validated against Mews and the property it belongs to is read before anything is stored, so a bad token returns `invalid_credentials` rather than a dead connection. The first sync (listings, rooms, reservations) is queued on success.\n\nTo try it without a Mews customer, send the demo access token from Mews's documentation with `environment: \"demo\"`.\n\nNo API key required when called with a `sessionId` \u2014 the session is the capability token.",
|
|
30976
|
+
"tags": [
|
|
30977
|
+
"Connect"
|
|
30978
|
+
],
|
|
30979
|
+
"requestBody": {
|
|
30980
|
+
"required": true,
|
|
30981
|
+
"content": {
|
|
30982
|
+
"application/json": {
|
|
30983
|
+
"schema": {
|
|
30984
|
+
"type": "object",
|
|
30985
|
+
"properties": {
|
|
30986
|
+
"sessionId": {
|
|
30987
|
+
"type": "string",
|
|
30988
|
+
"description": "Connect session id from `POST /v1/connect/mews`. Omit when calling with your API key."
|
|
30989
|
+
},
|
|
30990
|
+
"credentials": {
|
|
30991
|
+
"type": "object",
|
|
30992
|
+
"properties": {
|
|
30993
|
+
"accessToken": {
|
|
30994
|
+
"type": "string",
|
|
30995
|
+
"description": "The property's Connector API access token."
|
|
30996
|
+
},
|
|
30997
|
+
"environment": {
|
|
30998
|
+
"type": "string",
|
|
30999
|
+
"enum": [
|
|
31000
|
+
"production",
|
|
31001
|
+
"demo"
|
|
31002
|
+
],
|
|
31003
|
+
"default": "production",
|
|
31004
|
+
"description": "`demo` targets Mews's public demo environment."
|
|
31005
|
+
}
|
|
31006
|
+
},
|
|
31007
|
+
"required": [
|
|
31008
|
+
"accessToken"
|
|
31009
|
+
],
|
|
31010
|
+
"description": "The property's Mews Connector API access token."
|
|
31011
|
+
}
|
|
31012
|
+
},
|
|
31013
|
+
"required": [
|
|
31014
|
+
"credentials"
|
|
31015
|
+
]
|
|
31016
|
+
}
|
|
31017
|
+
}
|
|
31018
|
+
}
|
|
31019
|
+
},
|
|
31020
|
+
"responses": {
|
|
31021
|
+
"200": {
|
|
31022
|
+
"description": "Credentials accepted, the connection stored and its first sync queued",
|
|
31023
|
+
"content": {
|
|
31024
|
+
"application/json": {
|
|
31025
|
+
"schema": {
|
|
31026
|
+
"type": "object",
|
|
31027
|
+
"properties": {
|
|
31028
|
+
"provider": {
|
|
31029
|
+
"type": "string",
|
|
31030
|
+
"example": "mews"
|
|
31031
|
+
},
|
|
31032
|
+
"connected": {
|
|
31033
|
+
"type": "boolean"
|
|
31034
|
+
},
|
|
31035
|
+
"pmsConnectionId": {
|
|
31036
|
+
"type": "string",
|
|
31037
|
+
"description": "Id of the stored connection."
|
|
31038
|
+
},
|
|
31039
|
+
"created": {
|
|
31040
|
+
"type": "boolean",
|
|
31041
|
+
"description": "False when an existing connection was updated."
|
|
31042
|
+
},
|
|
31043
|
+
"sessionId": {
|
|
31044
|
+
"type": "string",
|
|
31045
|
+
"nullable": true
|
|
31046
|
+
},
|
|
31047
|
+
"accountInfo": {
|
|
31048
|
+
"type": "object",
|
|
31049
|
+
"properties": {
|
|
31050
|
+
"externalAccountId": {
|
|
31051
|
+
"type": "string",
|
|
31052
|
+
"description": "The Mews property id these credentials belong to."
|
|
31053
|
+
},
|
|
31054
|
+
"accountName": {
|
|
31055
|
+
"type": "string",
|
|
31056
|
+
"nullable": true
|
|
31057
|
+
},
|
|
31058
|
+
"propertyIds": {
|
|
31059
|
+
"type": "array",
|
|
31060
|
+
"items": {
|
|
31061
|
+
"type": "string"
|
|
31062
|
+
},
|
|
31063
|
+
"description": "Every property the credentials cover."
|
|
31064
|
+
}
|
|
31065
|
+
}
|
|
31066
|
+
},
|
|
31067
|
+
"webhooks": {
|
|
31068
|
+
"type": "object",
|
|
31069
|
+
"properties": {
|
|
31070
|
+
"registered": {
|
|
31071
|
+
"type": "integer",
|
|
31072
|
+
"description": "Webhook subscriptions created at the PMS (Cloudbeds). Mews webhooks are enabled once per integration by Mews, so this is 0 there."
|
|
31073
|
+
},
|
|
31074
|
+
"error": {
|
|
31075
|
+
"type": "string",
|
|
31076
|
+
"description": "Why subscribing failed, if it did. The connection still syncs by polling."
|
|
31077
|
+
}
|
|
31078
|
+
}
|
|
31079
|
+
}
|
|
31080
|
+
}
|
|
31081
|
+
}
|
|
31082
|
+
}
|
|
31083
|
+
}
|
|
31084
|
+
},
|
|
31085
|
+
"400": {
|
|
31086
|
+
"$ref": "#/components/responses/BadRequest"
|
|
31087
|
+
},
|
|
31088
|
+
"401": {
|
|
31089
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
31090
|
+
},
|
|
31091
|
+
"404": {
|
|
31092
|
+
"$ref": "#/components/responses/NotFound"
|
|
31093
|
+
},
|
|
31094
|
+
"422": {
|
|
31095
|
+
"$ref": "#/components/responses/UnprocessableEntity"
|
|
31096
|
+
}
|
|
31097
|
+
}
|
|
31098
|
+
}
|
|
31099
|
+
},
|
|
31100
|
+
"/v1/listings/{id}/units": {
|
|
31101
|
+
"get": {
|
|
31102
|
+
"operationId": "listListingUnits",
|
|
31103
|
+
"summary": "List a listing's units (rooms)",
|
|
31104
|
+
"description": "The physical rooms under a listing. For a hotel-model PMS (Mews, Cloudbeds) a listing is a room type: prices, restrictions and availability are set on the room type, and each reservation is assigned one of these rooms (`reservation.unit.id`). A room can belong to more than one room type.\n\nAny other listing is a single home, which is its own unit, and returns an empty list.",
|
|
31105
|
+
"tags": [
|
|
31106
|
+
"Listings"
|
|
31107
|
+
],
|
|
31108
|
+
"parameters": [
|
|
31109
|
+
{
|
|
31110
|
+
"name": "id",
|
|
31111
|
+
"in": "path",
|
|
31112
|
+
"required": true,
|
|
31113
|
+
"schema": {
|
|
31114
|
+
"type": "integer"
|
|
31115
|
+
},
|
|
31116
|
+
"description": "Listing id."
|
|
31117
|
+
}
|
|
31118
|
+
],
|
|
31119
|
+
"responses": {
|
|
31120
|
+
"200": {
|
|
31121
|
+
"description": "The listing's units",
|
|
31122
|
+
"content": {
|
|
31123
|
+
"application/json": {
|
|
31124
|
+
"schema": {
|
|
31125
|
+
"type": "object",
|
|
31126
|
+
"properties": {
|
|
31127
|
+
"listingId": {
|
|
31128
|
+
"type": "integer"
|
|
31129
|
+
},
|
|
31130
|
+
"total": {
|
|
31131
|
+
"type": "integer"
|
|
31132
|
+
},
|
|
31133
|
+
"data": {
|
|
31134
|
+
"type": "array",
|
|
31135
|
+
"items": {
|
|
31136
|
+
"type": "object",
|
|
31137
|
+
"properties": {
|
|
31138
|
+
"id": {
|
|
31139
|
+
"type": "string",
|
|
31140
|
+
"description": "The PMS's id for the room; `reservation.unit.id` refers to it."
|
|
31141
|
+
},
|
|
31142
|
+
"name": {
|
|
31143
|
+
"type": "string",
|
|
31144
|
+
"example": "101"
|
|
31145
|
+
},
|
|
31146
|
+
"active": {
|
|
31147
|
+
"type": "boolean"
|
|
31148
|
+
},
|
|
31149
|
+
"parentId": {
|
|
31150
|
+
"type": "string",
|
|
31151
|
+
"nullable": true,
|
|
31152
|
+
"description": "A sub-space's parent room (a bed in a dorm), else null."
|
|
31153
|
+
},
|
|
31154
|
+
"housekeepingStatus": {
|
|
31155
|
+
"type": "string",
|
|
31156
|
+
"nullable": true,
|
|
31157
|
+
"description": "The PMS's housekeeping state, verbatim (e.g. `Dirty`, `Clean`, `Inspected`)."
|
|
31158
|
+
},
|
|
31159
|
+
"floor": {
|
|
31160
|
+
"type": "string",
|
|
31161
|
+
"nullable": true
|
|
31162
|
+
},
|
|
31163
|
+
"source": {
|
|
31164
|
+
"type": "string",
|
|
31165
|
+
"example": "mews"
|
|
31166
|
+
}
|
|
31167
|
+
}
|
|
31168
|
+
}
|
|
31169
|
+
}
|
|
31170
|
+
}
|
|
31171
|
+
}
|
|
31172
|
+
}
|
|
31173
|
+
}
|
|
31174
|
+
},
|
|
31175
|
+
"401": {
|
|
31176
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
31177
|
+
},
|
|
31178
|
+
"404": {
|
|
31179
|
+
"$ref": "#/components/responses/NotFound"
|
|
31180
|
+
},
|
|
31181
|
+
"422": {
|
|
31182
|
+
"$ref": "#/components/responses/UnprocessableEntity"
|
|
31183
|
+
}
|
|
31184
|
+
}
|
|
31185
|
+
}
|
|
31186
|
+
},
|
|
31187
|
+
"/v1/reservations/{id}/cancel": {
|
|
31188
|
+
"post": {
|
|
31189
|
+
"operationId": "cancel_reservation",
|
|
31190
|
+
"summary": "Cancel a reservation",
|
|
31191
|
+
"description": "Cancels a reservation where it lives.\n\n- **Mews or Cloudbeds** (hotel-model PMS): cancelled in the PMS, then read back, so Repull and the PMS agree. No cancellation fee is charged.\n- **Direct, website or owner bookings**: cancelled in Repull \u2014 the nights are released and `reservation.cancelled` fires.\n- **A channel booking** (Airbnb, Booking.com, VRBO) or a booking owned by another PMS: `409 reservation_owned_by_channel`. Cancel it there; the cancellation reaches Repull with the next sync.\n\nCancelling an already-cancelled reservation is not an error: the response carries `alreadyCancelled: true`.\n\nReturns `403 listing_inactive` when the listing is inactive.",
|
|
31192
|
+
"tags": [
|
|
31193
|
+
"Reservations"
|
|
31194
|
+
],
|
|
31195
|
+
"parameters": [
|
|
31196
|
+
{
|
|
31197
|
+
"name": "id",
|
|
31198
|
+
"in": "path",
|
|
31199
|
+
"required": true,
|
|
31200
|
+
"schema": {
|
|
31201
|
+
"type": "integer"
|
|
31202
|
+
},
|
|
31203
|
+
"description": "Reservation id."
|
|
31204
|
+
}
|
|
31205
|
+
],
|
|
31206
|
+
"requestBody": {
|
|
31207
|
+
"required": false,
|
|
31208
|
+
"content": {
|
|
31209
|
+
"application/json": {
|
|
31210
|
+
"schema": {
|
|
31211
|
+
"type": "object",
|
|
31212
|
+
"properties": {
|
|
31213
|
+
"reason": {
|
|
31214
|
+
"type": "string",
|
|
31215
|
+
"description": "Why it was cancelled; recorded on the reservation (and in the PMS's notes)."
|
|
31216
|
+
}
|
|
31217
|
+
}
|
|
31218
|
+
}
|
|
31219
|
+
}
|
|
31220
|
+
}
|
|
31221
|
+
},
|
|
31222
|
+
"responses": {
|
|
31223
|
+
"200": {
|
|
31224
|
+
"description": "Cancelled",
|
|
31225
|
+
"content": {
|
|
31226
|
+
"application/json": {
|
|
31227
|
+
"schema": {
|
|
31228
|
+
"type": "object",
|
|
31229
|
+
"properties": {
|
|
31230
|
+
"id": {
|
|
31231
|
+
"type": "string"
|
|
31232
|
+
},
|
|
31233
|
+
"confirmationCode": {
|
|
31234
|
+
"type": "string",
|
|
31235
|
+
"nullable": true
|
|
31236
|
+
},
|
|
31237
|
+
"listingId": {
|
|
31238
|
+
"type": "string",
|
|
31239
|
+
"nullable": true
|
|
31240
|
+
},
|
|
31241
|
+
"status": {
|
|
31242
|
+
"type": "string",
|
|
31243
|
+
"enum": [
|
|
31244
|
+
"cancelled"
|
|
31245
|
+
]
|
|
31246
|
+
},
|
|
31247
|
+
"checkIn": {
|
|
31248
|
+
"type": "string",
|
|
31249
|
+
"format": "date",
|
|
31250
|
+
"nullable": true
|
|
31251
|
+
},
|
|
31252
|
+
"checkOut": {
|
|
31253
|
+
"type": "string",
|
|
31254
|
+
"format": "date",
|
|
31255
|
+
"nullable": true
|
|
31256
|
+
},
|
|
31257
|
+
"updatedAt": {
|
|
31258
|
+
"type": "string",
|
|
31259
|
+
"nullable": true
|
|
31260
|
+
},
|
|
31261
|
+
"alreadyCancelled": {
|
|
31262
|
+
"type": "boolean",
|
|
31263
|
+
"description": "Present and true when the reservation was already cancelled."
|
|
31264
|
+
},
|
|
31265
|
+
"pms": {
|
|
31266
|
+
"type": "object",
|
|
31267
|
+
"description": "Present when the cancellation was made in a PMS.",
|
|
31268
|
+
"properties": {
|
|
31269
|
+
"provider": {
|
|
31270
|
+
"type": "string",
|
|
31271
|
+
"example": "mews"
|
|
31272
|
+
},
|
|
31273
|
+
"applied": {
|
|
31274
|
+
"type": "array",
|
|
31275
|
+
"items": {
|
|
31276
|
+
"type": "string"
|
|
31277
|
+
}
|
|
31278
|
+
},
|
|
31279
|
+
"errors": {
|
|
31280
|
+
"type": "array",
|
|
31281
|
+
"items": {
|
|
31282
|
+
"type": "object",
|
|
31283
|
+
"properties": {
|
|
31284
|
+
"section": {
|
|
31285
|
+
"type": "string"
|
|
31286
|
+
},
|
|
31287
|
+
"message": {
|
|
31288
|
+
"type": "string"
|
|
31289
|
+
},
|
|
31290
|
+
"code": {
|
|
31291
|
+
"type": "string"
|
|
31292
|
+
}
|
|
31293
|
+
}
|
|
31294
|
+
}
|
|
31295
|
+
}
|
|
31296
|
+
}
|
|
31297
|
+
}
|
|
31298
|
+
}
|
|
31299
|
+
}
|
|
31300
|
+
}
|
|
31301
|
+
}
|
|
31302
|
+
},
|
|
31303
|
+
"401": {
|
|
31304
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
31305
|
+
},
|
|
31306
|
+
"404": {
|
|
31307
|
+
"$ref": "#/components/responses/NotFound"
|
|
31308
|
+
},
|
|
31309
|
+
"409": {
|
|
31310
|
+
"description": "The reservation belongs to a channel or another PMS (`reservation_owned_by_channel`), or the PMS connection is gone (`no_connection`)."
|
|
31311
|
+
},
|
|
31312
|
+
"422": {
|
|
31313
|
+
"$ref": "#/components/responses/UnprocessableEntity"
|
|
31314
|
+
}
|
|
31315
|
+
}
|
|
31316
|
+
}
|
|
29915
31317
|
}
|
|
29916
31318
|
}
|
|
29917
31319
|
}
|