Référence de l'API
Chaque route que sert l'API, qui peut l'appeler, et comment fonctionnent la connexion, les permissions, les erreurs, les listes, les réservations et les limites.
Pour le pack Full Stack
URL de base et format des réponses
Chaque route est servie sous le préfixe /api. En local, l'URL de base est http://localhost:8000/api. Sur un serveur, c'est l'adresse de votre API suivie de /api, la même valeur que lisent les deux frontends dans NEXT_PUBLIC_API_BASE_URL (Variables d'environnement). Les photographies sont servies hors du préfixe, sur /media/….
Les routes du site sont publiques ; celles du tableau de bord demandent le jeton bearer d'un admin, et la plupart aussi une permission. Les corps de requête sont en JSON, sauf pour les fichiers téléversés. Chaque réponse arrive dans la même enveloppe :
{
"success": true,
"data": { },
"message": ""
}data contient le résultat. message est une courte phrase que certaines écritures renseignent, dans la langue de la requête, et vide sinon. Les prix sont en dollars américains entiers, et les dates sont des jours calendaires de la société écrits YYYY-MM-DD.
La vérification de santé ne demande aucun jeton :
curl http://localhost:8000/api/health{"success":true,"data":{"status":"ok","database":"up"},"message":""}Quand la base de données ne peut pas être lue, elle répond quand même 200, avec "status":"degraded" et "database":"down". La vérification de santé de l'image Docker lit ce champ.
Erreurs
Un échec garde l'enveloppe, avec success: false et le statut HTTP. message est une phrase dans la langue de la requête, code la clé non traduite qui la sous-tend, et un refus qui nomme quelque chose ajoute dans details les valeurs derrière sa phrase :
{
"success": false,
"data": null,
"message": "Booking B0021 already holds some of these nights.",
"code": "dates_taken",
"details": { "held_by": "booking", "reference": "B0021" }
}Un corps que le pipe de validation refuse porte code: "validation_failed" et errors, indexé par le nom complet de chaque champ :
{
"success": false,
"data": null,
"message": "guest_email must be an email",
"errors": { "guest_email": ["guest_email must be an email"] },
"code": "validation_failed"
}- Raisonnez sur
code, jamais sur la phrase, qui change avec la langue. Les refus de réservation et de disponibilité portent des codes commedates_taken,min_nights,capacity,cancellation_window_passed,awaiting_paymentetpayment_method_unavailable, et une limiterate_limited. errorsapparaît lors d'un échec de validation, avec les problèmes sous le nom du champ tel que la requête l'a écrit (check_in,guest_email). Un champ inconnu dans un corps est refusé.- Une route protégée sans jeton, ou avec un jeton expiré, répond
401; un jeton sans la permission répond403. - Des nuits déjà retenues répondent
409, une étape de réservation depuis le mauvais statut422, et une requête au-delà d'une limite429.
Listes et pagination
{ "data": [ ], "page": 1, "page_size": 6, "total": 12, "total_pages": 2 }- Les séjours, réservations, demandes et avis se paginent avec
pageetpage_size: 6 séjours par page sur le site (24 au plus), 20 dans le tableau de bord (50 au plus), 10 réservations et 20 demandes (50 au plus chacune), 8 avis. Les listes du tableau de bord renvoient aussicountspar statut. - Les admins, rôles et paramètres se paginent avec
pageetpage_count(les paramètres acceptent aussipage_size), 10 par défaut et 100 au plus, et répondent{ data, page, limit, total, totalPages }. - Les filtres de séjours du site sont validés : une valeur inconnue est refusée avec
400plutôt qu'ignorée, tandis qu'une clé que l'API ne lit pas est ignorée, si bien qu'un lien partagé avec des paramètres en plus fonctionne toujours.
Langue
Envoyez Accept-Language: ar pour des messages en arabe ; toute autre valeur répond en anglais. Les séjours, destinations et questions de la page d'accueil portent les deux langues sous la forme { "en": "…", "ar": "…" } quel que soit l'en-tête, et le client en choisit une.
Connexion
Se connecter en tant qu'admin
Terminalcurl -X POST http://localhost:8000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"admin@hollina.example","password":"Admin@123"}'data.access_tokenest le jeton, avectoken_typevalantBeareret l'admin avec ses rôles et ses permissions. Le jeton dureJWT_EXPIRATION,7dpar défaut, etexpires_inrapporte cette valeur telle qu'elle est écrite.GET /api/auth/merenvoie l'admin connecté avec ses rôles et ses permissions.Appeler une route protégée
Terminalcurl http://localhost:8000/api/bookings/manage -H "Authorization: Bearer YOUR_TOKEN"
- Un e-mail inconnu et un mauvais mot de passe répondent tous deux
401avec le même message. - Dix connexions échouées depuis une même adresse en 15 minutes répondent
429jusqu'à ce que le plus ancien échec ait 15 minutes (RATE_LIMIT_LOGIN). Les connexions réussies ne sont pas comptées. - Il n'y a ni inscription ni route de déconnexion : les comptes viennent du seed ou de la gestion des admins, et un client se déconnecte en oubliant son jeton.
- Les voyageurs n'ont pas de comptes. Les routes de réservation d'un voyageur acceptent l'
access_tokende la réservation en?token=, ou l'e-mail utilisé pour la faire en?email=; une paire erronée répond404.
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
POST | /api/auth/login | N'importe qui | Connexion d'un admin : email, password |
GET | /api/auth/me | Tout administrateur connecté | L'admin connecté, ses rôles et ses permissions |
Permissions
Les routes du tableau de bord vérifient une permission nommée <area>.<action>. Un admin détient chaque permission de chacun de ses rôles, et une route qui en nomme plusieurs accepte n'importe laquelle. Les 32 permissions et les deux rôles du seed sont listés dans Admins, rôles et permissions.
Les séjours sur le site
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/stays | N'importe qui | Les séjours publiés. destination (slug), checkIn et checkOut (YYYY-MM-DD, les deux ou aucun : seuls les séjours libres chaque nuit), guests (le minimum qu'il doit loger), type (villa, apartment, cabin, chalet, loft, cottage), sort (recommended, price_asc, price_desc, rating), page, page_size |
GET | /api/stays/featured | N'importe qui | Les séjours en vedette de la page d'accueil : les références du paramètre home_featured_references, dans l'ordre, publiés seulement |
GET | /api/stays/hero | N'importe qui | Le séjour nommé par home_hero_stay_reference, ou null |
GET | /api/stays/facets | N'importe qui | Les séjours publiés comptés par type et par destination, pour les filtres et la page d'accueil |
GET | /api/stays/lookup | N'importe qui | Les séjours publiés par identifiant, pour les séjours enregistrés : ?ids=1,2,3, 12 au plus |
GET | /api/stays/:slug | N'importe qui | Un séjour publié en entier, avec ses photographies, ses équipements, son règlement intérieur et sa destination |
GET | /api/stays/:slug/similar | N'importe qui | Jusqu'à trois séjours publiés similaires |
GET | /api/stays/:slug/availability | N'importe qui | Les nuits déjà retenues entre from et to, 92 jours au plus |
GET | /api/stays/:slug/quote | N'importe qui | checkIn, checkOut, guests (1 à 50) : nuits, tarif par nuit, sous-total, frais de ménage, total, available et le reason du refus (past, min_nights, capacity, taken) |
GET | /api/stays/:slug/reviews | N'importe qui | Les avis publiés du séjour, les plus récents d'abord, avec sa moyenne |
Destinations, questions et paramètres de la société
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/destinations | N'importe qui | Les destinations marquées visibles, dans leur ordre de tri |
GET | /api/destinations/:slug | N'importe qui | Une destination |
GET | /api/faq | N'importe qui | Les questions et réponses de la page d'accueil, dans l'ordre |
GET | /api/settings/public | N'importe qui | Les paramètres que le site affiche : company_name, le slogan et la description dans les deux langues, contact_email, contact_phone, contact_address_hint, currency, timezone, les heures d'arrivée et de départ par défaut, allow_pay_on_arrival, cancellation_policy, home_featured_references, home_hero_stay_reference et service_email_signature |
GET | /api/payments/methods | N'importe qui | Ce que le paiement peut proposer, par ordre de priorité : { methods: [{ method, hosted }], allowPayOnArrival, simulated }. Seuls les moyens des processeurs configurés sont listés, on_arrival tant que son paramètre est activé, et simulated vaut true tant que le simulateur prend carte et PayPal faute de processeur configuré |
Réservations
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
POST | /api/bookings | N'importe qui | Le paiement : stay_slug, check_in, check_out, guests, guest_first_name, guest_last_name, guest_email, payment_method (card, paypal, on_arrival), client_token (8 à 64 caractères), et en option guest_phone, special_requests, locale (en, ar) et, pour le simulateur seulement, card_number, card_name, card_expiry (MM/YY), card_cvc. Répond 201 avec { reference, access_token, status, payment_status, payment_method, total, currency, redirect_url, failure_reason } |
GET | /api/bookings/:reference | Quiconque a le jeton ou l'e-mail de la réservation | La réservation du voyageur, avec can_cancel et can_review |
POST | /api/bookings/:reference/settle | Quiconque a le jeton ou l'e-mail de la réservation | Appelée par la page de retour : capture une commande PayPal approuvée, et répond avec l'état actuel de la réservation pour Stripe. Peut être appelée sans risque à répétition |
POST | /api/bookings/:reference/cancel | Quiconque a le jeton ou l'e-mail de la réservation | Le voyageur annule, tant que la réservation est en attente ou confirmée et au moins sept jours avant l'arrivée locale ; plus tard, répond 422 avec cancellation_window_passed |
POST | /api/bookings/:reference/review | Quiconque a le jeton ou l'e-mail de la réservation | Noter une réservation terminée, une seule fois : rating (1 à 5, demis autorisés), comment (10 à 2000 caractères) |
POST | /api/webhooks/payments/:provider | Le fournisseur, par sa signature | stripe ou paypal. Chaque événement vérifié répond 200 ; une mauvaise signature répond 401, un fournisseur inconnu 404 |
- Un
client_tokenrépété renvoie le reçu de la première réservation au lieu d'en faire une seconde, et un champcompanyrempli est traité comme un robot : la réponse est la même, et rien n'est stocké. - Un
payment_methodqueGET /api/payments/methodsne liste pas (PayPal avec seulement Stripe configuré, la carte avec seulement PayPal, le paiement à l'arrivée avec son paramètre désactivé) répond422avecpayment_method_unavailable, avant que quoi que ce soit soit écrit. - Les nuits sont vérifiées quand la réservation est écrite : des nuits retenues répondent
409avecdates_taken, et le minimum d'un séjour, sa capacité ou une arrivée dans le passé422avec la raison. - Un moyen hébergé répond
pendingavec uneredirect_urlvers Stripe ou PayPal ; la réservation n'est confirmée que par le webhook du processeur ou la capture PayPal.
Questions à l'hôte
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
POST | /api/inquiries | N'importe qui | Le formulaire de contact et la boîte de dialogue de question de la page d'un séjour : name, email, message (10 à 4000 caractères), client_token, et en option phone, stay_slug (un séjour publié), check_in, check_out, guests |
- Un
client_tokenrépété renvoie le premier envoi au lieu d'en stocker un second, et un champcompanyrempli est traité comme un robot. - Chaque adresse peut envoyer cinq réservations, cinq questions et cinq avis en dix minutes ; le suivant répond
429.
Gérer les séjours
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/stays/manage | Les admins avec stays.view | Chaque séjour, brouillons compris. status, type, destination, guests, bedrooms, nights (le plus long minimum), price (le tarif par nuit le plus élevé), sort (updated, rate_asc, rate_desc), q, page, page_size |
GET | /api/stays/manage/:id | Les admins avec stays.view | Un séjour en entier |
POST | /api/stays/manage | Les admins avec stays.create | Créer un brouillon. Obligatoires : title, short_description, description et location_hint (en, ar), type, destination_id, bedrooms, beds, bathrooms, max_guests, nightly_rate, cleaning_fee, min_nights |
PUT | /api/stays/manage/:id | Les admins avec stays.edit | Modifier n'importe quel champ, galerie comprise (media, jusqu'à 30 éléments) |
PATCH | /api/stays/manage/:id/status | Les admins avec stays.publish | Définir status : draft ou published. Publier demande trois photographies et les deux langues |
PUT | /api/stays/manage/:id/media | Les admins avec stays.edit | Remplacer la galerie, dans l'ordre ; la position un est la couverture |
DELETE | /api/stays/manage/:id | Les admins avec stays.delete | Supprimer le séjour ; refusé avec 409 tant qu'il existe une réservation non annulée |
Le calendrier et les dates bloquées
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/calendar | Les admins avec calendar.view | La vue mensuelle : month (YYYY-MM) et en option stay |
GET | /api/availability/blocks | Les admins avec calendar.view | Chaque blocage, le plus proche d'abord |
POST | /api/availability/blocks | Les admins avec calendar.block | Bloquer des nuits : stay_id, from, to (exclusif, comme un départ), et en option reason (maintenance, owner_use, other) et note. Un conflit répond 409 avec code dates_taken et details: { held_by, reference }, en nommant la réservation ou le blocage qui gêne |
PUT | /api/availability/blocks/:id | Les admins avec calendar.block | Modifier un blocage |
DELETE | /api/availability/blocks/:id | Les admins avec calendar.block | Retirer un blocage |
Réservations, demandes et avis
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/bookings/manage | Les admins avec bookings.view | Les réservations. status, from et to (plage d'arrivée), q, stay, payment, method, guests, sort (newest, check_in, total), page, page_size ; avec les totaux par statut |
GET | /api/bookings/manage/:reference | Les admins avec bookings.view | Une réservation avec sa chronologie et les actions permises maintenant, chacune avec sa raison quand elle ne l'est pas |
PATCH | /api/bookings/manage/:reference | Les admins avec bookings.edit | action (confirm, check_in, complete, cancel) et admin_notes. Une étape depuis le mauvais statut répond 422 avec sa raison |
GET | /api/inquiries | Les admins avec inquiries.view | Les demandes. status, q, from, to, stay, page, page_size ; avec les totaux par statut |
GET | /api/inquiries/:id | Les admins avec inquiries.view | Une demande avec son séjour |
PATCH | /api/inquiries/:id | Les admins avec inquiries.edit | Définir status (new, replied, closed) et admin_notes |
GET | /api/reviews/manage | Les admins avec reviews.view | Les avis. status, stay (identifiant ou slug), rating (un minimum), q, since (7, 30, 90, 365 jours), page ; avec les totaux |
PATCH | /api/reviews/manage/:id | Les admins avec reviews.moderate | Définir status : published ou hidden |
GET | /api/overview | Admins avec overview.view | La vue d'ensemble : les cartes du mois, les arrivées et départs du jour, les réservations en attente et les dernières, les meilleurs séjours, les pays des voyageurs, les réservations par statut, les derniers avis et les demandes ouvertes |
GET | /api/overview/series | Admins avec overview.view | Les réservations, le revenu et l'occupation de chacun des douze derniers mois |
Destinations, questions et paramètres
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/destinations/manage | Les admins avec destinations.view | Chaque destination, masquées comprises |
POST | /api/destinations/manage | Les admins avec destinations.create | En ajouter une : name, tagline et description (en, ar), et en option slug, cover_url, cover_alt, sort_order, is_active |
PUT | /api/destinations/manage/:id | Les admins avec destinations.edit | En modifier un |
DELETE | /api/destinations/manage/:id | Les admins avec destinations.delete | En supprimer une ; refusé tant que des séjours lui appartiennent |
GET | /api/faq/manage | Admins avec settings.view | Chaque question de la page d'accueil, masquées comprises |
POST | /api/faq/manage | Admins avec settings.edit | En ajouter une : question et answer (en, ar), en option sort_order et is_active |
PUT | /api/faq/manage/:id | Admins avec settings.edit | En modifier un |
DELETE | /api/faq/manage/:id | Admins avec settings.edit | En supprimer une |
GET | /api/settings | Admins avec settings.view | Chaque paramètre. search, category, page, page_size ou page_count |
GET | /api/settings/payments-status | Admins avec settings.view | { stripe: { configured, testMode }, paypal: { configured, sandbox }, simulator } : si chaque processeur est configuré et en test ou en réel, et si le simulateur est utilisé, ce qui n'est le cas que tant qu'aucun processeur n'est configuré. Jamais une clé |
GET | /api/settings/:key | Admins avec settings.view | Un paramètre par sa clé |
PATCH | /api/settings/:key | Admins avec settings.edit | Changer la value d'un paramètre |
DELETE | /api/settings/:key | Admins avec settings.edit | Supprimer un paramètre |
Admins et rôles
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/admins | Admins avec admins.view | Les admins. email, name, phone, page, page_count |
GET | /api/admins/statistics | Admins avec admins.view | Les nombres pour la liste des admins |
GET | /api/admins/:id | Admins avec admins.view | Un admin, par identifiant ou nom d'utilisateur |
POST | /api/admins | Admins avec admins.create | Ajouter un admin : first_name, last_name, email, password et password_confirmation (6 caractères ou plus), en option phone |
PATCH | /api/admins/:id | Admins avec admins.edit | Modifier un admin |
PATCH | /api/admins/:id/roles | Admins avec admins.assign_roles | Définir les rôles d'un admin : role_ids |
DELETE | /api/admins/:id | Admins avec admins.delete | Supprimer un admin |
PATCH | /api/admins/profile | Tout administrateur connecté | Changer les propres first_name, last_name, email, phone ou profile_picture de l'admin connecté. Le mot de passe a sa propre route |
PATCH | /api/admins/profile/password | Tout administrateur connecté | Modifier son propre mot de passe en tant qu'admin connecté : current_password, password, password_confirmation |
GET | /api/roles | Admins avec roles.view | Les rôles. name, guard_name, created_from, created_to, page, page_count |
GET | /api/roles/statistics | Admins avec roles.view | Les nombres pour la liste des rôles |
GET | /api/roles/select | Admins avec roles.view | L'identifiant et le nom de chaque rôle, pour un sélecteur |
GET | /api/roles/permissions | Admins avec roles.view | Toutes les permissions, groupées par domaine |
GET | /api/roles/:id | Admins avec roles.view | Un rôle avec ses permissions |
POST | /api/roles | Admins avec roles.create | Ajouter un rôle |
PUT | /api/roles/:id | Admins avec roles.edit | Renommer ou décrire un rôle |
POST | /api/roles/:id/permissions | Admins avec roles.assign_permissions | Définir les permissions d'un rôle |
DELETE | /api/roles/:id | Admins avec roles.delete | Supprimer un rôle |
Notifications et fichiers téléversés
| Méthode | Chemin | Qui peut l'appeler | Rôle |
|---|---|---|---|
GET | /api/notifications | Tout administrateur connecté | Les 30 notifications les plus récentes de l'admin connecté |
PATCH | /api/notifications/read-all | Tout administrateur connecté | Toutes les marquer comme lues |
PATCH | /api/notifications/:id/read | Tout administrateur connecté | En marquer une comme lue |
DELETE | /api/notifications/:id | Tout administrateur connecté | En supprimer une |
POST | /api/helpers/upload | Tout administrateur connecté | Stocker un fichier (multipart file, avec path pour le dossier, for pour le préréglage de taille comme stay, cover ou profile, et type). Les photographies sont réencodées en JPEG, de 1920 pixels de large au plus ; les vidéos sont acceptées en MP4, WebM, MOV ou M4V ; 150 Mo au plus. Répond avec les adresses du fichier stocké |
Un fichier téléversé n'a pas de permission propre : ce que devient le fichier est vérifié par la route qui l'enregistre. Les notifications sont conservées 30 jours.
Limites par adresse
| Route | Limite | Variable |
|---|---|---|
POST /api/auth/login | 10 connexions échouées par 15 minutes | RATE_LIMIT_LOGIN |
POST /api/bookings | 5 par 10 minutes | Aucune |
POST /api/inquiries | 5 par 10 minutes | Aucune |
POST /api/bookings/:reference/review | 5 par 10 minutes | Aucune |
Une requête au-delà d'une limite répond 429. Les compteurs vivent dans la mémoire de l'API : un redémarrage les efface. Derrière un reverse proxy, définissez TRUST_PROXY pour que chaque visiteur soit compté sur sa propre adresse.
L'assistant IA et ses conversations
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
La route de streaming de l'assistant, sa liste de modèles et les conversations enregistrées.
Serveur MCP
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
L'endpoint MCP pour les agents de code et la façon dont il est autorisé.
Mises à jour en direct via WebSocket
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
Les namespaces Socket.IO qu'écoute le tableau de bord, leurs événements et la façon dont une connexion est autorisée.
Routes du mode démo
Inclus avec votre achat. Connectez-vous pour le lire, ou ouvrez-le dans votre téléchargement.
Les routes qui n'existent que pour un build de démo publique.