Technical evaluation
The integration questions SaaS platforms send us before a first call, each answered with what exists today and linked to the relevant documentation. Start with the Quickstart and the API reference if you want to poke at the API first. The commercial side is covered in Repull for platforms.
Q1 – Q7
Yes. This is exactly what the hosted Connect flow is built for: your end-users each authorize their own channel account (e.g. their own Airbnb host account) in your Repull workspace. Each connected account is tracked, tokened, and health-monitored independently.
Docs: Connect (multi-channel), OAuth Connect, Connect Widget.
There is no technical cap on connected accounts. Plans are priced by listing: Free covers up to 3 listings, Starter is $99/month with 10 listings included and $5 per listing from the 11th up to 100, and above 100 listings (where a platform serving many hosts lands) it is a Custom plan with volume pricing and one partner workspace for all your customers.
Docs: Pricing, Repull for platforms.
Yes. Access and refresh tokens are stored per connected account, fully isolated. One user revoking access affects only their account: you receive an account.disconnected webhook for that account with a machine-readable reason, and every other account keeps syncing.
Yes. Pass your internal user ID as state when you create the Connect session. When the user finishes, the connect.session.completed webhook returns that state together with the connected account, so you map the two once. From then on every webhook delivery carries an account block (provider and externalAccountId, the provider's own ID) plus the X-Repull-Account and X-Repull-Account-Id headers, and reservations, conversations and reviews carry the same account on every record.
Docs: OAuth Connect, Webhooks.
Yes. GET /v1/connect lists every connection in your workspace (id, provider, status, external account id). There is also a dedicated per-channel health endpoint, e.g. GET /v1/channels/airbnb/connection, that returns every connected Airbnb account with its connection status and last-disconnect reason, built to be polled from a status surface.
Docs: API reference, Connect.
Yes, verbatim:
POST /v1/connect returns a hosted session URL (30-minute TTL)redirectUrl with status=connected&accountId=… plus your stateaccount.created and connect.session.completed webhooks fireDocs: Connect, Quickstart.
Yes, end to end: Airbnb login, permission/scope handling (read-only, messaging or full access), token exchange, refresh tokens, and expiration handling are all managed by Repull. When a refresh is rejected or access is revoked upstream, the account is flagged and you receive account.disconnected with a reason (refresh_token_rejected, auth_expired, revoked_upstream, manual_disconnect) so you can prompt the user back through the same hosted flow to re-authenticate.
Docs: Airbnb channel.
Q8 – Q9
Yes. There is no separate sandbox: every account gets a live sk_live_*key on signup (free tier, no credit card), so you test directly against the real API: create real properties, reservations, and webhook subscriptions and remove them when you're done. The webhook system has first-class testing tools of its own: POST /v1/webhooks/{id}/test/{event_type} fires realistic fixture payloads for any event type, plus ping and replay endpoints and full delivery logs.
One honest caveat: Airbnb itself does not offer sandbox host accounts, so an end-to-end OAuth test requires a real Airbnb login regardless of environment. Everything downstream of that (webhooks, data shapes, error handling) is fully testable with fixture events, no live Airbnb connection required.
Docs: Manage webhooks.
Yes.The hosted Connect pages are white-labeled per workspace: app name, logo (light and dark variants), primary and accent colors for both themes, support email in the footer, your own terms and privacy URLs, a default redirect URL and a default language. The URL stays on connect.repull.dev and the page carries a “Powered by Repull” link.
Docs: Connect Widget.
Q10 – Q14
Yes. A user can hold several connections at once (Airbnb, Booking.com, Vrbo and a PMS), and a workspace can hold many accounts per channel: many Airbnb hosts, many Booking.com properties, many Vrbo accounts. The one limit today is one connection per property management system per workspace. The hosted session can show a multi-channel picker or be locked to specific providers via allowedProviders.
Docs: Connect (multi-channel), PMS coverage.
Yes. DELETE /v1/connect/{provider} revokes the OAuth token where the channel supports it, purges stored credentials, and stops all sync jobs for that connection. Pass an accountId to disconnect one account without touching the others on the same channel.
Yes. GET /v1/listings is cursor-paginated and filterable by ?channel=airbnb|booking|vrbo. Every listing carries a channels[] array with the platform, the original channel property ID (externalId), and active/sync status, so you always know which channel each property belongs to and its native ID. Optional ?include=content,details,amenities expansions.
Docs: List Properties, Property Details, Listing Content & Details.
Airbnb: yes, through POST /v1/reviews/{id}/reply, when the host connected with full access. Airbnb only grants review writes with its property-management permission, so read-only and messaging connections can read reviews but not reply to them. Booking.com and Vrbo: in testing. Replies go through the same endpoint, but they have not yet been proven on a live review.
Docs: Reviews, OAuth Connect.
Yes. GET /v1/reviews is a unified cross-channel review stream (Airbnb, Booking.com, Vrbo) with filters for platform, listing, rating range, responded/unanswered status, and guest-vs-host reviews. Review updates, including host responses, are reflected on the same records.
review.created and review.responded webhooks tell you when a review arrives or gets a response. The endpoint is served from our database, never from a live channel call, so polling it is cheap too.
Docs: List Reviews.
Q15
The live catalog is at Webhook event types and machine-readable at GET /v1/webhooks/event-types (with sample payloads). Current events:
reservation.createdreservation.updatedreservation.cancelledreservation.message.receivedreservation.message.sentreservation.message.updatedreservation.alteration.createdreservation.alteration.respondedreservation.request.createdreservation.request.updatedinquiry.createdinquiry.updatedlisting.createdlisting.updatedlisting.deletedlisting.suspendedlisting.reactivatedcalendar.updatedaccount.createdconnect.session.completedaccount.disconnectedreview.createdreview.respondedai.operation.completedai.operation.failedpayment.completedpayment.refundedpayout.completedmigration.completedmigration.failedrepull.pingusage.quota.warningDeliveries are HMAC-SHA256 signed (Stripe-style) with retries, replay, and full delivery logs: Verify signatures, Retries, Manage webhooks.
Q16 – Q17
Syncs are background jobs. Connecting an account fans out parallel sync pipelines (listings, calendar/pricing, messages, reviews, transactions) on our queue infrastructure; you do not manage any of it. Initial sync duration is dominated by the channel's own rate limits, so it scales with account size: large portfolios complete in the background while the connection is already usable.
Reads are paginated at up to 100 items per page with cursor pagination (stable at any depth), so 100,000 reviews is roughly 1,000 calls, trivial against the default rate limit of 600 requests per minute. Ongoing changes arrive via webhooks, so you never re-crawl.
Docs: Rate limits, Idempotency.
Synchronized.Repull syncs channel data into our own database and serves the API from there. That is a core design decision: fast, consistent reads that never block on, or get rate-limited by, Airbnb's API, and your app keeps working even while an upstream is flaky. Responses include a data_freshness envelope (last_synced_at, stale flag) so you always know how fresh the data is.
Q18 – Q20
Per listing, with an API call allowance per plan, not per reservation, review, webhook or connected account. Free: $0, up to 3 listings, 1,000 calls/month. Starter: $99/month, 10 listings included, $5 per listing from the 11th up to 100, 100,000 calls/month, webhooks included. Custom: 100+ listings with volume pricing and API limits sized to your integration.
Docs: Pricing, Credits & usage.
That is Custom-plan territory. Pricing at that scale depends on listing counts per user and API volume, and we price it as a platform partnership rather than a per-seat rack rate. Send us your numbers and you get a concrete proposal: how platform pricing works.
Starter includes email support; Custom includes priority email support, and for a large platform integration we can set up a shared channel with our engineering team.
Day to day, the API is built to be self-serve: every error response carries a request_id, a machine-readable code, a fix field with the exact next step, and a deep link into the error docs.
Questions? hello@repull.dev