Dernière actualisation le 26/07/2026 à 04:23
⚡ Challenge Quinté : participez dès maintenant !

API turf.bzh - documentation

Accès programmatique aux données hippiques turf.bzh : programme, partants exacts, cotes PMU en direct, arrivées, Quinté+. Format JSON, lecture seule. Que vous vouliez remplir un tableur, recevoir une alerte ou brancher un bot, commencez par les Premiers pas ci-dessous : une URL qui marche dans votre navigateur suffit.

Premiers pas en 5 minutes

Le chemin le plus court, sans écrire une ligne de code : une adresse qui marche dans votre navigateur.

  1. Débloquez la Licence API (19,90 € une fois) sur api-licence.php, avec un abonnement turf.bzh actif.
  2. Générez votre clé sur Mon accès API (elle ne s'affiche qu'une fois, copiez-la).
  3. Collez cette adresse dans la barre de votre navigateur, en remplaçant la clé, et validez :
    https://www.turf.bzh/api/v1/programme?api_key=tbz_live_VOTRE_CLE
    Vous voyez le programme du jour en JSON. Si ça s'affiche, vous êtes prêt.
  4. Pour un tableau propre qui s'ouvre dans Excel, ajoutez &format=csv à la fin de l'adresse.
Prendre un modèle prêt à l'emploi
Pratique, mais à connaître : la clé dans l'adresse (?api_key=) convient à un test rapide ou à un fichier gardé sur votre ordinateur. Ne la mettez jamais dans une page web publique ni un lien partagé : dans ce cas, préférez l'en-tête Authorization côté serveur (voir Authentification).

Accès

Deux conditions, vérifiées à chaque requête :

  • La Licence API (paiement unique, à vie) : api-licence.php
  • Un abonnement turf.bzh actif. En cas de résiliation, l'API est suspendue ; elle se réactive seule au réabonnement, sans re-payer.

URL de base : https://www.turf.bzh/api/v1/ - HTTPS uniquement. Les réponses ne sont jamais mises en cache (Cache-Control: no-store) : ce que vous recevez est frais.

Une clé, deux usages. La même clé couvre les endpoints DONNÉES (programme, partants, cotes en direct, arrivées, base historique - illimités) et les endpoints CHATBZH (question à l'agent, méthodes), qui consomment vos crédits IA comme sur le site.

Authentification

Générez votre clé personnelle sur Mon accès API (affichée une seule fois). Envoyez-la à chaque requête, de préférence en en-tête :

Authorization: Bearer tbz_live_VOTRE_CLE

Alternatives tolérées : l'en-tête X-Api-Key: tbz_live_..., ou le paramètre ?api_key=tbz_live_... pour les outils qui ne savent pas poser d'en-tête (Google Sheets, tableurs, liens de test). Attention avec le paramètre d'URL : la clé peut traîner dans des historiques. En cas de doute, régénérez-la (l'ancienne meurt immédiatement).

La clé est personnelle : pas de partage, pas d'usage mutualisé. Chaque clé est auditée.

Quickstart

curl - le programme du jour

curl -H "Authorization: Bearer tbz_live_VOTRE_CLE" \
  "https://www.turf.bzh/api/v1/programme"

Python - cotes live d'une course, toutes les 60 secondes

import requests, time

KEY = "tbz_live_VOTRE_CLE"
URL = "https://www.turf.bzh/api/v1/courses/2026-07-26/R1C4/cotes"

while True:
    r = requests.get(URL, headers={"Authorization": f"Bearer {KEY}"}, timeout=15)
    j = r.json()
    if "error" in j:
        print("Erreur:", j["error"]["message"])
        break
    for p in j["data"]["partants"]:
        print(p["num"], p["cheval"], p["cote"])
    time.sleep(60)  # restez au-dessus de 30 s : les cotes sont cachées côté serveur

Google Sheets - partants dans une feuille

Le plus simple, sans en-tête à gérer : la fonction IMPORTDATA avec la clé en paramètre et &format=csv. Mettez votre clé dans une cellule (ici A1) :

