/api/v1/metoute clé valideOrganisation et droits de la clé (test de connexion des connecteurs)
Lokyzen · Développeurs
Connectez vos outils à Lokyzen : logements, disponibilités, devis, réservations, voyageurs et webhooks. Spécification complète au format OpenAPI 3.1 : /api/v1/openapi.json.
Créer une clé APIhttps://lokyzen.com/api/v1Authorization: Bearer hl_<préfixe>_<secret>. Les clés se créent dans Lokyzen, menu Intégrations › API (rôle propriétaire ou administrateur) ; la clé complète n’est affichée qu’une fois.properties:read, calendar:write, rates:write, reservations:read, reservations:write, guests:read, guests:write, messages:read, messages:write, tasks:read, tasks:write, payments:read, payments:write, accounting:read, accounting:write, reviews:read, webhooks:write. Un droit manquant renvoie 403.Idempotency-Key sur les POST, PATCH et PUT ; rejouer la requête avec la même clé (pendant 24 h) renvoie la même réponse sans doublon.AAAA-MM-JJ, horodatages ISO 8601.nextCursor ; passez-le en paramètre cursor pour la page suivante (null à la fin).{ "error": { "code": "…", "message": "…", "details": … } } avec le code HTTP correspondant (400, 401, 403, 404, 409, 429)./api/v1/metoute clé valideOrganisation et droits de la clé (test de connexion des connecteurs)
/api/v1/propertiesproperties:readLogements (équipements, situation), types de logement (pièces, lits, salles de bain), unités et plans tarifaires
/api/v1/room-types/{id}/availabilityproperties:readDisponibilités, prix et restrictions par nuit (400 jours au plus)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| from * | requête | string | Date AAAA-MM-JJ |
| to * | requête | string | Date AAAA-MM-JJ |
/api/v1/quotesreservations:readDevis exact (mêmes calculs que le back-office) et disponibilité
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"roomTypeId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"checkIn": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
"checkOut": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
"adults": {
"type": "integer",
"minimum": 1,
"maximum": 50
},
"children": {
"default": 0,
"type": "integer",
"minimum": 0,
"maximum": 50
},
"ratePlanId": {
"description": "Tarif (GET /properties) ; absent = tarif par défaut",
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"promoCode": {
"anyOf": [
{
"type": "string",
"maxLength": 30
},
{
"type": "null"
}
]
}
},
"required": [
"roomTypeId",
"checkIn",
"checkOut",
"adults"
]
}/api/v1/reservationsreservations:readRéservations (pagination par curseur, filtre de période, synchronisation incrémentale)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| from | requête | string | Séjours qui se terminent après cette date |
| to | requête | string | Séjours qui commencent avant cette date |
| status | requête | inquiry | option | confirmed | cancelled | no_show | completed | |
| updatedSince | requête | date-time | Modifiées depuis (ISO 8601) : synchronisation incrémentale |
| cursor | requête | uuid | |
| limit | requête | integer |
/api/v1/reservationsreservations:writeCréer une réservation (prix calculé par Lokyzen, restrictions de séjour appliquées)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"roomTypeId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"checkIn": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
"checkOut": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
"adults": {
"type": "integer",
"minimum": 1,
"maximum": 50
},
"children": {
"default": 0,
"type": "integer",
"minimum": 0,
"maximum": 50
},
"ratePlanId": {
"description": "Tarif (GET /properties) ; absent = tarif par défaut",
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"status": {
"default": "confirmed",
"type": "string",
"enum": [
"option",
"confirmed"
]
},
"externalId": {
"description": "Identifiant dans votre système (unique)",
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
]
},
"notes": {
"anyOf": [
{
"type": "string",
"maxLength": 5000
},
{
"type": "null"
}
]
},
"guest": {
"type": "object",
"properties": {
"firstName": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"lastName": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"email": {
"anyOf": [
{
"type": "string",
"format": "email",
"pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
},
{
"type": "null"
}
]
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 30
},
{
"type": "null"
}
]
},
"locale": {
"default": "fr",
"type": "string",
"enum": [
"fr",
"en",
"es",
"de",
"it",
"pt"
]
},
"country": {
"anyOf": [
{
"type": "string",
"minLength": 2,
"maxLength": 2
},
{
"type": "null"
}
]
}
},
"required": [
"firstName",
"lastName"
]
}
},
"required": [
"roomTypeId",
"checkIn",
"checkOut",
"adults",
"guest"
]
}/api/v1/reservations/{id}reservations:readUne réservation
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid |
/api/v1/reservations/{id}reservations:writeChanger le statut (confirmer, annuler…) ; le remboursement éventuel n’est jamais exécuté automatiquement
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"confirmed",
"cancelled",
"no_show",
"completed"
]
},
"reason": {
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "null"
}
]
},
"party": {
"type": "string",
"enum": [
"guest",
"host"
]
}
},
"required": [
"status"
]
}/api/v1/reservations/{id}/stayreservations:writeModifier le séjour (dates, logement, voyageurs) ; restrictions de séjour appliquées
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"checkIn": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
"checkOut": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
"unitId": {
"description": "Logement physique (GET /properties → roomTypes[].units) ; par défaut, celui de la réservation",
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"adults": {
"type": "integer",
"minimum": 1,
"maximum": 50
},
"children": {
"type": "integer",
"minimum": 0,
"maximum": 50
},
"reprice": {
"default": false,
"description": "Recalculer le prix (imposé si le type de logement ou le nombre de voyageurs change) ; sinon le prix convenu est conservé",
"type": "boolean"
}
},
"required": [
"checkIn",
"checkOut"
]
}/api/v1/reservations/{id}/messagesmessages:readMessages échangés avec le voyageur de la réservation (hors notes internes)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| cursor | requête | uuid | |
| limit | requête | integer |
/api/v1/reservations/{id}/messagesmessages:writeEnvoyer un message au voyageur (visible dans la messagerie Lokyzen)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"body": {
"type": "string",
"minLength": 1,
"maxLength": 10000
},
"channel": {
"default": "auto",
"description": "auto : canal de la plateforme, sinon e-mail, sinon SMS, sinon page voyageur",
"type": "string",
"enum": [
"email",
"sms",
"whatsapp",
"guest_page",
"airbnb",
"booking",
"vrbo",
"expedia",
"google_vr",
"auto"
]
},
"subject": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
}
},
"required": [
"body"
]
}/api/v1/reservations/{id}/paymentspayments:readÉchéancier, paiements reçus, remboursements et solde
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid |
/api/v1/reservations/{id}/paymentspayments:writeEnregistrer un paiement reçu hors Lokyzen (virement, espèces, chèque…)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"method": {
"type": "string",
"enum": [
"cash",
"bank_transfer",
"card_terminal",
"cheque_vacances",
"ancv_connect",
"cheque",
"channel"
]
},
"amountCents": {
"type": "integer",
"minimum": 1,
"maximum": 10000000
},
"receivedOn": {
"description": "Obligatoire, sauf pour un chèque annoncé (chequeStatus expected)",
"anyOf": [
{
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
{
"type": "null"
}
]
},
"dueId": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"note": {
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "null"
}
]
},
"chequeStatus": {
"description": "Chèque ou chèques-vacances : expected (annoncé, hors du payé), received (reçu, à encaisser) ou cashed (encaissé, par défaut)",
"anyOf": [
{
"type": "string",
"enum": [
"expected",
"received",
"cashed"
]
},
{
"type": "null"
}
]
},
"cashOn": {
"description": "Date d'encaissement prévue, obligatoire pour expected et received : rappel aux gestionnaires ce jour-là",
"anyOf": [
{
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
{
"type": "null"
}
]
},
"cashedOn": {
"description": "Date d'encaissement (cashed), par défaut receivedOn",
"anyOf": [
{
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
{
"type": "null"
}
]
},
"chequeReference": {
"description": "N° du chèque et banque ; n° de ticket (card_terminal) ou de transaction (ancv_connect)",
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
]
}
},
"required": [
"method",
"amountCents"
]
}/api/v1/reservations/{id}/payment-linkspayments:writeCréer un lien de paiement sécurisé (valable 14 jours)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"dueId": {
"description": "Échéance à régler ; sinon amountCents, sinon tout le solde",
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"amountCents": {
"anyOf": [
{
"type": "integer",
"minimum": 100,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"sendEmail": {
"default": false,
"description": "Envoyer aussi le lien au voyageur par e-mail",
"type": "boolean"
}
}
}/api/v1/guestsguests:readVoyageurs (recherche par e-mail, synchronisation incrémentale)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| requête | string | ||
| updatedSince | requête | date-time | Modifiés depuis (ISO 8601) : synchronisation incrémentale |
| cursor | requête | uuid | |
| limit | requête | integer |
/api/v1/guestsguests:writeCréer un voyageur ; s’il existe déjà (même e-mail ou téléphone), sa fiche est complétée et renvoyée
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"firstName": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"lastName": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"email": {
"anyOf": [
{
"type": "string",
"maxLength": 200,
"format": "email",
"pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
},
{
"type": "null"
}
]
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 30
},
{
"type": "null"
}
]
},
"address": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"locale": {
"default": "fr",
"type": "string",
"enum": [
"fr",
"en",
"es",
"de",
"it",
"pt"
]
},
"country": {
"anyOf": [
{
"type": "string",
"minLength": 2,
"maxLength": 2
},
{
"type": "null"
}
]
}
},
"required": [
"firstName",
"lastName"
]
}/api/v1/guests/{id}guests:readUn voyageur
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid |
/api/v1/guests/{id}guests:writeModifier un voyageur (seuls les champs envoyés changent)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"firstName": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"lastName": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"email": {
"anyOf": [
{
"type": "string",
"maxLength": 200,
"format": "email",
"pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
},
{
"type": "null"
}
]
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 30
},
{
"type": "null"
}
]
},
"landline": {
"description": "Téléphone fixe (simple coordonnée, sans déduplication ni SMS)",
"anyOf": [
{
"type": "string",
"maxLength": 30
},
{
"type": "null"
}
]
},
"address": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"locale": {
"type": "string",
"enum": [
"fr",
"en",
"es",
"de",
"it",
"pt"
]
},
"country": {
"anyOf": [
{
"type": "string",
"minLength": 2,
"maxLength": 2
},
{
"type": "null"
}
]
},
"notes": {
"anyOf": [
{
"type": "string",
"maxLength": 5000
},
{
"type": "null"
}
]
},
"tags": {
"maxItems": 30,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 40
}
},
"marketingConsent": {
"description": "Consentement marketing (horodaté, source « api »)",
"type": "boolean"
}
}
}/api/v1/webhookswebhooks:writeS’abonner à des événements (REST hooks Zapier / Make) ; le secret de signature n’est renvoyé qu’ici
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "URL https:// qui recevra les événements (POST JSON signé)"
},
"events": {
"minItems": 1,
"type": "array",
"items": {
"type": "string",
"enum": [
"*",
"reservation.created",
"reservation.confirmed",
"reservation.updated",
"reservation.cancelled",
"reservation.checkin_completed",
"payment.received",
"payment.refunded",
"guest.created",
"message.received",
"review.received",
"task.created",
"task.completed",
"reservation.*"
]
}
},
"description": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"source": {
"default": "manual",
"type": "string",
"enum": [
"zapier",
"make",
"manual"
]
}
},
"required": [
"url",
"events"
]
}/api/v1/webhookswebhooks:writeAbonnements de l’organisation (sans le secret)
/api/v1/webhooks/{id}webhooks:writeSe désabonner
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid |
/api/v1/blocksproperties:readDates bloquées (travaux, usage du propriétaire…) qui chevauchent la période
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| from * | requête | string | Date AAAA-MM-JJ |
| to * | requête | string | Date AAAA-MM-JJ |
| propertyId | requête | uuid | |
| cursor | requête | uuid | |
| limit | requête | integer |
/api/v1/blockscalendar:writeBloquer des dates (fermées à la vente sur tous les canaux)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"unitId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "Logement physique (GET /properties → roomTypes[].units)"
},
"startDate": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
"endDate": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Exclu : premier jour de nouveau disponible"
},
"reason": {
"default": "other",
"type": "string",
"enum": [
"maintenance",
"owner_use",
"personal",
"other"
]
},
"note": {
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "null"
}
]
}
},
"required": [
"unitId",
"startDate",
"endDate"
]
}/api/v1/blocks/{id}calendar:writeDébloquer des dates
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid |
/api/v1/taskstasks:readTâches d’une période ou d’une réservation
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| from | requête | string | Tâches dont la fenêtre se termine après cette date (obligatoire sans reservationId) |
| to | requête | string | Tâches qui commencent avant cette date (62 jours au plus après from) |
| propertyId | requête | uuid | |
| reservationId | requête | uuid | |
| providerId | requête | uuid | |
| status | requête | todo | assigned | in_progress | done | validated | cancelled | Par défaut, toutes sauf annulées |
| cursor | requête | uuid | |
| limit | requête | integer |
/api/v1/tasks/{id}tasks:readUne tâche (avec sa liste de points à vérifier)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid |
/api/v1/tasks/{id}/assigntasks:writeAssigner la tâche à un prestataire (notifié) ou la désassigner
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"providerId": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
],
"description": "null : désassigner"
}
},
"required": [
"providerId"
]
}/api/v1/tasks/{id}/completetasks:writeMarquer la tâche terminée (points obligatoires de la liste cochés)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"report": {
"anyOf": [
{
"type": "string",
"maxLength": 5000
},
{
"type": "null"
}
]
}
}
}/api/v1/providerstasks:readPrestataires actifs (ménage, maintenance…)
/api/v1/invoicesaccounting:readFactures, avoirs et reçus émis (numérotation continue)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| from | requête | string | Émises à partir de cette date |
| to | requête | string | Émises avant cette date |
| type | requête | invoice | credit_note | receipt | quittance | |
| reservationId | requête | uuid | |
| cursor | requête | uuid | |
| limit | requête | integer |
/api/v1/invoices/{id}accounting:readUne facture, un avoir ou un reçu
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid |
/api/v1/invoices/{id}/pdfaccounting:readPDF de la pièce (Factur-X pour les factures et avoirs)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid |
/api/v1/expensesaccounting:readDépenses des logements (réparations, fournitures…)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| from | requête | string | Date AAAA-MM-JJ |
| to | requête | string | Date AAAA-MM-JJ |
| propertyId | requête | uuid | |
| unbilledOnly | requête | true | false | Seulement les dépenses pas encore reprises dans un relevé |
| cursor | requête | uuid | |
| limit | requête | integer |
/api/v1/expensesaccounting:writeEnregistrer une dépense (refacturable au propriétaire)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"propertyId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"date": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
"label": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"category": {
"type": "string",
"enum": [
"repair",
"supplies",
"cleaning",
"utilities",
"tax",
"other"
]
},
"amountCents": {
"type": "integer",
"minimum": 1,
"maximum": 100000000,
"description": "TTC"
},
"vatCents": {
"default": 0,
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"rechargeable": {
"default": false,
"description": "Refacturée au propriétaire sur son relevé",
"type": "boolean"
},
"markupBp": {
"default": 0,
"description": "Majoration refacturée, en points de base (1000 = 10 %)",
"type": "integer",
"minimum": 0,
"maximum": 5000
}
},
"required": [
"propertyId",
"date",
"label",
"category",
"amountCents"
]
}/api/v1/owner-statementsaccounting:readRelevés de gérance mensuels des propriétaires
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| period | requête | string | Mois AAAA-MM |
| status | requête | draft | sent | paid | |
| ownerClientId | requête | uuid | |
| cursor | requête | uuid | |
| limit | requête | integer |
/api/v1/owner-statements/{id}/pdfaccounting:readPDF du relevé de gérance
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid |
/api/v1/rate-plans/{id}/overridesrates:writePrix et restrictions par nuit sur une période (seuls les champs envoyés changent ; null rétablit la règle du plan)
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| id * | chemin | uuid | |
| Idempotency-Key | en-tête | string | Rejouer la requête avec la même clé renvoie la même réponse sans doublon (24 h) |
{
"type": "object",
"properties": {
"from": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Date AAAA-MM-JJ"
},
"to": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Exclu (comme pour les disponibilités) : 731 nuits au plus"
},
"weekdays": {
"description": "Jours concernés, 1 = lundi … 7 = dimanche ; par défaut tous",
"minItems": 1,
"maxItems": 7,
"type": "array",
"items": {
"type": "integer",
"minimum": 1,
"maximum": 7
}
},
"priceCents": {
"description": "Prix de la nuit ; null : revenir au prix du plan",
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 10000000
},
{
"type": "null"
}
]
},
"minStay": {
"anyOf": [
{
"type": "integer",
"minimum": 1,
"maximum": 365
},
{
"type": "null"
}
]
},
"maxStay": {
"anyOf": [
{
"type": "integer",
"minimum": 1,
"maximum": 365
},
{
"type": "null"
}
]
},
"closedToArrival": {
"type": [
"boolean",
"null"
]
},
"closedToDeparture": {
"type": [
"boolean",
"null"
]
},
"stopSell": {
"description": "Fermer à la vente",
"type": [
"boolean",
"null"
]
}
},
"required": [
"from",
"to"
]
}/api/v1/reviewsreviews:readAvis des voyageurs (site, espace voyageur et plateformes), note sur 100
| Paramètre | Emplacement | Type | Description |
|---|---|---|---|
| propertyId | requête | uuid | |
| source | requête | string | direct, airbnb, booking… |
| since | requête | date-time | Reçus depuis (ISO 8601) |
| cursor | requête | uuid | |
| limit | requête | integer |
Le prix est calculé par Lokyzen (mêmes règles que le back-office) ; obtenez roomTypeId via GET /properties et vérifiez le tarif avec POST /quotes.
curl -X POST https://lokyzen.com/api/v1/reservations \
-H "Authorization: Bearer hl_xxxxxxxx_votre_cle" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3f1c2b9e-commande-1234" \
-d '{
"roomTypeId": "0190a1b2-…",
"checkIn": "2027-07-14",
"checkOut": "2027-07-21",
"adults": 2,
"status": "confirmed",
"externalId": "CMD-1234",
"guest": { "firstName": "Camille", "lastName": "Martin", "email": "camille@example.com", "locale": "fr" }
}'Créez un abonnement dans Lokyzen (Intégrations › Webhooks) ou par l’API (POST /api/v1/webhooks, utilisé par les REST hooks Zapier et Make). Chaque événement est envoyé en POST JSON. Abonnez-vous à des événements précis, à une famille (reservation.*) ou à tous (*).
reservation.createdreservation.confirmedreservation.updatedreservation.cancelledreservation.checkin_completedpayment.receivedpayment.refundedguest.createdmessage.receivedreview.receivedtask.createdtask.completed{
"id": "0190b3c4-…",
"type": "reservation.created",
"createdAt": "2027-07-01T09:30:00.000Z",
"data": { … la ressource concernée (réservation, paiement, voyageur…) }
}En-tête Lokyzen-Signature: t=<unix>,v1=<signature>, où la signature est le HMAC-SHA256 (hexadécimal) de la chaîne t.corps calculé avec le secret de l’abonnement (whsec_…). Vérifiez-la sur le corps brut et refusez les horodatages trop anciens :
import { createHmac, timingSafeEqual } from 'node:crypto'
// body : corps brut de la requête (chaîne), avant JSON.parse
export function verifyLokyzen(body, header, secret, toleranceSec = 300) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')))
const t = Number(parts.t)
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false
const expected = createHmac('sha256', secret).update(`${t}.${body}`).digest('hex')
const given = Buffer.from(parts.v1 ?? '', 'hex')
const wanted = Buffer.from(expected, 'hex')
return given.length === wanted.length && timingSafeEqual(given, wanted)
}