# Catalogue des champs

> Version générique : tous les champs sont listés avec la formule minimale qui y donne accès (`FREE`, `PRO`, `PARTNER`). Envoyez votre clé API (`Authorization: Bearer th_live_…`) ou connectez-vous à votre espace développeur pour obtenir la version personnalisée.

48 champs au total. La colonne « Formule » indique la formule minimale qui y donne accès ; un administrateur peut ajuster les champs d'un compte.

Un champ dont la dépendance n'est pas activée n'est jamais renvoyé. Tous les champs `formats.*` dépendent de `formats.id`.

Les données suivantes ne sont jamais exposées : descriptions, alias, contacts de l'organisation, avis détaillés, données internes de synchronisation.

### core

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `core.id` | `id` | `string` | `FREE` | Identifiant unique et stable de la course (cuid). Clé à utiliser pour vos upserts. |
| `core.slug` | `slug` | `string` | `FREE` | Identifiant lisible et unique de la course. |
| `core.name` | `name` | `string` | `FREE` | Nom de la course. |
| `core.url` | `url` | `string` | `FREE` | URL absolue de la fiche course sur Trail Horizon (lien source à afficher). |
| `core.nextEditionDate` | `nextEditionDate` | `date` | `FREE` | Date de la prochaine édition. |
| `core.lastEditionDate` | `lastEditionDate` | `date` | `FREE` | Date de la dernière édition passée. |
| `core.firstEditionDate` | `firstEditionDate` | `date` | `FREE` | Date de la première édition. |
| `core.updatedAt` | `updatedAt` | `date` | `FREE` | Date de dernière modification d'un champ exposé. |

### core.status

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `core.status` | `status` | `enum` | `PRO` | Statut : ACTIVE, CANCELLED ou DISCONTINUED. |

### core.verifiedAt

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `core.verifiedAt` | `verifiedAt` | `date` | `PRO` | Date de dernière vérification des données. |

### location

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `location.city` | `location.city` | `string` | `FREE` | Ville de départ. |
| `location.lat` | `location.lat` | `number` | `FREE` | Latitude du départ (WGS84). |
| `location.lon` | `location.lon` | `number` | `FREE` | Longitude du départ (WGS84). |
| `location.region` | `location.region` | `string` | `FREE` | Région. |
| `location.country` | `location.country` | `string` | `FREE` | Pays. |
| `location.continent` | `location.continent` | `string` | `FREE` | Continent. |

### links

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `links.website` | `links.website` | `string` | `FREE` | Site officiel. |
| `links.registration` | `links.registration` | `string` | `FREE` | Page d'inscription. |
| `links.facebook` | `links.facebook` | `string` | `FREE` | Page Facebook. |
| `links.instagram` | `links.instagram` | `string` | `FREE` | Compte Instagram. |
| `links.youtube` | `links.youtube` | `string` | `FREE` | Chaîne YouTube. |

### formats

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `formats.id` | `formats[].id` | `string` | `FREE` | Identifiant unique et stable du format. Requis par tous les champs `formats.*`. |
| `formats.name` | `formats[].name` | `string` | `FREE` | Nom du format. (requiert `formats.id`) |
| `formats.distance` | `formats[].distance` | `number` | `FREE` | Distance en km (édition affichée). (requiert `formats.id`) |
| `formats.elevation` | `formats[].elevation` | `number` | `FREE` | Dénivelé positif en mètres (édition affichée). (requiert `formats.id`) |
| `formats.category` | `formats[].category` | `enum` | `FREE` | Catégorie du format (11 valeurs fermées). (requiert `formats.id`) |
| `formats.type` | `formats[].type` | `enum` | `FREE` | Type : STANDARD, RELAY, STAGE, KIDS, WALK, FIXED_TIME, VERTICAL. (requiert `formats.id`) |

### formats.rankingTypes

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `formats.rankingTypes` | `formats[].rankingTypes` | `enum[]` | `FREE` | Systèmes de classement : ITRA, UTMB Index, Betrail. (requiert `formats.id`) |

### formats.tags

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `formats.tags` | `formats[].tags` | `string[]` | `FREE` | Mots-clés libres décrivant le format. (requiert `formats.id`) |

### formats.schedule

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `formats.startAt` | `formats[].startAt` | `date` | `PRO` | Date de départ de l'édition affichée (midi UTC si l'heure est inconnue). (requiert `formats.id`) |
| `formats.hasStartTime` | `formats[].hasStartTime` | `boolean` | `PRO` | Indique si l'heure de `startAt` est connue. (requiert `formats.id`) |
| `formats.timezone` | `formats[].timezone` | `string` | `PRO` | Fuseau IANA du départ. (requiert `formats.id`) |
| `formats.duration` | `formats[].duration` | `number` | `PRO` | Durée en minutes (formats à temps fixe). (requiert `formats.id`) |

### formats.registration

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `formats.registrationStatus` | `formats[].registrationStatus` | `enum` | `PRO` | État des inscriptions : OPEN, FULL, CLOSED, NOT_YET_OPEN. (requiert `formats.id`) |
| `formats.registrationOpensAt` | `formats[].registrationOpensAt` | `date` | `PRO` | Date d'ouverture des inscriptions. (requiert `formats.id`) |
| `formats.maxParticipants` | `formats[].maxParticipants` | `number` | `PRO` | Nombre maximal de participants. (requiert `formats.id`) |

### formats.pricing

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `formats.price` | `formats[].price` | `number` | `PRO` | Prix de l'inscription. (requiert `formats.id`) |
| `formats.currency` | `formats[].currency` | `string` | `PRO` | Devise ISO 4217 (EUR par défaut). (requiert `formats.id`) |

### formats.trace

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `formats.traceUrl` | `formats[].traceUrl` | `string` | `PRO` | Lien vers la trace du parcours. (requiert `formats.id`) |

### formats.gear

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `formats.practicalInfoStructured.requiredGear` | `formats[].practicalInfoStructured.requiredGear` | `object` | `PRO` | Matériel obligatoire structuré (sous-ensemble de `practicalInfoStructured`). (requiert `formats.id`) |

### formats.practicalInfo

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `formats.practicalInfo` | `formats[].practicalInfo` | `string` | `PARTNER` | Texte des informations pratiques et du matériel. (requiert `formats.id`) |
| `formats.practicalInfoStructured` | `formats[].practicalInfoStructured` | `object` | `PARTNER` | Informations pratiques structurées complètes. (requiert `formats.id`, `formats.practicalInfoStructured.requiredGear`) |

### rating

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `rating.averageRating` | `averageRating` | `number` | `PRO` | Note moyenne des coureurs, arrondie à 0,1. |

### images

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `images.logo` | `images.logo` | `string` | `PARTNER` | URL du logo. |
| `images.card` | `images.card` | `string` | `PARTNER` | URL de la vignette. |
| `images.coverDesktop` | `images.coverDesktop` | `string` | `PARTNER` | URL de la couverture paysage. |
| `images.coverPhone` | `images.coverPhone` | `string` | `PARTNER` | URL de la couverture mobile. |

### history

| Champ | Emplacement dans le JSON | Type | Formule | Description |
| --- | --- | --- | --- | --- |
| `history.editions` | `(endpoint)` | `endpoint` | `PARTNER` | Endpoint `/races/{id}/editions` (historique des éditions). |
