{"openapi":"3.1.0","info":{"title":"Organzia API","version":"1.0.0","description":"API mobile pour Organzia. Authentification via Sanctum + cl\u00e9 application optionnelle."},"servers":[{"url":"https:\/\/organzia.be\/api","description":"API principale"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Sanctum token"},"appKey":{"type":"apiKey","in":"header","name":"X-Organzia-App-Key","description":"Cl\u00e9 d\u2019application optionnelle configur\u00e9e c\u00f4t\u00e9 backend."}}},"security":[{"bearerAuth":[],"appKey":[]}],"paths":{"\/login":{"post":{"summary":"Connexion utilisateur","description":"Authentifie un membre, un admin ou un coach et retourne un token Sanctum par session\/appareil.","security":[],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"user":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"Acc\u00e8s interdit"}},"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"},"device_name":{"type":"string","description":"Nom de l\u2019appareil ou de la session."}},"required":["email","password","device_name"]}}}}}},"\/me":{"get":{"summary":"Utilisateur courant","description":"Retourne le compte connect\u00e9.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"user":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/my-clubs":{"get":{"summary":"Mes clubs","description":"Retourne les clubs actuellement accessibles au compte authentifi\u00e9. Utilisez public_id dans l\u2019en-t\u00eate X-Organzia-Club-Id pour s\u00e9lectionner le contexte actif.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"public_id":{"type":"string"},"name":{"type":"string"},"logo_url":{"type":"string","format":"uri","nullable":true},"role":{"type":"string"},"member_id":{"type":"integer","nullable":true},"is_default":{"type":"boolean"}}}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/logout":{"post":{"summary":"D\u00e9connexion","description":"R\u00e9voque le token courant.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":[]}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/profile":{"get":{"summary":"Profil","description":"Retourne le profil actif dans le club s\u00e9lectionn\u00e9, la famille r\u00e9elle du membre actif et la liste des clubs accessibles au compte.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","description":"Membre actif dans le club s\u00e9lectionn\u00e9, ou compte utilisateur si aucun membre n\u2019est li\u00e9.","properties":{"id":{"type":"integer"},"tenant_id":{"type":"integer","nullable":true},"family_id":{"type":"integer","nullable":true},"family_name":{"type":"string","nullable":true},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"full_name":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email","nullable":true},"phone":{"type":"string","nullable":true},"birth_date":{"type":"string","format":"date","nullable":true},"status":{"type":"string","nullable":true},"member_type":{"type":"string","nullable":true},"profile_photo_path":{"type":"string","nullable":true},"profile_photo_url":{"type":"string","format":"uri","nullable":true},"photo_url":{"type":"string","format":"uri","nullable":true},"avatar_url":{"type":"string","format":"uri","nullable":true},"calendar_feed_url":{"type":"string","format":"uri","nullable":true,"description":"URL ICS priv\u00e9e \u00e0 ajouter dans Google Calendar ou un autre agenda."},"family":{"type":"object","nullable":true,"description":"Famille r\u00e9elle du membre actif dans le club s\u00e9lectionn\u00e9. Les membres sont filtr\u00e9s par tenant et par autorisation du compte.","properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true},"members":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"member_id":{"type":"integer"},"public_id":{"type":"string","nullable":true},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"full_name":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email","nullable":true},"phone":{"type":"string","nullable":true},"birth_date":{"type":"string","format":"date","nullable":true},"profile_photo_path":{"type":"string","nullable":true},"profile_photo_url":{"type":"string","format":"uri","nullable":true},"photo_url":{"type":"string","format":"uri","nullable":true},"avatar_url":{"type":"string","format":"uri","nullable":true},"family_id":{"type":"integer","nullable":true},"family_name":{"type":"string","nullable":true},"relationship":{"type":"string","enum":["self","child","parent","guardian","spouse","member","other"],"description":"self pour le membre actif, sinon valeur d\u00e9riv\u00e9e du type de membre familial."}}}}}},"user":{"type":"object","description":"Compte utilisateur li\u00e9 au profil actif, utile pour les applications qui distinguent compte et fiche membre.","properties":{"id":{"type":"integer"},"tenant_id":{"type":"integer","nullable":true},"member_id":{"type":"integer","nullable":true},"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email","nullable":true},"phone":{"type":"string","nullable":true},"locale":{"type":"string","nullable":true},"timezone":{"type":"string","nullable":true},"profile_photo_path":{"type":"string","nullable":true},"profile_photo_url":{"type":"string","format":"uri","nullable":true},"photo_url":{"type":"string","format":"uri","nullable":true},"avatar_url":{"type":"string","format":"uri","nullable":true}}}}},"clubs":{"type":"array","description":"Clubs accessibles au compte. Utiliser public_id dans X-Organzia-Club-Id pour changer de contexte.","items":{"type":"object","properties":{"id":{"type":"integer"},"public_id":{"type":"string"},"name":{"type":"string"},"logo_url":{"type":"string","format":"uri","nullable":true},"role":{"type":"string"},"member_id":{"type":"integer","nullable":true},"is_default":{"type":"boolean"}}}}}},"example":{"data":{"id":48,"first_name":"Jonathan","last_name":"Hamende","full_name":"Jonathan Hamende","name":"Jonathan Hamende","email":"jonathan@example.com","phone":"+32...","birth_date":"1992-01-01","profile_photo_path":"member-photos\/jonathan.webp","profile_photo_url":"https:\/\/organzia.be\/storage\/member-photos\/jonathan.webp","photo_url":"https:\/\/organzia.be\/storage\/member-photos\/jonathan.webp","avatar_url":"https:\/\/organzia.be\/storage\/member-photos\/jonathan.webp","calendar_feed_url":"https:\/\/organzia.be\/calendar\/loc_...ics","family_id":211,"family_name":"Hamende","family":{"id":211,"name":"Hamende","members":[{"id":48,"member_id":48,"public_id":"member_xxx","first_name":"Jonathan","last_name":"Hamende","full_name":"Jonathan Hamende","name":"Jonathan Hamende","email":"jonathan@example.com","phone":"+32...","birth_date":"1992-01-01","profile_photo_path":"member-photos\/jonathan.webp","profile_photo_url":"https:\/\/organzia.be\/storage\/member-photos\/jonathan.webp","photo_url":"https:\/\/organzia.be\/storage\/member-photos\/jonathan.webp","avatar_url":"https:\/\/organzia.be\/storage\/member-photos\/jonathan.webp","family_id":211,"family_name":"Hamende","relationship":"self"},{"id":52,"member_id":52,"public_id":"member_yyy","first_name":"Leana","last_name":"Hamende Radulovic","full_name":"Leana Hamende Radulovic","name":"Leana Hamende Radulovic","email":null,"phone":null,"birth_date":"2014-01-01","profile_photo_path":null,"profile_photo_url":null,"photo_url":null,"avatar_url":null,"family_id":211,"family_name":"Hamende","relationship":"child"}]},"user":{"id":12,"tenant_id":1,"member_id":48,"name":"Jonathan Hamende","email":"jonathan@example.com","phone":"+32...","locale":"fr","timezone":"Europe\/Brussels","profile_photo_path":"member-photos\/jonathan.webp","profile_photo_url":"https:\/\/organzia.be\/storage\/member-photos\/jonathan.webp","photo_url":"https:\/\/organzia.be\/storage\/member-photos\/jonathan.webp","avatar_url":"https:\/\/organzia.be\/storage\/member-photos\/jonathan.webp"}},"clubs":[{"id":1,"public_id":"club_x7f9...","name":"Boxer Free Fight Team","logo_url":"https:\/\/organzia.be\/storage\/association-logos\/logo.webp","role":"member","member_id":48,"is_default":true}]}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/planning":{"get":{"summary":"Planning","description":"Retourne les sessions de cours \u00e0 venir.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"club_id":{"type":"integer","nullable":true},"club_name":{"type":"string","nullable":true},"club_public_slug":{"type":"string","nullable":true},"course_session_id":{"type":"integer"},"course_id":{"type":"integer"},"course_image_url":{"type":"string","format":"uri","nullable":true},"course_name":{"type":"string","nullable":true},"min_age":{"type":"integer","nullable":true,"minimum":0},"max_age":{"type":"integer","nullable":true,"minimum":0},"minimum_age":{"type":"integer","nullable":true,"minimum":0},"maximum_age":{"type":"integer","nullable":true,"minimum":0},"age_min":{"type":"integer","nullable":true,"minimum":0},"age_max":{"type":"integer","nullable":true,"minimum":0},"age_from":{"type":"integer","nullable":true,"minimum":0},"age_to":{"type":"integer","nullable":true,"minimum":0},"course_public_slug":{"type":"string","nullable":true},"start_at":{"type":"string","format":"date-time"},"end_at":{"type":"string","format":"date-time"},"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"courseLocation":{"type":"object","nullable":true,"properties":{"id":{"type":"integer","nullable":true},"name":{"type":"string","nullable":true},"address_line":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"country":{"type":"string","nullable":true}}},"member_names":{"type":"array","items":{"type":"string"}}}}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/courses":{"get":{"summary":"Cours","description":"Retourne les cours, leurs horaires, leur image et leurs coachs.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"image_url":{"type":"string","format":"uri","nullable":true},"min_age":{"type":"integer","nullable":true,"minimum":0},"max_age":{"type":"integer","nullable":true,"minimum":0},"minimum_age":{"type":"integer","nullable":true,"minimum":0},"maximum_age":{"type":"integer","nullable":true,"minimum":0},"age_min":{"type":"integer","nullable":true,"minimum":0},"age_max":{"type":"integer","nullable":true,"minimum":0},"age_from":{"type":"integer","nullable":true,"minimum":0},"age_to":{"type":"integer","nullable":true,"minimum":0},"price_options":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"period":{"type":"string","enum":["season","half_season","quarter","month"]},"label":{"type":"string"},"duration_months":{"type":"integer","nullable":true},"amount_cents":{"type":"integer"},"discounts_enabled":{"type":"boolean"}}}},"coaches":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"public_id":{"type":"string","nullable":true},"public_slug":{"type":"string","nullable":true},"full_name":{"type":"string"},"photo_url":{"type":"string","format":"uri","nullable":true}}}}}}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/fees":{"get":{"summary":"Cotisations","description":"Retourne les cotisations du membre connect\u00e9 avec le membre, le club, le montant et le statut.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"member_name":{"type":"string","nullable":true},"course_name":{"type":"string","nullable":true},"club_name":{"type":"string","nullable":true},"organization_name":{"type":"string","nullable":true},"club_public_slug":{"type":"string","nullable":true},"course_image_url":{"type":"string","format":"uri","nullable":true},"club_logo_url":{"type":"string","format":"uri","nullable":true},"amount_due_cents":{"type":"integer"},"amount_due_label":{"type":"string"},"status":{"type":"string"},"status_label":{"type":"string"},"currency":{"type":"string","nullable":true},"amount_paid_cents":{"type":"integer"},"balance_due_cents":{"type":"integer"},"receipt_available":{"type":"boolean"},"receipt_download_url":{"type":"string","format":"uri","nullable":true}}}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/events":{"get":{"summary":"\u00c9v\u00e9nements","description":"Retourne les \u00e9v\u00e9nements disponibles.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/notifications":{"get":{"summary":"Notifications","description":"Retourne les notifications du compte.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/members":{"get":{"summary":"Membres","description":"Retourne les membres du club actif. La r\u00e9ponse est pagin\u00e9e. Utilisez per_page jusqu\u2019\u00e0 250 et parcourez les pages lorsque le club contient davantage de membres.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"tenant_id":{"type":"integer","nullable":true},"family_id":{"type":"integer","nullable":true},"family_name":{"type":"string","nullable":true},"family":{"type":"object","nullable":true,"properties":{"id":{"type":"integer"},"name":{"type":"string","nullable":true}}},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email","nullable":true},"phone":{"type":"string","nullable":true},"status":{"type":"string","nullable":true},"member_type":{"type":"string","nullable":true},"profile_photo_path":{"type":"string","nullable":true},"profile_photo_url":{"type":"string","format":"uri","nullable":true},"photo_url":{"type":"string","format":"uri","nullable":true},"avatar_url":{"type":"string","format":"uri","nullable":true}}}},"links":{"type":"object"},"meta":{"type":"object","properties":{"current_page":{"type":"integer"},"last_page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"}}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"Num\u00e9ro de page, \u00e0 partir de 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"per_page","in":"query","required":false,"description":"Nombre de membres par page. Maximum 250.","schema":{"type":"integer","minimum":1,"maximum":250,"default":250}}]}},"\/communications":{"get":{"summary":"Communications","description":"Retourne les communications r\u00e9centes.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/surveys":{"get":{"summary":"Enqu\u00eates","description":"Retourne les enqu\u00eates actives ou cl\u00f4tur\u00e9es.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/shop-products":{"get":{"summary":"Produits","description":"Retourne les produits actifs du webshop.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/attestations":{"get":{"summary":"Attestations","description":"Retourne les attestations du compte ou du membre avec course_name, club_name, season_name, member_name et download_url.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"course_name":{"type":"string"},"club_name":{"type":"string"},"season_name":{"type":"string","nullable":true},"member_name":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"download_url":{"type":"string"}}}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/attestations\/{attestation}\/download":{"get":{"summary":"T\u00e9l\u00e9charger une attestation","description":"Retourne le PDF de l\u2019attestation si elle est accessible au compte connect\u00e9.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Fichier PDF","content":{"application\/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/reports":{"get":{"summary":"Rapports","description":"Retourne les rapports disponibles pour les admins.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/family":{"post":{"summary":"Cr\u00e9er une famille","description":"Cr\u00e9e le foyer du membre connect\u00e9.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"primary_contact_name":{"type":"string"},"primary_contact_email":{"type":"string","format":"email"},"primary_contact_phone":{"type":"string"},"billing_address":{"type":"string"}},"required":["name","primary_contact_name","primary_contact_email","primary_contact_phone","billing_address"]}}}}}},"\/family\/members":{"post":{"summary":"Ajouter un membre au foyer","description":"Ajoute un enfant ou membre rattach\u00e9 au foyer courant.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"birth_date":{"type":"string","format":"date"},"national_registry_number":{"type":"string"},"address_line":{"type":"string"},"postal_code":{"type":"string"},"city":{"type":"string"},"clothing_size":{"type":"string"},"emergency_contact_name":{"type":"string"},"emergency_contact_phone":{"type":"string"}},"required":["first_name","last_name","email","phone","birth_date","national_registry_number","address_line","postal_code","city","clothing_size","emergency_contact_name","emergency_contact_phone"]}}}}}},"\/family\/members\/{member}":{"put":{"summary":"Modifier un membre du foyer","description":"Met \u00e0 jour un membre appartenant au foyer courant.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"birth_date":{"type":"string","format":"date"},"national_registry_number":{"type":"string"},"address_line":{"type":"string"},"postal_code":{"type":"string"},"city":{"type":"string"},"clothing_size":{"type":"string"},"emergency_contact_name":{"type":"string"},"emergency_contact_phone":{"type":"string"}},"required":["first_name","last_name","email","phone","birth_date","national_registry_number","address_line","postal_code","city","clothing_size","emergency_contact_name","emergency_contact_phone"]}}}}}},"\/family\/members\/link":{"post":{"summary":"Rattacher un membre existant","description":"Rattache un membre tenant au foyer courant.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"member_id":{"type":"integer"}},"required":["member_id"]}}}}}},"\/family\/members\/search":{"get":{"summary":"Recherche membre \u00e0 rattacher","description":"Recherche un membre du tenant par nom ou email. Param\u00e8tre query: q.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/cart":{"get":{"summary":"Panier inscriptions","description":"Retourne le panier de r\u00e9servations de cours du compte dans le club actif.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"member":{"type":"object"},"course":{"type":"object"},"price_option":{"type":"object","nullable":true},"quote":{"type":"object","properties":{"base_price_cents":{"type":"integer"},"discount_cents":{"type":"integer"},"final_price_cents":{"type":"integer"},"period":{"type":"string","enum":["season","half_season","quarter","month"]},"price_option_id":{"type":"integer","nullable":true},"price_option":{"type":"object","nullable":true},"total_cents":{"type":"integer"}}}}}},"subtotal_cents":{"type":"integer"},"discount_cents":{"type":"integer"},"total_cents":{"type":"integer"}}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/cart\/items":{"post":{"summary":"Ajouter au panier","description":"Ajoute un couple membre\/cours au panier.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"member_id":{"type":"integer"},"course_id":{"type":"integer"},"price_option_id":{"type":"integer","nullable":true,"description":"Formule du cours. Si absent, la formule saisonni\u00e8re est utilis\u00e9e."}},"required":["member_id","course_id","price_option_id"]}}}}},"delete":{"summary":"Retirer du panier","description":"Retire une ligne du panier par index.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"index":{"type":"integer"}},"required":["index"]}}}}}},"\/cart\/checkout":{"post":{"summary":"Valider les r\u00e9servations","description":"Valide le panier courant avec un corps vide, ou r\u00e9serve directement un couple member_id\/course_id.","security":[{"bearerAuth":[],"appKey":[]}],"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"requestBody":{"required":false,"content":{"application\/json":{"schema":{"oneOf":[{"type":"object","description":"Corps vide: valide les lignes d\u00e9j\u00e0 pr\u00e9sentes dans le panier de session.","properties":{},"additionalProperties":false},{"type":"object","description":"Inscription directe sans utiliser le panier.","properties":{"member_id":{"type":"integer"},"course_id":{"type":"integer"},"price_option_id":{"type":"integer","nullable":true}},"required":["member_id","course_id"],"additionalProperties":false}]}}}}}},"\/surveys\/{survey}\/responses":{"post":{"summary":"R\u00e9pondre \u00e0 une enqu\u00eate","description":"Enregistre les r\u00e9ponses du compte connect\u00e9.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"answers":{"type":"object"}},"required":["answers"]}}}}}},"\/events\/{event}\/registrations":{"post":{"summary":"Inscription \u00e9v\u00e9nement","description":"Inscrit un membre ou un participant externe \u00e0 un \u00e9v\u00e9nement publi\u00e9.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"member_id":{"type":"integer"},"event_ticket_id":{"type":"integer"},"event_venue_seat_id":{"type":"integer"},"attendee_name":{"type":"string"},"attendee_email":{"type":"string","format":"email"},"notes":{"type":"string"}},"required":["member_id","event_ticket_id","event_venue_seat_id","attendee_name","attendee_email","notes"]}}}}}},"\/support-tickets":{"get":{"summary":"Tickets support","description":"Liste les tickets visibles pour le compte.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]},"post":{"summary":"Cr\u00e9er un ticket support","description":"Cr\u00e9e une demande de support.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"subject":{"type":"string"},"description":{"type":"string"},"category":{"type":"string","enum":["bug","question","request","billing","other"]},"priority":{"type":"string","enum":["low","normal","high","urgent"]}},"required":["subject","description","category","priority"]}}}}}},"\/support-tickets\/{supportTicket}":{"get":{"summary":"D\u00e9tail ticket support","description":"Retourne un ticket et ses r\u00e9ponses.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/support-tickets\/{supportTicket}\/replies":{"post":{"summary":"R\u00e9pondre \u00e0 un ticket","description":"Ajoute une r\u00e9ponse visible au ticket.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"body":{"type":"string"}},"required":["body"]}}}}}},"\/fees\/{fee}\/pay":{"post":{"summary":"Paiement cotisation","description":"Cr\u00e9e un checkout en ligne pour une cotisation accessible au foyer.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"checkout_url":{"type":"string","format":"uri"}}}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/fees\/{fee}\/receipt":{"get":{"summary":"Re\u00e7u de cotisation","description":"Retourne le PDF du re\u00e7u avec les ristournes, les paiements re\u00e7us et le solde \u00e9ventuel.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Fichier PDF","content":{"application\/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/shop-orders\/{shopOrder}\/pay":{"post":{"summary":"Paiement commande webshop","description":"Cr\u00e9e un checkout en ligne pour une commande webshop.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/check-in\/resolve":{"post":{"summary":"R\u00e9soudre un QR de salle","description":"Identifie la salle du club actif et retourne les s\u00e9ances actuellement pointables pour les membres accessibles au compte.","security":[{"bearerAuth":[],"appKey":[]}],"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"token":{"type":"string","example":"loc_K7m42Qx9..."}},"required":["token"]}}}},"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"location":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"address_line":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"city":{"type":"string","nullable":true}}},"sessions":{"type":"array","items":{"type":"object","properties":{"course_session_id":{"type":"integer"},"course_id":{"type":"integer"},"course_name":{"type":"string","nullable":true},"course_image_url":{"type":"string","format":"uri","nullable":true},"start_at":{"type":"string","format":"date-time"},"end_at":{"type":"string","format":"date-time"},"members":{"type":"array","items":{"type":"object","properties":{"member_id":{"type":"integer"},"member_name":{"type":"string"},"already_checked_in":{"type":"boolean"},"status":{"type":"string","enum":["present","late","absent","excused"],"nullable":true},"checked_in_at":{"type":"string","format":"date-time","nullable":true}}}}}}}}},"message":{"type":"string"}}},"example":{"data":{"location":{"id":12,"name":"Salle Omnisports Saintes","address_line":"Chauss\u00e9e d\u2019Enghien 225","postal_code":"1480","city":"Tubize"},"sessions":[{"course_session_id":13576,"course_id":560,"course_name":"MMA & Self Defense","course_image_url":"https:\/\/organzia.be\/storage\/course-images\/example.webp","start_at":"2026-09-04T19:00:00+02:00","end_at":"2026-09-04T21:00:00+02:00","members":[{"member_id":48,"member_name":"Jonathan Hamende","already_checked_in":false,"status":null,"checked_in_at":null}]}]}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."},"409":{"description":"Incoh\u00e9rence m\u00e9tier: membre non accessible, non inscrit ou s\u00e9ance dans une autre salle."},"422":{"description":"Donn\u00e9es invalides ou fen\u00eatre de pointage ferm\u00e9e."},"429":{"description":"Trop de requ\u00eates."}}}},"\/check-in":{"post":{"summary":"Enregistrer un pointage QR","description":"Valide le QR, la salle, la s\u00e9ance, la fen\u00eatre de pointage, les membres accessibles et les inscriptions avant de cr\u00e9er une pr\u00e9sence present\/qr_code.","security":[{"bearerAuth":[],"appKey":[]}],"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"token":{"type":"string","example":"loc_K7m42Qx9..."},"course_session_id":{"type":"integer","example":13576},"member_ids":{"type":"array","items":{"type":"integer"},"example":[48,52]}},"required":["token","course_session_id","member_ids"]}}}},"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"course_session_id":{"type":"integer"},"course_name":{"type":"string","nullable":true},"location_name":{"type":"string"},"start_at":{"type":"string","format":"date-time"},"attendances":{"type":"array","items":{"type":"object","properties":{"member_id":{"type":"integer"},"member_name":{"type":"string","nullable":true},"status":{"type":"string","enum":["present","late","absent","excused"]},"method":{"type":"string","enum":["qr_code","manual","import"]},"checked_in_at":{"type":"string","format":"date-time","nullable":true},"already_checked_in":{"type":"boolean"}}}}}},"message":{"type":"string"}}},"example":{"data":{"course_session_id":13576,"course_name":"MMA & Self Defense","location_name":"Salle Omnisports Saintes","start_at":"2026-09-04T19:00:00+02:00","attendances":[{"member_id":48,"member_name":"Jonathan Hamende","status":"present","method":"qr_code","checked_in_at":"2026-09-04T18:52:14+02:00","already_checked_in":false}]},"message":"Pr\u00e9sence enregistr\u00e9e."}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."},"409":{"description":"Incoh\u00e9rence m\u00e9tier: membre non accessible, non inscrit ou s\u00e9ance dans une autre salle."},"422":{"description":"Donn\u00e9es invalides ou fen\u00eatre de pointage ferm\u00e9e."},"429":{"description":"Trop de requ\u00eates."}}}},"\/admin\/members":{"post":{"summary":"Admin - cr\u00e9er membre","description":"Cr\u00e9e un membre dans le tenant courant.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"birth_date":{"type":"string","format":"date"},"national_registry_number":{"type":"string"},"address_line":{"type":"string"},"postal_code":{"type":"string"},"city":{"type":"string"},"clothing_size":{"type":"string"},"emergency_contact_name":{"type":"string"},"emergency_contact_phone":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]},"member_type":{"type":"string","enum":["member","child","parent"]},"family_id":{"type":"integer"},"internal_notes":{"type":"string"}},"required":["first_name","last_name","email","phone","birth_date","national_registry_number","address_line","postal_code","city","clothing_size","emergency_contact_name","emergency_contact_phone","status","member_type","family_id","internal_notes"]}}}}}},"\/admin\/members\/{member}":{"put":{"summary":"Admin - modifier membre","description":"Met \u00e0 jour un membre du tenant courant.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"birth_date":{"type":"string","format":"date"},"national_registry_number":{"type":"string"},"address_line":{"type":"string"},"postal_code":{"type":"string"},"city":{"type":"string"},"clothing_size":{"type":"string"},"emergency_contact_name":{"type":"string"},"emergency_contact_phone":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]},"member_type":{"type":"string","enum":["member","child","parent"]},"family_id":{"type":"integer"},"internal_notes":{"type":"string"}},"required":["first_name","last_name","email","phone","birth_date","national_registry_number","address_line","postal_code","city","clothing_size","emergency_contact_name","emergency_contact_phone","status","member_type","family_id","internal_notes"]}}}}},"delete":{"summary":"Admin - supprimer membre","description":"Archive un membre du tenant courant.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":[]}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/admin\/members\/{member}\/toggle-status":{"patch":{"summary":"Admin - basculer statut membre","description":"Active ou d\u00e9sactive un membre.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/admin\/course-registrations":{"get":{"summary":"Admin - inscriptions aux cours","description":"Liste les inscriptions du club actif, avec priorit\u00e9 aux r\u00e9servations \u00e0 valider.","security":[{"bearerAuth":[],"appKey":[]}],"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["reserved","waiting_list","confirmed","cancelled"]}},{"name":"course_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"member_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"search","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"status":{"type":"string","enum":["reserved","waiting_list","confirmed","cancelled"]},"status_label":{"type":"string"},"created_at":{"type":"string","format":"date-time","nullable":true},"member":{"type":"object","nullable":true,"properties":{"id":{"type":"integer"},"public_id":{"type":"string","nullable":true},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email","nullable":true}}},"course":{"type":"object","nullable":false,"properties":{"id":{"type":"integer"},"public_id":{"type":"string","nullable":true},"public_slug":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"image_url":{"type":"string","format":"uri","nullable":true}}}}}},"meta":{"type":"object","properties":{"current_page":{"type":"integer"},"last_page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"}}}}},"example":{"data":[{"id":123,"status":"reserved","status_label":"En attente","created_at":"2026-08-13T12:00:00+00:00","member":{"id":48,"public_id":"member_xxx","first_name":"Jonathan","last_name":"Hamende","name":"Jonathan Hamende","email":"jonathan@example.test"},"course":{"id":7,"public_id":"course_xxx","public_slug":"mma-self-defense","name":"MMA & Self Defense","image_url":"https:\/\/organzia.be\/storage\/course-images\/mma.webp"}}],"meta":{"current_page":1,"last_page":1,"per_page":25,"total":1}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."},"422":{"description":"Param\u00e8tres invalides"}}},"post":{"summary":"Admin - inscrire \u00e0 un cours","description":"Inscrit un membre \u00e0 un cours.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"member_id":{"type":"integer"},"course_id":{"type":"integer"},"price_option_id":{"type":"integer","nullable":true,"description":"Formule du cours. Si absent, la formule saisonni\u00e8re est utilis\u00e9e."}},"required":["member_id","course_id","price_option_id"]}}}}}},"\/admin\/course-registrations\/{courseRegistration}\/confirm":{"patch":{"summary":"Admin - confirmer inscription","description":"Confirme une r\u00e9servation de cours et g\u00e9n\u00e8re la cotisation li\u00e9e.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/admin\/course-registrations\/{courseRegistration}":{"delete":{"summary":"Admin - supprimer inscription","description":"Supprime une inscription de cours.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":[]}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/admin\/fees":{"get":{"summary":"Admin - cotisations","description":"Liste les cotisations des membres du club actif.","security":[{"bearerAuth":[],"appKey":[]}],"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","unpaid","late","partial","paid"]}},{"name":"member_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"course_id","in":"query","required":false,"schema":{"type":"integer"}},{"name":"search","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"status":{"type":"string","enum":["pending","unpaid","late","partial","paid"]},"status_label":{"type":"string"},"amount_due_cents":{"type":"integer"},"amount_due_label":{"type":"string"},"currency":{"type":"string"},"due_at":{"type":"string","format":"date","nullable":true},"paid_at":{"type":"string","format":"date-time","nullable":true},"member":{"type":"object","nullable":true,"properties":{"id":{"type":"integer"},"public_id":{"type":"string","nullable":true},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email","nullable":true}}},"course":{"type":"object","nullable":true,"properties":{"id":{"type":"integer"},"public_id":{"type":"string","nullable":true},"public_slug":{"type":"string","nullable":true},"name":{"type":"string","nullable":true}}}}}},"meta":{"type":"object","properties":{"current_page":{"type":"integer"},"last_page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"}}}}},"example":{"data":[{"id":456,"status":"pending","status_label":"\u00c0 payer","amount_due_cents":15000,"amount_due_label":"150,00 EUR","currency":"EUR","due_at":"2026-09-01","paid_at":null,"member":{"id":48,"public_id":"member_xxx","first_name":"Jonathan","last_name":"Hamende","name":"Jonathan Hamende","email":"jonathan@example.test"},"course":{"id":7,"public_id":"course_xxx","public_slug":"mma-self-defense","name":"MMA & Self Defense"}}],"meta":{"current_page":1,"last_page":1,"per_page":25,"total":1}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."},"422":{"description":"Param\u00e8tres invalides"}}}},"\/admin\/fees\/{fee}\/paid":{"patch":{"summary":"Admin - marquer cotisation pay\u00e9e","description":"Marque une cotisation et ses \u00e9ch\u00e9ances comme pay\u00e9es.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/admin\/fees\/{fee}\/late":{"patch":{"summary":"Admin - marquer cotisation en retard","description":"Marque une cotisation comme en retard.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/admin\/course-sessions\/{courseSession}\/attendance":{"get":{"summary":"Admin\/coach - lire les pr\u00e9sences","description":"Retourne les membres inscrits \u00e0 une s\u00e9ance du club actif et leur statut de pr\u00e9sence.","security":[{"bearerAuth":[],"appKey":[]}],"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}},{"name":"courseSession","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"course_session":{"type":"object","properties":{"id":{"type":"integer"},"course_id":{"type":"integer"},"course_name":{"type":"string","nullable":true},"starts_at":{"type":"string","format":"date-time","nullable":true},"ends_at":{"type":"string","format":"date-time","nullable":true}}},"members":{"type":"array","items":{"type":"object","properties":{"member_id":{"type":"integer"},"member_name":{"type":"string"},"status":{"type":"string","enum":["present","late","absent","excused"]},"present":{"type":"boolean"},"method":{"type":"string","enum":["qr_code","manual","import"],"nullable":true},"checked_in_at":{"type":"string","format":"date-time","nullable":true},"recorded_at":{"type":"string","format":"date-time","nullable":true}}}},"trial_participants":{"type":"array","description":"Participants inscrits \u00e0 un cours d\u2019essai. Ils ne poss\u00e8dent pas encore de member_id.","items":{"type":"object","properties":{"type":{"type":"string","enum":["trial"]},"trial_registration_id":{"type":"integer"},"member_id":{"type":"integer","nullable":true},"member_name":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email","nullable":true},"birth_date":{"type":"string","format":"date","nullable":true},"status":{"type":"string","enum":["present","late","absent","excused"]},"present":{"type":"boolean"},"method":{"type":"string","enum":["manual"]},"checked_in_at":{"type":"string","format":"date-time","nullable":true},"recorded_at":{"type":"string","format":"date-time","nullable":true}}}},"participants":{"type":"array","description":"Liste unifi\u00e9e des membres et participants d\u2019essai.","items":{"type":"object","properties":{"type":{"type":"string","enum":["member","trial"]},"member_id":{"type":"integer","nullable":true},"trial_registration_id":{"type":"integer","nullable":true},"member_name":{"type":"string"},"status":{"type":"string","enum":["present","late","absent","excused"]},"present":{"type":"boolean"}}}}}}}},"example":{"data":{"course_session":{"id":789,"course_id":7,"course_name":"MMA & Self Defense","starts_at":"2026-08-14T18:00:00+02:00","ends_at":"2026-08-14T20:00:00+02:00"},"members":[{"member_id":48,"member_name":"Jonathan Hamende","status":"present","present":true,"method":"qr_code","checked_in_at":"2026-08-14T18:05:00+02:00","recorded_at":"2026-08-14T18:05:00+02:00"}],"trial_participants":[{"type":"trial","trial_registration_id":901,"member_id":null,"member_name":"Lina Martin","first_name":"Lina","last_name":"Martin","email":"lina@example.com","birth_date":null,"status":"absent","present":false,"method":"manual","checked_in_at":null,"recorded_at":"2026-08-14T17:00:00+02:00"}],"participants":[{"type":"trial","trial_registration_id":901,"member_id":null,"member_name":"Lina Martin","status":"absent","present":false}]}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."},"422":{"description":"Param\u00e8tres invalides"}}}},"\/admin\/course-locations\/{courseLocation}\/check-in":{"get":{"summary":"Admin - configuration QR de salle","description":"Retourne l\u2019URL de pointage permanent et les param\u00e8tres de fen\u00eatre de pointage.","security":[{"bearerAuth":[],"appKey":[]}],"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}},{"name":"courseLocation","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"course_location_id":{"type":"integer"},"location_name":{"type":"string"},"check_in_enabled":{"type":"boolean"},"check_in_url":{"type":"string","format":"uri"},"pdf_url":{"type":"string","format":"uri"},"print_url":{"type":"string","format":"uri"},"qr_code_url":{"type":"string","format":"uri"},"check_in_open_before_minutes":{"type":"integer"},"check_in_close_after_minutes":{"type":"integer"},"check_in_token_regenerated_at":{"type":"string","format":"date-time","nullable":true}}}}},"example":{"data":{"course_location_id":12,"location_name":"Salle Omnisports Saintes","check_in_enabled":true,"check_in_url":"https:\/\/organzia.be\/check-in\/loc_K7m42Qx9...","pdf_url":"https:\/\/organzia.be\/check-in\/loc_K7m42Qx9...\/pdf","print_url":"https:\/\/organzia.be\/check-in\/loc_K7m42Qx9...\/print","qr_code_url":"https:\/\/organzia.be\/api\/admin\/course-locations\/12\/check-in\/qr-code","check_in_open_before_minutes":30,"check_in_close_after_minutes":45,"check_in_token_regenerated_at":null}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."},"409":{"description":"Incoh\u00e9rence m\u00e9tier: membre non accessible, non inscrit ou s\u00e9ance dans une autre salle."},"422":{"description":"Donn\u00e9es invalides ou fen\u00eatre de pointage ferm\u00e9e."},"429":{"description":"Trop de requ\u00eates."}}}},"\/admin\/course-locations\/{courseLocation}\/check-in\/qr-code":{"get":{"summary":"Admin - QR code de salle","description":"Retourne le QR code permanent de la salle en SVG par d\u00e9faut ou PNG via ?format=png.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Fichier PDF","content":{"image\/svg+xml":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/admin\/course-locations\/{courseLocation}\/check-in\/regenerate":{"post":{"summary":"Admin - r\u00e9g\u00e9n\u00e9rer QR de salle","description":"Invalide imm\u00e9diatement l\u2019ancien jeton et retourne la nouvelle URL.","security":[{"bearerAuth":[],"appKey":[]}],"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}},{"name":"courseLocation","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"course_location_id":{"type":"integer"},"location_name":{"type":"string"},"check_in_enabled":{"type":"boolean"},"check_in_url":{"type":"string","format":"uri"},"pdf_url":{"type":"string","format":"uri"},"print_url":{"type":"string","format":"uri"},"qr_code_url":{"type":"string","format":"uri"},"check_in_open_before_minutes":{"type":"integer"},"check_in_close_after_minutes":{"type":"integer"},"check_in_token_regenerated_at":{"type":"string","format":"date-time","nullable":true}}}}},"example":{"data":{"course_location_id":12,"location_name":"Salle Omnisports Saintes","check_in_enabled":true,"check_in_url":"https:\/\/organzia.be\/check-in\/loc_K7m42Qx9...","pdf_url":"https:\/\/organzia.be\/check-in\/loc_K7m42Qx9...\/pdf","print_url":"https:\/\/organzia.be\/check-in\/loc_K7m42Qx9...\/print","qr_code_url":"https:\/\/organzia.be\/api\/admin\/course-locations\/12\/check-in\/qr-code","check_in_open_before_minutes":30,"check_in_close_after_minutes":45,"check_in_token_regenerated_at":null}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."},"409":{"description":"Incoh\u00e9rence m\u00e9tier: membre non accessible, non inscrit ou s\u00e9ance dans une autre salle."},"422":{"description":"Donn\u00e9es invalides ou fen\u00eatre de pointage ferm\u00e9e."},"429":{"description":"Trop de requ\u00eates."}}}},"\/admin\/course-locations\/{courseLocation}\/check-in\/settings":{"patch":{"summary":"Admin - param\u00e8tres QR de salle","description":"Active\/d\u00e9sactive le pointage QR et configure les fen\u00eatres.","security":[{"bearerAuth":[],"appKey":[]}],"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}},{"name":"courseLocation","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"course_location_id":{"type":"integer"},"location_name":{"type":"string"},"check_in_enabled":{"type":"boolean"},"check_in_url":{"type":"string","format":"uri"},"pdf_url":{"type":"string","format":"uri"},"print_url":{"type":"string","format":"uri"},"qr_code_url":{"type":"string","format":"uri"},"check_in_open_before_minutes":{"type":"integer"},"check_in_close_after_minutes":{"type":"integer"},"check_in_token_regenerated_at":{"type":"string","format":"date-time","nullable":true}}}}},"example":{"data":{"course_location_id":12,"location_name":"Salle Omnisports Saintes","check_in_enabled":true,"check_in_url":"https:\/\/organzia.be\/check-in\/loc_K7m42Qx9...","pdf_url":"https:\/\/organzia.be\/check-in\/loc_K7m42Qx9...\/pdf","print_url":"https:\/\/organzia.be\/check-in\/loc_K7m42Qx9...\/print","qr_code_url":"https:\/\/organzia.be\/api\/admin\/course-locations\/12\/check-in\/qr-code","check_in_open_before_minutes":30,"check_in_close_after_minutes":45,"check_in_token_regenerated_at":null}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."},"409":{"description":"Incoh\u00e9rence m\u00e9tier: membre non accessible, non inscrit ou s\u00e9ance dans une autre salle."},"422":{"description":"Donn\u00e9es invalides ou fen\u00eatre de pointage ferm\u00e9e."},"429":{"description":"Trop de requ\u00eates."}},"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"check_in_enabled":{"type":"boolean","example":true},"check_in_open_before_minutes":{"type":"integer","minimum":0,"maximum":180,"example":30},"check_in_close_after_minutes":{"type":"integer","minimum":0,"maximum":240,"example":45}},"required":["check_in_enabled","check_in_open_before_minutes","check_in_close_after_minutes"]}}}}}},"\/admin\/event-registrations\/{registration}\/check-in":{"patch":{"summary":"Admin - check-in \u00e9v\u00e9nement","description":"Valide la pr\u00e9sence ou le ticket \u00e9v\u00e9nement.","security":[{"bearerAuth":[],"appKey":[]}],"responses":{"200":{"description":"Succ\u00e8s","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."}},"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}}]}},"\/admin\/attendance\/{courseSession}":{"post":{"summary":"Admin\/coach - enregistrer les pr\u00e9sences","description":"Enregistre les pr\u00e9sences des membres et des participants de cours d\u2019essai. Les membres utilisent l\u2019objet members index\u00e9 par member_id. Les participants d\u2019essai utilisent trial_registrations avec leur trial_registration_id.","security":[{"bearerAuth":[],"appKey":[]}],"parameters":[{"name":"X-Organzia-Club-Id","in":"header","required":false,"description":"public_id opaque du club \u00e0 utiliser comme contexte actif. Si absent, l\u2019API utilise le club principal du compte.","schema":{"type":"string"}},{"name":"courseSession","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"members":{"type":"object","description":"Statuts index\u00e9s par member_id.","additionalProperties":{"type":"string","enum":["present","late","absent","excused"]}},"trial_registrations":{"type":"array","description":"Participants d\u2019essai \u00e0 modifier. trial_registration_id doit appartenir \u00e0 la s\u00e9ance et au club actif.","items":{"type":"object","required":["trial_registration_id","status"],"properties":{"trial_registration_id":{"type":"integer","example":901},"status":{"type":"string","enum":["present","late","absent","excused"]}}}}}},"example":{"members":{"48":"present"},"trial_registrations":[{"trial_registration_id":901,"status":"absent"}]}}}},"responses":{"200":{"description":"Pr\u00e9sences enregistr\u00e9es","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["member","trial"]},"member_id":{"type":"integer","nullable":true},"trial_registration_id":{"type":"integer","nullable":true},"member_name":{"type":"string","nullable":true},"status":{"type":"string","enum":["present","late","absent","excused"]},"present":{"type":"boolean"},"method":{"type":"string","enum":["manual"],"nullable":true},"checked_in_at":{"type":"string","format":"date-time","nullable":true},"recorded_at":{"type":"string","format":"date-time","nullable":true}}}}}},"example":{"data":[{"type":"member","member_id":48,"trial_registration_id":null,"member_name":"Jonathan Hamende","status":"present","present":true,"method":"manual"},{"type":"trial","member_id":null,"trial_registration_id":901,"member_name":"Lina Martin","status":"absent","present":false,"method":"manual"}]}}}},"401":{"description":"Non authentifi\u00e9"},"403":{"description":"X-Organzia-Club-Id correspond \u00e0 un club existant mais non autoris\u00e9 pour ce compte."},"404":{"description":"X-Organzia-Club-Id inconnu, ressource introuvable ou club introuvable."},"422":{"description":"Statut invalide, membre non inscrit ou participant d\u2019essai ne correspondant pas \u00e0 la s\u00e9ance."}}}}}}