creno.
Documentation

Prenez des rendez-vous en moins d'une heure.

Deux parcours, un seul backend. Prenez notre widget, ou construisez votre propre interface sur la même API. Choisissez celui qui convient à votre stack.

Sur cette page

1. Obtenez votre clé API

Chaque compte reçoit une clé publiable (pk_live_...) depuis votre tableau de bord. Elle peut être utilisée sans risque dans du code côté client. La véritable protection est la liste des origines autorisées à l'appeler, que vous configurez aussi dans le tableau de bord. Enregistrez chaque domaine sur lequel vous l'intégrerez (y compris localhost pendant vos tests).

Utilisez notre widget

Nous affichons l'interface de réservation, vous n'avez qu'à l'insérer.

React, Next.js, Astro

Si votre site est construit avec un framework basé sur React, utilisez le composant directement.

Voir sur npm ↗
npm install @creno/react
import { BookingWidget } from "@creno/react";
import "@creno/react/style.css";

export default function BookingPage() {
  return (
    <BookingWidget
      apiUrl="https://api.crenoapp.com"
      apiKey="pk_live_..."
    />
  );
}

Propriétés

Propriété Type Description
apiUrl * string L'URL de base de votre API Créno.
apiKey * string Votre clé publiable (peut être exposée sans risque dans le JS du navigateur).
resourceId string Cible un calendrier précis. Omettez-la pour utiliser votre calendrier par défaut.
labels Partial<Labels> Remplacez n'importe quelle chaîne de l'interface. Le français et l'anglais sont fournis d'origine ; pour toute autre langue, utilisez cette propriété.
formatLocale string La locale de formatage des dates et heures, par ex. « fr-CA ». Par défaut, la locale du navigateur.
onBooked (booking) => void Appelée une fois qu'une réservation est créée avec succès.

Vue

Enveloppe Vue 3 du même composant. Charge automatiquement le script d'intégration ; aucune balise <script> à ajouter vous-même.

Voir sur npm ↗
npm install @creno/vue
<script setup>
import { BookingWidget } from "@creno/vue";
</script>

<template>
  <BookingWidget
    api-url="https://api.crenoapp.com"
    api-key="pk_live_..."
    @booked="(booking) => console.log(booking.id)"
  />
</template>

Propriétés

Propriété Description
apiUrl * L'URL de base de votre API Créno.
apiKey * Votre clé publiable.
resourceId Cible un calendrier précis.
labels Remplacez n'importe quelle chaîne de l'interface.
@booked Émis avec la réservation créée.

N'importe quel autre site

HTML simple, Shopify, Webflow, Squarespace, ou partout ailleurs où vous pouvez coller une balise script. Aucune étape de compilation, aucun framework requis.

<script src="https://cdn.crenoapp.com/embed.js" defer></script>

<creno-widget
  api-url="https://api.crenoapp.com"
  api-key="pk_live_..."
></creno-widget>

S'affiche à l'intérieur d'un Shadow DOM, donc il ne peut jamais entrer en conflit avec le CSS de votre site, dans un sens comme dans l'autre : vos styles n'y entreront pas, et ceux du widget n'en sortiront pas.

Attributs

Attribut Description
api-url * L'URL de base de votre API Créno.
api-key * Votre clé publiable.
resource-id Cible un calendrier précis.
locale par ex. « fr-CA ».

Personnalisation

Chaque couleur, rayon d'arrondi et police est une propriété CSS personnalisée. Remplacez-les depuis votre propre feuille de style, sans configuration de build ni propriété de composant requise, et ça fonctionne de façon identique pour le composant React comme pour la balise script.

creno-widget, .my-booking-page {
  --pbw-color-accent: #b8452f;
  --pbw-color-accent-hover: #963a27;
  --pbw-radius-lg: 8px;
}
Variable Valeur par défaut Contrôle
--pbw-color-accent #2563eb Couleur principale de la marque : boutons, date sélectionnée, liens
--pbw-color-accent-hover #1d4ed8 État de survol du bouton principal
--pbw-color-accent-soft #eff6ff Teinte pâle utilisée pour les fonds au survol
--pbw-color-surface #ffffff Fond de la carte
--pbw-color-border #e5e7eb Couleur de bordure par défaut
--pbw-color-text #111827 Couleur de texte principale
--pbw-radius-lg 16px Rayon d'arrondi de la carte
--pbw-font system font stack Police utilisée partout

Construisez votre propre interface

C'est vous qui affichez. Nous restons le backend et l'infrastructure.

Node.js

Client TypeScript, sans dépendance d'exécution (fetch natif de Node 18+). Une classe d'erreur distincte par type d'erreur, la même taxonomie que le kit Python.

Voir sur npm ↗
npm install @creno/node
import { CrenoClient, CrenoConflictError } from "@creno/node";

const client = new CrenoClient("pk_live_...");

const availability = await client.getAvailability({ from: "2026-08-01", to: "2026-08-07" });

try {
  const booking = await client.createBooking({
    startAt: availability.slots[0].startAt,
    customerName: "Jane Doe",
    customerEmail: "jane@example.com",
  });
} catch (err) {
  if (err instanceof CrenoConflictError) {
    // that slot was just taken, re-check availability and retry
  }
}

