Skip to content
Se connecter
Veridien Docs

Offres et codes promo

Les endpoints du catalogue répondent à « que puis-je réserver dans chaque type de chambre ». Ceux-ci répondent à « quelles offres s'appliquent à ce séjour », ce dont un moteur de réservation a besoin pour présenter ses offres : noms publics, descriptions, images, contenu d'un forfait et prix pour le groupe concerné.

Un tarif, un forfait et une promotion sont tous le même type d'objet. Ils se distinguent par kind et par la façon dont leur prix dérive d'un tarif parent, ce qui explique qu'un forfait se distribue et se tarife exactement comme n'importe quel autre tarif.


GET /rate-plans

Portée : availability:read

Toutes les offres que l'établissement a publiées pour le moteur de réservation, tarifées pour le séjour et le groupe demandés.

ParamètreRequisNotes
check_inouiYYYY-MM-DD.
check_outouiYYYY-MM-DD, exclu.
adultsnon2 par défaut.
childrennon0 par défaut.
room_type_idnonRestreindre à un seul type de chambre.
curl "$VRDN_BASE/rate-plans?check_in=2026-08-01&check_out=2026-08-04&adults=2" \
  -H "Authorization: Bearer $VRDN_KEY"
{
  "check_in": "2026-08-01",
  "check_out": "2026-08-04",
  "data": [
    {
      "rate_plan_id": "5c1e8f4a-2b7d-4a9c-8e6f-1d3b9a5c7e02",
      "room_type_id": "9b2f6c3e-8d1a-4f5b-a7c9-4e0d2b8f1a63",
      "room_type_name": "Ocean Suite",
      "public_name": "Half Board Escape",
      "kind": "package",
      "description": "Breakfast and dinner included daily.",
      "image_url": "https://cdn.example.com/half-board.jpg",
      "inclusions": [
        { "label": "Breakfast", "frequency": "perGuestPerNight", "included_quantity": 1 },
        { "label": "Dinner", "frequency": "perGuestPerNight", "included_quantity": 1 }
      ],
      "min_los": 2,
      "max_los": null,
      "currency": "USD",
      "total": "1341.60",
      "room_subtotal": "1020.00",
      "taxes_total": "321.60",
      "base_occupancy": 2,
      "nightly_rates": [{ "date": "2026-08-01", "day_of_week": 6, "rate": "340.00", "source": "interval" }]
    }
  ]
}

Une offre n'apparaît que si toutes les conditions suivantes sont réunies. Ce qui échoue est simplement absent de la réponse ; il n'y a ni entrée partielle ni entrée « indisponible ».

  • Le tarif est actif et l'établissement l'a activé pour le moteur de réservation.
  • Le séjour tombe dans la fenêtre de réservation et la fenêtre de séjour de l'offre.
  • La durée du séjour respecte le minimum et le maximum de l'offre, et chaque nuit tombe un jour de la semaine autorisé.
  • Le type de chambre peut accueillir le groupe.
  • Le tarif n'est pas réservé à un code promotionnel.

Les offres protégées par un code promotionnel n'apparaissent jamais ici. Elles ne sont accessibles que par une validation de code réussie, décrite plus bas.

inclusions liste ce qu'un forfait regroupe, avec la fréquence à laquelle chaque élément revient : perStay, perNight, perGuest ou perGuestPerNight. Ces entrées sont descriptives. Le prix auquel un forfait se vend est l'unique total ; l'établissement répartit ce total entre les prestations en interne pour que chaque composant reçoive le bon traitement fiscal, mais le client ne paie qu'un seul montant.


POST /promo-codes/validate

Portée : availability:read

ChampRequisNotes
codeouiLa casse et les espaces autour sont ignorés.
check_inouiYYYY-MM-DD.
check_outouiYYYY-MM-DD, exclu.
room_type_idnonS'il est fourni et que l'offre du code porte sur un autre type de chambre, la réponse est l'uniforme valid: false.
adultsnon2 par défaut.
childrennon0 par défaut.
child_agesnon[] par défaut. Quand il n'est pas vide, sa longueur donne le nombre d'enfants et prime sur children.

