For software vendors

Every guest conversation,
inside your product.

Read and answer guest messages from Airbnb, Booking.com and Vrbo through one API. Your customers keep their PMS; your product gets the inbox.

What your product gets

A complete inbox, not a notification feed.

Threads, history, replies and attachments from every channel, normalized into one shape.

One list of threads

Conversations from every connected channel in a single paginated list, filterable by channel and account.

Replies that go out on the right channel

Send once. The message is delivered on whichever channel the guest wrote from, and recorded in the thread.

Real-time delivery

Webhooks fire on every new guest message, and on replies the host sends from the channel's own app, so your inbox never drifts.

How it works

An inbox in three calls and a webhook.

List the threads, read one, reply. Subscribe to message events so new messages appear the moment they arrive.

  1. 1

    Connect the host

    The host connects Airbnb, Booking.com or Vrbo through Repull Connect. Their PMS stays connected as it is.

  2. 2

    Load the threads

    GET /v1/conversations returns every thread; the messages endpoint returns its history.

  3. 3

    Reply and listen

    POST a message to answer, and handle reservation.message.received to keep the inbox live.

inbox.ts · ts
const api = (path: string, init?: RequestInit) =>
  fetch(`https://api.repull.dev${path}`, {
    ...init,
    headers: {
      Authorization: `Bearer ${process.env.REPULL_API_KEY}`,
      'Content-Type': 'application/json',
    },
  }).then(r => r.json())

// Every thread, from every channel, in one list
const { data: threads } = await api('/v1/conversations?limit=50')

// One thread's history, oldest first
const { data: messages } = await api(`/v1/conversations/${threads[0].id}/messages?order=asc`)

// Reply — it goes out on the channel the guest wrote from
await api(`/v1/conversations/${threads[0].id}/messages`, {
  method: 'POST',
  body: JSON.stringify({ message: 'Hi Alex, check-in is from 4pm.' }),
})
webhook.ts · ts
// POST /webhooks/repull — subscribed to reservation.message.received
export async function POST(req: Request) {
  const event = await req.json() // verify X-Repull-Signature first
  if (event.event === 'reservation.message.received') {
    const { threadId, channel, senderName, body } = event.data
    await inbox.push({ threadId, channel, from: senderName, body })
  }
  return new Response(null, { status: 200 })
}

Channel coverage

What works where

AirbnbThreads, send, edit and unsend, mark as read. Pre-approvals and special offers need full access, which Airbnb doesn't allow alongside another PMS.
Booking.comConversations, send, attachments.
VrboConversations, send text. Pre-approve inquiries and edit the quote.
Host's PMSGuest messages from every channel the PMS manages, direct bookings included, for the PMSs we connect to. Replies go back through the PMS where its API allows it.

Coverage is checked against the live API. Full channel and PMS coverage

Alongside any PMS

Your customers keep the tools they already run.

The PMS stays in charge of the listing

On Airbnb and Vrbo, Repull connects with messaging-level access. The host's PMS keeps managing listings and calendars, and your product never competes with it for control.

Booking.com through the host's extranet login

In beta: reservations, messages and reviews from Booking.com, without the host moving their connectivity provider away from their PMS.

One integration, every channel

The same endpoints and the same webhook events whether the guest booked on Airbnb, Booking.com or Vrbo. You build it once.

How Repull works alongside a PMS→

The API behind it

Endpoints and events

GET /v1/conversations

Every thread across channels, cursor-paginated.

GET /v1/conversations/{id}/messages

A thread's history, newest or oldest first.

POST /v1/conversations/{id}/messages

Reply to the guest on their channel, with idempotency keys.

POST /v1/conversations/{id}/pre-approval

Pre-approve an inquiry — Vrbo, or Airbnb with full access.

reservation.message.received

Webhook: a guest sent a message.

reservation.message.sent

Webhook: the host replied, including from the channel's own app.

Ship the inbox your customers keep asking for.

Free to start. Connect a test account and have messages flowing today.