Aller à l'article
Aniq-UI

HollinaRéférence de l'API

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 :

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 :

Terminal
curl http://localhost:8000/api/health
Réponse
{"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 :

Erreur
{
  "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 :

Erreur de validation
{
  "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 comme dates_taken, min_nights, capacity, cancellation_window_passed, awaiting_payment et payment_method_unavailable, et une limite rate_limited.
  • errors apparaî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épond 403.
  • Des nuits déjà retenues répondent 409, une étape de réservation depuis le mauvais statut 422, et une requête au-delà d'une limite 429.

Listes et pagination

Une liste
{ "data": [ ], "page": 1, "page_size": 6, "total": 12, "total_pages": 2 }
  • Les séjours, réservations, demandes et avis se paginent avec page et page_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 aussi counts par statut.
  • Les admins, rôles et paramètres se paginent avec page et page_count (les paramètres acceptent aussi page_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 400 plutô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

  1. Se connecter en tant qu'admin

    Terminal
    curl -X POST http://localhost:8000/api/auth/login \
      -H "Content-Type: application/json" \
      -d '{"email":"admin@hollina.example","password":"Admin@123"}'

    data.access_token est le jeton, avec token_type valant Bearer et l'admin avec ses rôles et ses permissions. Le jeton dure JWT_EXPIRATION, 7d par défaut, et expires_in rapporte cette valeur telle qu'elle est écrite. GET /api/auth/me renvoie l'admin connecté avec ses rôles et ses permissions.

  2. Appeler une route protégée

    Terminal
    curl 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 401 avec le même message.
  • Dix connexions échouées depuis une même adresse en 15 minutes répondent 429 jusqu'à 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_token de la réservation en ?token=, ou l'e-mail utilisé pour la faire en ?email= ; une paire erronée répond 404.
MéthodeCheminQui peut l'appelerRôle
POST/api/auth/loginN'importe quiConnexion d'un admin : email, password
GET/api/auth/meTout 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éthodeCheminQui peut l'appelerRôle
GET/api/staysN'importe quiLes 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/featuredN'importe quiLes 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/heroN'importe quiLe séjour nommé par home_hero_stay_reference, ou null
GET/api/stays/facetsN'importe quiLes séjours publiés comptés par type et par destination, pour les filtres et la page d'accueil
GET/api/stays/lookupN'importe quiLes séjours publiés par identifiant, pour les séjours enregistrés : ?ids=1,2,3, 12 au plus
GET/api/stays/:slugN'importe quiUn séjour publié en entier, avec ses photographies, ses équipements, son règlement intérieur et sa destination
GET/api/stays/:slug/similarN'importe quiJusqu'à trois séjours publiés similaires
GET/api/stays/:slug/availabilityN'importe quiLes nuits déjà retenues entre from et to, 92 jours au plus
GET/api/stays/:slug/quoteN'importe quicheckIn, 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/reviewsN'importe quiLes 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éthodeCheminQui peut l'appelerRôle
GET/api/destinationsN'importe quiLes destinations marquées visibles, dans leur ordre de tri
GET/api/destinations/:slugN'importe quiUne destination
GET/api/faqN'importe quiLes questions et réponses de la page d'accueil, dans l'ordre
GET/api/settings/publicN'importe quiLes 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/methodsN'importe quiCe 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éthodeCheminQui peut l'appelerRôle
POST/api/bookingsN'importe quiLe 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/:referenceQuiconque a le jeton ou l'e-mail de la réservationLa réservation du voyageur, avec can_cancel et can_review
POST/api/bookings/:reference/settleQuiconque a le jeton ou l'e-mail de la réservationAppelé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/cancelQuiconque a le jeton ou l'e-mail de la réservationLe 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/reviewQuiconque a le jeton ou l'e-mail de la réservationNoter une réservation terminée, une seule fois : rating (1 à 5, demis autorisés), comment (10 à 2000 caractères)
POST/api/webhooks/payments/:providerLe fournisseur, par sa signaturestripe ou paypal. Chaque événement vérifié répond 200 ; une mauvaise signature répond 401, un fournisseur inconnu 404
  • Un client_token répété renvoie le reçu de la première réservation au lieu d'en faire une seconde, et un champ company rempli est traité comme un robot : la réponse est la même, et rien n'est stocké.
  • Un payment_method que GET /api/payments/methods ne liste pas (PayPal avec seulement Stripe configuré, la carte avec seulement PayPal, le paiement à l'arrivée avec son paramètre désactivé) répond 422 avec payment_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 409 avec dates_taken, et le minimum d'un séjour, sa capacité ou une arrivée dans le passé 422 avec la raison.
  • Un moyen hébergé répond pending avec une redirect_url vers 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éthodeCheminQui peut l'appelerRôle
POST/api/inquiriesN'importe quiLe 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_token répété renvoie le premier envoi au lieu d'en stocker un second, et un champ company rempli 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éthodeCheminQui peut l'appelerRôle
GET/api/stays/manageLes admins avec stays.viewChaque 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/:idLes admins avec stays.viewUn séjour en entier
POST/api/stays/manageLes admins avec stays.createCré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/:idLes admins avec stays.editModifier n'importe quel champ, galerie comprise (media, jusqu'à 30 éléments)
PATCH/api/stays/manage/:id/statusLes admins avec stays.publishDéfinir status : draft ou published. Publier demande trois photographies et les deux langues
PUT/api/stays/manage/:id/mediaLes admins avec stays.editRemplacer la galerie, dans l'ordre ; la position un est la couverture
DELETE/api/stays/manage/:idLes admins avec stays.deleteSupprimer le séjour ; refusé avec 409 tant qu'il existe une réservation non annulée

Le calendrier et les dates bloquées

MéthodeCheminQui peut l'appelerRôle
GET/api/calendarLes admins avec calendar.viewLa vue mensuelle : month (YYYY-MM) et en option stay
GET/api/availability/blocksLes admins avec calendar.viewChaque blocage, le plus proche d'abord
POST/api/availability/blocksLes admins avec calendar.blockBloquer 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/:idLes admins avec calendar.blockModifier un blocage
DELETE/api/availability/blocks/:idLes admins avec calendar.blockRetirer un blocage

Réservations, demandes et avis

MéthodeCheminQui peut l'appelerRôle
GET/api/bookings/manageLes admins avec bookings.viewLes 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/:referenceLes admins avec bookings.viewUne réservation avec sa chronologie et les actions permises maintenant, chacune avec sa raison quand elle ne l'est pas
PATCH/api/bookings/manage/:referenceLes admins avec bookings.editaction (confirm, check_in, complete, cancel) et admin_notes. Une étape depuis le mauvais statut répond 422 avec sa raison
GET/api/inquiriesLes admins avec inquiries.viewLes demandes. status, q, from, to, stay, page, page_size ; avec les totaux par statut
GET/api/inquiries/:idLes admins avec inquiries.viewUne demande avec son séjour
PATCH/api/inquiries/:idLes admins avec inquiries.editDéfinir status (new, replied, closed) et admin_notes
GET/api/reviews/manageLes admins avec reviews.viewLes avis. status, stay (identifiant ou slug), rating (un minimum), q, since (7, 30, 90, 365 jours), page ; avec les totaux
PATCH/api/reviews/manage/:idLes admins avec reviews.moderateDéfinir status : published ou hidden
GET/api/overviewAdmins avec overview.viewLa 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/seriesAdmins avec overview.viewLes réservations, le revenu et l'occupation de chacun des douze derniers mois

Destinations, questions et paramètres

MéthodeCheminQui peut l'appelerRôle
GET/api/destinations/manageLes admins avec destinations.viewChaque destination, masquées comprises
POST/api/destinations/manageLes admins avec destinations.createEn ajouter une : name, tagline et description (en, ar), et en option slug, cover_url, cover_alt, sort_order, is_active
PUT/api/destinations/manage/:idLes admins avec destinations.editEn modifier un
DELETE/api/destinations/manage/:idLes admins avec destinations.deleteEn supprimer une ; refusé tant que des séjours lui appartiennent
GET/api/faq/manageAdmins avec settings.viewChaque question de la page d'accueil, masquées comprises
POST/api/faq/manageAdmins avec settings.editEn ajouter une : question et answer (en, ar), en option sort_order et is_active
PUT/api/faq/manage/:idAdmins avec settings.editEn modifier un
DELETE/api/faq/manage/:idAdmins avec settings.editEn supprimer une
GET/api/settingsAdmins avec settings.viewChaque paramètre. search, category, page, page_size ou page_count
GET/api/settings/payments-statusAdmins 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/:keyAdmins avec settings.viewUn paramètre par sa clé
PATCH/api/settings/:keyAdmins avec settings.editChanger la value d'un paramètre
DELETE/api/settings/:keyAdmins avec settings.editSupprimer un paramètre

Admins et rôles

MéthodeCheminQui peut l'appelerRôle
GET/api/adminsAdmins avec admins.viewLes admins. email, name, phone, page, page_count
GET/api/admins/statisticsAdmins avec admins.viewLes nombres pour la liste des admins
GET/api/admins/:idAdmins avec admins.viewUn admin, par identifiant ou nom d'utilisateur
POST/api/adminsAdmins avec admins.createAjouter un admin : first_name, last_name, email, password et password_confirmation (6 caractères ou plus), en option phone
PATCH/api/admins/:idAdmins avec admins.editModifier un admin
PATCH/api/admins/:id/rolesAdmins avec admins.assign_rolesDéfinir les rôles d'un admin : role_ids
DELETE/api/admins/:idAdmins avec admins.deleteSupprimer un admin
PATCH/api/admins/profileTout 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/passwordTout administrateur connectéModifier son propre mot de passe en tant qu'admin connecté : current_password, password, password_confirmation
GET/api/rolesAdmins avec roles.viewLes rôles. name, guard_name, created_from, created_to, page, page_count
GET/api/roles/statisticsAdmins avec roles.viewLes nombres pour la liste des rôles
GET/api/roles/selectAdmins avec roles.viewL'identifiant et le nom de chaque rôle, pour un sélecteur
GET/api/roles/permissionsAdmins avec roles.viewToutes les permissions, groupées par domaine
GET/api/roles/:idAdmins avec roles.viewUn rôle avec ses permissions
POST/api/rolesAdmins avec roles.createAjouter un rôle
PUT/api/roles/:idAdmins avec roles.editRenommer ou décrire un rôle
POST/api/roles/:id/permissionsAdmins avec roles.assign_permissionsDéfinir les permissions d'un rôle
DELETE/api/roles/:idAdmins avec roles.deleteSupprimer un rôle

Notifications et fichiers téléversés

MéthodeCheminQui peut l'appelerRôle
GET/api/notificationsTout administrateur connectéLes 30 notifications les plus récentes de l'admin connecté
PATCH/api/notifications/read-allTout administrateur connectéToutes les marquer comme lues
PATCH/api/notifications/:id/readTout administrateur connectéEn marquer une comme lue
DELETE/api/notifications/:idTout administrateur connectéEn supprimer une
POST/api/helpers/uploadTout 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

RouteLimiteVariable
POST /api/auth/login10 connexions échouées par 15 minutesRATE_LIMIT_LOGIN
POST /api/bookings5 par 10 minutesAucune
POST /api/inquiries5 par 10 minutesAucune
POST /api/bookings/:reference/review5 par 10 minutesAucune

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.

Bloqué sur une étape ?

Trouvez une solution avant de tout recommencer.

Dépannage

Préférences des Cookies

Nous utilisons des cookies pour améliorer votre expérience de navigation, analyser le trafic du site et personnaliser le contenu. En cliquant sur "Accepter Tout", vous consentez à notre utilisation des cookies pour l'analyse et la publicité personnalisée.