Full listing feeds
Full publish pulls (GET …/:landlordKey/listings/full) need rich catalogue data operators edit in Property & listing details (booking engine) — finish Getting Started — Recommended Setup Sequence steps 11–13 (Integrations, Integration field capability, Listings wizard + Full integration pill) before partners ingest. Resolve landlordKey and externalId per Property & Unit Mapping; pair ongoing sync with partial Listings & Availability and Onboarding a New Property — Step 7. Guide pairing after go-live: Setup sequence after go-live (hub: API Reference — Setup sequence after go-live).
Start with Which listings appear (full catalogue includes unlinked units; partial GET /listings does not) and landlordKey, then Platform matrix to pick the right full-feed prefix, then Last blocked night before you map catalogue occupancy. For Inlife, also read Recognised cities — unknown cities are omitted from the catalogue, not returned as a broken row — and id + room.id (the stored propertyId_roomId split). Inlife room extraTenantsPrice is 0 when numPeople is 1 — Extra tenants price. Platform markup applies only to rent — Listings & Availability — Platform markup. When a unit is variable, Uniplaces / Spotahome headline rent is the highest month — Variable rent headline. Units without a usable positive rent are omitted from both pulls — Usable rent. depositValue (and Uniplaces listing_pricing.deposit.value) is the computed security deposit — Computed deposit. cleaningFeeValue is the property cleaning amount (frequency is not on the catalogue) — Cleaning fee. The exit fee is not a catalogue field — Exit fee. Local Rent Cap is not a catalogue field — Local rent cap. Photos, address, amenities, and marketing copy live on this pull — Catalogue fields. When the unit has All bills included, listing JSON is billsIncluded: true with a null cap — All bills included. Uniplaces / Inlife landlord_email is the platform Integration Email — Landlord email. maxStayPeriod 0 means no maximum (12 is twelve months) — Maximum stay. For Uniplaces, reference_id is what inbound webhooks echo as offer_api_reference. For Housing Anywhere, listingReference is what inbound webhooks echo as listing_external_reference. Housing Anywhere partial rows also turn booking windows into extra calendar blocks — Booking windows vs blockedPeriods. Housing Anywhere money is euros on the partial pull and cents on the full catalogue — Euros on partial, cents on full. Then Example requests and Choosing partial vs full. Pair publish pulls with Listings & Availability (partial sync and booking import). Resolve externalId in Property & Unit Mapping; subscribe to listing.updated via Webhooks & Notifications when configured. Habit-specific shortcuts live under Related below.
Major marketplace integrations expose a second listing pull beyond the shared partial contract in Listings & Availability. Full feeds return publish-ready JSON shaped for each partner’s catalogue ingest — descriptions, amenities, photos, location blocks, and partner-specific sections — not just calendar, pricing, and availability windows.
- Partial —
GET /{platform}-integration/listingsandGET /{platform}-integration/listings/:externalId— sharedListingDto(or platform extension) for sync and booking import. Linked-only (a Channels mapping is required). See Listings & Availability and API Reference — Partial vs full integration feeds. - Full —
GET /{platform}-integration/:landlordKey/listings/full(+ single-listing variants) — partner schema for listing create/update on the channel. Every listing on the account (then rent / city / Integration listings filters) — Which listings appear.
Which listings appear
Resolve landlordKey first — landlordKey. Confirm the listing key you store — Uniplaces reference_id, Housing Anywhere listingReference, Inlife id + room.id. Partial calendar pulls: Listings & Availability.
Partial GET /listings and full GET …/listings/full are different payloads and different sets of units. A longer catalogue array is expected until every unit has a Channels mapping.
| Feed | Which units | Listing key when the unit is not on Channels |
|---|---|---|
Partial GET /{platform}-integration/listings | Only units with a Channels mapping for that platform | The row is omitted |
Full GET /{platform}-integration/{landlordKey}/listings/full | Every listing on the matched account (then rent / city / Integration listings filters) | The Vivin listing id — Uniplaces reference_id, Housing Anywhere listingReference, Spotahome listing id, Inlife id + room.id |
Save an external ID on Listings → Channels before you expect the unit on calendar/booking pulls or on POST /bookings. The full catalogue can include the unit before that mapping exists so the marketplace can create the listing. Echo that Vivin listing id on inbound webhooks (Uniplaces offer_api_reference, Housing Anywhere listing_external_reference).
Partial POST /bookings still needs a Channels mapping (except Kiwi, Capital Rooms, Porta85 & Lisbeyond). A row that appears only on the full feed is not yet bookable on the partial create route.
Both feeds still omit a unit with no usable rent — Usable rent required. Inlife full feed also omits unknown cities — Recognised cities. A unit marked Excluded from feed on Integration listings is omitted from both pulls for that platform, even when Channels has an ID.
Kiwi, Capital Rooms, Porta85, and Lisbeyond are the exception on the partial side: those single-landlord pulls already return every listing on the provisioned account.

Usable rent
Both the partial pull and the full catalogue omit a unit whose rent is not a usable positive amount. Partners never receive rent: 0.
| Unit pricing | What counts as usable |
|---|---|
| Fixed | Top-level rent greater than 0 |
| Variable | A non-empty month grid and every month greater than 0 |
Bulk GET …/listings (and GET …/listings/full) simply leave the row out. Single-listing GET …/listings/{externalId} (and GET …/{externalId}/full) return 404 with message Listing not available. Full details: Listings & Availability — Usable rent required.
This is not Inlife’s city omit (full catalogue only) — Recognised cities. Extra Charge on a one-person unit still publishes 0 on the row — Extra tenants price.

