API SIGPAS

API HTTP JSON pour les logiciels des clubs et les agents IA.

Comprendre les données

Saison
GET /seasons fournit une liste courte pour choisir son id et ses dates. Une saison peut chevaucher deux années civiles. Suivre detail_path pour les paramètres complets disponibles dans ce club (groups:read).
Commune
GET /communes?postal_code=… fournit les communes du référentiel SIGPAS, comme le formulaire adhérent. Utiliser exactement city_code, y compris les particularités locales ; ne pas déduire un code INSEE du code postal.
Personne
/members/{id} est une fiche du club, conservée entre les saisons. Créer une fiche ne crée aucune inscription.
Adhérent de la saison
/seasons/{id}/members contient les personnes ayant au moins une inscription annuelle validée, sans doublon. Les participants uniquement inscrits à un événement en sont exclus.
Groupe ou événement
Chaque groupe et événement appartient à une saison. Suivre son members_path pour lire ses participants validés.
Inscription
Lien entre une personne et un groupe ou événement. Son état valid vaut null (en attente), true (validée) ou false (refusée).
Séance
Occurrence datée d’un cours, créneau ou événement, identifiée par date, type et course_id. Utiliser /attendance pour les personnes attendues à une date précise.

Télécharger le contrat OpenAPI 3.2 · Métadonnées OAuth

Version du contrat : 1.4 · Changements.

Le contrat renvoie un en-tête ETag. Utilisez-le dans If-None-Match : une réponse 304 Not Modified évite de télécharger à nouveau le document inchangé.

Lire openapi.json à l’URL du club concerné : les champs dépendent des fonctionnalités activées. Conserver le contrat et son ETag par URL de club, puis revalider avec If-None-Match. Un changement de configuration peut modifier le contrat sans changer sa version. Les permissions de l’intégration sont indiquées dans GET /context ; elles restent nécessaires pour les opérations disponibles.

Activation pour ce club

État : désactivée.

Un directeur peut modifier cet état dans Administration → Fonctionnalités, rubrique Accès pour logiciels externes. Lorsque l’API est désactivée, la demande de jeton et les routes métier répondent avec l’erreur integration_api_disabled.

Les métadonnées OAuth publient également sigpas_api_enabled et sigpas_activation_uri. Ces extensions SIGPAS permettent à un client automatisé d’indiquer l’état du club et d’orienter son utilisateur vers ces instructions.

Démarrage

Créez un accès dans Administration → Accès pour logiciels externes, puis accordez les autorisations utiles. Base de cette API : https://sigpas.fr/ugsp/api/v1.

Échangez le secret contre un jeton de dix minutes. Conservez le secret sur votre serveur.

curl --user "$SIGPAS_CLIENT_ID:$SIGPAS_CLIENT_SECRET" --data grant_type=client_credentials https://sigpas.fr/ugsp/api/v1/token

curl -H "Authorization: Bearer $SIGPAS_ACCESS_TOKEN" "https://sigpas.fr/ugsp/api/v1/seasons?limit=50"

Le corps de la réponse contient data. Pour parcourir une liste, transmettez pagination.next_after dans after jusqu’à obtenir null. Les présences et les inscriptions d’une personne utilisent offset et next_offset. Maximum : 100 éléments par page. Les recherches d’adhérents et de groupes renvoient meta.truncated : s’il vaut true, affinez les critères ; leurs résultats ne sont pas une liste exhaustive. La recherche GET /communes?postal_code=… retourne toutes les correspondances sans pagination.

Pour affecter un paiement, consultez /payments/{id}/allocation-options, puis transmettez les clés choisies dans allocations avec PATCH. SIGPAS contrôle l’adhérent, la saison, les montants disponibles et les inscriptions concernées.

Choisir un parcours

Pour les adhérents et activités d’une saison, commencez par GET /seasons. Chaque résultat fournit directement members_path, groups_path et events_path. La saison est le point d’entrée normal ; les collections couvrant toutes les saisons sont réservées aux exports.

La liste des saisons reste courte. detail_path conduit aux paramètres complets disponibles pour ce club avec le droit groups:read. La création, la modification et la suppression exigent groups:write.

Ajouter les chemins à la base API du club (qui se termine par /api/v1), y compris lorsqu’ils commencent par /. Remplacer {id} par l’identifiant choisi à cette étape.

Consulter ou modifier les paramètres d’une saison
  1. GET /seasons — Choisir la saison dans la liste courte.
  2. GET /seasons/{id} — Suivre detail_path pour lire les paramètres disponibles pour ce club.
  3. PATCH /seasons/{id} — Fournir uniquement les champs à modifier, décrits dans le contrat du club, avec Idempotency-Key.
Renseigner la commune d’une personne ou la priorité géographique d’une saison
  1. GET /communes — Fournir postal_code sur cinq chiffres ; choisir la commune parmi les résultats et reprendre exactement city_code.
Lister les adhérents d’une saison
  1. GET /seasons — Choisir la saison demandée d’après ses dates.
  2. GET /seasons/{id}/members — Suivre members_path et toute la pagination.
Lister les participants d’un groupe
  1. GET /seasons — Choisir la saison demandée.
  2. GET /seasons/{id}/groups — Suivre groups_path et choisir le groupe.
  3. GET /groups/{id}/members — Suivre le members_path du groupe choisi.
Lister les participants d’un événement
  1. GET /seasons — Choisir la saison demandée.
  2. GET /seasons/{id}/events — Suivre events_path et choisir l’événement.
  3. GET /events/{id}/members — Suivre le members_path de l’événement choisi.
Trouver les groupes d’un jour de la semaine
  1. GET /seasons — Choisir la saison demandée.
  2. POST /groups/search — Fournir season_id et day, par exemple mardi. Il s’agit des horaires habituels ; pour une date précise, utiliser le parcours des séances.
Retrouver une personne et ses inscriptions
  1. GET /seasons — Choisir la saison demandée.
  2. POST /members/search — Fournir season_id et query (nom ou email du membre ou parent). La recherche porte sur les adhérents validés de la saison.
  3. GET /members/{id}/registrations — Suivre registrations_path pour les inscriptions annuelles et événementielles, y compris celles en attente ou refusées.
Consulter les séances et participants d’une date
  1. GET /attendance — Fournir date au format YYYY-MM-DD pour lister les séances.
  2. GET /attendance — Conserver date, ajouter type et course_id de la séance choisie pour lire les participants attendus et leur présence.
Consulter les présences d’une personne
  1. GET /members/{id}/attendance — Après identification dans la saison, suivre attendance_path. season_id est obligatoire. Une présence non renseignée ne signifie pas une absence.
Faire l’appel
  1. GET /attendance — Choisir la séance à la date voulue, puis lire ses participants avec date, type et course_id.
  2. POST /attendance — Fournir date, type, course_id, member_id et presence, avec une clé Idempotency-Key unique par écriture.
curl -H "Authorization: Bearer $SIGPAS_ACCESS_TOKEN" \
  "https://sigpas.fr/ugsp/api/v1/seasons/3/members?limit=50"

curl -X POST -H "Authorization: Bearer $SIGPAS_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"season_id":3,"query":"parent@example.com"}' https://sigpas.fr/ugsp/api/v1/members/search

curl -X POST -H "Authorization: Bearer $SIGPAS_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"season_id":3,"day":"mardi"}' https://sigpas.fr/ugsp/api/v1/groups/search

Ces deux recherches sont des lectures : aucune clé Idempotency-Key n’est demandée. Elles utilisent POST afin que les noms et emails ne figurent pas dans l’URL des journaux HTTP.

Exports globaux et migration

