connection_reauth_required

The channel or PMS no longer accepts this connection for the listing or the action — revoked, or granted without write access. Reconnect it; retrying will not help.

HTTP 403The request was authenticated, but not allowed.

When it fires

A write to Airbnb — for example PUT /v1/channels/airbnb/listings/{id}/pricing or /availability — reached Airbnb, and Airbnb no longer accepts the connection for that listing. One of:

  • The host's authorization expired or was revoked on Airbnb.
  • Airbnb refused to refresh the connection's access.

messagecarries Airbnb's own wording where there is any.

The inquiry and booking-request actions (pre-approvals, special offers, accepting and declining requests) return it too, whenever Airbnb answers with an authorization error. A connection made with read-only or messaging access is refused before Airbnb is contacted, with 403 insufficient_access instead.

This code means the account authorization needs renewing, and reconnecting is what fixes it. A listing that Airbnb has simply never had API sync switched on for is a different problem with a different fix — 403 listing_not_api_connected, where reconnecting the account does nothing and the host has to turn sync on for that one listing inside Airbnb.

Reservation writes on a PMS listing

Creating, changing, cancelling or quoting a booking on a listing managed in a PMS returns this code when the PMS refused the write because the connection was revoked, or was granted without write access to bookings. Nothing was written. provider names the PMS and reconnect carries the call that fixes it. The access each PMS needs:

  • Beds24 — an invite code with write:bookings, plus bookings-personal (guest details) and bookings-financial (price).
  • BookingSync — bookings_write (or bookings_write_owned, which limits changes to bookings your app made) and clients_write.
  • Hospitable — reservation:write; a personal access token needs write access.
  • OwnerRez — the OAuth app's full scope.
  • iGMS — the direct-bookings scope.

This refusal is not stored against your Idempotency-Key, so after reconnecting, retry with the same key.

Response shape

Every Repull error follows the same envelope. The code is stable and safe to switch on.

{
  "error": {
    "code": "connection_reauth_required",
    "message": "Authentication failed for listing 22616426",
    "fix": "Airbnb no longer accepts this connection for this listing, so retrying cannot succeed. Reconnect Airbnb at https://repull.dev/dashboard/connections (or re-run `POST /v1/connect/airbnb`), make sure this listing is selected, then retry.",
    "docs_url": "https://repull.dev/docs/errors/connection_reauth_required",
    "request_id": "req_01J5X7Y8Z9ABCDEF12345678"
  }
}

How to fix

  1. PMS reservation writes: reconnect the PMS named in `provider` with `POST /v1/connect/{provider}` (the envelope's `reconnect`), granting booking write access, then retry with the same `Idempotency-Key`.
  2. Stop retrying. The same request fails the same way until the connection is renewed.
  3. Reconnect Airbnb at https://repull.dev/dashboard/connections, or start a new Connect session with `POST /v1/connect/airbnb` and send the host through the returned `url`.
  4. On Airbnb's consent screen, make sure the listing you were writing to is selected.
  5. Retry the original request once the connection is active again.

Common gotchas

  • If only some listings fail, this is not your code. An expired or revoked authorization takes the whole account down at once. When other listings on the same host still accept writes, the one that fails is almost certainly not API-connected on Airbnb — see listing_not_api_connected, and do not send the host through the connect flow again.
  • Not the same as a missing connection. A workspace with no Airbnb connection at all gets 404 no_connection; a listing that is not connected to Airbnb in your workspace gets 404 not_found.
  • Calendar writes through PUT /v1/availability/{propertyId} report the same situation in synced.authErrors instead of failing the call.

Examples

curl

# A write Airbnb no longer authorizes
curl -X PUT https://api.repull.dev/v1/channels/airbnb/listings/4118/availability \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "calendar", "operations": [{"dates": ["2026-07-01"], "availability": "unavailable"}]}'
# → 403 connection_reauth_required

# Recovery: start a new Airbnb Connect session and send the host to the returned url
curl -X POST https://api.repull.dev/v1/connect/airbnb \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"redirectUrl": "https://your-app.com/callback"}'

TypeScript

import { Repull } from '@repull/sdk'

const repull = new Repull({ apiKey: process.env.REPULL_API_KEY! })

const res = await fetch('https://api.repull.dev/v1/channels/airbnb/listings/4118/availability', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.REPULL_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ type: 'calendar', operations: [{ dates: ['2026-07-01'], availability: 'unavailable' }] }),
})

if (res.status === 403) {
  const { error } = await res.json()
  if (error.code === 'connection_reauth_required') {
    // Do not retry — ask the host to reconnect Airbnb and select this listing
    const session = await repull.connect.airbnb.create({ redirectUrl: 'https://your-app.com/callback' })
    return { needsReconnect: true, redirectTo: session.url }
  }
}

If you're an AI agent

The channel or PMS no longer accepts this connection (for a PMS: revoked, or no booking write access; `provider` names it). Do not retry. For a PMS, have the user reconnect with POST /v1/connect/{provider} granting booking write access, then retry with the same Idempotency-Key. For Airbnb: tell the user to reconnect Airbnb at https://repull.dev/dashboard/connections (or via POST /v1/connect/airbnb) and make sure the listing is selected, then retry the original request.

Hit an error that isn't covered? Email hello@repull.dev with the request id from the response headers.

AI