Aller au contenu
Nouveau : l'assistant d'import crée la fiche de votre hôtel en quelques minutes
Otelvya

Développeurs

Branchez Otelvya sur n'importe quel site

Une API REST JSON simple pour afficher les chambres, les prix et les disponibilités d'un hôtel, et créer des réservations directes. Des modules prêts à l'emploi pour WordPress, Joomla et Drupal, et un widget pour toutes les autres plateformes.

URL de basehttps://otelvya.com/api/v1

Démarrer en deux minutes

  1. Dans Otelvya, ouvrez Moteur de réservation › Intégrer à votre site : vous y trouvez l'identifiant de l'hôtel (slug).
  2. Les lectures publiques (fiche, chambres, disponibilités, calendrier) ne demandent aucune clé et sont lisibles depuis un navigateur (CORS ouvert).
  3. Pour créer des réservations, créez une clé avec la portée « Lecture + réservations » et appelez l'API depuis votre serveur.

Authentification

Les endpoints de réservation exigent une clé d'API, transmise dans l'en-tête Authorization (Bearer) ou X-Api-Key. La clé n'est affichée qu'une fois à sa création ; seule son empreinte est conservée. Elle se garde côté serveur : les endpoints authentifiés n'acceptent pas les appels depuis un navigateur.

Portées : « read » (lecture) et « bookings » (création et consultation des réservations de l'hôtel de la clé). Une clé révoquée cesse immédiatement de fonctionner.

Idempotence

Envoyez un en-tête Idempotency-Key unique avec chaque création : rejouer la même requête (coupure réseau, nouvel essai) renvoie la même réservation au lieu d'en créer une seconde. La même clé avec un corps différent est refusée (409).

Prix recalculés côté serveur

Le montant d'une réservation est toujours recalculé par Otelvya. Transmettez expectedTotal (le total affiché au client) : si le prix a changé entre-temps, la réservation est refusée avec price_changed plutôt que facturée à un autre montant.

Exemples

curl — Rechercher des disponibilités
curl "https://otelvya.com/api/v1/hotels/riad-atlas/availability?checkIn=2026-11-20&checkOut=2026-11-22&adults=2&lang=fr"
JavaScript — Rechercher des disponibilités
const res = await fetch(
  "https://otelvya.com/api/v1/hotels/riad-atlas/availability?" +
    new URLSearchParams({ checkIn: "2026-11-20", checkOut: "2026-11-22", adults: "2", lang: "en" })
);
const data = await res.json();
if (!res.ok) throw new Error(data.error.code + ": " + data.error.message);
for (const o of data.offers) {
  console.log(o.room.name, o.meal.label, o.total, o.currency, o.bookingUrl);
}
curl — Créer une réservation (serveur)
curl -X POST "https://otelvya.com/api/v1/hotels/riad-atlas/bookings" \
  -H "Authorization: Bearer $OTELVYA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-2026-000123" \
  -d '{
    "checkIn": "2026-11-20", "checkOut": "2026-11-22", "adults": 2,
    "roomId": "<room.id>", "ratePlanId": "<ratePlan.id>",
    "expectedTotal": 245.00,
    "guest": { "firstName": "Salma", "lastName": "Bennani",
               "email": "salma@example.com", "phone": "+212600000000", "country": "MA" }
  }'