GET /members?all=true contient toutes les fiches, y compris sans inscription et des anciennes saisons. Ne choisir cet export que si toutes les fiches sont explicitement demandées. Utiliser aussi all=true sur GET /groups et GET /events pour couvrir toutes les saisons. Depuis le contrat 1.4, l’absence de all reste acceptée avec HTTP 200, les mêmes données et la même pagination, mais cet usage est déprécié (en-têtes Deprecation et Link rel="deprecation"). Aucune date de suppression n’est fixée.

Le contrat 1.4 rétablit les appels sans all, refusés par les contrats 1.2 et 1.3. Ils renvoient 200 OK avec les mêmes données et la même pagination. L’en-tête Deprecation indique la dépréciation depuis le 9 septembre 2026 ; le lien Link: rel="deprecation" renvoie à cette section. Seule l’omission de all est dépréciée, les exports explicites restent pris en charge. Aucune date de suppression n’est fixée et aucun en-tête Sunset n’est envoyé.

Une intégration qui utilisait GET /members pour les adhérents doit utiliser GET /seasons/{id}/members. Ajouter all=true uniquement aux exports complets intentionnels, sur chaque page. Ce changement nécessite d’adapter les clients existants.

Écritures

Envoyez Content-Type: application/json et une clé Idempotency-Key unique de 16 à 128 caractères. Après une coupure, renvoyez exactement la même requête avec la même clé : son écriture ne sera pas répétée. Les écritures renvoient l’identifiant ; utilisez GET pour lire la ressource.

curl -X POST -H "Authorization: Bearer $SIGPAS_ACCESS_TOKEN" \
  -H "Content-Type: application/json" -H "Idempotency-Key: import-membre-000001" \
  --data '{"email":"camille@example.com","first_name":"Camille","last_name":"Martin"}' https://sigpas.fr/ugsp/api/v1/members

PATCH modifie uniquement les champs fournis. Les champs inconnus sont refusés. Les dates utilisent YYYY-MM-DD, les dates-heures 2026-09-06T14:00:00+02:00. Les paiements utilisent amount_cents ; les tarifs des activités cost_euros. Pour les limites de naissance, birth_year_start est l’année la plus récente, birth_year_end la plus ancienne.

Une inscription respecte les règles du club : pièces requises, critères d’accès, disponibilités et capacités. Les actions validate, refuse et cancel appliquent les règles de gestion et les notifications configurées. L’annulation supprime l’inscription selon ces règles. Pour un événement exigeant un paiement préalable, l’API crée une préinscription en attente. Le règlement en ligne s’effectue ensuite dans le parcours SIGPAS.

Découverte automatique

Les pages d’accueil, de connexion et d’administration du club annoncent l’API dans leur en-tête HTTP et leur code HTML. service-desc conduit au contrat OpenAPI, service-doc à cette documentation et service-meta aux métadonnées de la ressource protégée. Les clients OAuth peuvent ensuite utiliser les métadonnées standard du serveur d’autorisation (RFC 8414) et de la ressource (RFC 9728). Un agent IA compatible HTTP/OpenAPI utilise le même contrat et les mêmes autorisations.

La racine de l’API et GET /context exposent un guide avec les concepts, les parcours et les autorisations de chaque étape. Il est aussi publié dans x-sigpas-guide du contrat OpenAPI.

Clé publique RSA

Déposez une clé publique RSA PEM d’au moins 2048 bits. Signez une assertion JWT avec RS256 : iss et sub valent le client_id ; aud vaut https://sigpas.fr/ugsp/api/v1/token ; iat et exp sont des timestamps entiers, espacés de 300 secondes au maximum. Chaque jti contient 16 à 191 caractères et ne peut être utilisé qu’une fois.

POST /token accepte un formulaire application/x-www-form-urlencoded avec grant_type=client_credentials, client_id, client_assertion et client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer. Le champ facultatif scope permet de demander un sous-ensemble des autorisations, séparées par des espaces. Une seule méthode d’authentification est autorisée par requête.

Autorisations et limites

Chaque jeton est limité au club qui l’a délivré. Les droits d’écriture ne donnent aucun droit dans un autre domaine. Tout client authentifié peut lister les saisons afin de commencer son parcours. Les données médicales, les paiements et les fichiers sont séparés des fiches adhérents. Les listes nominatives des groupes exigent aussi members:read ; celles des événements exigent également registrations:read.

Les documents acceptent PDF, JPEG et PNG (10 Mio maximum), encodés en base64 dans content_base64. Les routes /content téléchargent le fichier sous contrôle du jeton. Les modifications médicales exigent un season_id ; questionnaire et certificat doivent être envoyés dans des requêtes séparées. Une déclaration ou correction de certificat remet sa décision en attente, sauf si le champ valid est explicitement fourni.

Quota : 300 requêtes par minute et par intégration ; 30 demandes de jeton par minute, par IP et par club. Une réponse 429 indique de réessayer après le délai Retry-After. Les erreurs de ressources utilisent application/problem+json (RFC 9457), avec status, code et detail. Les erreurs OAuth utilisent error et error_description ; error_uri conduit aux instructions lorsqu’une action de l’utilisateur est nécessaire.

Les fichiers du club sont dans /documents. Les pièces déposées sur les fiches adhérents sont dans /member-documents/{id}, avec dépôt/remplacement par PUT et suppression par DELETE sur /member-documents/{id}/fields/{field_id}. Les factures générées sont accessibles par /annual-registrations/{id}/invoice et /event-registrations/{id}/invoice avec documents:read et payments:read.

Notifications automatiques

Configurez une destination HTTPS dans Administration → Accès pour logiciels externes → Notifications automatiques. Copiez sa clé de vérification sur le serveur destinataire. Les messages sont des CloudEvents 1.0 en JSON (Content-Type: application/cloudevents+json), signés selon Standard Webhooks. Le schéma JSON et la section webhooks du contrat OpenAPI décrivent leur format.

id identifie le message ; type indique le changement ; source identifie le club par son URL API canonique ; time est la date du changement en UTC. data.resource donne le type de ressource, son identifiant, son URL API et les scopes nécessaires. data.context conserve les identifiants liés au changement et data.links propose les lectures complémentaires.

Les présences indiquent l’adhérent, le type de séance, son identifiant, la date et la nouvelle présence. Les pièces adhérents indiquent member_id et field_id, avec un lien de téléchargement. Les factures exigent aussi payments:read. La validation mensuelle des heures indique l’adhérent, l’année et le mois ; son lien /staff-hours/{id}?month=YYYY-MM renvoie le total en secondes et les entrées paginées. Cette lecture exige staff_hours:read et la fonctionnalité de relevé des heures.

  1. Lisez le corps HTTP brut avant tout décodage JSON. Vérifiez que webhook-timestamp diffère de votre horloge de moins de cinq minutes.
  2. Retirez le préfixe whsec_ de la clé puis décodez-la en base64. Calculez HMAC-SHA256 sur webhook-id + "." + webhook-timestamp + "." + corps_brut. Comparez en temps constant sa valeur base64 au suffixe v1, de webhook-signature.
  3. Vérifiez que source correspond au club configuré et que l’identifiant signé correspond au champ id. Enregistrez durablement le message, en dédupliquant (source, id), puis répondez 200 ou 204.
  4. Traitez-le en arrière-plan : obtenez un jeton OAuth, puis lisez data.resource.url. N’envoyez ce jeton qu’à la base API de confiance configurée. Suivez la pagination pour récupérer toutes les entrées.

La notification signale un changement ; GET renvoie l’état courant. Plusieurs modifications rapides peuvent arriver dans un ordre différent. Relire la ressource permet de converger vers son état actuel. Après une suppression ou une annulation, deleted vaut true et les identifiants sont conservés ; GET peut renvoyer 404. Une suppression d’adhérent invalide aussi ses données liées. Un lien complémentaire peut renvoyer 403 si son domaine n’est pas autorisé.

