Okkre
PlanningLe point de départ opérationnel du clubRéservationsDu créneau disponible à la réservation directeSite du clubUne expérience publique toujours à jour
Okkre ConnectLes connexions utiles au clubDécouvrir →
Clubs fondateursTarifs
DocumentationBien démarrer avec OkkreBlogLes actualités et réflexions OkkreNouveautésSuivre les évolutions du produit
À proposLa vision derrière OkkreDécouvrir →
FAQ
FonctionnalitésPlanningLe point de départ opérationnel du clubRéservationsDu créneau disponible à la réservation directeSite du clubUne expérience publique toujours à jourOkkre ConnectLes connexions utiles au club
Clubs fondateursTarifs
RessourcesDocumentationBien démarrer avec OkkreBlogLes actualités et réflexions OkkreNouveautésSuivre les évolutions du produitÀ proposLa vision derrière Okkre
FAQConnexion
  • Découvrir Okkre / Discover Okkre
  • Planning / Schedule
  • Réservations / Bookings
  • Site du club / Club website
  • API publique / Public API
  • Intégration IA / AI integration
Documentation Retour
Okkre

Fonctionnalités

  • Planning
  • Réservations
  • Site du club
  • Okkre Connect

Produit

  • Tarifs
  • À propos
  • Clubs fondateurs
  • Contact

Ressources

  • Documentation
  • Contact
  • Blog
  • Nouveautés

Informations légales

  • Confidentialité
  • CGU
  • Politique de cookies
© Okkre 2026Pensé pour garder les yeux sur le terrain

Intégration IA / AI integration

Guide API pour assistants IA (anglais) / API integration guide for AI assistants (English).

Guide original en anglais à transmettre à votre assistant IA. Original guide in English to share with your AI assistant.

Télécharger le Markdown / Download Markdown

Use this file when an LLM must generate code that integrates a club website with the Okkre public API.

Core Contract

Base URL:

/api/v1/clubs/{clubId}

Authentication:

Authorization: Bearer <api_key>

Every request needs both values: {clubId} in the URL identifies the club and the API key authorizes the request. The key must belong to that club.

Scopes:

  • read: read courts, availability, API-created reservations.
  • book: all read permissions plus create/cancel reservations.

Never expose a book key in browser code. Prefer server-side calls.

Endpoints

MethodPathScopePurpose
GET/courtsreadList active courts.
GET/availability?from=YYYY-MM-DD&to=YYYY-MM-DD&sport=padel&court_id=...readList available slots using the club's configured duration and price.
POST/reservationsbookCreate an idempotent reservation.
GET/reservations/{externalId}readRead one API-created reservation.
DELETE/reservations/{externalId}bookCancel one API-created reservation.
POST/reservations/{externalId}/cancelbookCancel one API-created reservation.

Data Shapes

Court response:

{
  "courts": [
    {
      "id": "uuid",
      "name": "Terrain 1",
      "sport": "padel",
      "environment": "indoor",
      "display_order": 1
    }
  ]
}

Availability response:

{
  "availability": [
    {
      "court": "Terrain 1",
      "date": "2026-09-12",
      "start_time": "18:00",
      "end_time": "20:00",
      "price_cents": 2400
    }
  ]
}

Create reservation request:

{
  "external_id": "site-order-123",
  "court": "Terrain 1",
  "date": "2026-09-12",
  "start_time": "18:00",
  "end_time": "19:30",
  "person": {
    "first_name": "Ada",
    "last_name": "Lovelace",
    "email": "ada@example.com"
  },
  "notes": "Optional"
}

Create/read/cancel reservation response:

{
  "reservation": {
    "id": "uuid",
    "external_id": "site-order-123",
    "court_id": "uuid",
    "starts_at": "2026-09-12T16:00:00.000Z",
    "ends_at": "2026-09-12T17:30:00.000Z",
    "price_cents": 2400,
    "status": "confirmed",
    "cancellation_reason": null
  },
  "idempotent_replay": false
}

GET /reservations/{externalId} returns the same reservation object without idempotent_replay.

Error shape:

{
  "error": {
    "code": "slot_unavailable",
    "message": "Ce terrain est deja occupe sur ce creneau."
  }
}

Validation Rules

  • from, to, date: YYYY-MM-DD.
  • Availability range: 31 days maximum.
  • Times: HH:MM, 24-hour format.
  • Reservation start must be on the hour or half-hour.
  • Reservation duration must be positive and a multiple of 30 minutes.
  • court: readable court name is preferred; UUID also works.
  • person.email or person.phone is required.
  • person.email: basic email format.
  • person.phone: 6 to 30 characters.
  • person.first_name and person.last_name: required, max 80 characters each.
  • notes: optional, truncated to 500 characters.
  • Cancellation reason: optional, truncated to 300 characters.

Integration Algorithm

  1. On page load, call GET /courts or directly call GET /availability.
  2. Show availability slots to the user. Slots are returned in local club date and time fields, with price_cents for the complete configured slot. Send the returned start and end times unchanged when booking.
  3. When the user confirms, call POST /reservations from the backend with a stable external_id.
  4. If response is 201 or 200 with idempotent_replay: true, treat the reservation as created.
  5. If response is 409 and error.code is slot_unavailable, refresh availability and ask the user to choose another slot.
  6. To cancel, call either DELETE /reservations/{externalId} or POST /reservations/{externalId}/cancel.

TypeScript Helper

type OkkreReservationInput = {
  external_id: string;
  court: string;
  date: string;
  start_time: string;
  end_time: string;
  person: {
    first_name: string;
    last_name: string;
    email?: string;
    phone?: string;
  };
  notes?: string;
};

async function okkreFetch<T>(
  baseUrl: string,
  apiKey: string,
  path: string,
  init: RequestInit = {},
): Promise<T> {
  const response = await fetch(`${baseUrl}${path}`, {
    ...init,
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
      ...init.headers,
    },
  });

  const data = await response.json().catch(() => null);
  if (!response.ok) {
    const code = data?.error?.code ?? "unknown_error";
    const message = data?.error?.message ?? `Okkre API error ${response.status}`;
    throw new Error(`${code}: ${message}`);
  }
  return data as T;
}

export async function createOkkreReservation(
  baseUrl: string,
  apiKey: string,
  input: OkkreReservationInput,
) {
  return okkreFetch(baseUrl, apiKey, "/reservations", {
    method: "POST",
    body: JSON.stringify(input),
  });
}

Common Error Handling

  • missing_api_key, invalid_authorization_header, api_key_not_found, api_key_revoked: ask the admin to check the API key.
  • api_key_wrong_club: check the {clubId} in the URL.
  • insufficient_scope: use a book key for create/cancel.
  • validation_error: fix request fields.
  • invalid_period: fix availability date range.
  • reservation_not_found: unknown or non-API reservation.
  • slot_unavailable: refresh availability and retry with another slot.