Tout le handball français, en JSON.
Clubs, équipes, matchs, classements, joueurs et arbitres de la FFHandball. Une API REST en lecture seule, mise à jour chaque nuit.
curl "/matchs?statut=joue&limit=1" \
-H "Authorization: Bearer ffhb_…"
ASC Le Geldar de Kourou33
Cosma Hand24
Voir le JSON
{
"data": [{
"id_ffhb_match": "2667833",
"date_heure": "2026-10-03T19:00:00.000Z",
"statut": "joue",
"journee": 3,
"equipe_dom_nom": "ASC LE GELDAR DE KOUROU",
"equipe_ext_nom": "COSMA HAND",
"score_dom": 33,
"score_ext": 24,
"poule_id_ffhb": "191400",
"competition_nom": "COUPE DE LA LIGUE PRENATIONALE MASCULINE",
"fdm_url": null
}],
"meta": { "total": 144, "limit": 1, "offset": 0 }
}
curl "/clubs?departement=57&limit=1" \
-H "Authorization: Bearer ffhb_…"
3mtMetz
Voir le JSON
{
"data": [{
"id_ffhb": "12121",
"code_ffhb": "5657119",
"nom": "3mt",
"ville": "Metz",
"departement_code": "57",
"telephone": "674159773",
"email": "5657119@ffhandball.net",
"site_web": null
}],
"meta": { "total": 3605, "limit": 1, "offset": 0 }
}
Ce que contient la base
Volumes constatés le 12 octobre 2026. Les saisons de 2023-2024 à 2026-2027 sont disponibles, et la saison en cours est rafraîchie chaque nuit à 02:00 (UTC).
| Ressource | Enregistrements | Ce que vous y trouvez |
|---|---|---|
| Clubs | 3 605 | Coordonnées, ville, département, équipes engagées, salles |
| Compétitions | 3 204 | Championnats et coupes, poules et classements |
| Matchs | 109 642 | Calendrier, scores, statut, lien vers la feuille de match |
| Joueurs | 244 180 | Fiche par numéro de licence, matchs joués, statistiques |
| Arbitres et salles | – | Officiels de chaque match, adresse des salles |
Endpoints
Toutes les routes de données sont en GET et renvoient du JSON. Le détail des paramètres et des schémas de réponse est dans la documentation interactive ; la spécification complète est en OpenAPI.
| Chemin | Rôle |
|---|---|
/clubs | Rechercher des clubs (q, departement) |
/clubs/{id} | Fiche d'un club. L'identifiant est l'id FFHB ou le code à 7 chiffres. |
/clubs/{id}/matchs | Calendrier du club |
/clubs/{id}/equipes | Équipes engagées |
/clubs/{id}/joueurs | Joueurs du club |
/clubs/{id}/classements | Classements des équipes du club |
/matchs | Lister les matchs (poule_id_ffhb, date_from, date_to, statut) |
/matchs/{id} | Détail d'un match |
/classements | Classement d'une poule (poule_id_ffhb obligatoire) |
/competitions, /competitions/{id} | Compétitions et leurs poules |
/poules/{id} | Détail d'une poule |
/equipes/{id} | Équipe, avec /matchs et /joueurs |
/joueurs/{licence} | Fiche d'un joueur, avec /matchs |
/stats-joueurs | Statistiques des joueurs |
/arbitres, /arbitres/{id} | Arbitres, avec /matchs |
/salles/{id} | Salle, avec /matchs |
/search | Recherche transversale |
/saisons, /departements, /ligues | Référentiels |
/health, /ready | État de l'API et de la base, sans clé |
Utiliser l'API
Premier appel
curl "/clubs?q=metz&limit=5" \
-H "Authorization: Bearer $FFHB_KEY"const res = await fetch("/clubs?q=metz&limit=5", {
headers: { Authorization: `Bearer ${process.env.FFHB_KEY}` },
});
const { data, meta } = await res.json();
console.log(meta.total, data[0].nom);import os, requests
r = requests.get(
"/clubs",
params={"q": "metz", "limit": 5},
headers={"Authorization": f"Bearer {os.environ['FFHB_KEY']}"},
)
r.raise_for_status()
print(r.json()["meta"]["total"])L'API n'envoie pas d'en-têtes CORS : appelez-la depuis votre serveur, pas depuis le navigateur de vos visiteurs, pour ne pas exposer votre clé.
Règles à connaître
- Clé API
- Quand l'accès par clé est activé, envoyez-la dans
Authorization: Bearer ffhb_…ou dansX-API-Key. Une clé absente, révoquée ou expirée renvoie alors401./health,/ready,/docset/openapi.jsonn'en demandent jamais. - Pagination
- Les listes prennent
limit(100 maximum, 20 par défaut) etoffset. La réponse contientdataetmetaavectotal,limitetoffset. - Quota
- 120 requêtes par minute, comptées par clé, ou par adresse IP sans clé. Les en-têtes
X-RateLimit-Limit,X-RateLimit-RemainingetX-RateLimit-Resetindiquent où vous en êtes. Au-delà,429etRetry-After. - Erreurs
- Le corps est
{ "error": { "code", "message" } }, avec les codesBAD_REQUEST,UNAUTHORIZED,NOT_FOUND,RATE_LIMIT_EXCEEDED,INTERNAL_ERRORetSERVICE_UNAVAILABLE. - Statut d'un match
a_jouer,joue,reporte,annuleouforfait. Le score restenulltant que le match n'est pas joué.