Développeurs

Intégrer la réservation Daytio à un site internet

Vous créez ou gérez le site d'un professionnel qui utilise Daytio ? Trois façons d'y mettre sa prise de rendez-vous, de la plus simple à la plus complète.

Trois façons d'intégrer

Pas à pas

  1. 1

    Accédez aux réglages du pro

    Connectez-vous au compte Daytio du professionnel (il peut vous donner ses accès, ou faire ces étapes avec vous), puis ouvrez Réglages → Site internet. Tout ce qu'il faut pour les trois intégrations s'y trouve.

  2. 2

    Choisissez l'intégration

    Un simple bouton ? Copiez le lien (section 1). La réservation dans la page ? Copiez le code du widget (section 2). Un parcours sur mesure ? Passez à l'étape 3.

  3. 3

    Créez une clé API

    Section 3 → « Créer une clé API ». Donnez-lui un nom et indiquez l'adresse du site (https://…). La clé (dtk_live_…) ne s'affiche qu'une fois : copiez-la tout de suite. Si le pro est abonné, cette première clé ajoute l'option API à son abonnement.

  4. 4

    Vérifiez que la clé répond

    Un premier appel doit renvoyer le nom de l'établissement :

    curl https://daytio.com/api/v1/business \
      -H "Authorization: Bearer dtk_live_…"
  5. 5

    Construisez le parcours

    Listez les prestations, affichez les créneaux libres de celle choisie, puis réservez. Si la prestation exige un paiement en ligne, redirigez le client vers le lien Stripe renvoyé : il revient ensuite sur votre site.

1. Le lien de réservation

Chaque pro a une adresse permanente. Ajoutez ?prestation=<nom de la prestation> pour en présélectionner une.

https://daytio.com/votre-salon
https://daytio.com/votre-salon?prestation=Coupe%20femme

2. Le widget

Collez ces deux lignes à l'endroit voulu. Le script crée le cadre et ajuste sa hauteur tout seul — n'écrivez pas d'<iframe> à la main. Blocs disponibles : reservation, horaires (et carte, commande pour un restaurant).

<div data-daytio="reservation" data-slug="votre-salon"></div>
<script src="https://daytio.com/embed.js" async></script>

Le contenu d'un cadre n'est pas indexé avec la page qui le contient : le widget fait réserver, il ne fait pas monter le site dans Google.

3. L'API

Option à 25 €/mois, activée par la première clé API

Adresse de base

https://daytio.com/api/v1

Authentification

Chaque requête porte la clé dans l'en-tête Authorization (ou X-Daytio-Key). La clé désigne l'établissement : aucun autre identifiant à fournir.

Authorization: Bearer dtk_live_…
# ou / or
X-Daytio-Key: dtk_live_…

Appels depuis le navigateur ou depuis un serveur

Depuis le navigateur, l'en-tête Origin doit correspondre à un site déclaré sur la clé, sinon la requête est refusée (origin_not_allowed). Une clé dans du JavaScript est lisible par tous les visiteurs : c'est cette liste qui empêche un autre site de l'utiliser. Si vous le pouvez, appelez l'API depuis votre serveur et gardez la clé côté serveur.

Limites

300 lectures par minute et 120 réservations par heure, par clé. Depuis un navigateur, la limite par appareil de la page Daytio s'applique aussi aux réservations. Au-delà : 429 rate_limited.

Format des réponses

JSON. Succès : { "data": … }. Erreur : { "error": { "code", "message" } }. Testez le code, qui est stable ; le message, en français, peut évoluer.

Heures et fuseau

Les instants sont en ISO 8601 (UTC). Affichez au client le champ time, l'heure locale du pro : c'est elle qui fait foi, le client se déplace chez lui.

Points d'accès

  • GET /businessL'établissement : nom, ville, fuseau, devise, règles de réservation, paiement en ligne.
  • GET /servicesLes prestations réservables, dans l'ordre choisi par le pro.
  • GET /staffLes collaborateurs (offre Équipe). Liste vide pour un pro seul.
  • GET /availabilityLes créneaux libres, 1 à 7 jours. Paramètres : services (identifiants séparés par des virgules), from (AAAA-MM-JJ), days, staff, anyStaff=1.
  • POST /bookingsRéserve un créneau. Le créneau est revérifié au moment de la réservation.
  • GET /payments/{sessionId}L'état d'une réservation payée en ligne.
GET /business

{
  "data": {
    "name": "Atelier Coiffure",
    "slug": "atelier-coiffure",
    "city": "Quimper",
    "timezone": "Europe/Paris",
    "currency": "EUR",
    "bookingUrl": "https://daytio.com/atelier-coiffure",
    "bookingOpen": true,
    …
  }
}
GET /availability?services=3f0c…&from=2026-10-12&days=7

{
  "data": {
    "timezone": "Europe/Paris",
    "durationMinutes": 45,
    "groupClass": false,
    "days": [
      {
        "date": "2026-10-12",
        "slots": [
          { "startsAt": "2026-10-12T07:00:00.000Z", "time": "09:00" },
          { "startsAt": "2026-10-12T07:45:00.000Z", "time": "09:45" }
        ]
      }
    ]
  }
}