Les envois suivent la validation de la transaction. Une transaction annulée ne produit aucun message. En cas de coupure ou de réponse 408, 425, 429 ou 5xx, SIGPAS réessaie jusqu’à huit fois, après 1 min, 5 min, 15 min, 1 h, 4 h, 12 h et 24 h. Un Retry-After en secondes peut augmenter le délai, jusqu’à 24 h. Chaque reprise conserve le même identifiant et le même corps, avec une nouvelle date de signature. Les autres erreurs 4xx et les redirections arrêtent la livraison. Une réponse 2xx confirme la réception.

Les droits, l’état de l’accès, les événements sélectionnés et l’adresse de destination sont revérifiés avant chaque tentative. Les messages devenus inéligibles sont abandonnés ; les changements survenus pendant une suspension ne sont pas rejoués. Une requête déjà partie peut encore arriver après la suspension. Les adresses privées et les redirections sont bloquées. Les messages terminés et l’historique des tentatives sont conservés 30 jours. Pour remplacer une clé compromise, révoquez la destination et créez-en une nouvelle.

Exemple de notification
{
  "specversion": "1.0",
  "id": "0123456789abcdef0123456789abcdef",
  "source": "https://sigpas.fr/ugsp/api/v1",
  "type": "registrations.validated",
  "subject": "annual-registrations/123",
  "time": "2026-09-06T12:00:00.000000Z",
  "datacontenttype": "application/json",
  "dataschema": "https://sigpas.fr/ugsp/api/v1/webhook-schema.json",
  "data": {
    "resource": {
      "type": "annual-registrations", "id": "123",
      "url": "https://sigpas.fr/ugsp/api/v1/annual-registrations/123",
      "required_scopes": ["registrations:read"], "deleted": false
    },
    "context": {"member_id": 42, "group_id": 7},
    "links": {
      "members": {"url": "https://sigpas.fr/ugsp/api/v1/members/42", "required_scopes": ["members:read"]},
      "groups": {"url": "https://sigpas.fr/ugsp/api/v1/groups/7", "required_scopes": ["groups:read"]}
    }
  }
}

Référence des opérations

Les opérations sont regroupées par domaine. Ce catalogue et le contrat OpenAPI proviennent des mêmes définitions.

Découverte et authentification

Découverte de l’API, documentation et authentification OAuth 2.0.

GET / — GET /

Autorisations : Public

GET /openapi.json — GET /openapi.json

Autorisations : Public

GET /docs — GET /docs

Autorisations : Public

Consulter les changements du contrat API — GET /changes

Retourne un résumé sémantique des évolutions du contrat API postérieures à la version indiquée.

Autorisations : Public

ParamètreEmplacementObligatoireFormat et contraintes
since query Non Dernière version du contrat connue par le client. Valeur par défaut : 0.0. {"type":"string","pattern":"^[0-9]+\\.[0-9]+(?:\\.[0-9]+)?$"}
GET /oauth-authorization-server — GET /oauth-authorization-server

Autorisations : Public

GET /oauth-protected-resource — GET /oauth-protected-resource

Autorisations : Public

GET /webhook-schema.json — GET /webhook-schema.json

Autorisations : Public

POST /token — POST /token

OAuth 2.0 client_credentials. Authentification client_secret_basic (HTTP Basic), client_secret_post ou private_key_jwt RS256. Utiliser une seule méthode. JWT : iss=sub=client_id, aud=URL canonique du token, iat/exp entiers, durée maximale 300 s, jti unique de 16 à 191 caractères, non réutilisable. Jeton opaque valable 600 s. Limite : 30 requêtes/minute/IP/club. Si l’API du club est désactivée, la réponse 403 contient unauthorized_client et error_uri vers les instructions d’activation.

Autorisations : Public

Corps : application/x-www-form-urlencoded

{
    "type": "object",
    "required": [
        "grant_type"
    ],
    "properties": {
        "grant_type": {
            "type": "string",
            "readOnly": true,
            "description": "Chemin à appeler avec GET, relatif à la base /api/v1 du club.",
            "const": "client_credentials"
        },
        "client_id": {
            "type": "string",
            "readOnly": true,
            "description": "Chemin à appeler avec GET, relatif à la base /api/v1 du club."
        },
        "client_secret": {
            "type": "string",
            "readOnly": true,
            "description": "Chemin à appeler avec GET, relatif à la base /api/v1 du club."
        },
        "client_assertion_type": {
            "type": "string",
            "readOnly": true,
            "description": "Chemin à appeler avec GET, relatif à la base /api/v1 du club.",
            "const": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
        },
        "client_assertion": {
            "type": "string",
            "readOnly": true,
            "description": "Chemin à appeler avec GET, relatif à la base /api/v1 du club."
        },
        "scope": {
            "type": "string",
            "readOnly": true,
            "description": "Chemin à appeler avec GET, relatif à la base /api/v1 du club."
        }
    }
}
GET /context — GET /context

Autorisations : Jeton requis

Rechercher les communes SIGPAS par code postal — GET /communes

Recherche exacte par code postal dans le même référentiel SIGPAS que le formulaire adhérent, avec ses alias et particularités locales. Tous les résultats sont renvoyés, sans pagination ; un code postal inconnu renvoie data: []. Reprendre city_code sans le normaliser.

Autorisations : Jeton requis

ParamètreEmplacementObligatoireFormat et contraintes
postal_code query Oui {"type":"string","pattern":"^[0-9]{5}$","examples":["20167","98830"]}
GET /member-documents/{id} — GET /member-documents/{id}

Autorisations : documents:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
PUT /member-documents/{id}/fields/{field_id} — PUT /member-documents/{id}/fields/{field_id}

Autorisations : documents:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
field_id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "required": [
        "content_base64"
    ],
    "properties": {
        "content_base64": {
            "type": "string",
            "minLength": 4,
            "maxLength": 13981016,
            "contentEncoding": "base64",
            "description": "PDF, JPEG ou PNG, maximum 10 Mio décodés."
        }
    }
}
DELETE /member-documents/{id}/fields/{field_id} — DELETE /member-documents/{id}/fields/{field_id}

Autorisations : documents:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
field_id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
GET /member-documents/{id}/fields/{field_id}/content — GET /member-documents/{id}/fields/{field_id}/content

Autorisations : documents:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
field_id path Oui {"type":"integer","minimum":1,"maximum":2147483647}

Parcours par saison

Parcours principal : choisir une saison, puis consulter ses adhérents, groupes et événements.

Lister les saisons du club en format court — GET /seasons

Point de départ des parcours par saison. Chaque saison expose members_path, groups_path et events_path, avec uniquement son nom et ses dates principales. detail_path mène aux paramètres complets et exige groups:read. Choisissez la saison dont les dates correspondent au besoin, puis suivez ces chemins plutôt que les collections globales.

Autorisations : Jeton requis

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
Créer une saison — POST /seasons

