Vai al contenuto principale

Webhooks and notifications

Housing Anywhere and Uniplaces can push paid and cancelled bookings to VIVIN through inbound webhooks; VIVIN sends no webhooks back to them.

Before you start​

ItemValue
Who it is forHousing Anywhere and Uniplaces. Every other partner sends bookings with POST /<prefix>/bookings
Base URLhttps://api.vivin.app. Each webhook is on its partner's Swagger page: /housinganywhere-integration and /uniplaces-integration
Listing IDsEcho the ID from VIVIN's full feed: listingReference for Housing Anywhere, reference_id for Uniplaces (Full listing feeds)
OutboundNone. To see results, poll the listing feeds (Tracking results)

Endpoints​

MethodPathAuth
POST/housinganywhere-integration/{landlordKey}/webhookAuthorization: Bearer <partner-token>
POST/uniplaces-integration/webhookx-api-key: <webhook-key> or Authorization: Bearer <partner-token> (Authentication)

How VIVIN handles a webhook​

  1. VIVIN checks the call at once: credentials, body, required fields, and that the listing belongs to a VIVIN account. A failed check returns an error.
  2. A paid event queues a booking, created in the background within about a minute, with the same background checks as POST …/bookings. For example, a stay that overlaps another booking is refused there.
  3. A cancelled event cancels the matching booking at once, as cancelled without refund. VIVIN finds it by your booking ID and the listing reference, so send the same values as on the paid event.
  4. VIVIN answers 201 with a small JSON body (Swagger lists 200). Treat any 2xx as delivered.

The body may only contain the fields listed for that webhook. Any other field, at the top level or inside the Uniplaces guest object, rejects the whole call with 400.

Housing Anywhere webhook​

POST /housinganywhere-integration/{landlordKey}/webhook

Path parameters​

NameTypeRequiredDescription
landlordKeystringYesThe landlord's key, or the Integration Email on the landlord's Housing Anywhere card (Settings → Integrations → Booking Platforms). The same key as the full feed

Request fields​

Every value must be a JSON string, as Housing Anywhere sends them. A JSON number returns 400.

NameTypeRequiredDescription
notification_typestringYesbooking_paid queues a booking. booking_cancelled or booking_canceled cancels it. Letter case is ignored
listing_external_referencestringYesThe listingReference from the Housing Anywhere full feed. The unit must belong to the landlord in the path
booking_uuidstringYesStored as the booking's reference. Used to find the booking on cancel and to drop duplicates
booking_start_date, booking_end_datestringPaid eventsCheck-in and check-out, YYYY-MM-DD. A time after a space is ignored
booking_pricestringPaid events, in practiceFirst-month rent in cents ("65000" is 650.00), shown as Provider platform payment. Without a value above 0, the booking fails in the background. booking_total is not used, because it includes Housing Anywhere's fee
tenant_first_name, tenant_last_namestringNoCut to 128 characters each. Missing values become Guest and Tenant
tenant_emailstringNoMatches an existing tenant or creates one. When missing, VIVIN uses a placeholder address that the landlord must replace
tenant_phonestringNoStored on a new tenant

Housing Anywhere's other fields are accepted and not used: booking_id, booking_total, booking_fee, booking_deposit, booking_currency, booking_tenants_count, booking_advertiser_uuid, booking_external_reference, listing_uuid, listing_alias, listing_price, listing_currency, listing_address, listing_house_number, listing_zip, listing_city, listing_neighborhood, listing_country_code, listing_lat, listing_lng, tenant_birth_date, tenant_gender_code, tenant_nationality and tenant_iso_country_code. VIVIN matches bookings on booking_uuid, not booking_id, and creates a Housing Anywhere booking for one tenant.

Example request​

curl -X POST "https://api.vivin.app/housinganywhere-integration/<landlordKey>/webhook" \
-H "Authorization: Bearer <partner-token>" \
-H "Content-Type: application/json" \
-d '{
"notification_type": "booking_paid",
"booking_uuid": "5d0c6f0e-2b1a-4c1e-9d7a-2f3e8c1a9b10",
"booking_start_date": "2026-10-01",
"booking_end_date": "2027-06-30",
"booking_price": "65000",
"booking_currency": "EUR",
"listing_external_reference": "HA-A101",
"tenant_first_name": "Casey",
"tenant_last_name": "Sample",
"tenant_email": "[email protected]",
"tenant_phone": "+15555550100"
}'

The Housing Anywhere webhook on its Swagger page: the landlordKey path parameter, the request body fields and the ok/message response

Uniplaces webhook​

POST /uniplaces-integration/webhook. One URL serves every landlord: VIVIN finds the landlord from the listing reference.

Request fields​

NameTypeRequiredDescription
eventstringYesHyphens or underscores, any letter case. booking-paid, booking-paid-success and payment-confirmed queue a booking. booking-cancelled, booking-canceled and booking-rejected cancel it. Any other event is acknowledged without action
offer_api_referencestring or numberNoThe reference_id from the Uniplaces full feed, and the preferred way to find the unit. When it is missing, VIVIN uses offer_id. Paid and cancel events need one of the two
offer_idstring or numberNoUsed only when offer_api_reference is missing. It matches only when the landlord linked the unit with that Uniplaces offer number
booking_id (or booking_Id)string or numberYesStored as the booking's reference. Used to find the booking on cancel and to drop duplicates
move_in_date, move_out_datestringPaid eventsCheck-in and check-out, YYYY-MM-DD
contract_price_amountnumberPaid events, in practiceAmount in cents (65000 is 650.00), shown as Provider platform payment. When missing, VIVIN uses booking_total. Without either, the booking fails in the background
booking_totalnumberNoAmount in cents, used only when contract_price_amount is missing
guest_name or guest.namestringNoThe first word becomes the first name, the rest the last name. Missing values become Guest and Tenant
guest_email or guest.emailstringNoMatches an existing tenant or creates one. When missing, VIVIN uses a placeholder address that the landlord must replace
guests_numbernumberNoTotal number of guests. Guests beyond the first are recorded as extra tenants