La taille du groupe est comparée à la capacité maximale du type de chambre, un groupe sous-déclaré peut donc être validé ici puis échouer à POST /holds.

Un code débloque un tarif. Il n'applique pas de remise de son côté : l'économie est déjà intégrée au tarif que le code révèle, le prix que vous recevez est donc le prix, sans rien de plus à calculer.

curl -X POST "$VRDN_BASE/promo-codes/validate" \
  -H "Authorization: Bearer $VRDN_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "SUMMER26",
    "check_in": "2026-08-01",
    "check_out": "2026-08-04",
    "adults": 2
  }'

Un code qui s'applique renvoie l'offre qu'il débloque, dans la même structure qu'une entrée de /rate-plans.

{
  "valid": true,
  "code": "SUMMER26",
  "rate_plan": {
    "rate_plan_id": "e2a9d7c4-3f6b-4c1e-9a8d-7b5f0c2e4a19",
    "room_type_id": "9b2f6c3e-8d1a-4f5b-a7c9-4e0d2b8f1a63",
    "room_type_name": "Ocean Suite",
    "public_name": "Early Bird",
    "kind": "promotion",
    "description": "Book 60 days ahead and save.",
    "image_url": "https://cdn.example.com/early-bird.jpg",
    "inclusions": [],
    "min_los": 3,
    "max_los": null,
    "currency": "USD",
    "total": "1140.36",
    "room_subtotal": "867.00",
    "taxes_total": "273.36",
    "nightly_rates": [{ "date": "2026-08-01", "day_of_week": 6, "rate": "289.00", "source": "interval" }]
  }
}

Un code qui ne s'applique pas renvoie une seule et même réponse, quelle qu'en soit la cause.

{
  "valid": false,
  "reason": "That code is not valid for these dates."
}

La réponse d'échec est volontairement identique pour un code qui n'existe pas, un code expiré, un code entièrement consommé et un code dont l'offre ne couvre pas les dates demandées. Les distinguer permettrait à un appelant de découvrir quels codes existent vraiment, la cause précise n'est donc jamais divulguée.

La correspondance des codes ignore la casse et les espaces autour, summer26 et SUMMER26 sont donc le même code.

La validation de code porte une limite plus stricte que le reste de l'API, en plus des limites par clé et par IP décrites dans Authentification. Des échecs répétés renvoient 429. Validez un code quand le client le soumet, pas à chaque frappe.


Passez le code à l'appel de réservation. Le serveur le résout à nouveau depuis zéro et retarife le séjour.

curl -X POST "$VRDN_BASE/holds" \
  -H "Authorization: Bearer $VRDN_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "guest_id": "c4e7b9d2-6a1f-4e3c-9b8d-2f5a7c0e1d46",
    "room_type_id": "9b2f6c3e-8d1a-4f5b-a7c9-4e0d2b8f1a63",
    "rate_plan_id": "e2a9d7c4-3f6b-4c1e-9a8d-7b5f0c2e4a19",
    "check_in": "2026-08-01",
    "check_out": "2026-08-04",
    "adults": 2,
    "promo_code": "SUMMER26"
  }'

Deux conséquences à prévoir dans votre conception :

  • Une réponse de validation est indicative. Elle reflète l'instant où elle a été émise. Si le code expire, est désactivé ou atteint sa limite d'utilisations avant que le client ait fini de payer, la réservation échoue au lieu d'honorer le prix annoncé plus tôt. Gérez cet échec dans votre parcours de paiement.
  • N'envoyez jamais de prix. Le serveur tarife lui-même chaque réservation et ignore tout montant fourni par un client. Un prix annoncé sert à l'affichage.

L'utilisation est comptée à la confirmation d'une réservation, pas à la validation d'un code, et elle est relâchée si la réservation est annulée. Un code limité à un nombre fixe d'utilisations ne peut pas être survendu par des réservations simultanées.