Crée une saison. Les options omises prennent les valeurs par défaut du schéma. Les dates de fin doivent suivre ou égaler les débuts correspondants ; les ouvertures prioritaires doivent précéder ou égaler l’ouverture générale. city_registration_start exige city_code.

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255,
            "description": "Nom affiché de la saison.",
            "examples": [
                "2026–2027"
            ]
        },
        "start_date": {
            "type": "string",
            "format": "date",
            "description": "Premier jour de la saison.",
            "examples": [
                "2026-09-01"
            ]
        },
        "end_date": {
            "type": "string",
            "format": "date",
            "description": "Dernier jour de la saison, inclus.",
            "examples": [
                "2027-08-31"
            ]
        },
        "registration_start": {
            "type": "string",
            "format": "date",
            "description": "Ouverture générale des inscriptions."
        },
        "registration_end": {
            "type": "string",
            "format": "date",
            "description": "Dernier jour des inscriptions, inclus."
        },
        "membership_cost_euros": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000000,
            "default": 0,
            "description": "Coût de l’adhésion à la saison, en euros entiers, hors tarifs des groupes et licences proposées."
        },
        "previous_registration_start": {
            "type": [
                "string",
                "null"
            ],
            "format": "date",
            "default": null,
            "description": "Ouverture prioritaire pour les anciens adhérents. null utilise l’ouverture générale."
        },
        "previous_registration_all": {
            "type": "boolean",
            "default": false,
            "description": "true étend la priorité à tous les anciens inscrits, saisons et événements ; false la limite aux adhérents de la saison précédente."
        },
        "city_registration_start": {
            "type": [
                "string",
                "null"
            ],
            "format": "date",
            "default": null,
            "description": "Ouverture prioritaire pour la commune désignée par city_code. null utilise l’ouverture générale."
        },
        "city_code": {
            "type": [
                "string",
                "null"
            ],
            "minLength": 5,
            "maxLength": 5,
            "default": null,
            "description": "Code de la commune bénéficiant de la priorité. Reprendre exactement city_code de GET /communes?postal_code=… ; null désactive la priorité géographique."
        },
        "max_annual_registrations": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2147483647,
            "default": 0,
            "description": "Nombre maximum d’inscriptions annuelles par adhérent dans cette saison. 0 signifie illimité."
        },
        "licence_immediate_payment": {
            "type": "boolean",
            "default": false,
            "description": "Lors d’un paiement échelonné, inclure le montant restant des licences dans la première échéance."
        }
    },
    "required": [
        "name",
        "start_date",
        "end_date",
        "registration_start",
        "registration_end"
    ]
}
Consulter tous les paramètres disponibles d’une saison — GET /seasons/{id}

Détail des paramètres de la saison disponibles pour ce club. Nécessite groups:read.

Autorisations : groups:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Modifier une saison — PATCH /seasons/{id}

Modifie les champs fournis et conserve les champs omis. null réinitialise une ouverture prioritaire à l’ouverture générale. Pour retirer la priorité géographique, mettre city_code et city_registration_start à null. Les règles de dates de la création s’appliquent aussi après modification.

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255,
            "description": "Nom affiché de la saison.",
            "examples": [
                "2026–2027"
            ]
        },
        "start_date": {
            "type": "string",
            "format": "date",
            "description": "Premier jour de la saison.",
            "examples": [
                "2026-09-01"
            ]
        },
        "end_date": {
            "type": "string",
            "format": "date",
            "description": "Dernier jour de la saison, inclus.",
            "examples": [
                "2027-08-31"
            ]
        },
        "registration_start": {
            "type": "string",
            "format": "date",
            "description": "Ouverture générale des inscriptions."
        },
        "registration_end": {
            "type": "string",
            "format": "date",
            "description": "Dernier jour des inscriptions, inclus."
        },
        "membership_cost_euros": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000000,
            "default": 0,
            "description": "Coût de l’adhésion à la saison, en euros entiers, hors tarifs des groupes et licences proposées."
        },
        "previous_registration_start": {
            "type": [
                "string",
                "null"
            ],
            "format": "date",
            "default": null,
            "description": "Ouverture prioritaire pour les anciens adhérents. null utilise l’ouverture générale."
        },
        "previous_registration_all": {
            "type": "boolean",
            "default": false,
            "description": "true étend la priorité à tous les anciens inscrits, saisons et événements ; false la limite aux adhérents de la saison précédente."
        },
        "city_registration_start": {
            "type": [
                "string",
                "null"
            ],
            "format": "date",
            "default": null,
            "description": "Ouverture prioritaire pour la commune désignée par city_code. null utilise l’ouverture générale."
        },
        "city_code": {
            "type": [
                "string",
                "null"
            ],
            "minLength": 5,
            "maxLength": 5,
            "default": null,
            "description": "Code de la commune bénéficiant de la priorité. Reprendre exactement city_code de GET /communes?postal_code=… ; null désactive la priorité géographique."
        },
        "max_annual_registrations": {
            "type": "integer",
            "minimum": 0,
            "maximum": 2147483647,
            "default": 0,
            "description": "Nombre maximum d’inscriptions annuelles par adhérent dans cette saison. 0 signifie illimité."
        },
        "licence_immediate_payment": {
            "type": "boolean",
            "default": false,
            "description": "Lors d’un paiement échelonné, inclure le montant restant des licences dans la première échéance."
        }
    },
    "required": []
}
Supprimer une saison — DELETE /seasons/{id}

Supprime la saison. Répond 409 season_in_use si des données liées empêchent la suppression (groupes, événements, créneaux, paiements, licences, etc.). Les données liées configurées en suppression en cascade sont supprimées avec elle.

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
Lister les adhérents inscrits dans une saison — GET /seasons/{id}/members

Liste paginée et sans doublon des adhérents ayant au moins une inscription annuelle validée dans la saison. Les personnes sans inscription validée ne sont jamais renvoyées. Chaque adhérent contient ses inscriptions de la saison et les chemins vers ses inscriptions et présences.

Autorisations : groups:read, members:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
Lister les groupes d’une saison — GET /seasons/{id}/groups

Liste paginée des groupes de la saison. Chaque groupe expose members_path.

Autorisations : groups:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
Lister les événements d’une saison — GET /seasons/{id}/events

Liste paginée des événements de la saison. Chaque événement expose members_path.

Autorisations : events:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
Rechercher un adhérent dans une saison — POST /members/search

Recherche, dans une saison obligatoire, un adhérent par nom ou prénom partiel, ou par adresse email exacte. La recherche couvre aussi les noms et emails des représentants légaux. group_id permet de limiter la recherche à un groupe de cette saison. Seules les inscriptions validées sont retenues. Utilisez POST afin que les données personnelles recherchées ne figurent pas dans l’URL ni dans les journaux d’accès HTTP.

Autorisations : members:read, groups:read

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "required": [
        "query",
        "season_id"
    ],
    "properties": {
        "query": {
            "type": "string",
            "minLength": 2,
            "maxLength": 127,
            "description": "Nom ou prénom partiel, ou adresse email exacte de l’adhérent ou d’un représentant légal."
        },
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "group_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 50,
            "default": 20
        }
    }
}
Rechercher des groupes dans une saison — POST /groups/search

Recherche les groupes d’une saison par nom, jour de pratique et/ou sport. Chaque résultat contient ses horaires, son nombre d’inscrits validés et members_path. Pour répondre à « qui participe à un groupe le mardi ? », recherchez day=mardi puis appelez GET /groups/{id}/members pour chaque groupe retenu.

Autorisations : groups:read

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "required": [
        "season_id"
    ],
    "properties": {
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "query": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255,
            "description": "Partie du nom du groupe."
        },
        "day": {
            "type": "string",
            "enum": [
                "lundi",
                "mardi",
                "mercredi",
                "jeudi",
                "vendredi",
                "samedi",
                "dimanche"
            ]
        },
        "sport_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 50,
            "default": 20
        }
    }
}

Fiches de personnes

Fiches de personnes conservées entre les saisons. Une fiche seule ne constitue pas une adhésion.

Créer une fiche de personne sans l’inscrire — POST /members

Crée la fiche d’une personne dans le club. Pour l’inscrire, créer ensuite une inscription annuelle avec member_id et group_id, ou événementielle avec member_id et event_id. La création de la fiche ne crée aucune inscription.

