Deux parcours, un seul backend. Prenez notre widget, ou construisez votre propre interface sur la même API. Choisissez celui qui convient à votre stack.
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).
Nous affichons l'interface de réservation, vous n'avez qu'à l'insérer.
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é | 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. |
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é | 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. |
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.
| 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 ». |
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 |
C'est vous qui affichez. Nous restons le backend et l'infrastructure.
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
}
} 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",
) 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.
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_... https://api.crenoapp.com 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 }
] 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" }
]
} 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.
| Point de terminaison | Limites de requêtes |
|---|---|
| POST /v1/public/bookings | 5 / minute |
| GET /v1/public/service-types, /v1/public/availability | 60 / minute |
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. |
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"}'