Repull for platforms: how it works when your customers are the hosts
These are the questions platforms actually ask before they commit — one agreement or many, what the unit is, who gets billed, what white-label really covers, and what happens at a few thousand properties. Answered with what exists today, including the parts that do not exist yet. Nothing here quotes a price: the commercial half is a conversation, and this page is the honest technical half you need before having it.
The shape, in one paragraph
You get one workspace and one API key. Every one of your users connects their own Airbnb, Booking.com or Vrbo accounts into that workspace through Connect, in your branding — many accounts per channel, side by side. Your product reads and writes all of them with the one key, and every webhook event says which connected account it came from, so you route it to the right user. Your users never sign up with Repull and never hold a key. That is the whole model — everything below is a consequence of it.
| Unit | What it is | In a platform integration |
|---|---|---|
| Workspace | The tenant: connections, listings, reservations, webhooks, keys. | One — yours. Billing identity and webhook subscriptions live here. |
| Connected account | One of your user’s channel accounts: an Airbnb host, a Booking.com property, a Vrbo account. | Many per channel. Each user connects their own; events and Airbnb rows name it. |
| Listing | A connected property. | Belongs to the account it came from. |
| API key | Bearer credential for the workspace. | One key reads every connected account. Scopes limit operations, not listings. |
Question 1
Can one platform hold a single agreement with Repull while providing the integration to many of its own users?
Yes, and it is what Repull is built for: one agreement, one Repull workspace for the platform, and all of the platform’s users connected inside it. Each user connects their own Airbnb, Booking.com or Vrbo account through the hosted Connect flow in your branding, and your product reads and writes every connected account with the one API key. Every connected account keeps its own identity — webhook events and every reservation, conversation and review say which account they came from — so you route each booking, message and review to the right user in your own product. Your users never sign up with Repull, never see a key and never sign anything with us. How the agreement itself is papered is a conversation, not a published plan.
In practice the platform never asks its users to sign anything with us, never shows them our brand except for one attribution link on the Connect page, and never hands them a credential. Your user clicks “connect Airbnb” inside your product, completes a hosted flow wearing your branding, and comes back. Their account is now one more connected account in your workspace.
Onboarding one of your users
// One workspace — yours — and one key for every user you onboard.
// 1. Mint a Connect session for this user, with your user id as state.
const res = await fetch('https://api.repull.dev/v1/connect', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.REPULL_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
redirectUrl: 'https://your-product.com/channels/done',
state: userId, // comes back to you
allowedProviders: ['airbnb', 'booking', 'vrbo-login'],
}),
})
const { url } = await res.json()
// 2. Redirect the user. They connect on your branded Connect page and
// come back with ?status=connected&state=<userId>. The
// connect.session.completed webhook carries the same state and the
// account they connected — store that account against the user.Question 2
How is it structured — per property, per user, or per connection?
The units are workspace, connected account, listing and API key. The workspace is yours — the platform’s — and it is the tenant boundary. Inside it, each of your users connects one or more channel accounts: several Airbnb host accounts, several Booking.com properties, several Vrbo accounts, side by side. A listing is a connected property and belongs to the account it came from. The API key belongs to the workspace, so your product reads every connected account with one key and tells them apart by account: every reservation, conversation and review carries an account (the provider and the provider’s own account id), every property lists its accounts, all four take an account filter, and every webhook event names the same account. What gets counted commercially is a separate question from how it is modelled, and it is worth answering against a real shape rather than guessing at in public.
- Many accounts per channel. Airbnb host accounts, Booking.com properties and Vrbo accounts from all of your users sit side by side in your workspace.
GET /v1/connect/{provider}lists them inaccounts, andDELETE /v1/connect/{provider}takes anaccountIdto disconnect one user's account without touching the others. - Every event names its account. Webhook deliveries carry an
accountblock —providerandexternalAccountId, the provider's own id — and the same account on theX-Repull-AccountandX-Repull-Account-Idheaders. - Every record names its account.
GET /v1/reservations,/v1/conversationsand/v1/reviewscarryaccounton every row and/v1/propertiescarriesaccounts; all four take?account=provider:externalAccountIdto read one user's data. - One key, workspace-wide. The key is yours and reads every connected account. Scopes narrow what it may do, not what it may see — which is what you want when the key only ever lives on your servers.
Route every event to the right user
// Every webhook event names the connected account it came from.
app.post('/repull/webhooks', (req, res) => {
const event = verify(req) // HMAC over the raw body
const { provider, externalAccountId } = event.account ?? {}
const userId = accountsToUsers.get(provider + ':' + externalAccountId)
// …hand event.data to that user's inbox, calendar or CRM
res.sendStatus(200)
})
// The provider's account id is also on the X-Repull-Account header,
// so you can shard before parsing the body.Question 3
Can the end customer be billed directly rather than the platform?
Not as a platform feature today. Billing attaches to a workspace, so the party that owns the workspace — normally you, the platform — is the party that is billed. There is no reseller billing object, and no mechanism for Repull to invoice a platform’s end customers on the platform’s behalf while the platform keeps administrative control. What does work is the other direction: an end customer can own and pay for their own workspace and give the platform a key to it. If billing your customers through us is a requirement rather than a preference, say so — it is the kind of thing worth building for the right partner, and it is not something to pretend already exists.
Is customer-direct billing a requirement for you?
If your model depends on us invoicing your customers while you keep administrative control, tell us the shape you need. It does not exist today, and it is a concrete thing to build with a partner behind it rather than a maybe.
Email hello@repull.devQuestion 4
If the end customer pays directly, can the platform still use the API inside its product?
Yes. Access follows the API key, and a key belongs to a workspace rather than to a person, so a customer who owns their own Repull workspace can issue a key and hand it to the platform, and the platform’s product calls the API against that workspace exactly as it calls its own. A key never reaches across workspaces, so this model means holding one extra key per such customer. It is the exception rather than the default: most platforms keep every user in their own partner workspace and only use a customer-owned workspace when a customer wants their own billing relationship with us.
| Platform holds the keys | Customer owns the workspace | |
|---|---|---|
| Who signs up | You, once per customer | Your customer |
| Who is billed | You | Your customer |
| Who holds the key | You | Your customer, who shares it with you |
| Onboarding UX | Fully inside your product, with your branding on Connect | Your customer leaves to sign up, then returns with a key |
| If they churn from you | You disable the workspace | They keep the workspace and the connections |
| Support surface | Yours | Split between you and us |
Both work technically. The second is genuinely better in one case: a customer large enough to want their own relationship, their own invoice and their own continuity if they ever leave your product. For everyone else the first is less friction and fewer credentials in your database.
Question 5
Are there partner, reseller, white-label or volume arrangements for SaaS platforms?
Commercially, yes — platform arrangements are exactly the conversation we want to have, and the terms are set per partner rather than published. Technically, white-labelling today means the hosted Connect pages a platform’s users land on carry the platform’s brand: app name, light and dark logos, primary and accent colours for both themes, support email, terms and privacy links, a default redirect back into the product, and a default language. What it does not mean: the Connect URL stays on connect.repull.dev, the page carries a "Powered by Repull" link, and there is no custom domain and no email sent from a partner domain. Everything past that — reseller terms, volume arrangements, co-marketing — is a conversation.
| Today | |
|---|---|
| Brand name on the hosted Connect pages | Yes |
| Your logo, light and dark variants | Yes |
| Your primary and accent colours, both themes | Yes |
| Your support email in the footer | Yes |
| Your terms and privacy links | Yes |
| Default redirect back into your product | Yes |
| Default language for the hosted pages | Yes |
| Connect served from your own domain | No — the URL stays on connect.repull.dev |
| Attribution removed | No — a "Powered by Repull" link is present |
| Email sent from your domain | No |
Set it once at /dashboard/settings/connect and it applies to every channel your users connect. The flow itself is the same shape as Stripe Connect or Plaid Link: your server mints a session and reads a status, and never touches a channel credential.
Question 6
What happens at several hundred or several thousand connected properties?
The API is built for that size: heavy list endpoints are keyset-cursor paginated with an offset alias for shallow paging, batch surfaces exist so you are not making one call per property (PATCH /v1/availability/batch, POST /v1/listings/pricing/bulk, POST /v1/listings/status), writes take an Idempotency-Key so a network timeout cannot double-book, and webhooks with delivery logs and replay mean you do not poll. Thousands of properties across hundreds of your users still live in your one workspace behind one key and one webhook endpoint; what is worth designing with us at that size is onboarding volume and how you map connected accounts to your users.
- Paginate with cursors. The heavy list endpoints are keyset-paginated, so page cost stays constant however deep you go.
?offset=exists as an alias for shallow paging and is the wrong tool for a full sweep. - Write in batches.
PATCH /v1/availability/batchfor calendar values across many properties,POST /v1/listings/pricing/bulkfor pricing decisions, andPOST /v1/listings/statusfor activation. One call, many properties, partial failures reported per item rather than failing the batch. - Send an idempotency key. Every write that creates something takes
Idempotency-Key. At platform volume a timeout is not an edge case, it is Tuesday. - Subscribe, do not poll. One
POST /v1/webhooksendpoint for your workspace, with delivery logs, replay and a test-fire endpoint per event type so you can build the handler before the first real event.
The two reads a platform support screen needs
# What is connected, for a support screen. curl https://api.repull.dev/v1/connect \ -H 'Authorization: Bearer sk_live_...' # What this workspace has consumed, for your own metering. curl https://api.repull.dev/v1/usage/summary \ -H 'Authorization: Bearer sk_live_...'
Planning for a few thousand properties?
Bring the number of users, the channel mix and how fast you expect to onboard them. Onboarding volume and account-to-user mapping at that size are worth designing together before you build them.
Email hello@repull.devQuestion 7
Are there setup, transaction or usage fees to plan for?
Usage is metered per workspace and is visible to you in the API before it is ever a surprise: GET /v1/usage/summary, GET /v1/usage/logs and GET /v1/usage/tier report what a workspace has consumed and what it is entitled to, so a platform can watch its own customers’ consumption programmatically. There is also no separate paid sandbox to budget for — you build against the real API from the first key. What any of it costs for a platform is deliberately not published, because a number that is right for a ten-customer integration is wrong for a thousand-customer one. Bring your shape and your volume and you will get a straight answer.
The reason there is no number on this page is not coyness. Platform arrangements differ by an order of magnitude depending on how many end customers sit behind them, which channels they use and who carries first-line support — and a figure published for one of those shapes is actively misleading for the others. What you can verify yourself before any conversation is the consumption: the usage endpoints report what a workspace has used and what it is entitled to, so you can model your own economics from real numbers rather than from ours.
Get the commercial answer for your actual shape
Send the number of end customers, the channels they need and roughly how many properties each one runs. You will get a concrete proposal back rather than a pricing table that does not fit.
Email hello@repull.devQuestion 8
What is the recommended commercial model for a platform embedding Repull?
One partner workspace, one key, one agreement with us. Every user you onboard connects their channel accounts into your workspace through Connect, in your branding, with your own user id as the session state. When they finish, the connect.session.completed webhook hands you that state and the account they connected; store the account against your user. From then on every event and every record names its account, and every list takes an account filter. Your users never deal with Repull directly, and adding a user is a Connect session, not a signup. Use a separate, customer-owned workspace only when a customer specifically wants their own billing relationship with us, or for Repull Migrate, which creates a workspace per property manager you move.
- 1Sign up once. Your workspace and its API key are the only Repull credentials in your system; keep the key on your servers.
- 2For each user, mint a Connect session with
POST /v1/connect, restrictingallowedProvidersto the channels your product supports. - 3Pass your user id as
state. When they finish,connect.session.completedreturns thatstatewith the account they connected — store the account against the user. - 4Subscribe one webhook endpoint with
POST /v1/webhooksand route every event by itsaccountblock. Use the test-fire and replay endpoints to build the handler before a real event arrives. - 5Read through the cross-channel endpoints wherever you can, so adding a channel later is a configuration change rather than a rewrite.
The deeper technical version of this — auth handling, webhook event types, sandboxing, per-channel coverage — is in the SaaS platform Q&A. Channel-by-channel detail lives in the Airbnb, Booking.com and Vrbo guides, and the full reference is in the docs.
Most platforms inherit whatever their customers already run, which in practice means a spread of property management systems rather than a single one. Each has its own auth model, its own field names and its own limits — the Guesty, Hostaway, Hospitable, Lodgify, OwnerRez, Smoobu and Beds24 guides each set out what that system exposes and what it costs you to keep, and the coverage matrix compares them side by side.
The honest list
What does Repull not do for platforms yet?
Stated plainly so nobody builds against them. A workspace holds one connection per property management system: connecting a second Hostaway, Guesty or other PMS account into the same workspace replaces the first, so today two of your users on the same PMS cannot sit side by side the way Airbnb, Booking.com and Vrbo accounts can — this is being fixed. API keys cannot be scoped to a subset of listings; scopes limit operations, not inventory. There is no general workspace-provisioning endpoint — the partner model does not need one; the one API-created workspace is Repull Migrate’s (`POST /v1/connect` with `purpose: "migrate"`, reached with `X-Workspace-Id`). There is no per-end-customer or reseller billing. White-labelling does not extend to a custom Connect domain or to email sent from a partner domain, and the hosted pages carry a "Powered by Repull" link. If one of these is load-bearing for your build, say so early.
Why this section exists
Tell us which of these is in your way
Name the missing piece, what you would build on it and when you need it. A specific requirement from a real integration is what gets built next.
Email hello@repull.dev