Autorisations : members:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "email": {
            "type": "string",
            "format": "email",
            "maxLength": 127,
            "description": "Adresse email de la personne. Un changement réinitialise sa validation."
        },
        "first_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "description": "Prénom de la personne."
        },
        "last_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "description": "Nom de famille de la personne."
        },
        "phone": {
            "type": [
                "string",
                "null"
            ],
            "maxLength": 15,
            "description": "Téléphone de la personne ; null signifie non renseigné et efface la valeur en écriture."
        },
        "birth_date": {
            "type": [
                "string",
                "null"
            ],
            "format": "date",
            "description": "Date de naissance au format YYYY-MM-DD ; null signifie non renseignée et efface la valeur en écriture."
        },
        "sex": {
            "type": [
                "string",
                "null"
            ],
            "enum": [
                "Homme",
                "Femme",
                null
            ],
            "description": "Sexe renseigné dans la fiche ; null signifie non renseigné et efface la valeur en écriture."
        },
        "city_code": {
            "type": [
                "string",
                "null"
            ],
            "maxLength": 5,
            "minLength": 5,
            "description": "Code de commune du référentiel SIGPAS. Reprendre exactement city_code de GET /communes?postal_code=… ; ce n’est pas un code postal. null signifie non renseigné et efface la valeur en écriture."
        },
        "address": {
            "type": [
                "string",
                "null"
            ],
            "maxLength": 10000,
            "description": "Adresse de la personne, hors commune ; null signifie non renseignée et efface la valeur en écriture."
        },
        "parents": {
            "type": "array",
            "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                    "type"
                ],
                "properties": {
                    "type": {
                        "type": "string",
                        "enum": [
                            "Pere",
                            "Mere",
                            "Institution",
                            "Responsable_legal",
                            "Famille_accueil",
                            "Sans_objet"
                        ],
                        "description": "Lien du représentant avec la personne : père, mère, institution, responsable légal, famille d’accueil ou sans objet."
                    },
                    "first_name": {
                        "type": "string",
                        "maxLength": 63,
                        "description": "Prénom du représentant."
                    },
                    "last_name": {
                        "type": "string",
                        "maxLength": 63,
                        "description": "Nom du représentant."
                    },
                    "title": {
                        "type": "string",
                        "maxLength": 63,
                        "description": "Intitulé du représentant ou de l’institution."
                    },
                    "phone": {
                        "type": "string",
                        "maxLength": 15,
                        "description": "Téléphone du représentant."
                    },
                    "email": {
                        "type": "string",
                        "maxLength": 127,
                        "description": "Adresse email du représentant."
                    },
                    "profession": {
                        "type": "string",
                        "maxLength": 127,
                        "description": "Profession du représentant."
                    }
                }
            },
            "maxItems": 2,
            "description": "Représentants légaux. En écriture, remplace toute la liste ; [] supprime tous les représentants. Un champ parents omis conserve la liste existante. Deux représentants au maximum en écriture."
        }
    },
    "required": [
        "email",
        "first_name",
        "last_name"
    ]
}
Consulter la fiche d’une personne — GET /members/{id}

Autorisations : members:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Modifier la fiche d’une personne — PATCH /members/{id}

Les champs omis sont conservés. null efface un champ nullable. parents remplace la liste entière des représentants ; [] les supprime tous. Modifier l’adresse email réinitialise sa validation si elle change. Pour city_code, reprendre un résultat de GET /communes?postal_code=… .

Autorisations : members:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "email": {
            "type": "string",
            "format": "email",
            "maxLength": 127,
            "description": "Adresse email de la personne. Un changement réinitialise sa validation."
        },
        "first_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "description": "Prénom de la personne."
        },
        "last_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 63,
            "description": "Nom de famille de la personne."
        },
        "phone": {
            "type": [
                "string",
                "null"
            ],
            "maxLength": 15,
            "description": "Téléphone de la personne ; null signifie non renseigné et efface la valeur en écriture."
        },
        "birth_date": {
            "type": [
                "string",
                "null"
            ],
            "format": "date",
            "description": "Date de naissance au format YYYY-MM-DD ; null signifie non renseignée et efface la valeur en écriture."
        },
        "sex": {
            "type": [
                "string",
                "null"
            ],
            "enum": [
                "Homme",
                "Femme",
                null
            ],
            "description": "Sexe renseigné dans la fiche ; null signifie non renseigné et efface la valeur en écriture."
        },
        "city_code": {
            "type": [
                "string",
                "null"
            ],
            "maxLength": 5,
            "minLength": 5,
            "description": "Code de commune du référentiel SIGPAS. Reprendre exactement city_code de GET /communes?postal_code=… ; ce n’est pas un code postal. null signifie non renseigné et efface la valeur en écriture."
        },
        "address": {
            "type": [
                "string",
                "null"
            ],
            "maxLength": 10000,
            "description": "Adresse de la personne, hors commune ; null signifie non renseignée et efface la valeur en écriture."
        },
        "parents": {
            "type": "array",
            "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                    "type"
                ],
                "properties": {
                    "type": {
                        "type": "string",
                        "enum": [
                            "Pere",
                            "Mere",
                            "Institution",
                            "Responsable_legal",
                            "Famille_accueil",
                            "Sans_objet"
                        ],
                        "description": "Lien du représentant avec la personne : père, mère, institution, responsable légal, famille d’accueil ou sans objet."
                    },
                    "first_name": {
                        "type": "string",
                        "maxLength": 63,
                        "description": "Prénom du représentant."
                    },
                    "last_name": {
                        "type": "string",
                        "maxLength": 63,
                        "description": "Nom du représentant."
                    },
                    "title": {
                        "type": "string",
                        "maxLength": 63,
                        "description": "Intitulé du représentant ou de l’institution."
                    },
                    "phone": {
                        "type": "string",
                        "maxLength": 15,
                        "description": "Téléphone du représentant."
                    },
                    "email": {
                        "type": "string",
                        "maxLength": 127,
                        "description": "Adresse email du représentant."
                    },
                    "profession": {
                        "type": "string",
                        "maxLength": 127,
                        "description": "Profession du représentant."
                    }
                }
            },
            "maxItems": 2,
            "description": "Représentants légaux. En écriture, remplace toute la liste ; [] supprime tous les représentants. Un champ parents omis conserve la liste existante. Deux représentants au maximum en écriture."
        }
    },
    "required": []
}
Consulter les inscriptions d’un adhérent pour une saison — GET /members/{id}/registrations

Liste les inscriptions annuelles et événementielles d’un adhérent dans une saison. Chaque entrée indique son type, son état et les chemins de l’inscription et de l’activité.

Autorisations : members:read, registrations:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
offset query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
season_id query Oui Identifiant obtenu avec GET /seasons. {"type":"integer","minimum":1,"maximum":2147483647}

registrations

Demandes annuelles ou ponctuelles, activité demandée, dates et état de validation. Les informations médicales et le détail des paiements sont exclus. Création, modification, validation, refus ou annulation d’une inscription.

GET /annual-registrations — GET /annual-registrations

Autorisations : registrations:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
Inscrire une personne à un groupe — POST /annual-registrations

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "member_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "group_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "slot_ids": {
            "type": "array",
            "items": {
                "type": "integer",
                "minimum": 1,
                "maximum": 2147483647
            },
            "maxItems": 100
        },
        "licence_id": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1,
            "maximum": 2147483647
        }
    },
    "required": [
        "member_id",
        "group_id"
    ]
}
GET /annual-registrations/{id} — GET /annual-registrations/{id}