Field names, nested objects, and required blocks follow each integration’s OpenAPI models (for example UniplacesFullFeedListingDto, SpotahomeFullFeedListingDto). Open your provisioned prefix on the API host — see Try requests in Swagger.
landlordKey
Resolve landlordKey against account integration email or stored key — see Property & Unit Mapping. Inbound Housing Anywhere webhooks use the same path resolution and echo listingReference as listing_external_reference — Housing Anywhere listingReference; Uniplaces uses a global webhook — Webhooks & Notifications — Uniplaces.
Full-feed paths include a landlordKey path segment. Vivin resolves it to the account whose listings you may export:
| Value in the path | Resolves to |
|---|---|
The account’s stored landlordKey | That Vivin account’s listings (whole-account feed) |
| The account’s integration email for that platform | The same account when the email matches the Integration Email on the platform card under Account Settings → Integrations (compared case-insensitively). That same address is landlordEmail / landlord_email in listing JSON — Landlord email |
Both forms scope the feed to the same account’s enabled listings. Use whichever identifier your onboarding contract names.
landlordKeyHousing Anywhere inbound webhooks (POST …/{landlordKey}/webhook) use the same path resolution as this feed: stored landlordKey or the Housing Anywhere integration email. Echo this feed’s listingReference as webhook listing_external_reference. Uniplaces is different: one global POST /uniplaces-integration/webhook with no path key. The listing comes from offer_api_reference, which echoes this feed’s reference_id. See Webhooks & Notifications — Housing Anywhere, Housing Anywhere listingReference, Webhooks & Notifications — Uniplaces, and Uniplaces reference_id.
Single-listing full routes use the same resolution rules plus the listing’s externalId (the integration reference you mapped in Listings).
Platform matrix
Inspect live schemas in Try requests in Swagger — models such as UniplacesFullFeedListingDto and HousingAnywhereFullFeedListingDto. Partial contrast: Listings & Availability.
| Platform | Route prefix | Full bulk path | Single full path | Response wrapper |
|---|---|---|---|---|
| Uniplaces | uniplaces-integration | GET /:landlordKey/listings/full | GET /:landlordKey/listings/:externalId/full | JSON array of Uniplaces-shaped listings (snake_case) |
| Spotahome | spotahome-integration | GET /:landlordKey/listings/full | GET /:landlordKey/listings/:externalId/full | { "properties": [ … ] } matching Spotahome JSON Feed |
| Housing Anywhere | housinganywhere-integration | GET /:landlordKey/listings/full | GET /:landlordKey/listings/:externalId/full | JSON array of HA-shaped listings |
| Inlife | inlife-integration | GET /:landlordKey/listings/full | GET /:landlordKey/listings/:externalId/full | JSON array of Inlife-shaped listings |
All full routes use the same Bearer secret as the partial routes on that prefix (for example UNIPLACES_INTEGRATION_SECRET, SPOTAHOME_INTEGRATION_SECRET). Webhook endpoints, where provisioned, are documented in each integration’s Swagger group.
Uniplaces reference_id
On the Uniplaces full feed, reference_id is the listing key partners store. Echo it as webhook offer_api_reference so Vivin can find the unit without a {landlordKey} in the callback URL.
| Unit state | reference_id value |
|---|---|
| Linked on Channels | Your Uniplaces externalId |
| Not yet linked | The Vivin listing id |
The full-feed poll still uses {landlordKey} in the path. Only the inbound webhook is global (POST /uniplaces-integration/webhook). See Webhooks & Notifications — Uniplaces.
Housing Anywhere listingReference
On the Housing Anywhere full feed, listingReference is the listing key partners store. Echo it as webhook listing_external_reference. Unlike Uniplaces, the Housing Anywhere callback URL still includes {landlordKey} — the same path resolution as this feed (stored key or integration email). The listing must belong to that account.
| Unit state | listingReference value |
|---|---|
| Linked on Channels | Your Housing Anywhere externalId |
| Not yet linked | The Vivin listing id |
The full-feed poll and the inbound webhook both use {landlordKey} in the path. See Webhooks & Notifications — Housing Anywhere.

Housing Anywhere — booking windows vs blockedPeriods
Housing Anywhere’s calendar connector does not apply listing booking windows on its own. Vivin therefore rewrites stay length from the first still-open window and, on some feeds, paints nights outside that envelope as occupancy.
| Feed | Occupancy | Stay length |
|---|---|---|
Partial GET /listings | Extra unavailabilities rows with reason Booking window restriction (before the earliest check-in, and after the latest check-out). bookingWindows stays on the listing. | minStayPeriod / maxStayPeriod rewritten from the window’s earliest check-in to latest check-out (months rounded down / up) |
Full GET …/listings/full | blockedPeriods from saved listing unavailabilities only (bookings and operator blocks). Extra restriction rows are not copied. | minimumStayMonths / maximumStayMonths from the same window math |
| Uniplaces / Spotahome / Inlife full | Occupancy arrays do include the window nights (blocked_periods, occupancies, unavailability) | Stay bounds follow the adjusted listing |
Which window, row dates, and last-blocked-night convention: Listings & Availability — Housing Anywhere booking windows. Housing Anywhere is the exception on this page: its endDate is the first free day (exclusive), not the last blocked night — Last blocked night.

Inlife id and room.id
On the Inlife full feed, the stored channel key is Inlife’s native propertyId_roomId pair — from Inlife Import or a listing URL like /house/{propertyId}/{roomId}. Vivin splits that string before publishing. Inlife joins the two parts again as _id = ${id}_${room.id} and splits on _ into exactly two segments.
| Unit state | listing id | room.id |
|---|---|---|
Linked with propertyId_roomId | propertyId | roomId |
No _ in the stored key (not yet linked, or a studio URL with only /house/{propertyId}) | that single token | the Vivin listing id |
Keep both segments underscore-free. Do not paste a joined propertyId_roomId into listing id.
Partial GET /listings still returns the joined externalId. Send that same joined value on POST /bookings. If a studio stored only the property id, Vivin also matches a propertyId_roomId booking against that property-id row — Property & Unit Mapping — Studio / single-unit.
Single-listing full uses the stored joined key: GET /inlife-integration/{landlordKey}/listings/{externalId}/full.