PHP — Créer une réservation (serveur)
<?php
$ch = curl_init("https://otelvya.com/api/v1/hotels/riad-atlas/bookings");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("OTELVYA_API_KEY"),
        "Content-Type: application/json",
        "Idempotency-Key: order-2026-000123",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "checkIn" => "2026-11-20", "checkOut" => "2026-11-22", "adults" => 2,
        "roomId" => $roomId, "ratePlanId" => $ratePlanId, "expectedTotal" => 245.00,
        "guest" => ["firstName" => "Salma", "lastName" => "Bennani",
                    "email" => "salma@example.com", "phone" => "+212600000000"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($status >= 400) {
    throw new RuntimeException($data["error"]["code"] . ": " . $data["error"]["message"]);
}
header("Location: " . ($data["booking"]["payment"]["url"] ?? $data["booking"]["confirmationUrl"]));

Interface POS & exports back-office

Comme les interfaces POS et back-office d'OPERA : n'importe quelle caisse, logiciel de facturation, de comptabilité ou de paie peut se brancher dès aujourd'hui sur Otelvya, sans accord partenaire. L'hôtel crée une clé dans Intégrations › Interfaces avec les portées nécessaires.

Portées : « pos » — recherche d'un client en séjour et imputation sur la chambre ; « exports » — factures émises, encaissements et écritures comptables ; « hr » — effectif sans données sensibles. Une clé « read » ou « bookings » ne peut ni imputer ni exporter.

Imputation sur la chambre

Le client doit être en séjour (arrivée enregistrée) et le module Réception actif pour l'hôtel. Le montant est TTC dans la devise de l'hôtel. La référence externe est unique par point de vente : renvoyer le même ticket ne crée pas de doublon (réponse 200, en-tête Idempotent-Replayed). Refus explicites : 409 not_in_house, folio_closed, module_inactive.

curl — Rechercher le client de la chambre 101
curl "https://otelvya.com/api/v1/hotels/riad-atlas/inhouse?room=101" \
  -H "Authorization: Bearer $OTELVYA_API_KEY"
curl — Imputer un ticket
curl -X POST "https://otelvya.com/api/v1/hotels/riad-atlas/folio-charges" \
  -H "Authorization: Bearer $OTELVYA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "room": "101",
    "amount": 185.50, "taxRate": 10,
    "label": "Ticket 4512 — dîner 2 couverts",
    "reference": "T-4512", "outlet": "Restaurant"
  }'
curl — Annuler une imputation
curl -X POST "https://otelvya.com/api/v1/hotels/riad-atlas/folio-charges/<charge.id>/void" \
  -H "Authorization: Bearer $OTELVYA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Ticket saisi sur la mauvaise chambre" }'

Exports facturation, comptabilité et paie

Formats JSON (défaut) ou CSV (format=csv, UTF-8, séparateur virgule). Période de 366 jours au plus, 5 000 lignes au plus (en-tête X-Export-Truncated au-delà). Les écritures exigent le module Comptabilité, l'effectif le module RH ; l'effectif n'expose jamais le RIB, la CIN, le n° de sécurité sociale ni la situation familiale.

curl — Exporter les factures du mois (CSV)
curl "https://otelvya.com/api/v1/hotels/riad-atlas/exports/invoices?from=2026-10-01&to=2026-10-31&format=csv" \
  -H "Authorization: Bearer $OTELVYA_API_KEY" -o factures.csv
curl — Exporter les écritures (CSV)
curl "https://otelvya.com/api/v1/hotels/riad-atlas/exports/journal?from=2026-10-01&to=2026-10-31&format=csv" \
  -H "Authorization: Bearer $OTELVYA_API_KEY" -o ecritures.csv
curl — Exporter l'effectif (portée hr)
curl "https://otelvya.com/api/v1/hotels/riad-atlas/exports/employees?format=csv" \
  -H "Authorization: Bearer $OTELVYA_API_KEY" -o effectif.csv

Évolution prévue

Pas de webhooks sortants pour l'instant : les logiciels interrogent l'API (par exemple chaque nuit pour les exports). L'envoi d'événements signés (imputation, facture émise) est une évolution prévue.

Référence des endpoints

Description complète au format OpenAPI 3.1, à importer dans Postman, Insomnia ou un générateur de client : /api/v1/openapi.json

GET/hotels/{slug}

Public · CORS ouvert

Fiche publique de l'hôtel : nom, étoiles, adresse, contact, description en 4 langues, équipements, photos, devise, horaires, URL du moteur et du site.

ParamètreEmplacementRequis
slugpathoui
langquerynon
GET/hotels/{slug}/rooms

Public · CORS ouvert

Types de chambres avec photos, capacité, équipements et prix « à partir de » sur les 30 prochaines nuits.

