Rapports de consommation avancés
Mis à jour le 29 juillet 2026
Construire des rapports de consommation
Des données de consommation que personne ne regarde ne servent à rien. Ce qui rend un rapport utile, c’est qu’il réponde à une question qu’on se pose vraiment, et il n’y en a que trois : est-ce que ça augmente, est-ce qu’il s’est passé quelque chose d’anormal, et où part l’argent.
Les trois sections qui suivent traitent ces questions dans cet ordre. Chacune produit un chiffre sur lequel on peut décider — pas un graphique de plus.
Rapport mensuel comparatif
Une consommation n’a de sens que comparée. Un mois à 400 dollars n’est ni bon ni mauvais dans l’absolu : ce qui compte est de savoir s’il succède à un mois à 200 ou à un mois à 600. Rapportez toujours l’évolution à ce que vous savez de l’activité — une hausse de 40 % après le lancement d’une fonctionnalité est attendue, la même hausse sans rien de nouveau mérite qu’on ouvre la section suivante.
import requests
import json
MANAGEMENT_API = "https://management-api.x.ai"
MGMT_KEY = "xai-mgmt-..."
TEAM_ID = "team-..."
def get_monthly_usage(year, month):
"""Récupère la consommation totale pour un mois donné."""
next_month = month + 1 if month < 12 else 1
next_year = year if month < 12 else year + 1
response = requests.post(
f"{MANAGEMENT_API}/v1/billing/teams/{TEAM_ID}/usage",
headers={
"Authorization": f"Bearer {MGMT_KEY}",
"Content-Type": "application/json"
},
json={
"analyticsRequest": {
"timeRange": {
"startTime": f"{year}-{month:02d}-01 00:00:00",
"endTime": f"{next_year}-{next_month:02d}-01 00:00:00",
"timezone": "Europe/Paris"
},
"timeUnit": "MONTH",
"values": [
{"name": "tokens", "aggregation": "SUM"},
{"name": "requests", "aggregation": "COUNT"}
],
"groupBy": ["model"]
}
}
)
return response.json()
# Comparer mars et avril 2026
mars = get_monthly_usage(2026, 3)
avril = get_monthly_usage(2026, 4)
print("=== Rapport comparatif Mars vs Avril 2026 ===")
print(json.dumps(mars, indent=2))
print(json.dumps(avril, indent=2))
Détection d’anomalies
L’écart-type sert ici à définir « anormal » sans avoir à fixer un seuil arbitraire : un jour au-delà de deux écarts-types de votre moyenne sort du régime habituel, quel que soit votre volume. C’est la méthode qui s’adapte toute seule quand votre activité croît, là où un seuil en dollars devient obsolète dès le mois suivant.
import requests
import statistics
MANAGEMENT_API = "https://management-api.x.ai"
MGMT_KEY = "xai-mgmt-..."
TEAM_ID = "team-..."
# Récupérer la consommation quotidienne du mois
response = requests.post(
f"{MANAGEMENT_API}/v1/billing/teams/{TEAM_ID}/usage",
headers={
"Authorization": f"Bearer {MGMT_KEY}",
"Content-Type": "application/json"
},
json={
"analyticsRequest": {
"timeRange": {
"startTime": "2026-03-01 00:00:00",
"endTime": "2026-04-01 00:00:00",
"timezone": "Europe/Paris"
},
"timeUnit": "DAY",
"values": [{"name": "tokens", "aggregation": "SUM"}]
}
}
)
data = response.json()
daily_values = [point.get("value", 0) for point in data.get("dataPoints", [])]
if daily_values:
mean = statistics.mean(daily_values)
stdev = statistics.stdev(daily_values) if len(daily_values) > 1 else 0
threshold = mean + 2 * stdev # Seuil à 2 écarts-types
for i, val in enumerate(daily_values):
if val > threshold:
print(f"Jour {i+1} : {val} tokens (anomalie, seuil = {threshold:.0f})")
Ventilation par modèle
C’est le rapport qui rapporte le plus, parce qu’il désigne une action concrète. Le coût total ne dit pas quoi faire ; la ventilation par modèle, si — elle révèle les tâches simples routées vers le modèle le plus cher, qui sont l’économie la plus facile à réaliser sur une facture d’API.
curl -X POST "https://management-api.x.ai/v1/billing/teams/$TEAM_ID/usage" \
-H "Authorization: Bearer $MANAGEMENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"analyticsRequest": {
"timeRange": {
"startTime": "2026-03-01 00:00:00",
"endTime": "2026-04-01 00:00:00",
"timezone": "UTC"
},
"timeUnit": "MONTH",
"values": [
{"name": "tokens", "aggregation": "SUM"},
{"name": "cost", "aggregation": "SUM"}
],
"groupBy": ["model"]
}
}'
Cette analyse peut révéler des opportunités d’optimisation : si une grande partie de vos requêtes utilise grok-4.20-0309-reasoning pour des tâches simples, basculer vers grok-4.3 pourrait réduire significativement les coûts.
Rapport hebdomadaire automatisé
L’envoi automatique change la nature de l’exercice : un rapport qu’il faut aller chercher n’est consulté qu’après l’incident, un rapport qui arrive est lu avant. L’hebdomadaire est le bon rythme pour la consommation d’API — assez fréquent pour rattraper une dérive avant la facture, assez espacé pour qu’on continue de l’ouvrir.
import requests
from datetime import datetime, timedelta
MANAGEMENT_API = "https://management-api.x.ai"
MGMT_KEY = "xai-mgmt-..."
TEAM_ID = "team-..."
# Semaine précédente
end = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
start = end - timedelta(days=7)
response = requests.post(
f"{MANAGEMENT_API}/v1/billing/teams/{TEAM_ID}/usage",
headers={
"Authorization": f"Bearer {MGMT_KEY}",
"Content-Type": "application/json"
},
json={
"analyticsRequest": {
"timeRange": {
"startTime": start.strftime("%Y-%m-%d %H:%M:%S"),
"endTime": end.strftime("%Y-%m-%d %H:%M:%S"),
"timezone": "Europe/Paris"
},
"timeUnit": "DAY",
"values": [
{"name": "tokens", "aggregation": "SUM"},
{"name": "requests", "aggregation": "COUNT"}
],
"groupBy": ["model"]
}
}
)
report = response.json()
print(f"=== Rapport hebdomadaire {start.date()} → {end.date()} ===")
# Formater le rapport pour email/Slack
# ... envoi via votre outil de notification préféré
Granularité et performance
Choisir la bonne granularité
| Cas d’usage | Granularité recommandée |
|---|---|
| Rapport mensuel | MONTH |
| Suivi quotidien | DAY |
| Analyse d’un pic | HOUR ou QUARTER_HOUR |
| Debug en temps réel | MINUTE |
| Analyse fine d’un incident | SECOND |
Plus la granularité est fine, plus la quantité de données retournées est importante : sur un mois, une granularité SECOND produit des millions de points, avec un temps de réponse et une consommation mémoire à l’avenant. La règle pratique est de choisir la granularité d’après la durée de ce que vous cherchez — un pic de quelques minutes est invisible en granularité MONTH, et noyé sous le bruit en granularité SECOND.
Points clés à retenir
- Combinez
SUM(total),COUNT(nombre) etgroupBy: ["model"]pour des rapports complets - La détection d’anomalies avec l’écart-type identifie les jours de surconsommation
- La ventilation par modèle révèle les opportunités d’optimisation des coûts
- Adaptez la granularité temporelle au cas d’usage : MONTH pour les rapports, HOUR pour le debug
- Automatisez les rapports hebdomadaires pour garder un œil sur la consommation