Python

Client typé pour tout backend Python : méthodes normales, plus une exception distincte par type d'erreur (créneau pris, limite de forfait, trop de requêtes...) au lieu d'analyser des codes de statut à la main.

Voir sur PyPI ↗
pip install creno
from creno import CrenoClient

client = CrenoClient(api_key="pk_live_...")

availability = client.get_availability(from_="2026-08-01", to="2026-08-07")
booking = client.create_booking(
    start_at=availability.slots[0].start_at,
    customer_name="Jane Doe",
    customer_email="jane@example.com",
)

Référence de l'API

Le widget et la balise script appellent tous les deux cette même API REST en dessous. Si vous construisez votre propre interface, ou si vous intégrez depuis un backend (Python, Ruby, PHP, Go, peu importe), vous pouvez l'appeler directement, aucune bibliothèque cliente n'est requise, seulement un client HTTP.

Authentification

Chaque requête doit inclure votre clé publiable dans l'en-tête X-API-Key. Cette clé identifie votre compte ; la véritable protection est la liste des origines autorisées que vous configurez dans le tableau de bord, appliquée aux requêtes provenant d'un navigateur (CORS). Les appels depuis un serveur (Python, etc.) ne passent pas par un navigateur, donc la vérification d'origine ne s'applique pas à eux, gardez tout de même votre clé secrète côté serveur.

X-API-Key: pk_live_...

URL de base

https://api.crenoapp.com

Points de terminaison

GET /v1/public/service-types

Liste les types de service actifs pour votre calendrier. Si elle retourne 0 ou 1 résultat, votre intégration peut sauter cette étape entièrement et omettre serviceTypeId partout ailleurs.

Paramètres Description
resourceId Optionnel. Omettez pour votre calendrier par défaut.
[
  { "id": "...", "resourceId": "...", "name": "Haircut", "active": true, "sortOrder": 0 }
]
GET /v1/public/availability

Retourne les créneaux réellement disponibles pour une plage de dates, après application des horaires récurrents, des exceptions et des réservations déjà prises.

Paramètres Description
from* Date de début, AAAA-MM-JJ.
to* Date de fin, AAAA-MM-JJ.
resourceId Optionnel. Omettez pour votre calendrier par défaut.
serviceTypeId Optionnel, si vous utilisez un menu de services.
{
  "resourceId": "...",
  "timezone": "America/Toronto",
  "slots": [
    { "startAt": "2026-08-03T13:00:00.000Z", "endAt": "2026-08-03T13:30:00.000Z" }
  ]
}
POST /v1/public/bookings

Crée une réservation. Revalidée côté serveur au moment de l'écriture (jamais basée uniquement sur un appel de disponibilité antérieur), et protégée contre les doubles réservations au niveau de la base de données.

{
  "startAt": "2026-08-03T13:00:00.000Z",
  "customerName": "Jane Doe",
  "customerEmail": "jane@example.com",
  "customerPhone": "+1 514 555 0100",
  "notes": "First visit",
  "resourceId": null,
  "serviceTypeId": null,
  "lang": "en"
}

startAt, customerName et customerEmail sont requis, tout le reste est optionnel. La réponse (201) est la réservation créée.

Limites de requêtes

Point de terminaison Limites de requêtes
POST /v1/public/bookings 5 / minute
GET /v1/public/service-types, /v1/public/availability 60 / minute

Réponses d'erreur

Toutes les erreurs retournent un corps JSON avec un champ error. Les codes qui comptent pour l'intégration :

Code Description
401 En-tête X-API-Key manquant ou invalide.
403 Origine non autorisée pour ce compte (voir la liste des origines dans le tableau de bord).
404 Aucun calendrier configuré pour ce compte, ou ressource introuvable.
409 Ce créneau vient d'être pris par quelqu'un d'autre, revalidez la disponibilité et réessayez.
402 Le forfait du compte a atteint sa limite (réservations, calendriers ou sites) ; le corps inclut limitType et plan.
429 Trop de requêtes ; la limite est appliquée par clé API, pas par adresse IP.

Tout autre langage

Pas de kit officiel pour Ruby, Go, PHP, etc., l'API REST elle-même suffit, avec n'importe quel client HTTP :

curl "https://api.crenoapp.com/v1/public/availability?from=2026-08-01&to=2026-08-07" \
  -H "X-API-Key: pk_live_..."

curl -X POST "https://api.crenoapp.com/v1/public/bookings" \
  -H "X-API-Key: pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"startAt":"2026-08-03T13:00:00.000Z","customerName":"Jane Doe","customerEmail":"jane@example.com"}'

Sous le capot

  • Une vraie vue de calendrier mensuel, pas une simple liste : choisissez une date, puis une heure.
  • Horaires récurrents : hebdomadaires, aux deux semaines, ou selon des motifs comme « le 3e mardi du mois ».
  • Les doubles réservations sont bloquées au niveau de la base de données, testées sous une charge concurrente réelle.
  • Menus de services optionnels. Un sélecteur n'apparaît que lorsqu'il y a vraiment un choix à faire.