Also accepted and not used: booking_date, rejection_reason, contract_price_currency, admin_fee_amount (a number), admin_fee_currency and accommodation_provider_id. The guest object accepts only name and email.

Example request​

curl -X POST "https://api.vivin.app/uniplaces-integration/webhook" \
-H "x-api-key: <webhook-key>" \
-H "Content-Type: application/json" \
-d '{
"event": "booking-paid",
"offer_api_reference": "UP-A101",
"booking_id": 1193557,
"guest_name": "Casey Sample",
"guest_email": "[email protected]",
"guests_number": 1,
"move_in_date": "2026-10-01",
"move_out_date": "2027-06-30",
"contract_price_amount": 65000,
"contract_price_currency": "EUR"
}'

Responses​

Both webhooks answer 201 with one of these bodies:

BodyMeaning
{ "ok": true }Booking queued, or booking cancelled
{ "ok": true, "message": "Booking already recorded" }A paid event for a booking that exists in VIVIN and is not cancelled. Nothing is queued
{ "ok": true, "message": "No active booking to cancel" }A cancel event for a booking VIVIN does not have, has already cancelled, or has not created yet (see Troubleshooting)
{ "ok": true, "message": "Ignored Uniplaces event: <event>" }A Uniplaces event VIVIN does not act on

The reply never says whether the queued booking was created. The landlord sees that in VIVIN.

Errors​

Errors use the standard error body:

{
"statusCode": 400,
"message": "Unsupported Housing Anywhere notification_type: booking_requested",
"error": "BadRequestException"
}
StatusmessageCauseWhat to do
400property <name> should not existA field the webhook does not acceptRemove it
400<field> must be a string, <field> must be a number conforming to the specified constraintsA value of the wrong JSON typeSend the type listed above
400notification_type must be a stringHousing Anywhere: no notification_typeSend it
400Unsupported Housing Anywhere notification_type: <value>Housing Anywhere: an event other than paid or cancelledDo not send other events
400listing_external_reference and booking_uuid are required for booking_paid (or for cancellation)Housing Anywhere: a missing referenceSend both
400Invalid booking_start_date or booking_end_dateHousing Anywhere: a missing date, or not YYYY-MM-DDFix the dates
400landlordKey must be a non-empty valueHousing Anywhere: blank landlordKey in the pathPut the landlord key in the path
400Uniplaces webhook event is requiredUniplaces: no eventSend it
400offer_api_reference (or offer_id) and booking_id are required for paid booking webhooks (or for cancellation webhooks)Uniplaces: a missing referenceSend both
400Invalid move_in_date or move_out_date for Uniplaces bookingUniplaces: a missing date, or not YYYY-MM-DDFix the dates
401Missing integration credentials and othersA missing or wrong keySee Authentication
404Listing not found for housinganywhere with externalId <id>The reference is neither a linked unit nor a VIVIN unit ID of the landlord in the path, or landlordKey matches no accountEcho listingReference from that landlord's full feed
404Listing not found for uniplaces with reference <id>The reference is neither a linked unit nor a VIVIN unit IDEcho reference_id from the full feed
409Ambiguous uniplaces reference <id>: matches listings on multiple accountsTwo landlord accounts linked the same ID, so VIVIN cannot tell which one you meanAsk the landlords to fix their unit links

Retries​

  • Fix the request before you retry a 4xx.
  • Retrying a paid event is safe: once the booking exists and is not cancelled, VIVIN answers Booking already recorded. A repeat that arrives before the first was processed is queued, then dropped as a duplicate without a notification.
  • A paid event for a booking ID that was imported and then cancelled is dropped: the booking is not created again (Retries and duplicates).
  • Webhooks are not rate-limited.

Tracking results​

VIVIN does not call your platform back. To check a booking or keep availability in sync, poll the listing feeds:

  • One unit, live: GET /<prefix>/listings/{externalId}. A new booking shows up as a new row in unavailabilities, and a cancelled one disappears.
  • All units: GET /<prefix>/listings, rebuilt about every 10 minutes.
  • Do not rely on the listing's updatedAt: new bookings and blocks do not change it.

The landlord gets an in-app notification for each booking created or refused, and an email for each refusal (How failures are reported). Nothing is sent to your platform.

Troubleshooting​

SymptomLikely cause and fix
No active booking to cancel right after a paid eventThe queued booking was not created yet, and it will still be created. Send the cancel again a few minutes later
404 with your own listing IDYour ID works only when the landlord linked the unit with it. Echo the ID from VIVIN's full feed
The booking was created with a placeholder emailThe webhook had no guest or tenant email. The landlord should replace it in the tenant's profile
The booking was refused for a missing platform paymentbooking_price (Housing Anywhere) or contract_price_amount and booking_total (Uniplaces) were missing or zero
Airbnb or Booking.com bookings are missingThey need no webhook. VIVIN collects them after the landlord connects those accounts under Settings → Integrations