Overlapping unavailabilities in full feeds
When multiple manual blocks or calendar holds overlap or touch on the same unit, Vivin merges them into a single closed date range before exporting to full feeds — Uniplaces blocked_periods, Spotahome occupancies, Housing Anywhere blockedPeriods, and Inlife unavailability. This matches the coalescing already applied on partial GET /listings exports, so partners do not receive duplicate or fragmented blocks for the same unavailable window. Open-ended blocks (no end date) are not merged: Spotahome and Inlife still publish them (to / end = null); Uniplaces and Housing Anywhere omit rows without an end. Closed-range ends are the last blocked night — Last blocked night.
Last blocked night on full feeds
Full catalogue occupancy uses the same inclusive last blocked night as partial GET /listings unavailabilities.to. Field names differ per partner; the night they name is not check-out.
| Platform | Occupancy field | Last blocked night | First bookable day after that block |
|---|---|---|---|
| Uniplaces | blocked_periods[] | to (YYYY-MM-DD) | next calendar day |
| Spotahome | availabilities.occupancies[] | to (YYYY-MM-DD; null when open-ended) | next calendar day, or prefer availabilities.available_from for the next move-in |
| Housing Anywhere | blockedPeriods[] | endDate (YYYY-MM-DD) — exclusive: this is already the first free day, not the last blocked night | endDate itself |
| Inlife | room.unavailability[] | end (YYYY-MM-DD; null when open-ended) | next calendar day; prefer firstAvailability / availableFrom (epoch milliseconds) for the next move-in |
Using the same sample as the partial feed (first blocked night 1 May, last blocked night 31 August):
| Meaning | Date |
|---|---|
| First blocked night | 1 May 2026 |
Last blocked night (Uniplaces / Spotahome to, Inlife end) | 31 August 2026 |
Housing Anywhere endDate (exclusive — the first free day) | 1 September 2026 |
| First check-in after this block | 1 September 2026 |
On Uniplaces, Spotahome and Inlife, honour every night from the start field through that last night inclusive, then open the calendar on the next calendar day. If you treat those end fields as check-out (or as exclusive), the catalogue offers 31 August while the unit is still occupied.
Housing Anywhere is the exception: blockedPeriods[].endDate is already the first free day, so honour every night from startDate up to but not including endDate. Treating HA's endDate as the last blocked night blocks 1 September when the unit is free.
Prefer the listing’s next-move-in field when you only need “when can someone arrive next”:
- Spotahome
availabilities.available_from(same value as partialavailableFrom) - Inlife
room.availableFromandroom.firstAvailability(epoch milliseconds — Inlife date fields) - Partial listing JSON
availableFromon Listings & Availability
Housing Anywhere clips startDate to today UTC when a block began in the past, and omits ranges that already ended. endDate is exclusive — the first free day (to + 1 day), the same convention as iCal DTEND — so a one-night block is sent as {startDate: D, endDate: D + 1}. Housing Anywhere full blockedPeriods come from listing unavailabilities after any Calendar Block (days) extra — extra booking-window nights on the partial pull are not copied here. Uniplaces, Spotahome, and Inlife full occupancy does include those window nights — Booking windows vs blockedPeriods. A Calendar Block extra is occupancy on every full feed (typically merged with the last stay into one range).
Calendar subscribers (Airbnb, Booking.com, Google Calendar) use the opposite end: exclusive DTEND is the free-again morning (to + 1 day) — iCal feeds — DTEND exclusive end. White-label booking sites read partial JSON, not this catalogue shape: Booking Engine API — Unavailability to. Operators comparing a live marketplace calendar to the hub: FAQ — Marketplace listing blocked through check-out night.
Inlife — recognised cities only
Inlife’s catalogue only accepts a fixed set of city keys. Vivin maps the property City (then Region if City is empty or unrecognised) from Full integration → Location & geography onto those keys. Matching ignores case, accents, and extra spaces (Lisbon, Lisboa, and Lisbôa all become Lisboa).
If neither field maps, Vivin omits the listing from the Inlife full feed. The unit stays in Vivin and still appears on Inlife partial GET /listings (calendar and booking import). The catalogue pull can therefore be shorter than the partial pull (unknown city) even while it is longer for unlinked units — Which listings appear. Do not treat either count gap as a mapping defect until you have checked City and Channels.
| Recognised Inlife region | Names that map (examples) |
|---|---|
| Lisboa | Lisbon, Lisboa, Lisbonne |
| Porto | Porto, Oporto |
| Madrid | Madrid |
| Barcelona | Barcelona |
| Roma | Rome, Roma |
| Milan | Milan, Milano |
| Sevilla | Seville, Sevilla |
| Valencia | Valencia |
| Aveiro | Aveiro |
| Braga | Braga |
Neighborhood does not select the region — only City, then Region. A district name in City (for example Alfama or Arroios) does not map. Picking a suggestion on Setup → Address writes the same City/Region fields.
A second omit: Inlife also skips a listing that has no usable rent (no fixed monthly rent and no valid per-month amounts). Set rent on the unit before expecting a catalogue row.

