Switch from Channex
Repull serves the Channex API, so switching does not mean rewriting your integration. You change two lines, the base URL and the API key, and the code you wrote against Channex keeps working. This guide covers the move itself: trying it on a pilot property, keeping your Channex ids, and moving each property's channel connections without a gap in bookings.
Channels
How the switch works
- Point your integration at Repull. Change the base URL and the key. Check the endpoints you use against the coverage table.
- Keep your ids (optional). One import call copies your Channex account under the property, room type, rate plan, webhook and channel ids your database already holds.
- Move the channels, one property at a time. Each channel connects to Repull alongside Channex, so bookings keep arriving throughout.
- Cut over. Activate the webhooks and stop the property on Channex.
1. Point your integration at Repull
- Create an API key in the Repull dashboard.
- Replace the base URL.
https://app.channex.io/api/v1becomeshttps://api.repull.dev/channex/api/v1. - Send the Repull key in the
user-api-keyheader, where your Channex key was.
BASE=https://api.repull.dev/channex/api/v1 KEY=sk_live_YOUR_KEY curl "$BASE/properties?pagination[page]=1&pagination[limit]=10" -H "user-api-key: $KEY"
Start with one pilot property. The Channex-compatible API reference covers conventions, webhooks and HMAC signing, the booking revision feed, and every endpoint's status. When Repull accepts a write but cannot apply all of it, the response says so in meta.warnings; log them while you test.
2. Keep your Channex ids
The import copies your Channex account into Repull under the same ids. Property, room type, rate plan, webhook and channel ids stay exactly the ones your database already holds, so your stored ids keep working against Repull. Skip this step if you would rather create properties fresh.
Pass your Channex API key. Repull only reads from Channex (nothing is written there) and does not store the key. It reads your properties, room types, rate plans, webhooks, signing keys, channels and upcoming bookings, and matches each Channex property to what is already connected in Repull (by Booking.com hotel and room ids, Airbnb and Vrbo listing ids, then title and address) or creates it. Start with dry_run: true to see the plan without writing anything.
curl -X POST "$BASE/migration/import" \
-H "user-api-key: $KEY" \
-H "Content-Type: application/json" \
-d '{ "migration": { "api_key": "YOUR_CHANNEX_KEY", "environment": "production", "dry_run": false } }'{
"data": {
"type": "migration",
"id": "6b0f6c55-2f0e-4d0a-9f43-1f3c2b7d9e10",
"attributes": {
"dry_run": false,
"complete": true,
"summary": {
"properties": { "matched": 11, "created": 1, "needs_action": 0 },
"room_types": { "matched": 37, "created": 2, "needs_action": 0 },
"rate_plans": { "matched": 39, "created": 14, "needs_action": 0 },
"webhooks": { "matched": 0, "created": 3, "needs_action": 0 },
"signing_keys": { "matched": 0, "created": 0, "needs_action": 1 },
"channels": { "matched": 9, "created": 3, "needs_action": 0 },
"bookings": { "read": 214, "linked": 198, "waiting": 16 }
},
"properties": [ { "channex_id": "4f6e7d8c-...", "title": "Seaside Hotel", "status": "matched", "detail": "..." } ],
"channels": [ { "channex_id": "a1b2c3d4-...", "channel": "BookingCom", "status": "matched",
"provider_switch": "required", "instructions": "In the Booking.com Extranet ..." } ],
"warnings": [],
"next_steps": [ "..." ]
}
}
}- Each entry says
matched,createdorneeds_action, with the reason indetail. - Upcoming Channex bookings are linked to their Repull reservation by OTA code.
waitingones link as soon as that reservation arrives through the channel. - Webhooks are recreated inactive, so nothing is delivered twice while Channex is still live.
- Channex never reveals signing secrets, so imported signing keys keep their id but need your secret. Install it with
POST /signing_keys/:id/rotateand{ "signing_key": { "secret": "..." } }; your verifier keeps working unchanged. - Re-runs are safe. If
completeisfalsethe time budget ran out; send the same request again and it continues where it stopped. The same import isPOST /v1/migrations/channexon the native API.
Not imported
3. Move the channels, one property at a time
Each channel in the report has provider_switch: switched (Repull already serves it), required (with the steps in instructions) or unsupported (a channel Repull does not connect). Without the import, use the channel list from GET /channels.
Move one property at a time. Each channel connects to Repull first, alongside Channex, and imports the property's listings and reservations. A new channel starts deactivated, so Repull does not push rates or availability until you activate it. The switch-over for a property is then: hand the channel over, activate it in Repull, deactivate it in Channex. Bookings keep arriving throughout, and the properties you have not moved yet stay on Channex untouched.
Booking.com
Switch the connectivity provider.In the Booking.com Extranet, under Account, Connectivity provider, the property replaces Channex with Repull. Then create the channel with the property's Hotel ID. Until Booking.com has authorised Repull for that hotel, the call returns a 422that says so; retry once the switch is done. Repull imports the property's rooms and reservations when it connects. Booking.com has one connectivity provider per property, so this step is the switch-over for that property.
curl -X POST "$BASE/channels" \
-H "user-api-key: sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "channel": {
"channel": "BookingCom",
"title": "Seaside Hotel - Booking.com",
"properties": ["PROPERTY_ID"],
"settings": { "hotel_id": "10167991" }
} }'Or connect alongside first. With settings.connection_method: "extranet_login", the response carries meta.connect.url, a hosted page where the property connects its Extranet login. That brings in reservations, guest messages and reviews while Channex stays the connectivity provider and keeps rates and availability. One Extranet login covers every property of the account. When the property is ready, switch the connectivity provider as above. See Connect with Extranet login.
Airbnb
Airbnb gives full access (listings, calendar and pricing) to one app per host account, and Channex holds it today. So connect Repull first with messaging or read_onlyaccess, which works next to Channex and imports the host's listings and reservations. At switch-over, the host disconnects Channex in Airbnb and reconnects Repull with full_access. Because access is per host account, all of that host's Airbnb listings move together.
curl -X POST "$BASE/channels" \
-H "user-api-key: sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "channel": {
"channel": "AirBNB",
"properties": ["PROPERTY_ID"],
"settings": { "access_type": "messaging", "redirect_uri": "https://pms.example.com/channels/done" }
} }'
# Send the host to meta.connect.url. At switch-over, repeat with "access_type": "full_access".POST /meta/airbnb/connection_link works as on Channex and returns the same hosted URL. Access types are explained in OAuth Connect.
Vrbo (beta)
The host signs in to Vrbo on the hosted page ("channel": "VRBO", then meta.connect.url). Repull imports the listings and reservations. At switch-over, stop the Vrbo channel in Channex and activate it in Repull. See Vrbo.
Switch-over, per property
- Hand the channel over: Booking.com connectivity provider, Airbnb
full_access, or stop Vrbo in Channex. POST /channels/:id/check_readinesslists anything unmapped or unconnected.POST /channels/:id/activatestarts rate and availability pushes for the mapped rooms and listings.- Push a full ARI window for the property, so every channel starts from your current values.
- Deactivate the property in Channex.
- Run
POST /migration/cutover(see step 4 below) to activate the webhooks and confirm the channel showsswitched.
4. Cut over
Cut-over activates the imported webhooks and reports, per channel, whether it is switched, required (with steps) or unsupported. It is safe to run as often as you like while channels move; done is true once nothing is left. Pass webhook_ids to activate only those webhooks.
curl -X POST "$BASE/migration/cutover" \ -H "user-api-key: $KEY"
{
"data": {
"type": "migration_cutover",
"id": "6b0f6c55-2f0e-4d0a-9f43-1f3c2b7d9e10",
"attributes": {
"webhooks": [ { "id": "e2d4f6a8-...", "callback_url": "https://pms.example.com/hooks/channex", "status": "activated", "detail": null } ],
"channels": [ { "channex_id": "a1b2c3d4-...", "channel": "BookingCom", "provider_switch": "switched", "instructions": null } ],
"summary": {
"webhooks": { "activated": 3, "already_active": 0, "left_inactive": 0, "needs_action": 0 },
"channels": { "switched": 9, "required": 2, "unsupported": 1 }
},
"done": false
}
}
}A webhook whose signing key has no secret yet stays inactive with needs_action; install the secret and run the cut-over again.
The Channels API and the mapping iframe work as on Channex if your product drives channel setup itself.