ParamètreEmplacementRequis
slugpathoui
langquerynon
GET/hotels/{slug}/availability

Public · CORS ouvert

Offres vendables pour un séjour : total et prix par nuit, pension, conditions d'annulation, chambres restantes (plafonné à 3) et lien de réservation pré-rempli.

ParamètreEmplacementRequis
slugpathoui
checkInqueryoui
checkOutqueryoui
adultsquerynon
childrenquerynon
promoquerynon
currencyquerynon
langquerynon
GET/hotels/{slug}/calendar

Public · CORS ouvert

Prix minimum et disponibilité pour chaque nuit (60 nuits au plus).

ParamètreEmplacementRequis
slugpathoui
fromquerynon
daysquerynon
POST/hotels/{slug}/bookings

Clé d'API requise

Crée une réservation avec les mêmes contrôles que le moteur public ; renvoie le code, le lien de confirmation et, si l'hôtel l'a activé, le lien de paiement en ligne.

ParamètreEmplacementRequis
slugpathoui
Idempotency-Keyheadernon
GET/hotels/{slug}/inhouse

Clé d'API requise

ParamètreEmplacementRequis
slugpathoui
roomquerynon
folioquerynon
namequerynon
POST/hotels/{slug}/folio-charges

Clé d'API requise

ParamètreEmplacementRequis
slugpathoui
POST/hotels/{slug}/folio-charges/{id}/void

Clé d'API requise

ParamètreEmplacementRequis
slugpathoui
idpathoui
GET/hotels/{slug}/exports/invoices

Clé d'API requise

ParamètreEmplacementRequis
slugpathoui
fromqueryoui
toqueryoui
formatquerynon
GET/hotels/{slug}/exports/payments

Clé d'API requise

ParamètreEmplacementRequis
slugpathoui
fromqueryoui
toqueryoui
formatquerynon
GET/hotels/{slug}/exports/journal

Clé d'API requise

ParamètreEmplacementRequis
slugpathoui
fromqueryoui
toqueryoui
formatquerynon
GET/hotels/{slug}/exports/employees

Clé d'API requise

ParamètreEmplacementRequis
slugpathoui
formatquerynon
GET/bookings/{code}

Clé d'API requise

Consulte une réservation de l'hôtel de la clé (statut, montants, paiement).

ParamètreEmplacementRequis
codepathoui
langquerynon

Erreurs

Toutes les erreurs ont la même forme, avec un code stable à tester dans votre code et un message lisible :

JSON
{ "error": { "code": "invalid_dates", "message": "La date d'arrivée est passée." } }

Limites de débit

  • Lectures publiques : 120 requêtes par minute et par adresse IP.
  • Avec une clé : 600 requêtes par minute et par clé (utile pour les plugins, qui appellent depuis l'adresse de votre serveur).
  • Créations de réservation : 10 par 10 minutes et par IP, 60 par 10 minutes et par clé.
  • Chaque réponse indique X-RateLimit-Limit, X-RateLimit-Remaining et X-RateLimit-Reset ; au-delà, réponse 429 avec Retry-After.

Disponibilité du service

Si le moteur de réservation d'un hôtel est hors ligne (abonnement) ou si la plateforme est en maintenance, l'API répond 503 avec un code explicite ; un hôtel inconnu répond 404. Aucune donnée interne n'est jamais exposée.

Modules prêts à l'emploi

WordPress

Codes courts, bloc Gutenberg, widget, cache de 5 minutes, traductions fr/en/es/ar. PHP 7.4+.

Télécharger

Joomla

Module de site pour Joomla 4 et 5 : recherche, chambres avec prix ou bouton, 4 langues.

Télécharger

Drupal

Module pour Drupal 10 et 11 : bloc configurable et page de réglages.

Télécharger

Toute autre plateforme

Wix, Squarespace, Webflow, Shopify, Google Sites, HTML : collez le code d'intégration généré dans Otelvya (recherche, bouton ou liste des chambres).

Une question technique ? Écrivez-nous depuis la page de contact.