=IMPORTDATA("https://www.turf.bzh/api/v1/programme?api_key=" & A1 & "&format=csv")

Pour poser un vrai en-tête Authorization (plus propre), passez par Apps Script (Extensions > Apps Script) :

function partants() {
  var url = "https://www.turf.bzh/api/v1/courses/2026-07-26/R1C4";
  var res = UrlFetchApp.fetch(url, {
    headers: { Authorization: "Bearer tbz_live_VOTRE_CLE" }
  });
  var data = JSON.parse(res.getContentText()).data;
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.clear();
  sheet.appendRow(["Num", "Cheval", "Driver", "Cote BZH", "Note IA"]);
  data.partants.forEach(function (p) {
    sheet.appendRow([p.num, p.name, p.jockey_driver, p.Cote_BZH, p.Note_IA]);
  });
}

Galerie de cas d'usage

Tutoriel - Excel qui se remplit tout seul

L'astuce : la même clé accepte ?api_key= dans l'URL et ?format=csv pour renvoyer un tableau propre. Excel n'a alors aucun en-tête à gérer, il suffit de lui donner une adresse.

Le plus simple : le pack prêt à l'emploi

Téléchargez le Pack Excel turf.bzh : programme et Quinté, cotes d'une course, value bets, plus un suivi de bankroll. Vous collez votre clé dans une cellule, l'onglet Mode d'emploi vous guide, puis vous cliquez sur Actualiser tout.