Operators: FAQ — Listing missing from Inlife. Integrators comparing counts: omitted listings are simply absent from the catalogue array.
Placeholder image URLs (full feeds)
Partner channels fetch every image URL Vivin publishes. Known placeholder or stock-image hosts (for example picsum.photos, placehold.co, via.placeholder.com, dummyimage.com, loremflickr.com) are stripped from full-feed exports across Uniplaces, Spotahome, Housing Anywhere, and Inlife — even when those URLs remain on listing or property image rows inside Vivin. This keeps partners from rejecting or silently skipping listings when a placeholder URL is unreachable on their side. Replace placeholders with real photo URLs before expecting a catalogue row to pass partner image minimums.
Catalogue fields live on the full feed
Partial GET /listings is calendar and pricing (ListingDto). Photos, street address, amenities, and marketing copy live on this catalogue pull — Listings & Availability — Catalogue fields.
| Catalogue | Typical catalogue fields |
|---|---|
| Uniplaces | location (street, number, postal, city), property_images or listing_images, property_description / listing_description, property_features / listing_features (a wi-fi slug when that amenity is on) |
| Spotahome | location (address, city, country, postal, lat/long), images, amenities, localized title / description |
| Housing Anywhere | address, description, images, facilities (wifi / internet booleans when set) |
| Inlife | Room photos (URL strings), property location, amenity booleans including wifi |
Operators fill those values on Listings — Photos and Full integration. Placeholder hosts are stripped — Placeholder image URLs.
A Wi-Fi amenity can appear on the catalogue. The Wi-Fi password is never on these payloads.



Inlife — date fields as epoch milliseconds
On the Inlife full feed, room-level move-in and listing timestamps are Unix epoch milliseconds (JavaScript Date.getTime / ES long) — not ISO-8601 strings.
Inlife indexes those properties as numbers. Send them as epoch milliseconds so the catalogue row matches their mapping. Convert in your consumer with new Date(value) when you need a calendar day.
Unavailability rows are the exception. Each block uses start / end as YYYY-MM-DD text (inclusive last blocked night — Last blocked night). Inlife does not read from / to on those rows, and it does not treat end as epoch milliseconds.
| Field | Serialization | Meaning |
|---|---|---|
availableFrom | epoch milliseconds | First day the room can be booked |
firstAvailability | epoch milliseconds | Next-move-in helper (often end + 1 day). Prefer this over treating end as check-out |
creationDate / modificationDate / updated | epoch milliseconds | Listing lifecycle timestamps |
unavailability[].start | YYYY-MM-DD | First blocked night (inclusive) |
unavailability[].end | YYYY-MM-DD or null | Last blocked night (inclusive); null when open-ended |
Example fragment (values are illustrative):
{
"availableFrom": 1735689600000,
"firstAvailability": 1736294400000,
"updated": 1717242896000,
"unavailability": [{ "start": "2025-02-01", "end": "2025-02-08" }]
}
Other Inlife full-feed scalars (rent amounts, booleans, photo URL strings) follow the OpenAPI models on the inlife-integration Swagger group — see InlifeFullFeedListingDto and nested DTOs. Listing id and room.id are the split propertyId_roomId — Inlife id and room.id. Room extraTenantsPrice is the same amount as partial extraPricePerTenant — Extra tenants price. Listing paidAtMovinDate advertises property Check-in payments (Security Deposit or Security Deposit + Last Rent) — it is not a POST /bookings input — Creating Bookings — Confirmation payments.
Extra tenants price
On the Inlife full feed, room extraTenantsPrice is copied from partial listing extraPricePerTenant. When numPeople (capacity) is 1, that amount is 0 — same rule as Listings & Availability — Extra price per tenant. Platform markup does not apply to this field — it is the stored Extra Charge, while catalogue rent headlines already include Markup — Listings & Availability — Platform markup. Uniplaces, Spotahome, and Housing Anywhere full catalogues do not publish a separate extra-tenant price field. Marketplace POST /bookings cannot send Extra Charge euros — Creating Bookings — Extra Charge. Marketplace POST /bookings also cannot send Second tenant identity — Creating Bookings — Second tenant. Marketplace POST /bookings also cannot send Guarantor identity or amount — Creating Bookings — Guarantor. Marketplace POST /bookings does record platform commission — Creating Bookings — Platform commission.

Variable rent headline
When a unit uses variable monthly rent, partner full catalogues do not copy a leftover base amount. They use the same highest-month headline as partial GET /listings rent — Listings & Availability — Variable rent headline.
| Catalogue | How the headline appears |
|---|---|
| Uniplaces | pricing.rents — integer euros, the highest month |
| Spotahome | Monthly headline on the pricing block — the highest month |
| Housing Anywhere | No single headline when variable: pricingType: "monthly" and monthlyPrices[].price in cents — Euros vs cents |
| Inlife | rentMonths map for variable rooms; bill from those months |
Charge each stay month from the month grid (partial rentsPerMonth, Housing Anywhere monthlyPrices, Inlife rentMonths). Do not apply the Uniplaces / Spotahome headline to every month.

Computed security deposit
Partner full catalogues copy the same computed security deposit as partial GET /listings depositValue — Listings & Availability — Computed deposit. Extra Deposit per Tenant is not on the catalogue. Marketplace POST /bookings does not set the amount — Creating Bookings — Deposit. Extra Deposit still adds at create from occupant headcount.
| Catalogue | How the deposit appears |
|---|---|
| Uniplaces | listing_pricing.deposit.value (integer euros) plus deposit.currency |
| Spotahome | Pricing deposit (integer euros) |
| Housing Anywhere | costs security-deposit — euros on the partial pull, cents on the full catalogue — Euros vs cents |
| Inlife | Room securityDeposit |
A Variable property deposit (Half Rent, 1 Rent, or 2 Rents) uses the highest month when the unit is variable — the same rent as the headline. Turning Security Deposit off publishes 0.

