Introduction
Nyama Sports Data est un fournisseur de données sportives : cotes pregame et live, résultats et scores en direct, issus de notre back office d'agrégation. L'API expose un schéma stable versionné v1. Chaque ressource est normalisée et accompagnée d'une enveloppe de traçabilité _provenance.
Format : JSON UTF-8. Cotes en format décimal. Dates en ISO 8601. Les horodatages de match (startsAt) sont exprimés dans le fuseau configuré pour votre compte (par défaut heure du Cameroun, UTC+1) ; les horodatages techniques (_provenance.fetchedAt) restent en UTC. Voir la section Fuseaux horaires.
Base URL & Authentification
Base URL : https://real-odds-api-production.up.railway.app Toutes les routes /agd/v1/* exigent un header : Authorization: Bearer <token-fourni-à-l-onboarding> La route /health est ouverte (pas de token).
Le token est remis lors de l'onboarding. Ne le partagez pas côté client.
curl -H "Authorization: Bearer <token-fourni-à-l-onboarding>" \ "https://real-odds-api-production.up.railway.app/agd/v1/fixtures?status=LIVE&limit=50"
Fuseaux horaires
Les horodatages de match (champ startsAt des fixtures) sont émis en ISO 8601 avec offset de fuseau — le fuseau configuré pour votre compte, par défaut l'heure du Cameroun (Africa/Douala, UTC+1).
"startsAt": "2026-06-26T18:55:00+01:00" // 18h55 heure du Cameroun // = exactement le même instant que "2026-06-26T17:55:00Z" (UTC)
C'est le même instantqu'en UTC, simplement exprimé dans le fuseau de votre compte. Un parseur ISO 8601 standard (datetime()) accepte indifféremment le suffixe Z ou l'offset ±HH:MM : aucun changement de code requis côté intégration.
À retenir : seuls les horodatages de match sont exprimés dans votre fuseau. Les horodatages techniques — notamment _provenance.fetchedAt — restent toujours en UTC (suffixe Z).
Enveloppe _provenance
Chaque objet renvoyé porte un champ _provenance décrivant l'origine de la donnée, sa fraîcheur et ses éventuelles lacunes.
"_provenance": {
"source": "the-odds-api", // fournisseur d'origine
"fetchedAt": "2026-06-26T19:31:21Z", // horodatage de récupération (UTC)
"rawId": "3", // identifiant brut côté source
"missing": ["logoUrl"], // champs absents dans la source
"warnings": [], // alertes de normalisation
"schemaVersion": "v1" // version du schéma
}Sports
GET https://real-odds-api-production.up.railway.app/agd/v1/sports
[
{
"id": "football",
"key": "football",
"name": "Football",
"isActive": true,
"_provenance": { "source": "the-odds-api", "fetchedAt": "2026-06-26T19:31:21Z",
"rawId": "3", "missing": [], "warnings": [], "schemaVersion": "v1" }
}
]Ligues
GET https://real-odds-api-production.up.railway.app/agd/v1/leagues?limit=1000
[
{
"id": "4033",
"sportId": "football",
"countryId": null,
"name": "Kategoria Superiore",
"season": "2026",
"type": "league",
"logoUrl": null,
"_provenance": { "source": "the-odds-api", "rawId": "4033", "missing": ["countryId","logoUrl"],
"warnings": [], "schemaVersion": "v1" }
}
]Équipes
GET https://real-odds-api-production.up.railway.app/agd/v1/teams?limit=1000
[
{
"id": "aj-deem",
"name": "AJ Deem",
"countryId": null,
"logoUrl": null,
"founded": null,
"venue": null,
"_provenance": { "source": "the-odds-api", "rawId": "aj-deem", "schemaVersion": "v1" }
}
]Matchs & Résultats
Les matchs sont filtrables par statut. Un résultat est simplement un match au statut FINISHED avec ses scores (homeScore / awayScore).
Coup d'envoi. startsAt est un ISO 8601 avec offset de fuseau (ex. 2026-06-26T18:55:00+01:00), correspondant au fuseau configuré pour votre compte (par défaut heure du Cameroun, UTC+1). C'est le même instant qu'en UTC — voir Fuseaux horaires.
Statut fiable. Le champ status n'est pas le statut brut du bookmaker (qui reste figé sur « live »). Il est recalculé à partir de plusieurs signaux réels, par ordre de fiabilité :
SCHEDULED— le coup d'envoi (startsAt) n'a pas encore eu lieu.FINISHED— dès qu'un de ces signaux est vrai : résultat final reçu (score FT), ou tous les marchés du match sont fermés (plus aucun pari possible), ou match commencé depuis plus de 4 h (garde-fou). Un match terminé est immédiatement settlable.LIVE— match commencé, dans la fenêtre de jeu, avec au moins un marché encore ouvert. Un matchLIVEest réellement en cours (il ne reste jamais « live » des heures après la fin).CANCELLED/POSTPONED/PAUSED— match annulé/abandonné, reporté, ou interrompu temporairement. Émis dès que le bookmaker le signale, pour que tu puisses annuler/suspendre les tickets concernés.
Scores mi-temps. homeHalftimeScore / awayHalftimeScore sont renseignés quand la donnée mi-temps est disponible. Sinon ils valent null et apparaissent dans _provenance.missing.
GET https://real-odds-api-production.up.railway.app/agd/v1/fixtures?status=LIVE|SCHEDULED|FINISHED&limit=100
GET https://real-odds-api-production.up.railway.app/agd/v1/fixtures/{id}{
"id": "5541815",
"leagueId": "43221",
"homeTeamId": "aj-deem",
"awayTeamId": "boland-brendan",
"startsAt": "2026-06-26T18:55:00+01:00", // fuseau du compte (déf. UTC+1) = 17:55:00Z
"status": "FINISHED",
"season": "2026",
"homeTeamName": "AJ Deem",
"awayTeamName": "Boland, Brendan",
"leagueName": "UTR PTT Waco Men 01",
"homeScore": 2,
"awayScore": 1,
"homeHalftimeScore": 1, // renseigné si la mi-temps est connue, sinon null
"awayHalftimeScore": 0,
"_provenance": { "source": "the-odds-api", "rawId": "5541815",
"missing": [], "schemaVersion": "v1" }
}Exemple sans mi-temps disponible : homeHalftimeScore / awayHalftimeScore à null, listés dans _provenance.missing :
{
"id": "5541900",
"status": "FINISHED",
"homeScore": 3,
"awayScore": 2,
"homeHalftimeScore": null,
"awayHalftimeScore": null,
"_provenance": { "source": "the-odds-api", "rawId": "5541900",
"missing": ["homeHalftimeScore", "awayHalftimeScore"],
"schemaVersion": "v1" }
}Cotes (pregame + live)
Les cotes sont regroupées par marché (clés canoniques) puis par sélection. Clés canoniques courantes : match-winner, over-under-X, both-teams-score, double-chance, asian-handicap.
GET https://real-odds-api-production.up.railway.app/agd/v1/odds/{id}{
"fixtureId": "5541815",
"bookmakerId": "betconstruct",
"markets": [
{
"key": "winner-of-the-match",
"name": "Winner of the match",
"status": "OPEN",
"margin": 15.0,
"selections": [
{ "key": "home", "label": "AJ Deem", "decimalOdds": 2.1275, "line": null, "status": "ACTIVE" },
{ "key": "away", "label": "Boland, Brendan", "decimalOdds": 2.2425, "line": null, "status": "ACTIVE" }
]
}
],
"_provenance": { "source": "the-odds-api", "schemaVersion": "v1" }
}Livescore
GET https://real-odds-api-production.up.railway.app/agd/v1/livescore/{id}Renvoie le score en direct quand disponible, sinon { "detail": "no livescore for fixture" }.
Scores par période. periodScores est rempli quand l'information de période existe : un tableau de { period, home, away } où home / away sont les points marqués dans cette période (non cumulés). Valeurs possibles de period : 1H, 2H, HT (foot), Q1…Q4 (basket), S1…S5 (tennis). Le champ period(période courante) est renseigné s'il est connu.
{
"fixtureId": "5541815",
"homeScore": 1,
"awayScore": 0,
"minute": 34,
"period": "2H", // période courante si connue, sinon null
"periodScores": [ // rempli si l'info de période existe, sinon []
{ "period": "1H", "home": 1, "away": 0 },
{ "period": "2H", "home": 0, "away": 0 }
],
"_provenance": { "source": "the-odds-api", "schemaVersion": "v1" }
}Limites & honnêteté des données
Pour éviter toute mauvaise surprise côté intégration, voici ce que la source (le BO BetConstruct de ce compte) n'expose pas, et que nous ne fournissons donc pas :
- Pas d'events détaillés : buts, cartons, remplacements, VAR. (Aucune route
match-events.) - Pas de compositions (lineups) ni de statistiques de match.
- Pas de settlement par sélection fourni par notre API.
Le settlement côté AGDTech se base donc sur : les scores finaux (FT), les scores mi-temps (HT, si disponibles) et les scores par période (periodScores, si disponibles).
Cadence de polling recommandée
| Domaine | Intervalle | Note |
|---|---|---|
| livescore | ~30 s | matchs LIVE uniquement |
| odds | ~2 min | plus rapproché si trading live |
| fixtures | ~30 min | catalogue stable |
Doc interactive auto-générée : https://real-odds-api-production.up.railway.app/redoc
Historique des mises à jour
Chaque modification de l'API est consignée ici. La dernière version est en tête. La date la plus récente apparaît en rouge en haut de page.
- IMPORTANT — Cotes JUSTES : decimalOdds est désormais la COTE JUSTE (marge bookmaker retirée), pas la cote brute roisbet. Formule : cote_juste = cote_roisbet × (1 + marge/100), avec la marge CONFIGURÉE par roisbet pour chaque type de pari. Chaque marché porte un champ margin (%) indiquant la marge retirée (cote_roisbet = cote_juste / (1 + margin/100)). But : vous recevez la cote réelle (probabilité vraie) et appliquez VOTRE propre marge.
- Marchés sans marge configurée : margin = null et decimalOdds = cote brute (cas rares/exotiques).
- Scores plus fiables : homeScore/awayScore, homeHalftimeScore/awayHalftimeScore et periodScores proviennent désormais du SCORE OFFICIEL BetConstruct (bloc livescore de la page match : score final, mi-temps, scores par période), au lieu d'une reconstruction heuristique. La mi-temps est donc disponible bien plus souvent et le score est exact.
- Rattachement par identifiant : le score est joint au match par son identifiant BetConstruct (plus fiable que par nom d'équipe), réduisant tout risque d'attribution erronée.
- Statut LIVE durci (anti « faux live ») : un match dont le coup d'envoi est passé mais SANS aucun score live ET dont les cotes ne bougent plus depuis 45 min n'est plus présenté comme LIVE → il passe FINISHED. BetConstruct ne le trade plus = il n'est pas réellement en jeu.
- Garde-fou de durée par sport : foot/futsal ~2h30, basket/volley/hand/rugby ~3h, hockey 3h30, tennis 6h. Au-delà, le match est FINISHED même sans signal explicite.
- Détection de fin enrichie : la période live « ended » et le statut « off » de BetConstruct déclenchent désormais FINISHED (en plus du score final et de la fermeture de tous les marchés).
- Statuts étendus : un match peut désormais être CANCELLED (annulé/abandonné), POSTPONED (reporté) ou PAUSED (interrompu) en plus de SCHEDULED/LIVE/FINISHED — un match abandonné ne reste plus « live » indéfiniment.
- Score mi-temps : garantie anti-erreur. homeHalftimeScore/awayHalftimeScore ne sont renseignés que si la mi-temps est isolable de façon certaine ; en cas de doute → null + _provenance.missing (jamais le score final renvoyé comme mi-temps).
- Cotes : marchés over/under toujours accompagnés de leur ligne (seuil) — un over/under sans ligne n'est plus émis. Asian handicap : la clé encode le signe (ex. asian-handicap-home-minus-1-5) pour éviter toute collision entre +1.5 et -1.5.
- Cotes : déduplication des marchés par clé canonique (plus de doublon match-winner pregame/live dans le même payload).
- _provenance.warnings : signale désormais les cas ambigus (ligne introuvable, orientation de handicap incertaine, score live pas encore connu) pour une intégration en toute transparence.
- Fixture/Livescore : champ status entièrement fiabilisé. Il n'est plus calculé sur le seul coup d'envoi : un match passe FINISHED dès le score final, OU dès que tous ses marchés sont fermés, OU après 4 h (garde-fou). Un match LIVE est donc réellement en cours — fini les matchs affichés « live » des heures après la fin.
- Cohérence garantie : le filtre ?status=LIVE|FINISHED|SCHEDULED renvoie exactement les mêmes matchs que le statut affiché.
- Fixture : champs homeHalftimeScore / awayHalftimeScore renseignés quand la mi-temps est disponible (sinon null + _provenance.missing).
- Fixture : champ status fiabilisé — calculé sur le coup d'envoi (SCHEDULED avant le match, LIVE ~5h après le coup d'envoi, FINISHED au-delà).
- Livescore : periodScores rempli quand l'info de période existe (1H/2H/HT/Q1-Q4/S1-S5), + champ period courant.
- Précision : pas d'events (buts, cartons, remplacements, VAR), lineups, stats ni settlement par sélection — le settlement se base sur FT + HT + scores par période.
- Fuseaux horaires : startsAt exprimé dans le fuseau du compte (par défaut UTC+1 Cameroun) ; _provenance.fetchedAt reste en UTC.
- Version initiale : endpoints /agd/v1/{sports,countries,leagues,teams,fixtures,odds,livescore}, enveloppe _provenance, format v1, auth Bearer.