CrenoSync

Développeurs · Version 1.0.0

Référence

Chaque point d’accès, champ et code d’erreur, générés à partir du contrat OpenAPI. Le guide explique comment ils s’assemblent.

← Retour à l’accueil

Adresses

  • Productionhttps://{business}.crenosync.ca/api/v1
  • Préproduction (essais)https://{business}.staging.crenosync.ca/api/v1

À propos des exemples : leurs identifiants, dates, clés et jetons sont des illustrations ; utilisez ceux de votre entreprise, et des dates à partir d’aujourd’hui. Les réponses d’exemple sont en anglais, comme le demande Accept-Language: en ; avec fr, les noms, les textes et les messages arrivent en français.

Entreprise

L’entreprise elle-même et ses politiques.

GET/site

L’entreprise

L’identité publique de l’entreprise, ses langues, sa devise, son fuseau horaire et ce que ses réservations peuvent demander.

Identifiants clé publiable ou clé secrète

Paramètres

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Exemple de requête

HTTP
HTTPGET /api/v1/site
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
Accept-Language: en

Réponses

  • 200

    Site

    L’entreprise.

    Exemple Une entreprise dont l’acompte se paie en ligne.

    JSON
    JSON{
        "name": "Évasion Alpha",
        "logo_url": "https://alpha.crenosync.ca/media/logo.png",
        "address": "1234 Saint-Denis St., Montréal, QC H2X 3K1",
        "phone": "514 555-0100",
        "website_url": "https://www.example.ca",
        "booking_url": "https://alpha.crenosync.ca/en/book",
        "languages": [
            "fr",
            "en"
        ],
        "default_language": "fr",
        "currency": "CAD",
        "timezone": "America/Toronto",
        "capabilities": {
            "online_payment": "deposit",
            "email_verification": false,
            "promo_codes": true,
            "shared_sessions": false
        }
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

  • 503

    Error

    business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

    En-têtes Retry-After

    Voir ses exemples

GET/policies

Les politiques en vigueur

La politique de confidentialité et les conditions générales en vigueur, dans la langue demandée, avec les identifiants de version qu’une commande doit renvoyer pour indiquer les textes acceptés par le visiteur. Affichez les deux textes (ou un lien vers eux) à côté des cases d’acceptation.

Identifiants clé publiable ou clé secrète

Paramètres

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Exemple de requête

HTTP
HTTPGET /api/v1/policies
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
Accept-Language: en

Réponses

  • 200

    Policies

    Les politiques.

    Exemple Les deux textes, abrégés ici.

    JSON
    JSON{
        "privacy": {
            "version_id": 3,
            "title": "Privacy policy",
            "html": "<h2>1. Introduction</h2><p>Évasion Alpha collects…</p>",
            "url": "https://alpha.crenosync.ca/en/privacy-policy",
            "published_at": "2026-10-19T15:56:55-04:00"
        },
        "terms": {
            "version_id": 2,
            "title": "Terms and conditions",
            "html": "<p>Arrive 15 minutes before your game…</p>",
            "url": null,
            "published_at": "2026-10-19T15:56:55-04:00"
        }
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

  • 503

    Error

    business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

    En-têtes Retry-After

    Voir ses exemples

Activités

Ce qui peut être réservé, et quand.

GET/activities

Lister les activités

Les activités ouvertes à la réservation, dans l’ordre d’affichage de l’entreprise.

Identifiants clé publiable ou clé secrète

Paramètres

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Exemple de requête

HTTP
HTTPGET /api/v1/activities
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
Accept-Language: en

Réponses

  • 200

    object

    Les activités.

    data liste de Activity obligatoire
    has_more boolean obligatoire

    Toujours false en v1 ; réservé à la pagination.

    Exemple Les activités de l’entreprise, une seule montrée ici.

    JSON
    JSON{
        "data": [
            {
                "id": "act_7Kq2mX9pLr",
                "slug": "labo-perdu",
                "name": "The Lost Lab",
                "description": "A lab abandoned overnight, an experiment still running. Find the antidote before the doors seal.",
                "theme": "Science",
                "highlights": null,
                "rules": "Arrive 15 minutes early.",
                "image_url": "https://alpha.crenosync.ca/media/rooms/labo-perdu.jpg",
                "display_order": 1,
                "duration_minutes": 60,
                "group": {
                    "min": 2,
                    "max": 6,
                    "recommended": "3-5"
                },
                "mode": "private",
                "shared": null,
                "difficulty": {
                    "levels": [
                        {
                            "level": 0,
                            "name": "Easy",
                            "success_rate": null
                        },
                        {
                            "level": 1,
                            "name": "Classic",
                            "success_rate": 62.5
                        }
                    ]
                },
                "success_rate": 62.5,
                "minimum_age": 8,
                "price_categories": [
                    {
                        "id": "cat_Rt6yU1oP3aSd",
                        "name": "Adults",
                        "age_min": 16,
                        "age_max": null,
                        "price": {
                            "amount": 3000,
                            "currency": "CAD"
                        },
                        "counts_toward_group": true,
                        "must_be_accompanied": false,
                        "can_accompany": true,
                        "min_per_booking": null,
                        "max_per_booking": null
                    },
                    {
                        "id": "cat_Wq3eR5tY7uIo",
                        "name": "Youths",
                        "age_min": 8,
                        "age_max": 15,
                        "price": {
                            "amount": 2200,
                            "currency": "CAD"
                        },
                        "counts_toward_group": true,
                        "must_be_accompanied": true,
                        "can_accompany": false,
                        "min_per_booking": null,
                        "max_per_booking": null
                    }
                ],
                "from_price": {
                    "amount": 2200,
                    "currency": "CAD"
                },
                "online_payment": "deposit",
                "deposit": {
                    "amount": {
                        "amount": 2000,
                        "currency": "CAD"
                    },
                    "per_person": false
                },
                "no_show_fee": null,
                "resources": [
                    {
                        "id": "res_Zp4xN7cB2qLe",
                        "type": "room",
                        "name": "The Lost Lab"
                    }
                ],
                "booking_url": "https://alpha.crenosync.ca/en/book?roomId=labo-perdu"
            }
        ],
        "has_more": false
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

  • 503

    Error

    business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

    En-têtes Retry-After

    Voir ses exemples

GET/activities/{activity_id}

Lire une activité

Identifiants clé publiable ou clé secrète

Paramètres

activity_id string obligatoire chemin

Exemple act_7Kq2mX9pLr

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Exemple de requête

HTTP
HTTPGET /api/v1/activities/act_7Kq2mX9pLr
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
Accept-Language: en

Réponses

  • 200

    Activity

    L’activité.

    Exemple Une salle privée à deux niveaux de difficulté, avec acompte.

    JSON
    JSON{
        "id": "act_7Kq2mX9pLr",
        "slug": "labo-perdu",
        "name": "The Lost Lab",
        "description": "A lab abandoned overnight, an experiment still running. Find the antidote before the doors seal.",
        "theme": "Science",
        "highlights": null,
        "rules": "Arrive 15 minutes early.",
        "image_url": "https://alpha.crenosync.ca/media/rooms/labo-perdu.jpg",
        "display_order": 1,
        "duration_minutes": 60,
        "group": {
            "min": 2,
            "max": 6,
            "recommended": "3-5"
        },
        "mode": "private",
        "shared": null,
        "difficulty": {
            "levels": [
                {
                    "level": 0,
                    "name": "Easy",
                    "success_rate": null
                },
                {
                    "level": 1,
                    "name": "Classic",
                    "success_rate": 62.5
                }
            ]
        },
        "success_rate": 62.5,
        "minimum_age": 8,
        "price_categories": [
            {
                "id": "cat_Rt6yU1oP3aSd",
                "name": "Adults",
                "age_min": 16,
                "age_max": null,
                "price": {
                    "amount": 3000,
                    "currency": "CAD"
                },
                "counts_toward_group": true,
                "must_be_accompanied": false,
                "can_accompany": true,
                "min_per_booking": null,
                "max_per_booking": null
            },
            {
                "id": "cat_Wq3eR5tY7uIo",
                "name": "Youths",
                "age_min": 8,
                "age_max": 15,
                "price": {
                    "amount": 2200,
                    "currency": "CAD"
                },
                "counts_toward_group": true,
                "must_be_accompanied": true,
                "can_accompany": false,
                "min_per_booking": null,
                "max_per_booking": null
            }
        ],
        "from_price": {
            "amount": 2200,
            "currency": "CAD"
        },
        "online_payment": "deposit",
        "deposit": {
            "amount": {
                "amount": 2000,
                "currency": "CAD"
            },
            "per_person": false
        },
        "no_show_fee": null,
        "resources": [
            {
                "id": "res_Zp4xN7cB2qLe",
                "type": "room",
                "name": "The Lost Lab"
            }
        ],
        "booking_url": "https://alpha.crenosync.ca/en/book?roomId=labo-perdu"
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

  • 503

    Error

    business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

    En-têtes Retry-After

    Voir ses exemples

GET/activities/{activity_id}/availability

Heures libres

Les jours et les heures qu’un groupe peut réserver, entre deux dates (31 jours au plus, à partir d’aujourd’hui). Une heure est listée seulement si elle est à venir, ni réservée ni retenue et, pour une activité partagée, s’il lui reste assez de places pour le groupe.

Demandez-les quand le visiteur ouvre le calendrier ou change la date ou la taille du groupe, pas à intervalles réguliers.

Identifiants clé publiable ou clé secrète

Paramètres

activity_id string obligatoire chemin

Exemple act_7Kq2mX9pLr

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

from string (date) obligatoire requête

Premier jour, date locale. Aujourd’hui ou plus tard.

Exemple 2026-11-14

to string (date) obligatoire requête

Dernier jour, date locale, inclus. Au plus 30 jours après from.

Exemple 2026-11-15

group_size integer requête

Les personnes qui comptent dans la taille du groupe (voir PriceCategory.counts_toward_group). Par défaut, le group.min de l’activité. Elle doit être comprise entre le group.min et le group.max de l’activité ; sinon la réponse est 422 validation_failed avec fields.group_size, puisqu’aucune heure ne pourrait être réservée pour ce groupe.

de 1 à 1000

Exemple 4

Exemple de requête

HTTP
HTTPGET /api/v1/activities/act_7Kq2mX9pLr/availability?from=2026-11-14&to=2026-11-15&group_size=4
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
Accept-Language: en

Réponses

  • 200

    Availability

    Les jours et les heures libres.

    Exemple Deux jours d’heures libres pour un groupe de 4.

    JSON
    JSON{
        "activity_id": "act_7Kq2mX9pLr",
        "from": "2026-11-14",
        "to": "2026-11-15",
        "group_size": 4,
        "timezone": "America/Toronto",
        "days": [
            {
                "date": "2026-11-14",
                "times": [
                    {
                        "time": "17:00",
                        "starts_at": "2026-11-14T17:00:00-05:00",
                        "places_left": null,
                        "still_needed": null,
                        "booking_url": "https://alpha.crenosync.ca/en/booking/widget?room=labo-perdu&date=2026-11-14&time=17%3A00&players=4"
                    },
                    {
                        "time": "19:30",
                        "starts_at": "2026-11-14T19:30:00-05:00",
                        "places_left": null,
                        "still_needed": null,
                        "booking_url": "https://alpha.crenosync.ca/en/booking/widget?room=labo-perdu&date=2026-11-14&time=19%3A30&players=4"
                    }
                ]
            },
            {
                "date": "2026-11-15",
                "times": [
                    {
                        "time": "13:00",
                        "starts_at": "2026-11-15T13:00:00-05:00",
                        "places_left": null,
                        "still_needed": null,
                        "booking_url": "https://alpha.crenosync.ca/en/booking/widget?room=labo-perdu&date=2026-11-15&time=13%3A00&players=4"
                    }
                ]
            }
        ]
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 422

    Error

    validation_failed, avec les messages de chaque champ dans error.fields ; ou une règle de réservation : group_invalid, difficulty_required, category_not_offered, promo_code_invalid, quote_hold_mismatch, return_url_not_allowed, verification_failed (avec error.attempts_left).

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

  • 503

    Error

    business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

    En-têtes Retry-After

    Voir ses exemples

Réservation

Sessions de réservation, soumissions, retenues et commandes.

POST/booking-sessions

Ouvrir une session de réservation

Un jeton d’invité pour la tentative de réservation d’un visiteur. Créez-le quand le visiteur commence à réserver (pas au chargement de la page), gardez-le pour ce visiteur seulement, et envoyez-le comme CrenoSync-Guest-Token avec chaque soumission, retenue et commande. Il dure 60 minutes. Une intégration côté serveur en crée un par visiteur elle aussi : les limites d’heures retenues s’appliquent par jeton d’invité, et à toutes les clés de l’entreprise ensemble (une deuxième clé ne donne pas plus de marge).

Identifiants clé publiable ou clé secrète

Exemple de requête

HTTP
HTTPPOST /api/v1/booking-sessions
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…

Réponses

  • 201

    BookingSession

    La session.

    Exemple Un jeton d’invité valide 60 minutes.

    JSON
    JSON{
        "token": "cs_gt_4fG7hJ2kL9mN3pQ6rS8tV1wX",
        "expires_at": "2026-11-10T15:01:55-05:00",
        "limits": {
            "holds": 3
        }
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

  • 503

    Error

    business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

    En-têtes Retry-After

    Voir ses exemples

POST/quotes

Calculer le prix d’une réservation

Le prix exact que CrenoSync demandera pour une heure, un groupe et un code promotionnel facultatif : chaque catégorie de prix, le rabais, les taxes, le total et le montant dû maintenant. Valide 15 minutes. Une soumission ne réserve rien ; retenez l’heure ensuite.

Le groupe est vérifié selon les règles de l’activité (taille, limites de chaque catégorie, accompagnement, niveau de difficulté). Une soumission ne garantit pas la disponibilité.

Identifiants clé publiable + jeton d’invité ou clé secrète + jeton d’invité

Paramètres

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Corps de la requête

QuoteRequest

Exemple de requête

HTTP
HTTPPOST /api/v1/quotes
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
CrenoSync-Guest-Token: cs_gt_…
Accept-Language: en
Content-Type: application/json

{
    "activity_id": "act_7Kq2mX9pLr",
    "date": "2026-11-14",
    "time": "19:30",
    "participants": [
        {
            "category_id": "cat_Rt6yU1oP3aSd",
            "quantity": 4
        }
    ],
    "difficulty_level": 1,
    "promo_code": null
}

Réponses

  • 201

    Quote

    La soumission.

    Exemple Le prix, avec un acompte à payer en ligne.

    JSON
    JSON{
        "id": "quo_2Jf9TzQk4mVw",
        "expires_at": "2026-11-10T14:17:11-05:00",
        "activity_id": "act_7Kq2mX9pLr",
        "date": "2026-11-14",
        "time": "19:30",
        "starts_at": "2026-11-14T19:30:00-05:00",
        "group_size": 4,
        "difficulty": {
            "level": 1,
            "name": "Classic"
        },
        "lines": [
            {
                "category_id": "cat_Rt6yU1oP3aSd",
                "name": "Adults",
                "quantity": 4,
                "unit_price": {
                    "amount": 3000,
                    "currency": "CAD"
                },
                "amount": {
                    "amount": 12000,
                    "currency": "CAD"
                }
            }
        ],
        "subtotal": {
            "amount": 12000,
            "currency": "CAD"
        },
        "discount": null,
        "taxes": [
            {
                "name": "GST",
                "rate": 5,
                "amount": {
                    "amount": 600,
                    "currency": "CAD"
                }
            },
            {
                "name": "QST",
                "rate": 9.9749999999999996447286321199499070644378662109375,
                "amount": {
                    "amount": 1197,
                    "currency": "CAD"
                }
            }
        ],
        "total": {
            "amount": 13797,
            "currency": "CAD"
        },
        "due_now": {
            "amount": 2000,
            "currency": "CAD"
        },
        "due_later": {
            "amount": 11797,
            "currency": "CAD"
        },
        "payment": "deposit"
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 409

    Error

    La requête est valide, mais la situation ne la permet pas : time_unavailable, activity_unavailable, quote_expired, quote_changed (avec error.quote), policy_changed (avec error.policies), hold_expired, hold_in_checkout, hold_already_used, checkout_in_progress, checkout_processing, checkout_closed, verification_locked, idempotency_key_reused, idempotency_in_progress. Les deux réponses …_in_progress portent Retry-After : envoyez la même requête de nouveau après ce délai.

    En-têtes Retry-After

    Voir ses exemples

  • 422

    Error

    validation_failed, avec les messages de chaque champ dans error.fields ; ou une règle de réservation : group_invalid, difficulty_required, category_not_offered, promo_code_invalid, quote_hold_mismatch, return_url_not_allowed, verification_failed (avec error.attempts_left).

    Voir ses exemples

  • 413

    Error

    payload_too_large : le corps de la requête dépasse ce que le serveur accepte.

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

  • 503

    Error

    business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

    En-têtes Retry-After

    Voir ses exemples

POST/holds

Retenir une heure

Réserve l’heure de la soumission (ou, pour une activité partagée, les places du groupe) pour cet invité pendant que le visiteur entre ses coordonnées. La retenue dure le temps de retenue de l’entreprise (10 minutes par défaut ; voir expires_at) et n’est pas renouvelée. Ouvrir une commande qui demande un paiement la prolonge pour la durée de la fenêtre de paiement, plus 5 minutes pour la confirmation du paiement. La fenêtre de paiement dure 30 minutes, écourtée pour finir 15 minutes avant le début de l’activité, mais ne dure jamais moins de 10 minutes : pour une commande ouverte dans les 25 dernières minutes avant le début, les 10 minutes l’emportent, et sa fenêtre peut finir après le début. Une heure abandonnée près de son début est ainsi offerte de nouveau à temps pour un visiteur de dernière minute, et une commande ouverte juste avant le début peut encore être payée. Une commande payée ou confirmée par code avant la fin de sa retenue est réservée, même si l’activité vient de commencer ; une commande ne peut pas être ouverte après le début. Quand la page du fournisseur de paiement dépasse la fenêtre, elle est fermée à la fin de la fenêtre, et l’heure est offerte de nouveau une fois que le fournisseur confirme que la page est fermée. Une réponse quote_changed à une commande laisse la retenue telle quelle.

Chaque jeton d’invité peut retenir quelques heures à la fois (BookingSession.limits) ; retenir une nouvelle heure à cette limite est refusé. Libérez la retenue d’un visiteur qui abandonne.

Identifiants clé publiable + jeton d’invité ou clé secrète + jeton d’invité

Paramètres

Idempotency-Key string obligatoire en-tête

Une valeur unique par opération à faire une seule fois, par exemple un UUID. Gardée 24 heures.

de 8 à 255 caractères

Exemple 6f1c2a4e-8b3d-4e9a-9c7f-2d5b1a0e3c84

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Corps de la requête

quote_id string obligatoire

Une soumission de cet invité, non expirée.

Exemple quo_2Jf9TzQk4mVw

Exemple de requête

HTTP
HTTPPOST /api/v1/holds
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
CrenoSync-Guest-Token: cs_gt_…
Idempotency-Key: 6f1c2a4e-8b3d-4e9a-9c7f-2d5b1a0e3c84
Accept-Language: en
Content-Type: application/json

{
    "quote_id": "quo_2Jf9TzQk4mVw"
}

Réponses

  • 201

    Hold

    La retenue.

    En-têtes Idempotent-Replayed

    Exemple L’heure retenue pour 10 minutes.

    JSON
    JSON{
        "id": "hld_Vb3nP8sQw1Zx",
        "quote_id": "quo_2Jf9TzQk4mVw",
        "activity_id": "act_7Kq2mX9pLr",
        "date": "2026-11-14",
        "time": "19:30",
        "starts_at": "2026-11-14T19:30:00-05:00",
        "places": 4,
        "status": "active",
        "expires_at": "2026-11-10T14:12:30-05:00"
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 409

    Error

    La requête est valide, mais la situation ne la permet pas : time_unavailable, activity_unavailable, quote_expired, quote_changed (avec error.quote), policy_changed (avec error.policies), hold_expired, hold_in_checkout, hold_already_used, checkout_in_progress, checkout_processing, checkout_closed, verification_locked, idempotency_key_reused, idempotency_in_progress. Les deux réponses …_in_progress portent Retry-After : envoyez la même requête de nouveau après ce délai.

    En-têtes Retry-After

    Voir ses exemples

  • 422

    Error

    validation_failed, avec les messages de chaque champ dans error.fields ; ou une règle de réservation : group_invalid, difficulty_required, category_not_offered, promo_code_invalid, quote_hold_mismatch, return_url_not_allowed, verification_failed (avec error.attempts_left).

    Voir ses exemples

  • 413

    Error

    payload_too_large : le corps de la requête dépasse ce que le serveur accepte.

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

  • 503

    Error

    business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

    En-têtes Retry-After

    Voir ses exemples

DELETE/holds/{hold_id}

Libérer une retenue

Rend l’heure. Peut être répété sans risque : une retenue déjà libérée ou expirée répond 204 elle aussi. Une retenue dont la commande est en cours d’ouverture ou attend un paiement ne peut pas être libérée (409 hold_in_checkout) ; annulez plutôt la commande.

Identifiants clé publiable + jeton d’invité ou clé secrète + jeton d’invité

Paramètres

hold_id string obligatoire chemin

Exemple hld_Vb3nP8sQw1Zx

Exemple de requête

HTTP
HTTPDELETE /api/v1/holds/hld_Vb3nP8sQw1Zx
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
CrenoSync-Guest-Token: cs_gt_…

Réponses

  • 204

    Libérée.

  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 409

    Error

    La requête est valide, mais la situation ne la permet pas : time_unavailable, activity_unavailable, quote_expired, quote_changed (avec error.quote), policy_changed (avec error.policies), hold_expired, hold_in_checkout, hold_already_used, checkout_in_progress, checkout_processing, checkout_closed, verification_locked, idempotency_key_reused, idempotency_in_progress. Les deux réponses …_in_progress portent Retry-After : envoyez la même requête de nouveau après ce délai.

    En-têtes Retry-After

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

POST/checkouts

Passer la commande

Réserve l’heure retenue avec les coordonnées du visiteur et son acceptation des politiques. quote_id est la soumission que le visiteur a vue ; elle doit porter sur le choix exact de la retenue (activité, date, heure, participants, niveau de difficulté), sinon la réponse est 422 quote_hold_mismatch.

Quand le prix a changé. Le prix est recalculé. S’il diffère de celui de la soumission (un prix, un taux de taxe ou la promotion a changé, ou la soumission a expiré et son prix ne tient plus), la réponse est 409 quote_changed avec une nouvelle soumission dans error.quote, et rien n’est facturé ni réservé :

  • la retenue est gardée telle quelle : même heure, mêmes places, même expires_at ;
  • la nouvelle soumission porte sur le choix de la retenue, avec le même code promotionnel, et peut donc servir avec la même retenue ;
  • aucune utilisation de la promotion n’a été prise (une utilisation n’est prise qu’à l’ouverture d’une commande) ;
  • affichez le nouveau prix, puis envoyez la commande de nouveau avec le nouveau quote_id, le même hold_id et une nouvelle Idempotency-Key (le corps a changé).

Si le code promotionnel ne s’applique plus du tout, la réponse est 422 promo_code_invalid : demandez une nouvelle soumission sans le code (la retenue est gardée). Si la retenue a pris fin entre-temps, la réponse est 409 hold_expired : recommencez à partir des disponibilités. Si une politique a changé, la réponse est 409 policy_changed avec les textes maintenant en vigueur ; affichez-les et demandez de nouveau.

Une commande par retenue. Envoyée de nouveau pour la même retenue (une nouvelle tentative avec une nouvelle Idempotency-Key, un deuxième onglet), la réponse est la commande déjà ouverte, si rien n’a changé ; une commande avec d’autres coordonnées la remplace. Pendant qu’une autre requête ouvre encore une commande de la même retenue, la réponse est 409 checkout_in_progress avec Retry-After : envoyez la requête de nouveau après ce délai, et la commande qu’elle a ouverte vous revient. Jamais deux pages de paiement pour une retenue.

Le status de la réponse dit la suite : confirmed, awaiting_verification (code par courriel) ou awaiting_payment (envoyez le visiteur à next_action.url).

Identifiants clé publiable + jeton d’invité ou clé secrète + jeton d’invité

Paramètres

Idempotency-Key string obligatoire en-tête

Une valeur unique par opération à faire une seule fois, par exemple un UUID. Gardée 24 heures.

de 8 à 255 caractères

Exemple 6f1c2a4e-8b3d-4e9a-9c7f-2d5b1a0e3c84

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Corps de la requête

CheckoutRequest

Exemple de requête

HTTP
HTTPPOST /api/v1/checkouts
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
CrenoSync-Guest-Token: cs_gt_…
Idempotency-Key: 6f1c2a4e-8b3d-4e9a-9c7f-2d5b1a0e3c84
Accept-Language: en
Content-Type: application/json

{
    "hold_id": "hld_Vb3nP8sQw1Zx",
    "quote_id": "quo_2Jf9TzQk4mVw",
    "customer": {
        "name": "Camille Tremblay",
        "email": "camille@example.com",
        "phone": "514 555-0199",
        "language": "en"
    },
    "consent": {
        "privacy_version_id": 3,
        "privacy_accepted": true,
        "terms_version_id": 2,
        "terms_accepted": true
    },
    "return_url": "https://www.example.ca/booking/thanks",
    "attribution": {
        "source": "newsletter",
        "medium": "email",
        "campaign": "fall-2026"
    },
    "external_reference": "order-1042"
}

Réponses

  • 201

    Checkout

    La commande.

    En-têtes Idempotent-Replayed

    Exemple Un acompte est dû : envoyez le visiteur à la page de paiement.

    JSON
    JSON{
        "id": "chk_Hd5rL2kTy9Mc",
        "status": "awaiting_payment",
        "next_action": {
            "type": "redirect",
            "url": "https://alpha.crenosync.ca/en/checkout/chk_Hd5rL2kTy9Mc?expires=1794339340&signature=3f9c0e…",
            "expires_at": "2026-11-10T14:35:40-05:00"
        },
        "amount_due_now": {
            "amount": 2000,
            "currency": "CAD"
        },
        "expires_at": "2026-11-10T14:35:40-05:00",
        "booking": null,
        "created_at": "2026-11-10T14:05:40-05:00"
    }

    Exemple Rien à payer en ligne, l’entreprise demande le code envoyé par courriel.

    JSON
    JSON{
        "id": "chk_Hd5rL2kTy9Mc",
        "status": "awaiting_verification",
        "next_action": {
            "type": "verify_email",
            "url": "https://alpha.crenosync.ca/en/checkout/chk_Hd5rL2kTy9Mc?expires=1794337950&signature=8b21d4…",
            "expires_at": "2026-11-10T14:12:30-05:00",
            "email_hint": "c•••••@example.com",
            "attempts_left": 5
        },
        "amount_due_now": {
            "amount": 0,
            "currency": "CAD"
        },
        "expires_at": "2026-11-10T14:12:30-05:00",
        "booking": null,
        "created_at": "2026-11-10T14:05:40-05:00"
    }

    Exemple Rien à payer en ligne et pas de code : réservé tout de suite.

    JSON
    JSON{
        "id": "chk_Hd5rL2kTy9Mc",
        "status": "confirmed",
        "next_action": null,
        "amount_due_now": {
            "amount": 0,
            "currency": "CAD"
        },
        "expires_at": null,
        "booking": {
            "reference": "PB7K2QXA-20261114"
        },
        "created_at": "2026-11-10T14:05:40-05:00"
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 409

    Error

    La requête est valide, mais la situation ne la permet pas : time_unavailable, activity_unavailable, quote_expired, quote_changed (avec error.quote), policy_changed (avec error.policies), hold_expired, hold_in_checkout, hold_already_used, checkout_in_progress, checkout_processing, checkout_closed, verification_locked, idempotency_key_reused, idempotency_in_progress. Les deux réponses …_in_progress portent Retry-After : envoyez la même requête de nouveau après ce délai.

    En-têtes Retry-After

    Voir ses exemples

  • 422

    Error

    validation_failed, avec les messages de chaque champ dans error.fields ; ou une règle de réservation : group_invalid, difficulty_required, category_not_offered, promo_code_invalid, quote_hold_mismatch, return_url_not_allowed, verification_failed (avec error.attempts_left).

    Voir ses exemples

  • 413

    Error

    payload_too_large : le corps de la requête dépasse ce que le serveur accepte.

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

  • 503

    Error

    business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

    En-têtes Retry-After

    Voir ses exemples

GET/checkouts/{checkout_id}

Lire une commande

L’état actuel d’une commande. Après une page de CrenoSync (paiement ou code par courriel), lisez-la avec le jeton de retour reçu sur votre return_url. Tant que le statut est processing, demandez de nouveau après quelques secondes, en attendant plus longtemps chaque fois (2, 4, 8 secondes…), pendant quelques minutes au plus : le paiement est en cours de confirmation auprès du fournisseur. S’il est encore processing ensuite, indiquez au visiteur que la réservation est en cours de confirmation et qu’un courriel suivra ; ne lui demandez jamais de payer de nouveau.

Identifiants clé publiable + jeton d’invité ou clé secrète + jeton d’invité ou clé publiable + jeton de retour ou clé secrète

Paramètres

checkout_id string obligatoire chemin

Exemple chk_Hd5rL2kTy9Mc

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Exemple de requête

HTTP
HTTPGET /api/v1/checkouts/chk_Hd5rL2kTy9Mc
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
CrenoSync-Guest-Token: cs_gt_…
Accept-Language: en

Réponses

  • 200

    Checkout

    La commande.

    Exemple Réservé après le paiement.

    JSON
    JSON{
        "id": "chk_Hd5rL2kTy9Mc",
        "status": "confirmed",
        "next_action": null,
        "amount_due_now": {
            "amount": 2000,
            "currency": "CAD"
        },
        "expires_at": null,
        "booking": {
            "reference": "PB7K2QXA-20261114"
        },
        "created_at": "2026-11-10T14:05:40-05:00"
    }

    Exemple Le paiement est en cours de confirmation : relisez-le dans quelques secondes.

    JSON
    JSON{
        "id": "chk_Hd5rL2kTy9Mc",
        "status": "processing",
        "next_action": null,
        "amount_due_now": {
            "amount": 2000,
            "currency": "CAD"
        },
        "expires_at": "2026-11-10T14:35:40-05:00",
        "booking": null,
        "created_at": "2026-11-10T14:05:40-05:00"
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

POST/checkouts/{checkout_id}/verify-email

Confirmer avec le code par courriel

Pour une commande awaiting_verification : le code à 6 chiffres que CrenoSync a envoyé par courriel au visiteur. Le bon code confirme la réservation. Cinq mauvais codes annulent la commande et libèrent l’heure (409 verification_locked). Le code fonctionne jusqu’à la fin de la retenue.

Identifiants clé publiable + jeton d’invité ou clé secrète + jeton d’invité

Paramètres

checkout_id string obligatoire chemin

Exemple chk_Hd5rL2kTy9Mc

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Corps de la requête

code string obligatoire

motif ^[0-9]{6}$

Exemple 482913

Exemple de requête

HTTP
HTTPPOST /api/v1/checkouts/chk_Hd5rL2kTy9Mc/verify-email
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
CrenoSync-Guest-Token: cs_gt_…
Accept-Language: en
Content-Type: application/json

{
    "code": "482913"
}

Réponses

  • 200

    Checkout

    La réservation est confirmée.

    Exemple Le bon code : réservé.

    JSON
    JSON{
        "id": "chk_Hd5rL2kTy9Mc",
        "status": "confirmed",
        "next_action": null,
        "amount_due_now": {
            "amount": 0,
            "currency": "CAD"
        },
        "expires_at": null,
        "booking": {
            "reference": "PB7K2QXA-20261114"
        },
        "created_at": "2026-11-10T14:05:40-05:00"
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 409

    Error

    La requête est valide, mais la situation ne la permet pas : time_unavailable, activity_unavailable, quote_expired, quote_changed (avec error.quote), policy_changed (avec error.policies), hold_expired, hold_in_checkout, hold_already_used, checkout_in_progress, checkout_processing, checkout_closed, verification_locked, idempotency_key_reused, idempotency_in_progress. Les deux réponses …_in_progress portent Retry-After : envoyez la même requête de nouveau après ce délai.

    En-têtes Retry-After

    Voir ses exemples

  • 422

    Error

    validation_failed, avec les messages de chaque champ dans error.fields ; ou une règle de réservation : group_invalid, difficulty_required, category_not_offered, promo_code_invalid, quote_hold_mismatch, return_url_not_allowed, verification_failed (avec error.attempts_left).

    Voir ses exemples

  • 413

    Error

    payload_too_large : le corps de la requête dépasse ce que le serveur accepte.

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

POST/checkouts/{checkout_id}/resend-code

Envoyer le code de nouveau

Trois codes par commande au plus, un par minute.

Identifiants clé publiable + jeton d’invité ou clé secrète + jeton d’invité

Paramètres

checkout_id string obligatoire chemin

Exemple chk_Hd5rL2kTy9Mc

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Exemple de requête

HTTP
HTTPPOST /api/v1/checkouts/chk_Hd5rL2kTy9Mc/resend-code
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
CrenoSync-Guest-Token: cs_gt_…
Accept-Language: en

Réponses

  • 202

    Checkout

    Un nouveau code a été envoyé.

    Exemple Un nouveau code est en route.

    JSON
    JSON{
        "id": "chk_Hd5rL2kTy9Mc",
        "status": "awaiting_verification",
        "next_action": {
            "type": "verify_email",
            "url": "https://alpha.crenosync.ca/en/checkout/chk_Hd5rL2kTy9Mc?expires=1794337950&signature=8b21d4…",
            "expires_at": "2026-11-10T14:12:30-05:00",
            "email_hint": "c•••••@example.com",
            "attempts_left": 5
        },
        "amount_due_now": {
            "amount": 0,
            "currency": "CAD"
        },
        "expires_at": "2026-11-10T14:12:30-05:00",
        "booking": null,
        "created_at": "2026-11-10T14:05:40-05:00"
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 409

    Error

    La requête est valide, mais la situation ne la permet pas : time_unavailable, activity_unavailable, quote_expired, quote_changed (avec error.quote), policy_changed (avec error.policies), hold_expired, hold_in_checkout, hold_already_used, checkout_in_progress, checkout_processing, checkout_closed, verification_locked, idempotency_key_reused, idempotency_in_progress. Les deux réponses …_in_progress portent Retry-After : envoyez la même requête de nouveau après ce délai.

    En-têtes Retry-After

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

  • 503

    Error

    business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

    En-têtes Retry-After

    Voir ses exemples

POST/checkouts/{checkout_id}/cancel

Annuler une commande

Le visiteur a abandonné avant la confirmation de la réservation : la commande prend fin, et son heure et son utilisation de promotion sont libérées. Peut être répété sans risque. Une commande dont le paiement est peut-être déjà en cours ne peut pas être annulée ainsi (409 checkout_processing) : CrenoSync finit d’abord de la vérifier auprès du fournisseur de paiement.

Identifiants clé publiable + jeton d’invité ou clé secrète + jeton d’invité

Paramètres

checkout_id string obligatoire chemin

Exemple chk_Hd5rL2kTy9Mc

Exemple de requête

HTTP
HTTPPOST /api/v1/checkouts/chk_Hd5rL2kTy9Mc/cancel
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
CrenoSync-Guest-Token: cs_gt_…

Réponses

  • 200

    Checkout

    La commande annulée.

    Exemple Abandonné : l’heure est de nouveau libre.

    JSON
    JSON{
        "id": "chk_Hd5rL2kTy9Mc",
        "status": "cancelled",
        "next_action": null,
        "amount_due_now": {
            "amount": 0,
            "currency": "CAD"
        },
        "expires_at": null,
        "booking": null,
        "created_at": "2026-11-10T14:05:40-05:00"
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 409

    Error

    La requête est valide, mais la situation ne la permet pas : time_unavailable, activity_unavailable, quote_expired, quote_changed (avec error.quote), policy_changed (avec error.policies), hold_expired, hold_in_checkout, hold_already_used, checkout_in_progress, checkout_processing, checkout_closed, verification_locked, idempotency_key_reused, idempotency_in_progress. Les deux réponses …_in_progress portent Retry-After : envoyez la même requête de nouveau après ce délai.

    En-têtes Retry-After

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

Réservations

Les réservations confirmées.

GET/bookings/{reference}

Lire une réservation

Une réservation confirmée faite par cette API. Un jeton d’invité ou un jeton de retour lit seulement la réservation de sa propre commande ; une clé secrète lit seulement les réservations faites avec cette clé. Il n’y a pas de recherche par nom, courriel ou téléphone.

Identifiants clé publiable + jeton d’invité ou clé secrète + jeton d’invité ou clé publiable + jeton de retour ou clé secrète

Paramètres

reference string obligatoire chemin

Le numéro de réservation.

Exemple PB7K2QXA-20261114

Accept-Language string en-tête

fr ou en. Par défaut : la langue par défaut de l’entreprise.

Valeurs fr en

Exemple de requête

HTTP
HTTPGET /api/v1/bookings/PB7K2QXA-20261114
Host: alpha.crenosync.ca
Authorization: Bearer cs_pk_…
CrenoSync-Guest-Token: cs_gt_…
Accept-Language: en

Réponses

  • 200

    Booking

    La réservation.

    Exemple Une réservation dont l’acompte est payé.

    JSON
    JSON{
        "reference": "PB7K2QXA-20261114",
        "status": "confirmed",
        "activity": {
            "id": "act_7Kq2mX9pLr",
            "name": "The Lost Lab"
        },
        "date": "2026-11-14",
        "time": "19:30",
        "starts_at": "2026-11-14T19:30:00-05:00",
        "group_size": 4,
        "difficulty": {
            "level": 1,
            "name": "Classic"
        },
        "lines": [
            {
                "name": "Adults",
                "quantity": 4,
                "amount": {
                    "amount": 12000,
                    "currency": "CAD"
                }
            }
        ],
        "price": {
            "subtotal": {
                "amount": 12000,
                "currency": "CAD"
            },
            "discount": null,
            "taxes": [
                {
                    "name": "GST",
                    "amount": {
                        "amount": 600,
                        "currency": "CAD"
                    }
                },
                {
                    "name": "QST",
                    "amount": {
                        "amount": 1197,
                        "currency": "CAD"
                    }
                }
            ],
            "total": {
                "amount": 13797,
                "currency": "CAD"
            }
        },
        "paid": {
            "amount": 2000,
            "currency": "CAD"
        },
        "balance": {
            "amount": 11797,
            "currency": "CAD"
        },
        "customer": {
            "name": "Camille Tremblay",
            "email": "camille@example.com",
            "phone": "514 555-0199",
            "language": "en"
        },
        "confirmation_url": "https://alpha.crenosync.ca/en/booking/confirmation?booking_number=PB7K2QXA-20261114&token=Gl22GGQx…",
        "channel": {
            "type": "api",
            "key_name": "Our website"
        },
        "attribution": {
            "source": "newsletter",
            "medium": "email",
            "campaign": "fall-2026"
        },
        "external_reference": "order-1042",
        "created_at": "2026-11-10T14:05:40-05:00"
    }
  • 401

    Error

    missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

    Voir ses exemples

  • 403

    Error

    not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

    Voir ses exemples

  • 404

    Error

    not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

    Voir ses exemples

  • 429

    Error

    rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

    En-têtes Retry-After

    Voir ses exemples

  • 500

    Error

    internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

    Voir ses exemples

Réponses d’erreur

Les réponses que plusieurs points d’accès ont en commun, surtout des refus, chacune avec des exemples. Toutes les erreurs ont la même forme : testez leur code, jamais leur message.

401 Unauthenticated

missing_key, invalid_key (aussi pour la clé d’une autre entreprise : une clé n’existe que sur l’adresse de sa propre entreprise), key_revoked, missing_guest_token, invalid_guest_token (inconnu, ou fait avec une autre clé), guest_token_expired, invalid_return_token (inconnu, fait avec une autre clé, remplacé par un plus récent, ou après ses 30 minutes). Trop de clés refusées d’une même adresse en une minute répondent 429 rate_limited pendant un moment, même avec une clé valide.

Exemple Une clé que l’entreprise ne connaît pas.

JSON
JSON{
    "error": {
        "code": "invalid_key",
        "message": "This API key is not valid for this business.",
        "request_id": "req_01JBQ7Z5K3W8"
    }
}

403 Forbidden

not_in_plan (le forfait de l’entreprise ne comprend pas l’API), integration_disabled, origin_not_allowed, secret_key_in_browser, not_allowed (cette clé ou ce jeton ne permet pas cela).

Exemple Une page Web d’un site qui n’est pas inscrit avec la clé.

JSON
JSON{
    "error": {
        "code": "origin_not_allowed",
        "message": "This website is not registered with this API key.",
        "request_id": "req_01JBQ7Z5K3W8"
    }
}

404 NotFound

not_found : aucun tel enregistrement pour cette clé ou ce jeton. Ceux d’un autre invité, d’une autre clé ou d’une autre entreprise répondent de la même façon.

Exemple Rien avec cet identifiant pour cette clé ou ce jeton.

JSON
JSON{
    "error": {
        "code": "not_found",
        "message": "Not found.",
        "request_id": "req_01JBQ7Z5K3W8"
    }
}

409 Conflict

La requête est valide, mais la situation ne la permet pas : time_unavailable, activity_unavailable, quote_expired, quote_changed (avec error.quote), policy_changed (avec error.policies), hold_expired, hold_in_checkout, hold_already_used, checkout_in_progress, checkout_processing, checkout_closed, verification_locked, idempotency_key_reused, idempotency_in_progress. Les deux réponses …_in_progress portent Retry-After : envoyez la même requête de nouveau après ce délai.

Exemple L’heure a été prise entre-temps : choisissez-en une autre.

JSON
JSON{
    "error": {
        "code": "time_unavailable",
        "message": "This time slot is no longer available.",
        "request_id": "req_01JBQ7Z5K3W8"
    }
}

Exemple Le prix a changé (paiement) : montrez le nouveau prix, puis passez au paiement avec lui.

JSON
JSON{
    "error": {
        "code": "quote_changed",
        "message": "The price changed since this quote. Show the new quote, then check out with it.",
        "request_id": "req_01JBQ7Z5K3W8",
        "quote": {
            "id": "quo_8Nc3Vx6Bm1Qa",
            "expires_at": "2026-11-10T14:20:40-05:00",
            "activity_id": "act_7Kq2mX9pLr",
            "date": "2026-11-14",
            "time": "19:30",
            "starts_at": "2026-11-14T19:30:00-05:00",
            "group_size": 4,
            "difficulty": {
                "level": 1,
                "name": "Classic"
            },
            "lines": [
                {
                    "category_id": "cat_Rt6yU1oP3aSd",
                    "name": "Adults",
                    "quantity": 4,
                    "unit_price": {
                        "amount": 3000,
                        "currency": "CAD"
                    },
                    "amount": {
                        "amount": 12000,
                        "currency": "CAD"
                    }
                }
            ],
            "subtotal": {
                "amount": 12000,
                "currency": "CAD"
            },
            "discount": null,
            "taxes": [
                {
                    "name": "GST",
                    "rate": 5,
                    "amount": {
                        "amount": 600,
                        "currency": "CAD"
                    }
                },
                {
                    "name": "QST",
                    "rate": 9.9749999999999996447286321199499070644378662109375,
                    "amount": {
                        "amount": 1197,
                        "currency": "CAD"
                    }
                }
            ],
            "total": {
                "amount": 13797,
                "currency": "CAD"
            },
            "due_now": {
                "amount": 2000,
                "currency": "CAD"
            },
            "due_later": {
                "amount": 11797,
                "currency": "CAD"
            },
            "payment": "deposit"
        }
    }
}

Exemple Le paiement de la même retenue est en cours de démarrage : attendez le délai Retry-After, puis renvoyez-le.

JSON
JSON{
    "error": {
        "code": "checkout_in_progress",
        "message": "A checkout for this time is already being started. Wait a moment, then try again.",
        "request_id": "req_01JBQ7Z5K3W8"
    }
}

422 ValidationFailed

validation_failed, avec les messages de chaque champ dans error.fields ; ou une règle de réservation : group_invalid, difficulty_required, category_not_offered, promo_code_invalid, quote_hold_mismatch, return_url_not_allowed, verification_failed (avec error.attempts_left).

Exemple Les champs à corriger, chacun avec ses messages.

JSON
JSON{
    "error": {
        "code": "validation_failed",
        "message": "The data sent is not valid.",
        "request_id": "req_01JBQ7Z5K3W8",
        "fields": {
            "customer.email": [
                "The email address is not valid."
            ],
            "time": [
                "The time field is required."
            ]
        }
    }
}

Exemple Un mauvais code, à la vérification du code envoyé par courriel.

JSON
JSON{
    "error": {
        "code": "verification_failed",
        "message": "This code is not right. Check the latest email we sent and try again.",
        "request_id": "req_01JBQ7Z5K3W8",
        "attempts_left": 4
    }
}

429 RateLimited

rate_limited, too_many_holds, business_busy, too_many_codes. Attendez le délai de Retry-After. Une page peut lire ces réponses depuis n’importe quel site Web. Une adresse au-delà de sa limite reçoit aussi 429 aux requêtes préalables (preflight) des navigateurs, qui les signalent comme une erreur réseau : attendez avant de réessayer.

Exemple Trop de requêtes : attendez le délai Retry-After.

JSON
JSON{
    "error": {
        "code": "rate_limited",
        "message": "Too many requests. Please try again later.",
        "request_id": "req_01JBQ7Z5K3W8"
    }
}

503 Unavailable

business_unavailable (suspendue, en maintenance ou encore en configuration), payment_unavailable, email_unavailable.

Exemple L’entreprise est en maintenance.

JSON
JSON{
    "error": {
        "code": "business_unavailable",
        "message": "This site is under maintenance. Please try again in a few minutes.",
        "request_id": "req_01JBQ7Z5K3W8"
    }
}

413 PayloadTooLarge

payload_too_large : le corps de la requête dépasse ce que le serveur accepte.

Exemple Un corps de requête au-delà de la limite.

JSON
JSON{
    "error": {
        "code": "payload_too_large",
        "message": "The request is too large.",
        "request_id": "req_01JBQ7Z5K3W8"
    }
}

500 InternalError

internal_error : une défaillance du côté de CrenoSync. Donnez le request_id en écrivant au soutien.

Exemple Une panne du côté de CrenoSync : citez le request_id.

JSON
JSON{
    "error": {
        "code": "internal_error",
        "message": "Something went wrong on our side. Please try again later.",
        "request_id": "req_01JBQ7Z5K3W8"
    }
}

Objets

Error object

error object obligatoire
error.code string obligatoire

Stable, pour les programmes. De nouveaux codes peuvent s’ajouter.

Exemple time_unavailable

error.message string obligatoire

Pour les personnes, dans la langue de la requête. Peut changer ; ne le testez jamais.

Exemple This time slot is no longer available.

error.request_id string obligatoire
error.fields object

Pour validation_failed, chaque champ invalide (chemin avec des points) et ses messages.

Exemple {"customer.email":["The email address is not valid."]}

error.attempts_left integer

Pour verification_failed.

error.quote Quote

Pour quote_changed, la nouvelle soumission, pour le même choix de la retenue et le même code promotionnel.

error.policies Policies

Pour policy_changed, les textes maintenant en vigueur.

Money object

amount integer obligatoire

Dans la plus petite unité de la devise (les cents).

Exemple 4250

currency string obligatoire

ISO 4217.

Exemple CAD

LocalizedText string | null

Du texte simple dans la langue de la requête (sauts de ligne gardés, sans HTML), ou null s’il est vide.

Site object

name string obligatoire

Exemple Évasion Alpha

logo_url string | null (uri)
address string | null
phone string | null
website_url string (uri)

Le site CrenoSync hébergé de l’entreprise.

booking_url string (uri) obligatoire

La page de réservation hébergée, comme lien de secours.

languages liste de string obligatoire

Liste ouverte.

Valeurs · liste ouverte fr en

default_language string obligatoire

Liste ouverte.

Valeurs · liste ouverte fr en

currency string obligatoire

Exemple CAD

timezone string obligatoire

Le fuseau horaire IANA de toutes les dates et heures locales.

Exemple America/Toronto

capabilities object obligatoire
capabilities.online_payment string obligatoire

none : tout se paie sur place. deposit : les activités peuvent demander un dépôt en ligne. full : les activités demandent le prix complet en ligne. guarantee : les activités enregistrent la carte du visiteur en garantie contre l’absence, sans rien payer en ligne. mixed : cela dépend de l’activité (son online_payment).

Valeurs · liste ouverte none deposit full guarantee mixed

capabilities.email_verification boolean obligatoire

Les réservations sans rien à payer en ligne sont confirmées par un code envoyé par courriel.

capabilities.promo_codes boolean obligatoire
capabilities.shared_sessions boolean obligatoire

Certaines activités permettent à plusieurs groupes de partager une séance.

Policies object

privacy Policy | null obligatoire

Null seulement tant que l’entreprise n’en a publié aucune.

terms Policy | null obligatoire

Null quand l’entreprise n’a pas de conditions générales.

Policy object

version_id integer obligatoire

Exemple 3

title string obligatoire
html string obligatoire

Du HTML nettoyé (titres, paragraphes, listes, liens, mise en évidence).

url string | null (uri)

Le même texte sur le site hébergé, quand il a sa propre page (la politique de confidentialité en a une ; les conditions sont affichées à la réservation).

published_at string (date-time) obligatoire

Activity object

id string obligatoire

Exemple act_7Kq2mX9pLr

slug string obligatoire

Lisible, pour vos propres adresses. Peut changer ; conservez id.

Exemple labo-perdu

name string obligatoire

Exemple Le Labo Perdu

description LocalizedText
highlights LocalizedText
image_url string | null (uri)
display_order integer
duration_minutes integer obligatoire

La durée de l’activité.

Exemple 60

group object obligatoire

Compte seulement les personnes des catégories qui comptent dans le groupe.

group.min integer obligatoire

Exemple 2

group.max integer | null obligatoire

Exemple 6

group.recommended string | null

Exemple 3-5

mode string obligatoire

private : un groupe par heure. shared : plusieurs groupes partagent une séance, jusqu’à ses places. Liste ouverte.

Valeurs · liste ouverte private shared

shared object | null

Pour une activité partagée.

shared.places_per_session integer

Exemple 12

shared.min_to_play integer | null

Les personnes dont la séance a besoin pour avoir lieu ; en dessous, l’entreprise peut annuler la séance.

difficulty object | null

Présent quand le visiteur doit choisir un niveau.

difficulty.levels liste de object obligatoire
difficulty.levels[].level integer obligatoire

Exemple 0

difficulty.levels[].name string obligatoire

Exemple Facile

difficulty.levels[].success_rate number | null

Exemple 62.5

success_rate number | null

L’unique taux de réussite de l’activité, quand elle n’a pas de niveaux.

minimum_age integer | null
price_categories liste de PriceCategory obligatoire
from_price Money | null

Le plus bas prix non nul par personne, avant taxes.

online_payment string obligatoire

Ce que la réservation demande de payer en ligne : none, deposit (voir deposit), full, le prix complet, taxes comprises, une fois la promotion déduite, ou guarantee : rien n’est payé, la carte du visiteur est enregistrée pour les frais d’absence (voir no_show_fee).

Valeurs · liste ouverte none deposit full guarantee

deposit object | null

Le dépôt dû en ligne, avant toute promotion ; null quand aucun dépôt ne se paie en ligne (rien, ou le prix complet).

deposit.amount Money
deposit.per_person boolean
no_show_fee object | null

Les frais d’absence d’une activité qui enregistre la carte du visiteur (online_payment: guarantee), d’au plus amount (par personne si per_person), facturés seulement si personne ne vient ou si la réservation est annulée moins de free_cancellation_hours heures avant son début ; null sinon.

no_show_fee.amount Money
no_show_fee.per_person boolean
no_show_fee.free_cancellation_hours integer
resources liste de Resource obligatoire

Ce qui est réservé pour l’activité. En v1, une salle. Plus tard, des personnes comme des entraîneurs.

booking_url string (uri) obligatoire

Cette activité sur la page de réservation hébergée.

PriceCategory object

id string obligatoire

Exemple cat_Rt6yU1oP3aSd

name string obligatoire

Exemple Adulte

age_min integer | null
age_max integer | null
price Money obligatoire

Par personne, avant taxes.

counts_toward_group boolean obligatoire

Si ces personnes comptent dans la taille du groupe et les places (un bébé peut ne pas compter).

must_be_accompanied boolean obligatoire
can_accompany boolean obligatoire
min_per_booking integer | null
max_per_booking integer | null

Resource object

id string obligatoire

Exemple res_Zp4xN7cB2qLe

type string obligatoire

Liste ouverte. room en v1 ; de nouveaux types comme person s’ajouteront. Affichez un type inconnu par son name.

Valeurs · liste ouverte room

name string obligatoire

Availability object

activity_id string obligatoire
from string (date) obligatoire
to string (date) obligatoire
group_size integer obligatoire
timezone string obligatoire

Exemple America/Toronto

days liste de object obligatoire

Seulement les jours qui ont au moins une heure libre.

days[].date string (date) obligatoire

Exemple 2026-11-14

days[].times liste de OpenTime obligatoire

OpenTime object

time string obligatoire

Exemple 19:30

starts_at string (date-time) obligatoire

Exemple 2026-11-14T19:30:00-05:00

places_left integer | null

Pour une séance partagée, les places encore libres ; null pour une heure privée.

still_needed integer | null

Pour une séance partagée avec un minimum, les personnes qu’il lui faut encore pour avoir lieu.

booking_url string (uri) obligatoire

Cette heure sur la page de réservation hébergée, pour les sites qui confient la réservation à CrenoSync.

BookingSession object

token string obligatoire

Exemple cs_gt_4fG7hJ2kL9mN3pQ6rS8tV1wX

expires_at string (date-time) obligatoire
limits object obligatoire
limits.holds integer obligatoire

Les heures que cette session peut retenir à la fois.

Exemple 3

ParticipantInput object

category_id string obligatoire
quantity integer obligatoire

de 0 à 1000

QuoteRequest object

activity_id string obligatoire
date string (date) obligatoire
time string obligatoire

motif ^([01][0-9]|2[0-3]):[0-5][0-9]$

Exemple 19:30

participants liste de ParticipantInput obligatoire

de 1 à 50 éléments

difficulty_level integer | null

Obligatoire quand l’activité a difficulty.

promo_code string | null

au plus 64 caractères

Quote object

id string obligatoire

Exemple quo_2Jf9TzQk4mVw

expires_at string (date-time) obligatoire
activity_id string obligatoire
date string (date) obligatoire
time string obligatoire
starts_at string (date-time) obligatoire
group_size integer obligatoire
difficulty object | null
difficulty.level integer
difficulty.name string
lines liste de object obligatoire
lines[].category_id string obligatoire
lines[].name string obligatoire
lines[].quantity integer obligatoire
lines[].unit_price Money obligatoire
lines[].amount Money obligatoire
subtotal Money obligatoire
discount object | null
discount.code string
discount.label string
discount.amount Money
taxes liste de object obligatoire
taxes[].name string obligatoire

Exemple TPS

taxes[].rate number obligatoire

En pourcentage.

Exemple 5

taxes[].amount Money obligatoire
total Money obligatoire
due_now Money obligatoire

Payé en ligne à la commande (le dépôt, ou le prix complet), possiblement 0.

due_later Money obligatoire

Payé sur place.

payment string obligatoire

Ce que la commande demande de payer en ligne : none, deposit, full, le prix complet, ou guarantee, rien de payé mais la carte du visiteur enregistrée pour les frais d’absence. Toute valeur autre que none envoie le visiteur à la page de paiement.

Valeurs · liste ouverte none deposit full guarantee

Hold object

id string obligatoire

Exemple hld_Vb3nP8sQw1Zx

quote_id string obligatoire
activity_id string obligatoire
date string (date) obligatoire
time string obligatoire
starts_at string (date-time) obligatoire
places integer obligatoire

Pour une séance partagée, les places retenues ; pour une heure privée, la taille du groupe.

status string obligatoire

Liste ouverte.

Valeurs · liste ouverte active in_checkout used released expired

expires_at string (date-time) obligatoire

Customer object

name string obligatoire

au plus 255 caractères

Exemple Camille Tremblay

email string (email) obligatoire

au plus 255 caractères

phone string obligatoire

au plus 30 caractères

Exemple 514 555-0199

language string

La langue des courriels envoyés au client ; par défaut, la langue de la requête.

Valeurs fr en

CheckoutRequest object

hold_id string obligatoire
quote_id string obligatoire

La soumission montrée au visiteur, pour le choix exact de la retenue. Après quote_changed, l’identifiant de la nouvelle soumission.

customer Customer obligatoire
notes string | null

au plus 5000 caractères

attribution Attribution | null

D’où vient le visiteur, pour les rapports de l’entreprise. Facultatif.

external_reference string | null

Votre propre référence pour cette réservation (un numéro de commande dans votre système), rendue avec la réservation. Son unicité n’est pas vérifiée. N’y mettez jamais de renseignements personnels.

au plus 100 caractères

motif ^[A-Za-z0-9._:/#-]{1,100}$

consent object obligatoire

Les versions montrées au visiteur (par GET /policies) et son acceptation explicite.

consent.privacy_version_id integer obligatoire
consent.privacy_accepted boolean obligatoire

Valeurs true

consent.terms_version_id integer | null

Obligatoire quand l’entreprise a des conditions.

consent.terms_accepted boolean | null

Obligatoire (true) quand l’entreprise a des conditions.

consent.no_show_fee_accepted boolean | null

Obligatoire (true) quand le payment de la soumission est guarantee : le visiteur a accepté les frais d’absence de l’activité (no_show_fee).

return_url string | null (uri)

Obligatoire quand le payment de la soumission n’est pas none ; facultatif sinon. L’adresse où le visiteur revient après une page de CrenoSync de next_action.url (paiement, code par courriel) ; CrenoSync ajoute checkout_id et return_token après # (https://www.example.ca/merci#checkout_id=chk_…&return_token=cs_rt_…), en gardant sa propre chaîne de requête. Sans elle, cette page se termine sur la confirmation hébergée.

L’adresse est analysée, jamais comparée comme du texte, et doit correspondre à l’une des adresses de retour inscrites avec la clé (sinon 422 return_url_not_allowed) :

  • https seulement ; http est accepté seulement pour un hôte de développement local (localhost, 127.0.0.1, *.localhost, *.test), et jamais en production ;
  • le schéma, l’hôte et le port sont exactement ceux de l’adresse inscrite (pas de joker, pas de sous-domaine) ;
  • le chemin est celui de l’adresse inscrite, ou continue sous lui après un / (/booking inscrite permet /booking/done, jamais /booking-done) ;
  • pas de nom d’utilisateur ni de mot de passe, et pas de fragment (#…).

Les navigateurs n’envoient jamais la partie après # à votre serveur, à ses journaux ou à un autre site. Lisez-la dans le script de la page, puis retirez-la de l’adresse (history.replaceState) avant que tout outil de statistiques ou autre script externe ne s’exécute.

au plus 2048 caractères

Checkout object

id string obligatoire

Exemple chk_Hd5rL2kTy9Mc

status string obligatoire

Liste ouverte : traitez un statut inconnu comme pas encore confirmé, et relisez-le plus tard.

  • awaiting_verification : attend le code envoyé par courriel.
  • awaiting_payment : attend le visiteur sur la page de paiement.
  • processing : le paiement est en cours de confirmation auprès du fournisseur.
  • confirmed : réservée ; voir booking.
  • expired : le temps est écoulé avant le code ou le paiement.
  • cancelled : abandonnée, ou trop de mauvais codes.
  • attention_required : payée, mais la réservation n’a pas pu se faire automatiquement. L’entreprise a été avertie et communiquera avec le client. Ne lui demandez jamais de payer de nouveau.

Valeurs · liste ouverte awaiting_verification awaiting_payment processing confirmed expired cancelled attention_required

next_action NextAction | null

Ce que le visiteur doit faire ensuite pour cette commande, ou null.

amount_due_now Money obligatoire
expires_at string | null (date-time)

Quand une commande en attente prend fin : la fin de la fenêtre de paiement (30 minutes, écourtée pour finir 15 minutes avant le début, mais jamais moins de 10 minutes, si bien qu’elle peut finir après le début pour une commande ouverte dans les 25 dernières minutes), ou de la retenue pour un code par courriel. Payée ou confirmée d’ici là, elle est réservée.

booking BookingSummary | null

Une fois confirmed.

created_at string (date-time) obligatoire

NextAction object

Une étape que le visiteur doit franchir pour cette commande. Chaque action, quel que soit son type, a une url : la page de CrenoSync où le visiteur franchit cette étape pour cette même commande. La page se termine sur votre return_url, ou sur la confirmation hébergée quand la commande n’en a pas.

Traitez à votre façon les types que vous connaissez. Pour un type inconnu, envoyez le visiteur à url. Ne l’envoyez jamais à booking_url et ne recommencez pas de soumission ni de retenue : cette commande retient déjà l’heure, et un paiement est peut-être déjà en cours.

type string obligatoire

Liste ouverte.

  • verify_email : demandez le code à 6 chiffres envoyé par courriel au visiteur et envoyez-le avec POST /checkouts/{id}/verify-email, ou envoyez le visiteur à url pour le taper sur la page de CrenoSync.
  • redirect : envoyez le visiteur à url, la page de paiement de CrenoSync.

Valeurs · liste ouverte verify_email redirect

url string (uri) obligatoire

La page de CrenoSync pour cette étape, sur l’adresse propre à l’entreprise. Ouvrez-la dans toute la fenêtre, jamais dans un cadre. C’est un lien signé pour cette commande seulement, valide jusqu’à expires_at : ne le conservez pas, ne le partagez pas, ne l’inscrivez dans aucun journal. Le premier navigateur qui l’ouvre et charge la page garde la commande et y franchit l’étape (il peut recharger, et y revient après le paiement) ; l’adresse perd aussitôt sa signature. Un autre navigateur qui ouvre le même lien est alors refusé : envoyez-le donc seulement au navigateur du visiteur lui-même.

Exemple https://alpha.crenosync.ca/fr/checkout/chk_Hd5rL2kTy9Mc?expires=1794339340&signature=3f9c…

expires_at string (date-time) obligatoire

Le moment où l’étape ne peut plus être franchie (la fin de la retenue ou de la fenêtre de paiement ; voir Checkout.expires_at).

Exemple 2026-11-10T14:35:40-05:00

email_hint string

Pour verify_email, l’adresse où le code est allé, en partie masquée.

Exemple c•••••@gmail.com

attempts_left integer

Pour verify_email, les mauvais codes encore permis.

Exemple 5

BookingSummary object

reference string obligatoire

Exemple PB7K2QXA-20261114

Booking object

reference string obligatoire

Exemple PB7K2QXA-20261114

status string obligatoire

Liste ouverte.

Valeurs · liste ouverte confirmed cancelled

activity object obligatoire
activity.id string obligatoire
activity.name string obligatoire
date string (date) obligatoire
time string obligatoire
starts_at string (date-time) obligatoire
group_size integer obligatoire
difficulty object | null
difficulty.level integer
difficulty.name string
lines liste de object obligatoire
lines[].name string obligatoire
lines[].quantity integer obligatoire
lines[].amount Money obligatoire
price object obligatoire
price.subtotal Money obligatoire
price.discount Money | null
price.taxes liste de object obligatoire
price.taxes[].name string obligatoire
price.taxes[].amount Money obligatoire
price.total Money obligatoire
paid Money obligatoire
balance Money obligatoire

Ce qui reste à payer sur place.

customer object

Avec un jeton d’invité ou la clé secrète : name, email, phone et language. Avec un jeton de retour : name, email_hint et language seulement.

customer.name string
customer.email string
customer.email_hint string

Le courriel, masqué, par exemple c••••••@example.com (lectures avec un jeton de retour).

customer.phone string
customer.language string

Liste ouverte.

Valeurs · liste ouverte fr en

confirmation_url string | null (uri)

La page de confirmation du client sur le site hébergé (lien privé). Null pour une lecture avec le jeton de retour.

channel object

Comment la réservation a été faite, selon CrenoSync.

channel.type string obligatoire

api pour chaque réservation que ce point d’accès rend. Liste ouverte (voir les conventions).

Valeurs · liste ouverte api

channel.key_name string | null

Le nom que le propriétaire a donné à la clé dans Paramètres › API.

attribution Attribution | null
external_reference string | null
created_at string (date-time) obligatoire

Attribution object

Les renseignements de campagne, comme dans utm_source, utm_medium et utm_campaign. Chaque valeur compte au plus 100 caractères parmi les lettres, les chiffres, les espaces et ._-+:/. N’y mettez jamais de renseignements personnels.

source string | null

au plus 100 caractères

motif ^[\p{L}\p{N} ._\-+:/]{1,100}$

Exemple facebook

medium string | null

au plus 100 caractères

motif ^[\p{L}\p{N} ._\-+:/]{1,100}$

Exemple social

campaign string | null

au plus 100 caractères

motif ^[\p{L}\p{N} ._\-+:/]{1,100}$

Exemple halloween-2026