Getting started with the Joivy Partner API
This guide explains how to authenticate and call the Joivy Partner API endpoints documented at xfeedreference.joivy.com. The reference is built on Scalar and exposes two OpenAPI specs: one for OAuth2 authentication and one for the main API.
client_id and client_secret issued by Joivy. These are used to obtain a bearer token from the identity provider.POST /token endpoint on the Authentication – OAuth2 spec. You'll receive a Bearer token valid for 3600 seconds.GET /api/Availability/{bedCode} to check if a bed is bookable, and GET /CommercialCondition/v2 to retrieve pricing, deposit, and discount details.POST /Booking/ValidateTaxCode, then submit the booking with POST /Booking.The OpenAPI specs #
The reference loads three distinct specs. Switch between them using the dropdown at the very top of the sidebar — it currently reads Main API, Authentication – OAuth2, or Authentication – API Key.
All partner endpoints: availability, bookings, commercial conditions, rentables, and more.
Single endpoint:
POST /tokenUsed to obtain bearer tokens.
Endpoints:
POST /apikey/generate and a sample protected resource.Describes the
X-API-KEY header scheme.GET /api/Ubiflow/Beds) require an API Key sent in the X-API-KEY header. Each spec has a Download OpenAPI Document link at the top of its page (JSON and YAML).OAuth2 Client Credentials flow #
The API uses OAuth2 Client Credentials. There is no user login — your application authenticates directly using its own client_id and client_secret.
client_secret
ciamlogin
3600 s
Bearer …
The identity provider is Microsoft Entra ID (Azure AD) hosted on Joivy's tenant. The token endpoint is:
https://joivysuppliers.ciamlogin.com/0d098523-a320-480a-b0fb-21dedf5231fd/oauth2/v2.0/token
Getting a token #
In the reference, open the Authentication – OAuth2 spec and click Get access token (Client Credentials). The body must be sent as application/x-www-form-urlencoded with the four required fields below.
client_credentialsapi://43869ec9-dd76-46ef-84c9-6de401dafd27/.defaultcurl https://joivysuppliers.ciamlogin.com/0d098523-a320-480a-b0fb-21dedf5231fd/oauth2/v2.0/token \ --request POST \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'client_id=<your-client-id>' \ --data-urlencode 'client_secret=<your-client-secret>' \ --data-urlencode 'scope=api://43869ec9-dd76-46ef-84c9-6de401dafd27/.default'
{ "token_type": "Bearer", "expires_in": 3600, "ext_expires_in": 3600, "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." }
401 Unauthorized errors on API calls.Using the token #
Most Main API endpoints are marked Auth Required and use OAuth2. Pass the token in every request via the Authorization header:
// 1. Obtain token const tokenRes = await fetch( 'https://joivysuppliers.ciamlogin.com/0d098523-a320-480a-b0fb-21dedf5231fd/oauth2/v2.0/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'client_credentials', client_id: CLIENT_ID, client_secret: CLIENT_SECRET, scope: 'api://43869ec9-dd76-46ef-84c9-6de401dafd27/.default' }) } ); const { access_token } = await tokenRes.json(); // 2. Call any Main API endpoint const res = await fetch('/api/Availability/BED001', { headers: { 'Authorization': `Bearer ${access_token}` } });
API Key authentication #
In addition to OAuth2, a subset of endpoints accept an API Key as their authentication scheme. The full spec is documented under Authentication – API Key in the spec switcher.
The API Key must be sent on every request in the X-API-KEY HTTP header. Endpoints currently protected by this scheme include:
X-API-KEYSecurity scheme
apiKey security schemecurl '/api/Ubiflow/Beds' \ -H 'X-API-KEY: <your-api-key>'
Obtaining an API Key
An API Key can be generated through the POST /apikey/generate endpoint described in the Authentication – API Key spec. This endpoint is itself protected and typically requires a valid OAuth2 bearer token to be called.
{ "apiKey": "sk_live_1234567890abcdef", "createdAt": "2026-01-01T12:00:00Z" }
Trying it from the reference
To call an API Key protected endpoint via Try it out:
GET /api/Ubiflow/Beds in the Main API spec, or any endpoint in the Authentication – API Key spec.401 Unauthorized.POST /apikey/generate if it is ever exposed.Availability #
Check whether a specific bed can be booked and retrieve its available check-in/check-out windows before presenting options to a tenant.
Query parameters
2025-09-01T00:00:00Zcurl '/api/Availability/BED001?checkInDate=2025-09-01T00:00:00Z&checkOutDate=2026-06-30T00:00:00Z' \ -H 'Authorization: Bearer <access_token>'
The response includes status (Occupied / Available), arrays of valid checkInDates and validCheckoutDates, and evaluedExitWindows with pricing per exit window. Use salableOnline to check if the bed can be booked through your portal.
CommercialCondition #
Retrieve the full pricing and contractual conditions for a bed before creating a booking. The values returned here must be forwarded directly into the booking request body.
Query parameters
POST /Booking: price → price, discountedPrice → discountedPrice, discountUntil → discountUntil, depositAmount → deposit, confirmationDeposit → downPayment.Booking #
Two endpoints handle the booking lifecycle. Validate the tenant's tax code first when required by Italian law, then create the booking.
POST /Booking — key request fields
commercialConditions.pricecommercialConditions.discountedPricediscountedPricecommercialConditions.depositAmountcommercialConditions.confirmationDepositOneGuarantor · NoGuarantor · OwnGuarantor · Garantme · Studapart · Smartgarant · None{ "tenantId": "123e4567-e89b-12d3-a456-426614174000", "contractId": "123e4567-e89b-12d3-a456-426614174000", "company": null, "paymentIntent": null }
number | null, omitting price, deposit, and downPayment when they have values from commercial conditions will result in a 400 Bad request or 406 Not Acceptable.Beds #
Retrieve the legal entity associated with a bed — useful for understanding which Joivy company entity is the contract counterpart for invoicing and compliance purposes.
The response returns id and code of the legal entity. This data typically drives the portal's invoice generation logic and determines the correct VAT number to display to the tenant.
Rentables #
Search and list available rental units. This is the main catalogue endpoint — use it to power listing pages with filters, sorting, and pagination.
Request body (RentablesSearchRequest)
Pricing and other valuestrue = ascendingit, en)Each item in the response includes the full unit descriptor: bed type, room type, accommodation type, address, geo-coordinates, building amenities, flat features, room features, media gallery, localized descriptions, availability windows, and commercial condition summary. This is the richest payload in the API.
/Rentables/ endpoint does not require authentication. It's the only endpoint in the Main API spec that can be called without a bearer token.Portals & Ubiflow #
Portals / GET /Beds returns a 200 with no body — it's used as a health/sync check to confirm which beds are associated with your portal credentials.
Ubiflow / GET /api/Ubiflow/Beds returns a rich JSON map keyed by bed identifier, containing room dimensions, energy ratings (DPE), geo-address, pricing, gallery URLs, and amenity counts. This feed is intended for syndication to the Ubiflow real-estate aggregator.
Try it out #
Every endpoint has an interactive Open API Client button at the bottom of the sidebar (or use the inline send panel on each endpoint). To test authenticated endpoints:
client_id, client_secret, grant_type=client_credentials, and scope. Click Send and copy the access_token from the response.bedCode) are editable inline. Query parameters and body fields appear in the form below the endpoint description. Hit Send and inspect the response status, headers, and JSON body.POST /Booking sent via "Try it out" will create a real booking. Always use test credentials and a test externalReference when experimenting.Error handling #
| Status | Meaning | Likely cause |
|---|---|---|
| 200 | OK | Success |
| 201 | Accepted | Booking created (async processing) |
| 400 | Bad request | Missing required field or malformed body (e.g. missing externalReference) |
| 401 | Unauthorized | Token missing, expired, or wrong scope |
| 404 | Not Found | bedCode does not exist or not visible to your portal |
| 406 | Not Acceptable | Pricing mismatch — price fields don't match current commercial conditions |
| 500 | Server Error | Retry with exponential back-off |
text/plain on error (not JSON). Parse accordingly — check Content-Type before calling .json().