Autorisations : registrations:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
PATCH /annual-registrations/{id} — PATCH /annual-registrations/{id}

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "member_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "group_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "slot_ids": {
            "type": "array",
            "items": {
                "type": "integer",
                "minimum": 1,
                "maximum": 2147483647
            },
            "maxItems": 100
        },
        "licence_id": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1,
            "maximum": 2147483647
        }
    },
    "required": []
}
DELETE /annual-registrations/{id} — DELETE /annual-registrations/{id}

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
POST /annual-registrations/{id}/validate — POST /annual-registrations/{id}/validate

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
POST /annual-registrations/{id}/refuse — POST /annual-registrations/{id}/refuse

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
POST /annual-registrations/{id}/cancel — POST /annual-registrations/{id}/cancel

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
GET /event-registrations — GET /event-registrations

Autorisations : registrations:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
Inscrire une personne à un événement — POST /event-registrations

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "member_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "event_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        }
    },
    "required": [
        "member_id",
        "event_id"
    ]
}
GET /event-registrations/{id} — GET /event-registrations/{id}

Autorisations : registrations:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
DELETE /event-registrations/{id} — DELETE /event-registrations/{id}

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
POST /event-registrations/{id}/validate — POST /event-registrations/{id}/validate

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
POST /event-registrations/{id}/refuse — POST /event-registrations/{id}/refuse

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
POST /event-registrations/{id}/cancel — POST /event-registrations/{id}/cancel

Autorisations : registrations:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
GET /annual-registrations/{id}/invoice — GET /annual-registrations/{id}/invoice

Autorisations : documents:read, payments:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
GET /event-registrations/{id}/invoice — GET /event-registrations/{id}/invoice

Autorisations : documents:read, payments:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}

groups

Paramètres des saisons, sports, groupes, créneaux, horaires, lieux, capacités et règles d’inscription. La liste nominative des inscrits nécessite aussi l’accès aux adhérents. Création, modification et suppression des saisons ; création et modification des groupes, créneaux, horaires, lieux et capacités.

GET /sports — GET /sports

Autorisations : groups:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
POST /sports — POST /sports

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 127
        }
    },
    "required": [
        "name"
    ]
}
GET /sports/{id} — GET /sports/{id}

Autorisations : groups:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
PATCH /sports/{id} — PATCH /sports/{id}

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 127
        }
    },
    "required": []
}
POST /groups — POST /groups

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255
        },
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "sport_id": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1,
            "maximum": 2147483647
        },
        "description": {
            "type": "string",
            "maxLength": 10000
        },
        "sex": {
            "type": "string",
            "enum": [
                "Homme",
                "Femme",
                "Homme et femme"
            ]
        },
        "type": {
            "type": "string",
            "enum": [
                "Loisir",
                "Intermediaire",
                "Competition"
            ]
        },
        "capacity": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 0,
            "maximum": 100000
        },
        "birth_year_start": {
            "type": "integer",
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "birth_year_end": {
            "type": "integer",
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "auto_validate": {
            "type": "boolean"
        },
        "invitation_only": {
            "type": "boolean"
        },
        "cost_euros": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000000,
            "description": "Montant en euros entiers."
        },
        "slot_count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
        },
        "slot_ids": {
            "type": "array",
            "items": {
                "type": "integer",
                "minimum": 1,
                "maximum": 2147483647
            },
            "maxItems": 100
        },
        "licence_ids": {
            "type": "array",
            "items": {
                "type": "integer",
                "minimum": 1,
                "maximum": 2147483647
            },
            "maxItems": 100
        }
    },
    "required": [
        "name",
        "season_id",
        "birth_year_start",
        "birth_year_end"
    ]
}
GET /groups/{id} — GET /groups/{id}

Autorisations : groups:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
PATCH /groups/{id} — PATCH /groups/{id}

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255
        },
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "sport_id": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1,
            "maximum": 2147483647
        },
        "description": {
            "type": "string",
            "maxLength": 10000
        },
        "sex": {
            "type": "string",
            "enum": [
                "Homme",
                "Femme",
                "Homme et femme"
            ]
        },
        "type": {
            "type": "string",
            "enum": [
                "Loisir",
                "Intermediaire",
                "Competition"
            ]
        },
        "capacity": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 0,
            "maximum": 100000
        },
        "birth_year_start": {
            "type": "integer",
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "birth_year_end": {
            "type": "integer",
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "auto_validate": {
            "type": "boolean"
        },
        "invitation_only": {
            "type": "boolean"
        },
        "cost_euros": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000000,
            "description": "Montant en euros entiers."
        },
        "slot_count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
        },
        "slot_ids": {
            "type": "array",
            "items": {
                "type": "integer",
                "minimum": 1,
                "maximum": 2147483647
            },
            "maxItems": 100
        },
        "licence_ids": {
            "type": "array",
            "items": {
                "type": "integer",
                "minimum": 1,
                "maximum": 2147483647
            },
            "maxItems": 100
        }
    },
    "required": []
}
GET /slots — GET /slots

Autorisations : groups:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
POST /slots — POST /slots

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255
        },
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "sport_id": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1,
            "maximum": 2147483647
        },
        "day": {
            "type": "string",
            "enum": [
                "lundi",
                "mardi",
                "mercredi",
                "jeudi",
                "vendredi",
                "samedi",
                "dimanche"
            ]
        },
        "hour": {
            "type": "integer",
            "minimum": 0,
            "maximum": 23
        },
        "minute": {
            "type": "integer",
            "minimum": 0,
            "maximum": 59
        },
        "duration_minutes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1440
        },
        "location": {
            "type": "string",
            "maxLength": 10000
        },
        "trainer_ids": {
            "type": "array",
            "items": {
                "type": "integer",
                "minimum": 1,
                "maximum": 2147483647
            },
            "maxItems": 100,
            "minItems": 1
        },
        "capacity": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000
        },
        "birth_year_start": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "birth_year_end": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "sex": {
            "type": [
                "string",
                "null"
            ],
            "enum": [
                "Homme",
                "Femme",
                "Homme et femme",
                null
            ]
        }
    },
    "required": [
        "name",
        "season_id",
        "day",
        "hour",
        "minute",
        "duration_minutes",
        "trainer_ids",
        "capacity"
    ]
}
GET /slots/{id} — GET /slots/{id}

Autorisations : groups:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
PATCH /slots/{id} — PATCH /slots/{id}

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255
        },
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "sport_id": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1,
            "maximum": 2147483647
        },
        "day": {
            "type": "string",
            "enum": [
                "lundi",
                "mardi",
                "mercredi",
                "jeudi",
                "vendredi",
                "samedi",
                "dimanche"
            ]
        },
        "hour": {
            "type": "integer",
            "minimum": 0,
            "maximum": 23
        },
        "minute": {
            "type": "integer",
            "minimum": 0,
            "maximum": 59
        },
        "duration_minutes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1440
        },
        "location": {
            "type": "string",
            "maxLength": 10000
        },
        "trainer_ids": {
            "type": "array",
            "items": {
                "type": "integer",
                "minimum": 1,
                "maximum": 2147483647
            },
            "maxItems": 100,
            "minItems": 1
        },
        "capacity": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100000
        },
        "birth_year_start": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "birth_year_end": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "sex": {
            "type": [
                "string",
                "null"
            ],
            "enum": [
                "Homme",
                "Femme",
                "Homme et femme",
                null
            ]
        }
    },
    "required": []
}
GET /lessons — GET /lessons