Réserver

Le consentement du client (consent: true) est obligatoire : affichez une case NON pré-cochée « J'accepte que mes données servent à gérer mon rendez-vous ». marketingConsent est une seconde case, facultative et distincte.

POST /bookings

{
  "services": ["3f0c…"],
  "startsAt": "2026-10-12T07:00:00.000Z",
  "client": {
    "firstName": "Camille",
    "lastName": "Martin",
    "email": "camille@example.com",
    "phone": "0612345678"
  },
  "consent": true,
  "returnUrl": "https://www.mon-salon.fr/reservation/merci"
}
  • Rendez-vous créé (201). Le client et le pro reçoivent leur e-mail de confirmation.
  • La prestation exige un paiement en ligne (200) : redirigez le client vers checkoutUrl. Rien n'est réservé tant qu'il n'a pas payé.
  • Toujours prévoir le refus : un créneau affiché peut être pris entre-temps (409 booking_failed). Proposez alors d'en choisir un autre.
// 201 — rendez-vous créé / appointment created
{ "data": { "status": "confirmed", "startsAt": "…", "endsAt": "…",
            "partySize": 1, "manageUrl": "https://daytio.com/rdv/…" } }

// 200 — paiement en ligne exigé / online payment required
{ "data": { "status": "payment_required",
            "checkoutUrl": "https://checkout.stripe.com/…" } }

// 409
{ "error": { "code": "booking_failed", "message": "…" } }

Paiement en ligne

Passez returnUrl (et cancelUrl si besoin), sur un site déclaré sur la clé. Après paiement, le client revient sur returnUrl avec ?daytio_session=… ; interrogez /payments/{id} jusqu'à obtenir confirmed (quelques secondes). Sans returnUrl, le client termine sur la page de confirmation Daytio.

États : confirmed (payé, réservé), processing (payé, confirmation en cours), awaiting_payment, expired (abandonné), failed (créneau pris entre-temps : remboursé).

GET /payments/cs_live_…

{ "data": { "status": "confirmed", "startsAt": "…",
            "amountPaid": 30, "currency": "EUR" } }

Codes d'erreur

  • missing_api_keyPas de clé dans la requête.
  • invalid_api_keyClé inconnue ou révoquée.
  • origin_not_allowedAppel navigateur depuis un site non déclaré sur la clé.
  • rate_limitedTrop de requêtes. Réessayez plus tard.
  • account_unavailableCompte du pro désactivé.
  • invalid_requestParamètre manquant ou invalide (le message dit lequel).
  • not_foundRessource introuvable.
  • booking_failedRéservation refusée (créneau pris, préavis, téléphone manquant…).
  • return_url_not_allowedreturnUrl / cancelUrl hors des sites déclarés.
  • unsupported_accountCompte restaurant : utilisez le widget ou le lien.

Exemple complet (JavaScript)

const API = "https://daytio.com/api/v1";
const KEY = "dtk_live_…"; // de préférence côté serveur / server-side if possible

async function daytio(path, init = {}) {
  const res = await fetch(API + path, {
    ...init,
    headers: {
      Authorization: "Bearer " + KEY,
      "Content-Type": "application/json",
      ...init.headers,
    },
  });
  const json = await res.json();
  if (json.error) throw Object.assign(new Error(json.error.message), json.error);
  return json.data;
}

// 1. Prestations / services
const services = await daytio("/services");

// 2. Créneaux libres sur 7 jours / free slots over 7 days
const today = new Date().toISOString().slice(0, 10);
const { days } = await daytio(
  "/availability?services=" + services[0].id + "&from=" + today + "&days=7",
);

// 3. Réserver le premier créneau / book the first slot
const slot = days.find((d) => d.slots.length)?.slots[0];
try {
  const booking = await daytio("/bookings", {
    method: "POST",
    body: JSON.stringify({
      services: [services[0].id],
      startsAt: slot.startsAt,
      client: { firstName: "Camille", lastName: "Martin", email: "camille@example.com" },
      consent: true, // case cochée par le client / box ticked by the client
      returnUrl: location.origin + "/reservation/merci",
    }),
  });
  if (booking.status === "payment_required") {
    location.href = booking.checkoutUrl; // Stripe, puis retour / then back
  } else {
    showConfirmation(booking); // booking.startsAt, booking.manageUrl
  }
} catch (e) {
  if (e.code === "booking_failed") askForAnotherSlot(e.message);
  else throw e;
}

// 4. Page /reservation/merci : état du paiement / payment status
const session = new URLSearchParams(location.search).get("daytio_session");
if (session) {
  const payment = await daytio("/payments/" + encodeURIComponent(session));
  // payment.status : confirmed | processing | awaiting_payment | expired | failed
}

Comptes restaurant : l'API couvre les rendez-vous et les cours. Pour les tables et la vente à emporter, utilisez le widget ou le lien.

Une question ?

Écrivez-nous, avec le nom de l'établissement concerné. daytio.com/contact