Le faire vous-même (Power Query)

  1. Ruban Données > Obtenir des données > À partir d'autres sources > Requête vide.
  2. Ouvrez Affichage > Éditeur avancé et collez ce code (adaptez l'endpoint) :
    let
        Cle = "tbz_live_VOTRE_CLE",
        Source = Csv.Document(
            Web.Contents("https://www.turf.bzh",
                [ RelativePath = "api/v1/programme",
                  Query = [ api_key = Cle, #"format" = "csv" ] ]),
            [Delimiter=";", Encoding=65001, QuoteStyle=QuoteStyle.Csv]),
        Promu = Table.PromoteHeaders(Source, [PromoteAllScalars=true])
    in
        Promu
  3. Fermer et charger. À la première fois, Excel demande le niveau de confidentialité de la source : choisissez Anonyme.
  4. Ensuite, Données > Actualiser tout met le tableau à jour quand vous voulez.
Le piège classique de Power Query (erreur "source de données dynamique") vient d'une URL construite en un seul morceau. On l'évite en gardant une adresse de base fixe (https://www.turf.bzh) et en passant le reste via RelativePath et Query, comme ci-dessus. Le pack Excel applique déjà cette recette. Rappel : votre clé est en clair dans le classeur, gardez-le sur votre ordinateur.

Tutoriel - alerte "baisse de cote" sur Telegram en 3 étapes

  1. Créez un bot Telegram. Dans Telegram, écrivez à @BotFather, envoyez /newbot : il vous donne un jeton. Récupérez aussi votre identifiant de discussion (chat_id) en écrivant à @userinfobot.
  2. Lisez les mouvements de cote d'une course avec l'endpoint /cotes/mouvements.
  3. Envoyez un message quand une cote baisse au-delà de votre seuil, via l'API Telegram.

Repérez d'abord les champs exacts de la réponse (le nom des colonnes peut évoluer) :

curl -H "Authorization: Bearer tbz_live_VOTRE_CLE" \
  "https://www.turf.bzh/api/v1/courses/2026-07-26/R1C4/cotes/mouvements?fenetre=5&limit=8"

Puis, un script à lancer à intervalle régulier (adaptez les noms de champs à ce que vous voyez) :

import requests

CLE   = "tbz_live_VOTRE_CLE"
BOT   = "JETON_BOTFATHER"      # de @BotFather
CHAT  = "VOTRE_CHAT_ID"        # de @userinfobot
DATE, COURSE = "2026-07-26", "R1C4"
SEUIL = 0.8                    # alerter si une cote perd au moins 0,8 point

api = requests.Session()
api.headers["Authorization"] = f"Bearer {CLE}"
url = f"https://www.turf.bzh/api/v1/courses/{DATE}/{COURSE}/cotes/mouvements"
data = api.get(url, params={"fenetre": 5, "limit": 8}, timeout=15).json().get("data", {})

for m in data.get("mouvements", []):
    evo = m.get("evolution_5min", m.get("evolution", 0)) or 0
    if evo <= -SEUIL:
        txt = f"Baisse {COURSE} : {m.get('cheval')} -> {m.get('cote')} ({evo})"
        requests.get(f"https://api.telegram.org/bot{BOT}/sendMessage",
                     params={"chat_id": CHAT, "text": txt}, timeout=15)

Pour lancer ce script automatiquement, utilisez le Planificateur de tâches (Windows) ou une tâche cron (Mac/Linux), ou passez par n8n/Make (voir plus bas). Pour un bot qui répond à des commandes, voir le tutoriel suivant.

Tutoriel - votre bot turf privé

Nous fournissons un bot Telegram prêt à héberger, en Python, qui tourne sur votre ordinateur et répond à vos commandes :

  • /course R1C4 - la fiche et les partants d'une course
  • /cotes R1C4 - les cotes PMU en direct
  • /tops ELO_Cheval - le top du jour d'un indicateur
  • /value - les value bets du jour
  • /analyse R1C4 - le classement multi-features d'une course

Il n'a besoin d'aucun serveur ni adresse publique (il utilise le "long polling" Telegram). Téléchargez-le, il est livré avec un mode d'emploi :

Télécharger le bot Telegram

En résumé : créez le bot avec @BotFather, mettez votre jeton et votre clé API dans config.py, lancez python bot.py. La même logique se transpose à Discord (bibliothèque discord.py) : une commande, un appel à l'API, une réponse.

Tutoriel - brancher ChatBZH à votre outil

Une question, une réponse complète en un seul appel. L'agent choisit ses outils (programme, cotes, indicateurs, vos méthodes), analyse et renvoie un texte. Cet endpoint consomme vos crédits IA (comme sur le site).

import requests

r = requests.post("https://www.turf.bzh/api/v1/chat",
    headers={"Authorization": "Bearer tbz_live_VOTRE_CLE"},
    json={"question": "Quels sont les 3 meilleurs ELO du Quinté du jour ?",
          "mode": "standard", "max_credits": 100},
    timeout=240)
j = r.json()
if "error" in j:
    print("Refus:", j["error"]["message"])   # ex : plafond de crédits dépassé, avant tout débit
else:
    d = j["data"]
    print(d["reponse"])                       # le texte de l'agent, à afficher dans votre outil
    print("Outils:", d.get("tools_utilises"))
    print("Crédits facturés:", d["credits"]["factures"], "- reste:", d["credits"]["solde_restant"])

Le JSON de réponse contient : reponse (le texte), tools_utilises (les outils appelés), credits.factures et credits.solde_restant, et forfait_applique (60 cr pour appliquer une méthode, 100 cr pour un backtest). Prévoyez un délai : un tour peut durer 30 à 180 secondes. Chaque appel est autonome (pas de mémoire de conversation), mettez tout le contexte utile dans la question.

Endpoints V1

Tout est en GET (sauf /chat). Les dates sont au format YYYY-MM-DD, les courses au format turfiste R1C4. Réponse : {"data": ..., "meta": {...}} en succès, {"error": {...}} sinon.

EndpointCe que ça renvoie
/v1/meÉtat de votre compte : licence, abonnement, clé, crédits IA, usage API du jour, limites.
/v1/statutFraîcheur de la base (healthcheck pour vos scripts) : fresh / stale / empty, nombre de courses chargées.
/v1/programmeLe programme du jour : courses, hippodromes, disciplines, heures, nombre de partants, drapeau Quinté+. Paramètre filter : all (défaut), upcoming, completed.
/v1/quinteLa course du Quinté+ du jour (source officielle turf.bzh) avec sa fiche complète et ses partants.
/v1/resultatsArrivées et rapports (SG/SP) des courses terminées du jour. Paramètre optionnel code_course.
/v1/courses/{date}/{rc}Fiche d'une course + partants EXACTS : numéro, cheval, driver/jockey, entraîneur, ferrure, musique, Cote BZH, ELO, Note IA, popularité... Fonctionne aussi sur l'historique (264 000+ courses). Le jour J, la colonne Cote est volontairement absente : utilisez /cotes (temps réel) ou Cote_BZH.
/v1/courses/{date}/{rc}/cotesCotes PMU en direct : cote actuelle, cote il y a 5 min, évolution, fraîcheur. Cache serveur adaptatif (rafraîchi plus vite à l'approche du départ).
/v1/courses/{date}/{rc}/cotes/mouvementsLes plus gros mouvements de cote sur une fenêtre glissante. Paramètres : fenetre (2-60 min, défaut 5), limit (1-8, défaut 5).
/v1/courses/{date}/{rc}/arriveeL'arrivée d'une course en quasi temps réel le jour J (source PMU live), rapports inclus quand disponibles.
/v1/courses/{date}/{rc}/indicateursFeatures calculées par partant : tendances ELO 30/90 j, forme récente, écarts, affinité distance/hippodrome, synergie jockey, signal IMDC, incidents...
/v1/courses/{date}/{rc}/analyseLe classement multi-features de la course (avec explication des rangs) + la LigneBZH du jour quand elle est disponible.
/v1/courses/{date}/{rc}/ecartsÉcarts de victoires/places : ceux du CHEVAL (vrai signal de forme) et ceux du numéro (folklore, présenté comme tel).
/v1/courses/{date}/{rc}/renifleurExclusif. Le carnet de notes du Renifleur : le résumé rédigé après l'arrivée de cette course, le cheval retenu pour la prochaine fois, et surtout les partants qui avaient déjà été repérés à leur dernière sortie. Contenu éditorial, lisez ce que ça vaut.
/v1/topsTop N du jour par indicateur (34 indicateurs : ELO_Cheval, Cote_BZH, Note_IA, IMDC, Popularite...). Paramètres : indicateur (requis), n (1-50), discipline, date.
/v1/value-betsLes value bets du jour (composite maison Cote_BZH_fiable). Paramètre n (1-30).
/v1/chevaux?recherche=Recherche d'un cheval par nom -> renvoie les idcheval à utiliser ensuite.
/v1/chevaux/{id}/historiqueLes dernières courses du cheval (max 50 par appel, filtre discipline).
/v1/chevaux/{id}/statsStats agrégées du cheval (periode_jours optionnel).
/v1/chevaux/{id}/lecturesLes lectures expertes actives du jour pour ce cheval.
/v1/chevaux/{id}/renifleurExclusif. Toutes les notes que Le Renifleur a écrites sur ce cheval, de la plus récente à la plus ancienne. Paramètre n_last (1-40, défaut 10).
/v1/personnes?recherche=&type=Recherche jockey/driver/entraîneur (moteur sémantique + repli) -> renvoie les ids.
/v1/personnes/{type}/{id}/statsStats d'un jockey ou entraîneur : periode_jours, discipline, hippodrome (jockey uniquement).
/v1/methodesLa liste de vos méthodes BZH enregistrées (créées dans ChatBZH). Pour les appliquer/backtester par API : voir /v1/chat ci-dessous.

Sortie tableur : ajoutez ?format=csv sur /programme, /courses/{date}/{rc}, /cotes, /tops et /value-bets pour recevoir un CSV UTF-8 (Excel FR, séparateur point-virgule).

Spec machine : openapi.json (OpenAPI 3, importable dans Postman, Swagger, ou un générateur de client).

Exemple de réponse (extrait de /v1/courses/{date}/{rc}/cotes) :

{
  "data": {
    "date": "2026-07-26",
    "code_course": "R1C4",
    "source": "pmu",
    "updated_at": "2026-07-26T13:01:02+02:00",
    "partants": [
      { "num": 1, "cheval": "EXEMPLE DU BOIS", "cote": 4.8,
        "cote_5min_ago": 5.2, "evolution_5min": -0.4,
        "fraicheur_label": "< 2 min", "np": false }
    ]
  },
  "meta": { "generated_at": "2026-07-26T13:01:02+02:00", "temps_reel": true }
}

Le carnet de notes du Renifleur

Après chaque réunion, Le Renifleur relit les commentaires officiels de fin de course, raconte l'épreuve en deux ou trois phrases et retient un cheval qui mérite un coup d'oeil la prochaine fois. C'est du contenu écrit, produit chaque jour, que vous ne trouverez nulle part ailleurs. Deux endpoints l'exposent.

Sur une course

curl -H "X-API-Key: VOTRE_CLE" \
  "https://www.turf.bzh/api/v1/courses/2026-07-25/R1C4/renifleur"
{
  "data": {
    "date": "2026-07-25",
    "code_course": "R1C4",
    "carnet_de_course": {
      "resume": "Comme une pâtissière qui sort son gâteau du four une seconde trop tard, ...",
      "cheval_retenu": { "numero": 8, "nom": "LORIGRE",
                         "raison": "A pointé en retard à l'usine, mais a fait les heures sup'." },
      "url": "/pronostics-pmu-25072026-R1C4.html"
    },
    "deja_reperes": [
      { "num": 3, "cheval": "PASSE COMPOSE", "repere_le": "2026-07-20", "repere_a": "Vichy",
        "portait_le_numero": 9, "jours_depuis": 6, "course_origine": "R2C1",
        "note": "Bloquée aux six cents, elle n'a jamais pu sortir." }
    ],
    "nb_deja_reperes": 1,
    "avertissement": "Note de course, pas un pronostic. ..."
  },
  "meta": { "date": "2026-07-25", "code_course": "R1C4" }
}

carnet_de_course vaut null tant que la course n'a pas été courue et débriefée. deja_reperes est le champ le plus intéressant : ce sont les partants du jour qui étaient passés sous le nez du Renifleur à leur sortie précédente. La note n'apparaît que sur leur course de rentrée, et pendant 60 jours au maximum.

Sur un cheval

curl -H "X-API-Key: VOTRE_CLE" \
  "https://www.turf.bzh/api/v1/chevaux/1347094367/renifleur?n_last=5"

Renvoie nb_notes et la liste des notes. nb_notes: 0 signifie que ce cheval n'a jamais été repéré sur la période conservée, soit 400 jours. Environ un cheval sur seize parmi les partants du jour porte une note active.

Ce que ça vaut, honnêtement

Nous mesurons ce carnet et nous publions le résultat, parce qu'un chiffre non vérifié ne vaut rien. Sur 2 411 rentrées analysées :

Arrivée à la rentréeChevaux repérésTous les partantsAttendu par la cote
Dans les trois premiers35,9 %27,8 %34,5 %
Dans les quatre premiers46,7 %37,0 %44,7 %
Gagnant11,9 %9,3 %12,0 %

Lecture : Le Renifleur repère des chevaux nettement meilleurs que la moyenne du peloton. Mais la troisième colonne dit l'essentiel : à cote égale, l'écart n'est pas significatif. Ces chevaux partent déjà à une cote qui tient compte de leur valeur. Un euro joué au gagnant sur chacun d'eux en rendrait 0,72.

Ne construisez pas un modèle de pari sur ce champ. Utilisez-le pour ce qu'il est : du contenu à afficher, un fil narratif pour vos utilisateurs, une mémoire de course. Chaque réponse porte un champ avertissement qui reprend ces chiffres, de sorte qu'un agent qui consomme l'API ne puisse pas les ignorer.

Droits d'usage

Ces textes sont produits et financés par turf.bzh. Leur réutilisation publique suppose une attribution visible à turf.bzh et un lien vers la course d'origine, fourni dans le champ url. La republication en masse sans attribution n'est pas couverte par la Licence API : voir les conditions.

Exemples copier-coller (Python, Node.js, PHP)

Le même appel dans trois langages : on lit le programme du jour, on affiche le contenu. Explorez la structure renvoyée, puis ciblez ce qui vous intéresse.

Python (requests)

import requests

r = requests.get("https://www.turf.bzh/api/v1/programme",
                 headers={"Authorization": "Bearer tbz_live_VOTRE_CLE"},
                 timeout=15)
j = r.json()
if "error" in j:
    print("Erreur:", j["error"]["message"])
else:
    print(j["data"])   # explorez, puis ciblez j["data"][...] selon vos besoins

Node.js (18+ : fetch intégré)

const KEY = "tbz_live_VOTRE_CLE";

const res = await fetch("https://www.turf.bzh/api/v1/programme", {
  headers: { Authorization: `Bearer ${KEY}` }
});
const j = await res.json();
if (j.error) {
  console.error("Erreur:", j.error.message);
} else {
  console.log(j.data);
}

PHP (cURL)

<?php
$ch = curl_init("https://www.turf.bzh/api/v1/programme");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ["Authorization: Bearer tbz_live_VOTRE_CLE"],
    CURLOPT_TIMEOUT        => 15,
]);
$j = json_decode(curl_exec($ch), true);
curl_close($ch);
if (isset($j["error"])) {
    echo "Erreur: " . $j["error"]["message"];
} else {
    print_r($j["data"]);
}

Postman, n8n et Make

Postman

Deux façons de démarrer : importez notre collection Postman prête (tous les endpoints rangés par thème), ou importez directement la spec openapi.json (Postman > Import > Link ou File).

  1. Importez la collection dans Postman.
  2. Ouvrez l'onglet Variables de la collection, remplacez api_key par votre clé, ajustez date et rc.
  3. L'authentification Bearer est déjà posée au niveau de la collection : lancez n'importe quelle requête.

n8n

Ajoutez un nœud HTTP Request : méthode GET, URL https://www.turf.bzh/api/v1/programme. Dans Authentication, choisissez Generic Credential Type > Header Auth, avec le nom Authorization et la valeur Bearer tbz_live_VOTRE_CLE. Enchaînez ensuite un nœud de traitement ou une notification (Telegram, e-mail...).

Make (ex-Integromat)

Module HTTP > Make a request : URL de l'endpoint, méthode GET, et un en-tête Authorization = Bearer tbz_live_VOTRE_CLE. Activez Parse response pour manipuler le JSON directement.

Depuis un navigateur (fetch cross-origin), l'API accepte les requêtes : elle renvoie les en-têtes CORS nécessaires et répond aux pré-vérifications. Mais ne mettez jamais votre clé en dur dans une page web publique (elle serait visible dans le code) : pour un outil public, faites transiter l'appel par votre propre serveur (relais), qui seul détient la clé.

POSTChatBZH par API - /v1/chat

Posez une question à ChatBZH comme sur le site : l'agent choisit ses outils (programme, cotes live, indicateurs, vos méthodes...), analyse, et renvoie une réponse complète en un seul JSON. Cet endpoint consomme les crédits IA de votre compte (mêmes règles que le site : plafond 300 cr par question, forfait 60 cr pour appliquer une méthode, 100 cr pour un backtest).

curl -X POST "https://www.turf.bzh/api/v1/chat" \
  -H "Authorization: Bearer tbz_live_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{"question": "Applique ma méthode Borda V2 sur R1C4", "mode": "standard", "max_credits": 100}'
  • question (requis) : votre question, comme dans le chat.
  • mode : standard (défaut) ou expert (analyse approfondie, coûte ~3x plus).
  • max_credits (5-300, défaut 300) : votre plafond d'acceptation. Si l'estimation dépasse, refus 402 cost_exceeds_max_credits AVANT tout débit - l'équivalent API de la modale de confirmation du site.
  • Réponse : reponse (texte), tools_utilises, credits.factures, credits.solde_restant, forfait_applique.
  • Patience : un tour peut durer 30 à 180 secondes (l'agent enchaîne plusieurs outils). Prévoyez un timeout client de 240 s. Limite : 10 questions/minute, 1 question à la fois par compte.
  • Chaque appel est autonome (pas de mémoire de conversation) : mettez tout le contexte dans la question.

Erreurs

Toute erreur renvoie un JSON uniforme :

{ "error": { "code": "subscription_required", "message": "...", "status": 403, "doc": "..." } }
HTTPcodeSignification
401missing_key / invalid_keyClé absente, inconnue ou révoquée. Générez / régénérez sur Mon accès API.
403api_lockedLicence API non débloquée sur ce compte.
403subscription_requiredAbonnement inactif. La licence reste acquise : réabonnez-vous et ça repart.
402insufficient_credits(/chat) Solde crédits IA insuffisant. Rechargez sur chatbzh-boutique.php.
402cost_exceeds_max_credits(/chat) L'estimation dépasse votre max_credits : augmentez-le ou simplifiez la question. Rien n'a été débité.
404not_foundRoute ou course inconnue (la réponse liste parfois les courses disponibles).
405method_not_allowedGET partout, sauf /v1/chat qui attend un POST.
422invalid_paramsParamètre mal formé (date, code course, bornes).
429rate_limitedLimite technique atteinte. Respectez l'en-tête Retry-After.
500 / 503internal_error / upstream_unavailableIncident côté serveur ou source amont : réessayez un peu plus tard.

Limites et bonnes pratiques

  • 60 requêtes/minute et 10 000/jour par clé (limite technique anti-abus, pas un compteur commercial). Réponse 429 + Retry-After au-delà.
  • /v1/chat : 10 questions/minute et une seule question à la fois par compte (le solde de crédits IA borne naturellement le reste).
  • Les cotes live sont rafraîchies côté serveur avec un cache adaptatif : interroger plus d'une fois toutes les 30 s n'apporte rien.
  • Ne mettez JAMAIS votre clé dans du code visible (page web publique, dépôt GitHub public, capture d'écran). En cas de fuite : régénérez.
  • Usage personnel uniquement : la revente, la redistribution des données ou le partage de clé sont interdits (CGV turf.bzh) et détectés par l'audit.
  • Contrat de version : sur /v1, des champs peuvent être AJOUTÉS, jamais retirés ni renommés. Codez tolérant aux champs inconnus.

Jeu responsable

Les données et indicateurs turf.bzh sont des outils d'aide à la décision pour un loisir. Aucune API, aucun indicateur, aucun modèle ne garantit un gain : les courses comportent une part d'incertitude irréductible. Automatiser ses analyses ne doit jamais devenir automatiser ses mises. Fixez-vous des limites de budget et de temps, et ne jouez que ce que vous pouvez vous permettre de perdre.

Changelog

V1 26/07/2026 - Lancement : clé API self-service, licence à vie 19,90 €, endpoints me, statut, programme, quinte, resultats, courses/{date}/{rc} (+ /cotes, /cotes/mouvements, /arrivee).

V2-V4 26/07/2026 - Données premium (indicateurs, analyse + LigneBZH, écarts, tops, value-bets, lectures, chevaux, personnes), format=csv, POST /v1/chat (crédits IA), /v1/methodes, spec openapi.json.

V5 26/07/2026 - Carnet de notes du Renifleur : /v1/courses/{date}/{rc}/renifleur et /v1/chevaux/{id}/renifleur. Contenu éditorial exclusif, avec la mesure de ce qu'il vaut publiée dans la section dédiée.

Docs 26/07/2026 - Documentation orientée cas d'usage : premiers pas en 5 min, galerie, tutoriels (Excel/Power Query, alerte Telegram, bot, ChatBZH), exemples Python/Node/PHP, outils n8n/Make, et modèles téléchargeables (pack Excel, collection Postman, bot).