Autorisations : groups:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
POST /lessons — POST /lessons

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "group_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "day": {
            "type": "string",
            "enum": [
                "lundi",
                "mardi",
                "mercredi",
                "jeudi",
                "vendredi",
                "samedi",
                "dimanche"
            ]
        },
        "hour": {
            "type": "integer",
            "minimum": 0,
            "maximum": 23
        },
        "minute": {
            "type": "integer",
            "minimum": 0,
            "maximum": 59
        },
        "duration_minutes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1440
        },
        "location": {
            "type": "string",
            "maxLength": 10000
        },
        "trainer_ids": {
            "type": "array",
            "items": {
                "type": "integer",
                "minimum": 1,
                "maximum": 2147483647
            },
            "maxItems": 100,
            "minItems": 1
        }
    },
    "required": [
        "group_id",
        "day",
        "hour",
        "minute",
        "duration_minutes",
        "trainer_ids"
    ]
}
GET /lessons/{id} — GET /lessons/{id}

Autorisations : groups:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
PATCH /lessons/{id} — PATCH /lessons/{id}

Autorisations : groups:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "group_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "day": {
            "type": "string",
            "enum": [
                "lundi",
                "mardi",
                "mercredi",
                "jeudi",
                "vendredi",
                "samedi",
                "dimanche"
            ]
        },
        "hour": {
            "type": "integer",
            "minimum": 0,
            "maximum": 23
        },
        "minute": {
            "type": "integer",
            "minimum": 0,
            "maximum": 59
        },
        "duration_minutes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1440
        },
        "location": {
            "type": "string",
            "maxLength": 10000
        },
        "trainer_ids": {
            "type": "array",
            "items": {
                "type": "integer",
                "minimum": 1,
                "maximum": 2147483647
            },
            "maxItems": 100,
            "minItems": 1
        }
    },
    "required": []
}
Lister les adhérents validés d’un groupe — GET /groups/{id}/members

Liste paginée des adhérents dont l’inscription à ce groupe est validée. Le groupe porte son season_id ; utilisez POST /groups/search pour le trouver par saison, jour ou nom.

Autorisations : groups:read, members:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}

events

Événements, dates, lieux, capacités, tarifs et paramètres d’inscription. Les participants relèvent des accès aux inscriptions et aux adhérents. Création, modification et suppression des événements et de leurs paramètres.

POST /events — POST /events

Autorisations : events:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255
        },
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "sport_id": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1,
            "maximum": 2147483647
        },
        "description": {
            "type": "string",
            "maxLength": 10000
        },
        "begin": {
            "type": "string",
            "format": "date-time"
        },
        "end": {
            "type": "string",
            "format": "date-time"
        },
        "location": {
            "type": "string",
            "maxLength": 10000
        },
        "capacity": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 0,
            "maximum": 100000
        },
        "registration_deadline": {
            "type": [
                "string",
                "null"
            ],
            "format": "date"
        },
        "registration_opening": {
            "type": [
                "string",
                "null"
            ],
            "format": "date"
        },
        "birth_year_start": {
            "type": "integer",
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "birth_year_end": {
            "type": "integer",
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "cost_euros": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000000,
            "description": "Montant en euros entiers."
        },
        "external_access": {
            "type": "boolean"
        },
        "external_cost_euros": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 0,
            "maximum": 10000000,
            "description": "Montant en euros entiers."
        },
        "membership_required": {
            "type": "boolean"
        },
        "auto_validate": {
            "type": "boolean"
        },
        "pre_registration_required": {
            "type": "boolean"
        },
        "external_registration": {
            "type": "boolean"
        }
    },
    "required": [
        "name",
        "season_id",
        "begin",
        "end",
        "birth_year_start",
        "birth_year_end"
    ]
}
GET /events/{id} — GET /events/{id}

Autorisations : events:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
PATCH /events/{id} — PATCH /events/{id}

Autorisations : events:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255
        },
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "sport_id": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1,
            "maximum": 2147483647
        },
        "description": {
            "type": "string",
            "maxLength": 10000
        },
        "begin": {
            "type": "string",
            "format": "date-time"
        },
        "end": {
            "type": "string",
            "format": "date-time"
        },
        "location": {
            "type": "string",
            "maxLength": 10000
        },
        "capacity": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 0,
            "maximum": 100000
        },
        "registration_deadline": {
            "type": [
                "string",
                "null"
            ],
            "format": "date"
        },
        "registration_opening": {
            "type": [
                "string",
                "null"
            ],
            "format": "date"
        },
        "birth_year_start": {
            "type": "integer",
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "birth_year_end": {
            "type": "integer",
            "minimum": 1900,
            "maximum": 2200,
            "description": "Année de naissance limite."
        },
        "cost_euros": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000000,
            "description": "Montant en euros entiers."
        },
        "external_access": {
            "type": "boolean"
        },
        "external_cost_euros": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 0,
            "maximum": 10000000,
            "description": "Montant en euros entiers."
        },
        "membership_required": {
            "type": "boolean"
        },
        "auto_validate": {
            "type": "boolean"
        },
        "pre_registration_required": {
            "type": "boolean"
        },
        "external_registration": {
            "type": "boolean"
        }
    },
    "required": []
}
Lister les participants validés d’un événement — GET /events/{id}/members

Autorisations : events:read, registrations:read, members:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}

attendance

Séances à appeler, participants attendus et statuts de présence, d’absence ou d’absence excusée. L’accès aux fiches complètes des participants nécessite aussi l’accès aux adhérents. Saisie et correction du statut de présence d’un participant pour un cours, un créneau ou un événement.

Consulter les séances ou participants d’une date — GET /attendance

Liste les séances à une date. Fournir type et course_id pour obtenir les participants attendus et leur présence.

Autorisations : attendance:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
offset query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
date query Oui {"type":"string","format":"date"}
type query Non {"type":"string","enum":["lesson","slot","event"]}
course_id query Non {"type":"integer","minimum":1,"maximum":2147483647}
Renseigner la présence d’un participant à une séance — POST /attendance

Autorisations : attendance:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "required": [
        "date",
        "type",
        "course_id",
        "member_id",
        "presence"
    ],
    "properties": {
        "date": {
            "type": "string",
            "format": "date"
        },
        "type": {
            "type": "string",
            "enum": [
                "lesson",
                "slot",
                "event"
            ]
        },
        "course_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "member_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "presence": {
            "type": "string",
            "enum": [
                "present",
                "absent",
                "excused"
            ]
        }
    }
}
Consulter les présences d’un adhérent pour une saison — GET /members/{id}/attendance

Historique paginé des présences effectivement renseignées pour un adhérent pendant une saison : cours, créneaux et événements. Une séance sans présence enregistrée n’est pas interprétée comme une absence. Les filtres de dates, de type et de présence sont facultatifs.

Autorisations : members:read, attendance:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
offset query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
season_id query Oui {"type":"integer","minimum":1,"maximum":2147483647}
date_from query Non {"type":"string","format":"date"}
date_to query Non {"type":"string","format":"date"}
type query Non {"type":"string","enum":["lesson","slot","event"]}
presence query Non {"type":"string","enum":["present","absent","excused"]}

payments

Montants, dates, modes, états et affectations aux inscriptions. Les numéros de carte et coordonnées bancaires ne sont pas inclus. Enregistrement, correction, affectation et suppression des paiements dans SIGPAS.

GET /payments — GET /payments

Autorisations : payments:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
POST /payments — POST /payments

Autorisations : payments:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "member_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "amount_cents": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
        },
        "method": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Mode de règlement manuel, sans coordonnées bancaires."
        },
        "type": {
            "type": "string",
            "enum": [
                "Paiement",
                "Reduction",
                "Remboursement",
                "Autre"
            ]
        },
        "received_on": {
            "type": "string",
            "format": "date"
        },
        "allocations": {
            "type": "array",
            "items": {
                "type": "string",
                "maxLength": 100,
                "minLength": 1
            },
            "maxItems": 100
        }
    },
    "required": [
        "member_id",
        "season_id",
        "amount_cents",
        "method",
        "received_on"
    ]
}
GET /payments/{id} — GET /payments/{id}