Cleaning fee value is the property amount
Partner full catalogues do not publish Cleaning fee frequency. They map the same euro amount as partial GET /listings cleaningFeeValue — Listings & Availability — Cleaning fee — or a partner boolean / included flag.
| Catalogue | How cleaning appears |
|---|---|
| Uniplaces | listing_pricing.cleaning and cleaning_included — booleans from listing details (cleaning included). No euro amount |
| Spotahome | pricing.servicesAndExpenses periodicCleaning: included when cleaning is included; otherwise availableForAdditionalFee with the euro amount and frequency: "onlyAtMoveIn" (that frequency is the catalogue mapping, not the property dropdown) |
| Housing Anywhere | costs cleaning-fee — euros on the partial pull, cents on the full catalogue, always payableAt: "monthly". A €0 line is omitted on the full object — Euros vs cents |
| Inlife | Room cleaningLadyPrice prefers the Full integration cleaning-lady price when set; otherwise a positive cleaningFeeValue |
When Cleaning fee is off, partial JSON is 0. Uniplaces still sends the included booleans from details. Housing Anywhere omits a zero cleaning line from the full catalogue. Marketplace POST /bookings does not set the amount — Creating Bookings — Cleaning fee.


Exit fee is not on listing JSON
Partner full catalogues do not publish an exit / check-out fee. Partial GET /listings also omits exitFeeValue — Listings & Availability — Exit fee.
| Catalogue | How the exit fee appears |
|---|---|
| Uniplaces | No exit-fee field. Pricing has deposit, admin fee, and cleaning included booleans — not an exit amount |
| Spotahome | No exit-fee service line. servicesAndExpenses can include periodicCleaning; admin fee is a separate amount |
| Housing Anywhere | No exit-fee cost type on partial costs[] or the full costs object — Euros vs cents |
| Inlife | No room exit-fee amount (cleaningLadyPrice is cleaning, not exit) |
The property Exit fee still copies onto bookings created from your platform (due at check-out). You cannot send it on POST /bookings.


Local rent cap is not on listing JSON
Partner full catalogues do not publish Local Rent Cap. Partial GET /listings also omits localRentCap — advertised rent is the full monthly amount — Listings & Availability — Local rent cap.
| Catalogue | How the local rent cap appears |
|---|---|
| Uniplaces | No cap field. listing_pricing.rents is the headline monthly rent |
| Spotahome | No cap field on pricing / services |
| Housing Anywhere | No local-rent-cap cost type on partial costs[] or the full costs object — Euros vs cents |
| Inlife | No room local-rent-cap amount (rent / rentMonths are the full advertised rent) |
When dual pricing is on in Vivin, the unit cap can still freeze onto a booking created from your platform (capped Rent plus Others). You cannot send the cap on POST /bookings.


All bills included publishes a null cap
When the operator ticks All bills included (No cap) on the unit, partner full catalogues follow the same contract as partial GET /listings: billsIncluded: true and billsIncludedMaxValue: null — Listings & Availability — All bills included. Do not copy the property euro ceiling onto that unit.
| Catalogue | How all-included bills appear |
|---|---|
| Uniplaces | listing_pricing.bills boolean — true when bills are included (unit No cap or property Bills Included) |
| Spotahome | [{ "name": "all", "option": "included", "value": "0" }] when bills are included |
| Housing Anywhere | Partial costs[] utility-bills is payableBy: "included-in-rent" with value: null. The full catalogue omits those included-in-rent lines (no other-additional-costs) — Euros vs cents |
| Inlife | Room billsIncluded: true. billsMax is omitted when the cap is null (not a membership-fee fallback) |
When the unit flag is off, Uniplaces / Spotahome / Inlife follow the property Bills Included flag and cap instead.

Landlord email is the Integration Email
Uniplaces landlord_email and Inlife landlord_email are the Integration Email from Settings → Integrations for that platform — the same value as landlordEmail on the shared listing JSON. They are not the property manager’s login, the General Information company email, or a per-unit contact. Vivin copies that one card onto every listing.
Uniplaces omits landlord_email from a listing when the Integration Email card is blank. Housing Anywhere full and Spotahome full catalogues do not include a landlord-email field (Spotahome’s legacy /listings/feed still copies landlordEmail).
The Integration Email is also accepted as {landlordKey} on these URLs — landlordKey. That path use is independent of the JSON field.


Maximum stay 0 means no limit
Partial listing JSON maxStayPeriod: 0 means no maximum — Listings & Availability — Maximum stay. 12 is twelve months, not unlimited. Full catalogues copy that stored number where they have a stay field:
| Catalogue | How stay bounds appear |
|---|---|
| Housing Anywhere full | minimumStayMonths / maximumStayMonths — 0 is published; omitted only when the value is missing |
| Inlife full | Room periodStayMin / periodStayMax |
| Spotahome full | stay.min_days / stay.max_days (including "0" when the maximum is 0) |
Spotahome legacy /listings/feed | stay.max_days is omitted when the maximum is 0 |
| Uniplaces full | No stay-period fields — use the partial pull |
Housing Anywhere can still rewrite stay months from a booking window — Booking windows vs blockedPeriods. Marketplace POST /bookings honours those published months (and capacity / availableFrom) — Creating Bookings — Honour listing. That POST does not set rent — advertised listing amounts become the payment plan — Creating Bookings — Rent.

Try requests in Swagger
Open your provisioned prefix on the API host, authorize with Bearer, and expand the listings (or partner-named) group — full routes appear alongside partial GET /listings where your contract includes them:

