Documentation
API d’utilisation
Consultez le nombre de jetons et les coûts associés à la clé API à l’origine de la requête. Une clé, ses propres données : aucun accès aux autres clés. Utilisez cette API pour alimenter vos tableaux de bord de facturation, vos rapprochements mensuels ou vos alertes de coût.
GET /v1/usage renvoie les données agrégées sur les jetons et les coûts de la clé API figurant dans l’en-tête Authorization. Regroupez les données par jour ou par heure ; vous pouvez aussi les ventiler par modèle. Vous ne pouvez pas lire les données d’une autre clé — pour cela, connectez-vous au tableau de bord.
Authentification
Transmettez votre clé API Kunavo en tant que jeton Bearer : il s’agit de la même clé dont vous voulez consulter l’utilisation. Le point de terminaison renvoie uniquement l’utilisation facturée à cette clé précise — aucun paramètre ne permet de demander les données d’une autre clé.
Requête
| Paramètre | Obligatoire | Par défaut | Remarques |
|---|---|---|---|
start_date | yes | — | YYYY-MM-DD, UTC. Inclusif. Doit être inférieur ou égal à aujourd’hui (UTC). |
end_date | yes | — | YYYY-MM-DD, UTC. Inclusif. Une date postérieure à aujourd’hui est interprétée comme aujourd’hui ; la réponse reprend la end_date utilisée. |
bucket | no | day | L’une des valeurs day, hour. |
group_by | no | (none) | Valeurs séparées par des virgules. Valeur(s) prise(s) en charge : model. Omettez ce paramètre pour obtenir une ligne par intervalle. |
bucket=day accepte jusqu’à 90 jours ; bucket=hour accepte jusqu’à 7 jours. Au-delà, la requête renvoie 400 invalid_request_error — répartissez la période sur plusieurs appels.tz= permettra de le faire côté serveur, sans modifier les champs existants.Exemples
Totaux quotidiens sur les 30 derniers jours, tous modèles confondus :
# Daily totals for the last 30 days
curl https://api.kunavo.com/v1/usage \
-G \
-H "Authorization: Bearer $KUNAVO_API_KEY" \
--data-urlencode "start_date=2026-04-28" \
--data-urlencode "end_date=2026-05-27"Une ligne par couple (jour, modèle) :
# Per-model daily breakdown — one row per (day, model)
curl https://api.kunavo.com/v1/usage \
-G \
-H "Authorization: Bearer $KUNAVO_API_KEY" \
--data-urlencode "start_date=2026-05-01" \
--data-urlencode "end_date=2026-05-27" \
--data-urlencode "group_by=model"Python — additionner les valeurs de la période pour obtenir un seul nombre :
import os, datetime as dt, requests
today = dt.date.today()
start = today - dt.timedelta(days=29) # last 30 days inclusive
r = requests.get(
"https://api.kunavo.com/v1/usage",
headers={"Authorization": f"Bearer {os.environ['KUNAVO_API_KEY']}"},
params={
"start_date": start.isoformat(),
"end_date": today.isoformat(),
"group_by": "model",
},
timeout=30,
)
r.raise_for_status()
body = r.json()
# body["data"] is one row per (day, model). Sum cost across the window:
total_usd = sum(float(row["cost_usd"]) for row in body["data"])
print(f"Spent ${total_usd:.4f} on key {body['api_key']['name']}")Réponse
200 OK — application/json avec une liste de lignes. Les intervalles sans activité sont omis ; le client comble les lacunes s’il a besoin d’une série continue.
{
"object": "list",
"api_key": {
"id": "k_abc123",
"name": "production",
"prefix": "sk-kn-aZ8x"
},
"start_date": "2026-05-01",
"end_date": "2026-05-27",
"bucket": "day",
"data": [
{
"bucket_start": "2026-05-01T00:00:00.000Z",
"model": "claude-sonnet-4-6",
"requests": 1284,
"errors": 7,
"input_tokens": 1532890,
"output_tokens": 245100,
"cached_input_tokens": 980000,
"cache_write_tokens": 12000,
"web_search_requests": 0,
"cost_usd": "3.452100"
},
{
"bucket_start": "2026-05-01T00:00:00.000Z",
"model": "gpt-5",
"requests": 88,
"errors": 0,
"input_tokens": 42000,
"output_tokens": 12300,
"cached_input_tokens": 0,
"cache_write_tokens": 0,
"web_search_requests": 0,
"cost_usd": "0.210400"
}
]
}| Champ | Type | Signification |
|---|---|---|
bucket_start | chaîne (ISO 8601, UTC) | Début du jour ou de l’heure agrégé par cette ligne. |
model | string | Identifiant du modèle. Présent uniquement lorsque group_. |
requests | number | Appels réussis pendant cet intervalle. |
errors | number | Appels terminés par une erreur, un délai d’attente dépassé ou une annulation. Non facturés. |
input_tokens | number | Nombre total de jetons d’entrée (comprend les sous-ensembles mis en cache et écrits dans le cache). |
output_ | number | Nombre total de jetons de sortie. |
cached_ | number | Sous-ensemble de input_tokens servi depuis le cache d’invite du fournisseur en amont. |
cache_ | number | Tokens écrits dans le cache pour cette période (Anthropic uniquement ; 0 ailleurs). |
web_ | number | Recherches Web côté serveur, facturées en supplément des jetons : celles de Claude via /v1/, et l’outil web_search d’OpenAI sur un modèle GPT via /v1/ (0 dans les autres cas). |
cost_usd | string | Montant facturé en USD pour cet intervalle, avec une précision de 6 décimales. Il s’agit d’une chaîne pour préserver la précision ; analysez-la sans risque avec parseFloat(). |
Decimal()).Mise en cache côté client
Le point de terminaison définit Cache-Control: private, max-age=60. La plupart des clients (navigateurs, requêtes avec session, tout cache HTTP de votre côté) renverront la même réponse pour les mêmes paramètres pendant une fenêtre de 60 secondes — ce qui convient aux tableaux de bord qui interrogent l’API à intervalles réguliers. Pour forcer une nouvelle lecture, modifiez la chaîne de requête (par exemple en ajoutant un paramètre &_=ts de contournement du cache) ou transmettez Cache-Control: no-cache de votre côté.
Erreurs
| Statut | Code | Quand |
|---|---|---|
401 | authentication_ | Clé Bearer manquante, mal formée ou révoquée. |
400 | invalid_ | Format de start_/end_ incorrect, date de fin antérieure à la date de début, date start_date postérieure à aujourd’hui, période dépassant la limite de l’intervalle ou valeur group_by non prise en charge. |
500 | internal_ | Base de données inaccessible ou erreur inattendue. |
Réserves
- Clés supprimées. Lorsque vous révoquez une clé API, les lignes d’utilisation antérieures perdent leur
api_key_id(défini sur null) ; leurs totaux historiques ne peuvent alors plus être récupérés via ce point de terminaison. Les données restent disponibles dans la vue agrégée du compte du tableau de bord. Si vous avez besoin d’une piste d’audit immuable par clé, récupérez et stockez les données avant de la révoquer. - Quasi temps réel. Les lignes sont disponibles quelques secondes après la fin de l’appel concerné. Aucun délai maximal de mise à jour n’est garanti ; si vous devez faire correspondre les données exactement à votre facture, interrogez les données de la veille une fois par jour plutôt qu’à la minute.
- Le coût correspond au montant facturé. La valeur
cost_usdcorrespond ici au montant débité de votre portefeuille. Elle tient déjà compte du planchermax(catalog, upstream × markup)décrit dans Facturation. Cette réponse ne contient aucun montant « de gros » distinct.
Étapes suivantes
- Facturation et registre — comment le
cost_usdde chaque appel est calculé avant d’apparaître ici. - Authentification — créer de nouvelles clés API (une par projet).
- Vue d’utilisation du tableau de bord — mêmes données avec des graphiques, le détail par appel et une agrégation globale pour toutes vos clés.