Autorisations : payments:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
PATCH /payments/{id} — PATCH /payments/{id}

Autorisations : payments:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "member_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "amount_cents": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
        },
        "method": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Mode de règlement manuel, sans coordonnées bancaires."
        },
        "type": {
            "type": "string",
            "enum": [
                "Paiement",
                "Reduction",
                "Remboursement",
                "Autre"
            ]
        },
        "received_on": {
            "type": "string",
            "format": "date"
        },
        "allocations": {
            "type": "array",
            "items": {
                "type": "string",
                "maxLength": 100,
                "minLength": 1
            },
            "maxItems": 100
        }
    },
    "required": []
}
GET /payments/{id}/allocation-options — GET /payments/{id}/allocation-options

Autorisations : payments:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}

documents

Métadonnées et contenu des documents déposés ou générés. Ces fichiers peuvent contenir des données personnelles sensibles. Dépôt, remplacement et suppression de documents.

GET /documents — GET /documents

Autorisations : documents:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
POST /documents — POST /documents

Autorisations : documents:write

ParamètreEmplacementObligatoireFormat et contraintes
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255
        },
        "description": {
            "type": "string",
            "maxLength": 10000
        },
        "content_base64": {
            "type": "string",
            "minLength": 4,
            "maxLength": 13981016,
            "contentEncoding": "base64",
            "description": "PDF, JPEG ou PNG, maximum 10 Mio décodés."
        }
    },
    "required": [
        "name",
        "content_base64"
    ]
}
GET /documents/{id} — GET /documents/{id}

Autorisations : documents:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
PATCH /documents/{id} — PATCH /documents/{id}

Autorisations : documents:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
        "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 255
        },
        "description": {
            "type": "string",
            "maxLength": 10000
        },
        "content_base64": {
            "type": "string",
            "minLength": 4,
            "maxLength": 13981016,
            "contentEncoding": "base64",
            "description": "PDF, JPEG ou PNG, maximum 10 Mio décodés."
        }
    },
    "required": []
}
DELETE /documents/{id} — DELETE /documents/{id}

Autorisations : documents:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}
GET /documents/{id}/content — GET /documents/{id}/content

Autorisations : documents:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}

medical

Attestations de questionnaire de santé, certificats médicaux, dates, types, décisions de validation et suivi par saison. Enregistrement des attestations et certificats, puis validation ou refus des pièces médicales.

GET /medical — GET /medical

Autorisations : medical:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
GET /medical/{id} — GET /medical/{id}

Autorisations : medical:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
PATCH /medical/{id} — PATCH /medical/{id}

Autorisations : medical:write

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
Idempotency-Key header Oui Une nouvelle clé par opération. Réutiliser la même clé et le même corps après une coupure. Même réponse d’identifiant, sans répéter l’écriture. Une autre requête avec cette clé renvoie 409. Clés conservées pendant la durée de vie de l’intégration. {"type":"string","minLength":16,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}

Corps : application/json

{
    "type": "object",
    "additionalProperties": false,
    "minProperties": 2,
    "properties": {
        "season_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
        },
        "health_questionnaire": {
            "type": [
                "boolean",
                "null"
            ],
            "description": "null : en attente ; true : validée ; false : refusée."
        },
        "certificate_begin": {
            "type": [
                "string",
                "null"
            ],
            "format": "date"
        },
        "certificate_end": {
            "type": [
                "string",
                "null"
            ],
            "format": "date"
        },
        "certificate_type": {
            "type": "string",
            "enum": [
                "standard",
                "performance",
                "elite",
                "reprise"
            ]
        },
        "valid": {
            "type": [
                "boolean",
                "null"
            ],
            "description": "null : en attente ; true : validée ; false : refusée."
        },
        "content_base64": {
            "type": "string",
            "minLength": 4,
            "maxLength": 13981016,
            "contentEncoding": "base64",
            "description": "PDF, JPEG ou PNG, maximum 10 Mio décodés."
        }
    },
    "required": [
        "season_id"
    ]
}
GET /medical/{id}/content — GET /medical/{id}/content

Autorisations : medical:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}

staff_hours

Relevés mensuels validés par le personnel, avec leurs dates, durées et descriptions. La saisie et la validation restent réservées au membre du personnel dans SIGPAS.

GET /staff-hours/{id} — GET /staff-hours/{id}

Heures du mois validé par le personnel, avec total_seconds et entries paginées. 404 si le mois n’est pas validé ; 403 si la fonctionnalité est désactivée.

Autorisations : staff_hours:read

ParamètreEmplacementObligatoireFormat et contraintes
id path Oui {"type":"integer","minimum":1,"maximum":2147483647}
month query Oui {"type":"string","pattern":"^[12][0-9]{3}-(0[1-9]|1[0-2])$"}
after query Non {"type":"integer","minimum":0,"default":0}
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}

Exports globaux

Exports globaux explicites, couvrant toutes les saisons.

Exporter toutes les fiches de personnes, inscrites ou non — GET /members

Export global exceptionnel de toutes les saisons. Utiliser all=true sur chaque page. Sans ce paramètre, la réponse reste HTTP 200 avec les mêmes données et la même pagination, mais les en-têtes Deprecation et Link rel="deprecation" signalent cet usage déprécié. Aucune date de suppression n’est fixée. Pour une lecture métier normale, commencez par GET /seasons et suivez le chemin saisonnier correspondant. Cette collection contient toutes les fiches de personnes du club, y compris celles sans inscription. Elle ne représente pas les adhérents d’une saison.

Autorisations : members:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
all query Non Confirmation explicite d’un export exceptionnel couvrant toutes les saisons. L’omission reste acceptée mais est dépréciée ; les réponses portent Deprecation et Link rel="deprecation". {"type":"boolean","const":true}
Exporter exceptionnellement les groupes de toutes les saisons — GET /groups

Export global exceptionnel de toutes les saisons. Utiliser all=true sur chaque page. Sans ce paramètre, la réponse reste HTTP 200 avec les mêmes données et la même pagination, mais les en-têtes Deprecation et Link rel="deprecation" signalent cet usage déprécié. Aucune date de suppression n’est fixée. Pour une lecture métier normale, commencez par GET /seasons et suivez le chemin saisonnier correspondant.

Autorisations : groups:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
all query Non Confirmation explicite d’un export exceptionnel couvrant toutes les saisons. L’omission reste acceptée mais est dépréciée ; les réponses portent Deprecation et Link rel="deprecation". {"type":"boolean","const":true}
Exporter exceptionnellement les événements de toutes les saisons — GET /events

Export global exceptionnel de toutes les saisons. Utiliser all=true sur chaque page. Sans ce paramètre, la réponse reste HTTP 200 avec les mêmes données et la même pagination, mais les en-têtes Deprecation et Link rel="deprecation" signalent cet usage déprécié. Aucune date de suppression n’est fixée. Pour une lecture métier normale, commencez par GET /seasons et suivez le chemin saisonnier correspondant.

Autorisations : events:read

ParamètreEmplacementObligatoireFormat et contraintes
limit query Non {"type":"integer","minimum":1,"maximum":100,"default":50}
after query Non Valeur next_after ou next_offset de la réponse précédente. {"type":"integer","minimum":0,"default":0}
all query Non Confirmation explicite d’un export exceptionnel couvrant toutes les saisons. L’omission reste acceptée mais est dépréciée ; les réponses portent Deprecation et Link rel="deprecation". {"type":"boolean","const":true}