Step-by-step UI flow: API Reference — Try requests in Swagger. Operator-maintained fields that populate full-feed blocks are mapped in Integration field capabilities.
Housing Anywhere — euros on partial, cents on full
Housing Anywhere listing JSON uses two money conventions. Do not copy one payload onto the other.
| Feed | How money appears | Costs shape |
|---|---|---|
Partial GET /listings | Euros, whole numbers (rounded up) | costs[] array — type plus value in EUR |
Full GET …/listings/full | Cents | costs object keyed by kebab-case ids |
€850 rent is rent: 850 on the partial pull and flatPrice: 85000 (or monthlyPrices[].price: 80000) on the full catalogue. Divide full-feed amounts by 100 before you treat them as euros. The same cents rule applies to costs.*.value and strictRentalPeriods[].price.
The partial row is the shared listing fields plus a costs array. Housing Anywhere expects integers on that pull — Vivin rounds fee amounts up to whole euros before building costs. Stay-duration admin fees still come from adminFeeMode / adminFeeTiers; the administration-fee cost line mirrors the flat adminFeeValue only (Listings & Availability — Admin fee). Marketplace POST /bookings does not set the amount — Creating Bookings — Admin fee.
Partial costs[] (euros)
| Field | Typical meaning |
|---|---|
type | security-deposit, administration-fee, cleaning-fee, utility-bills, and (when bills are included) internet-bill, gas-bill, electricity-bill, water-bill. There is no exit-fee type — Exit fee |
value | Amount in EUR (null when not applicable). A €0 line is payableBy: "landlord" |
payableAt / payableBy | When and who pays (move-in, monthly, tenant, landlord, included-in-rent, …) |
refundable / estimated / mandatory | Display and validation flags |
When bills are included, utility-bills (and the named utility lines) are payableBy: "included-in-rent". An All bills included unit publishes utility-bills with value: null (no euro cap) — All bills included. When bills are not included, utility-bills is the monthly cap the tenant pays (billsIncludedMaxValue). The cleaning-fee line copies cleaningFeeValue and always uses payableAt: "monthly" — Cleaning fee. There is no exit-fee line — Exit fee.
Full costs object (cents)
The catalogue object is not the same array. Vivin converts each euro amount to cents, renames utility-bills to other-additional-costs, and omits any line the tenant does not pay (included-in-rent, landlord) plus any zero or empty amount. Housing Anywhere rejects a positive amount marked included-in-rent.
membership-fee and parking appear on the full object only, when those amounts are set on the property Full integration → Partner platforms fields Membership fee amount and Parking fee amount.
So a unit with bills included — including All bills included (value: null) — can show utility-bills on the partial pull and no other-additional-costs on the full catalogue. That is expected.
Example — €850 rent, €850 deposit, bills included with a €50 cap (illustrative):
{
"rent": 850,
"depositValue": 850,
"billsIncluded": true,
"billsIncludedMaxValue": 50,
"costs": [
{
"type": "security-deposit",
"value": 850,
"payableAt": "move-in",
"payableBy": "tenant",
"refundable": true,
"estimated": false,
"mandatory": true
},
{
"type": "utility-bills",
"value": 50,
"payableAt": "monthly",
"payableBy": "included-in-rent",
"refundable": false,
"estimated": true,
"mandatory": true
}
]
}
The same unit on the full catalogue:
{
"pricingType": "flat",
"flatPrice": 85000,
"currencyCode": "EUR",
"costs": {
"security-deposit": {
"value": 85000,
"payableBy": "tenant",
"payableAt": "move-in",
"required": true,
"refundable": true,
"isEstimated": false
}
}
}
If bills are not included, that €50 cap becomes other-additional-costs with value: 5000 and payableBy: "tenant" on the full payload.
Stay months and extra calendar rows are a different habit — Booking windows vs blockedPeriods. Do not assume partial and full rows are byte-identical — poll the feed your integration contract specifies.



Spotahome — legacy feed vs partial vs full
Spotahome exposes three listing surfaces:
| Feed | Path | Use |
|---|---|---|
| Legacy JSON feed | GET /spotahome-integration/listings/feed or GET /spotahome-integration/listings/feed/:landlordKey | Older SpotAHomeFeed shape ({ "properties": [ … ] }). Prefer full feed for new work unless your contract still references /listings/feed. |
| Partial | GET /spotahome-integration/listings (+ /:externalId) | Shared ListingDto calendar/pricing contract — same as Listings & Availability. |
| Full | GET /spotahome-integration/:landlordKey/listings/full (+ single listing) | Spotahome JSON Feed rules (location fields, image minimums when URLs exist, etc.). Compare with Spotahome’s public example.json in their partner docs. |
Example requests
Authorize with Authentication before your first full-feed GET. Spotahome legacy /listings/feed contrast: Spotahome — legacy feed vs partial vs full.
Replace {base}, {landlordKey}, and {externalId} with values from onboarding.
GET /uniplaces-integration/{landlordKey}/listings/full HTTP/1.1
Host: api.vivin.app
Authorization: Bearer YOUR_API_KEY
GET /housinganywhere-integration/{landlordKey}/listings/{externalId}/full HTTP/1.1
Host: api.vivin.app
Authorization: Bearer YOUR_API_KEY
GET /spotahome-integration/listings/feed/{landlordKey} HTTP/1.1
Host: api.vivin.app
Authorization: Bearer YOUR_API_KEY
GET /inlife-integration/{landlordKey}/listings/full HTTP/1.1
Host: api.vivin.app
Authorization: Bearer YOUR_API_KEY
Choosing partial vs full
Calendar-only subscribers should read iCal feeds instead of JSON pulls. Booking import always uses POST /bookings — Creating Bookings.
| Your integration needs… | Poll |
|---|---|
| Calendar, pricing, availability windows, booking import | Partial — Listings & Availability (linked units only) |
| Rich catalogue publish (photos, amenities, partner blocks) | Full — this page (includes unlinked units — Which listings appear) |
| Compare unit counts or publish inventory before Channels mapping | Full — extra rows are unlinked units, not a mapping defect |
| Short-term calendar blocks only | iCal — iCal feeds (not JSON) |
Many partners poll both: full feed on a slower cadence for listing create/update, partial feed every 15–30 minutes for availability and rates. Partial JSON never grows a gallery — Catalogue fields.
Operator field mapping
Full feeds serialize from the same Listings / Full integration pill content operators maintain in the management app. Which Vivin fields populate each partner block — and which are required before publish — is summarised in Integration field capabilities and Property & listing details (booking engine).
Sync strategy
Partial poll cadence and updatedAt diffing: Listings & Availability — Sync Strategy. Push updates: Webhooks & Notifications (listing.updated).
| Feed type | Typical poll interval | Change detection |
|---|---|---|
| Full catalogue | Every few hours to daily (per partner SLA) | Re-pull entire array or diff by partner listing id + updatedAt when the schema exposes it |
| Partial calendar | Every 15–30 minutes | updatedAt on ListingDto rows — see Listings & Availability — Sync Strategy |
Import bookings through POST /{platform}-integration/bookings regardless of which listing feed you poll — see Creating Bookings.
Full listing feeds section cross-reference
Use the endpoints and fields above. Related integrator pages are linked inline where useful.
Related
Related below links catalogue publish payloads to setup, companion API guides, operator workflows, and escalation paths.
Setup sequence after go-live
Complete Account Settings — Recommended setup order before partner traffic.
- Setup steps 1–10 — Complete operator workspace basics (Recommended setup order) before requesting partner Bearer keys; property managers automating outside the browser use Management session authentication after step 3 (Users)
- Setup steps 11–12 (Integrations, Integration field capability, Tenant categories default for integrations) — Channel credentials, calendar horizons, and payload field expectations before
[email protected]onboarding; operator context: Integrations & Distribution - Setup step 13 (Listings) — Property wizard,
externalIdmapping, and Channels tab before first partner listing reads or writes - Setup steps 14–15 (Bookings, Tenants) — Validate imported reservation shape and tenant segments after partner traffic
- After steps 13–15 — Onboarding a New Property — Step 7 go-live verification before escalating partner pull, webhook, or mapping defects
- After step 13 — poll
GET …/:landlordKey/listings/fullonly after Property & listing details (booking engine) fields are publication-ready; contrast partial pulls in Listings & Availability - Partner credential requests — Email
[email protected](distinct from in-app Vivin support tickets in Get Help & Support)
Documentation map & escalation
- Getting Started — Recommended Setup Sequence before partner HTTP traffic;
- API Reference hub — Hub pairing matrix and partial vs full integration feeds;
- Get Help & Support — Request credentials or full-feed onboarding via
[email protected](hub: Setup sequence after go-live) - FAQ & Troubleshooting — Partner publish and sync questions (hub: Setup sequence after go-live)
- Settings > Integration field capability — Read-only matrix of fields each full-feed partner ingests
Companion API guides
Companion guides share Bearer authorization or error shapes with this page — start from API Reference hub.
- Listings & Availability — Partial
ListingDtocontract for calendar and booking import (last blocked night; linked-only vs this page’s unlinked rows — Which listings appear; Integration listings omit from both pulls; usable rent — Usable rent; full-feed field names: Last blocked night; Housing Anywhere euros vs cents — Euros vs cents; Inlife city omit is full-feed only — Recognised cities; Inlife joinedexternalId—id+room.id; extra occupant price is0when capacity is 1 — Extra tenants price; variable-rent headline — Variable rent headline; computed deposit — Computed deposit; cleaning fee amount — Cleaning fee; exit fee is omitted — Exit fee; photos, address, amenities, and copy — Catalogue fields; All bills included publishes anullcap — All bills included; landlord email is the Integration Email — Landlord email; maximum stay0is no cap — Maximum stay) - Property & Unit Mapping —
externalIdkeys that tie partial and full catalogue rows to the same unit (InlifepropertyId_roomId) - Webhooks & Notifications — Inbound booking events (Housing Anywhere
{landlordKey}+listing_external_reference; Uniplaces globalPOST /webhook+offer_api_reference) and outboundlisting.updatedwhere webhooks are provisioned - Creating Bookings — Inbound reservations after catalogue listings go live (POST does not set
billsIncludedMaxValue— Bills included; POST does not setcontractType/contractDayType— Contract type; POST does not set confirmation / check-in payments — Confirmation payments; POST does not set due day / due month — Due date; POST does not set check-in / check-out times — Check-in times; POST does not set days before due — Days before due; POST does not set check-in / check-out responsible — Check-in responsible; POST does not setleasePurpose— Lease purpose; POST does not setdepositReturnDueDay— Deposit Refund Limit; POST does not setbookingTags— Booking tags; POST does not setcreateCheckInMaintenanceTicket/createCheckOutMaintenanceTicket— Maintenance tickets; POST does not setignoreListingPreparationDays— Ignore unit preparation days; POST does not setignoreAvailableFrom— Allow check-in date in the past; POST does not setignorePenaltyFees— Exclude from penalty fees; POST does not setuseCheckInDateInContract/useCheckOutDateInContract— Use check in date as contract start date; POST always sends onboarding — Send onboarding; POST always uses unit contract rents — Use unit contract rents) - iCal feeds — Calendar export alternative when partners do not poll full JSON catalogues (exclusive
DTENDvs this page’s inclusive last blocked night —DTENDexclusive end) - Booking engine integration — White-label writes that complement full-feed publish payloads
- Booking Lifecycle & Validations — Server rules partner imports must satisfy after full-feed bookings land
- Error Handling — Rich catalogue errors when partial
ListingDtois insufficient - Authentication — Bearer token on full and partial routes
- AI usage — Operator JWT ledger when reconciling catalogue publish volume with internal LLM spend
Upstream & downstream workflows
- Processing a New Booking — Operator workflow after catalogue listings start receiving partner bookings
- Portfolio KPI review — Reconcile publish cadence with occupancy and revenue KPIs
- Manual block hygiene — Hygiene pass when full-feed occupancy disagrees with Analytics or Dashboard
- Managing a Check-out & Deposit Refund — Calendar release after departure ends stays imported via partner feeds
- Onboarding a New Property — Operator setup before full-feed partners poll catalogue rows
- Notification triage — Clear channel sync alerts after full-feed publishes change availability
Operator UI & settings
- Property & listing details (booking engine) — Operator Full integration pill source for full-feed payloads; Integration listings omits a unit from both pulls when Excluded from feed
- Listings — Photos pill — Gallery URLs on this catalogue; omitted from partial
GET /listings— Catalogue fields - Listings — Channels tab — Per-unit linkage operators complete before full-feed polling succeeds
- Listings — Rent Value — Positive monthly rent (every month on a variable grid) before a unit appears on partner pulls
- Listings — Maximum stay 0 — 0 is no maximum; 12 is twelve months — Maximum stay
- Listings — Payments tab — Cleaning fee Frequency is payment-plan only; catalogues publish the amount or a partner included flag — Cleaning fee. Exit fee is operator-only — Exit fee
- Bookings — Booking-level fee amounts — Override exit fee on a stay after import
- Listings — All bills included — Unit No cap publishes
billsIncluded: trueandbillsIncludedMaxValue: null— All bills included - Sales > Channels — Operator linkage before full-feed polling succeeds
- Settings > Integrations — Integration Email on Booking Platforms cards is Uniplaces / Inlife
landlord_email(and partiallandlordEmail) — Landlord email - Settings > Contract templates — Contract PDF generation for partner-created tenants
- Settings > Preferences — In-app notifications — Channel sync alerts when full-feed publishes change availability
- Settings > Emails — Lifecycle and payment Communication Rules for full-feed and engine reservations
- Create New — Inlife Full Import — Bulk rich import before full-feed partners poll catalogue rows
Deeper concept reads
- Integrations & Distribution — Operator-facing channel setup
- Payment Allocation — Two-layer receipts, invoiced-floor rent edits, and credit note reject/revert warnings
- Booking Lifecycle — Computed Upcoming → Ongoing → Ended / Canceled status model, list filters, and Timeline
- Tenant Portal — White-label engine bookings share the same portal branding and payment flows as marketplace imports
- FAQ — Tenant contract signing blocked — No PDF yet, mandatory Your Details gates, category locks, or Lease purpose; portal signing vs paper upload on Contract Info
Deeper workflow reads
See Upstream & downstream workflows above for the same guides.
Operator habit hubs
Day-to-day operator habits (lockout catch-up, pending receipts, payment triage, handoffs, and related playbooks) live on the Common Workflows habit hub.
Deep-link anchors for habit hubs
Lockout catch-up after password recovery
Pending manual receipt approval
Reject/revert mistaken receipts
Portfolio segmentation by tenant category
Notification row-click navigation
Payment alert to receivables triage
Confirmation alert triage
Finance debt receivables triage
Handling a Late Payment collections
Finance Income status drill-down
Cash flow forecast drill-down
Key glossary terms
- Glossary — landlordEmail — Uniplaces / Inlife
landlord_emailis the platform Integration Email, not the property manager’s login - Glossary — exitFeeValue — Exit fee is absent from listing JSON and full catalogues
- Glossary — cleaningFeeValue — Listing JSON cleaning amount; frequency is not on the pull
- Glossary — billsIncluded — Listing JSON
billsIncluded/billsIncludedMaxValue; All bills included publishes anullcap - Glossary — Notification row navigation — Operator alerts after partner imports create payment or booking-created notifications
- Glossary — Deposit lifecycle status — Full-feed catalogue updates do not expose deposit refund API; operators manage
depositStatusafter bookings import - Glossary — End-of-Booking cost split — Charge Time → End of Booking splits daily overage across every occupied unit; still-staying roommates stay in the denominator
- Glossary — Change history — Operator-initiated edits on Listings setup and Bookings Changelog; create-time defaults excluded
- Glossary — Archived booking ledger visibility — Delete Booking hides manual/provider_platform rows on Finance → Transactions; vIBAN and credit card stay visible
- Glossary — Finance tenant category cache refresh — Recategorizing a tenant updates
booking.tenantCategoryIdimmediately; ledger tabs reflect it on reload, while Overview can lag up to ~10 minutes - Glossary — Full term list
Module documentation hubs
for screen-by-screen operator follow-up.
- Listings module — Inventory source for publish payloads partners ingest (hub)
- Audit module — Manual blocks on published units that still appear in partner availability pulls (hub)
- Dashboard module — Post-login KPI snapshot with bell notification triage (hub)
- Analytics module — Month-range portfolio KPI charts with rankings and heatmaps (hub)
- Properties workspace — Legacy
/propertiesURL redirects into Listings (hub) - Booking engine details — Rich marketplace payload editor via the Full integration pill (hub)
- Finance module — Portfolio ledgers with payment approval and deposit settlement (hub)
- Tenants module — Tenant directory and profile sidebars for imported stays (hub)
- Sales module — Portfolio availability, monthly rent editing, and channel manager connections (hub)
- Utilities module — Bills Included ceiling model and tenant overage when actual costs exceed
billsIncludedMaxValue(hub) - Operations module — Maintenance tickets, cash flows, and check-in/out coordination (hub)
- Inbox module — Portfolio-wide WhatsApp workspace (hub)
- Notifications module — Full
/notificationshistory with search and filters (hub); Payment overdue alerts when full-feed partner imports leave unpaid schedules - AI Chat module — AI Assistant using Landlord MCP tools (hub)
- Account Settings — Workspace-wide financial policies, templates, integrations, and operational defaults (hub)