Aller au contenu

Utiliser l'API

Toutes les applis Kombine passent par une seule API REST. Avec un jeton d’accès personnel, tes propres outils peuvent l’utiliser aussi. Tout ce qui suit fonctionne avec curl et jq.

  • URL de base : https://api.kombine.dev/v1
  • Authentification : envoie le jeton sous la forme Authorization: Bearer kmb_pat_…
  • Format : du JSON en entrée, du JSON en sortie. Les dates et heures sont au format ISO 8601 (2026-10-23T09:00:00Z).
  • Référence complète : la spécification OpenAPI liste chaque endpoint et chaque champ. Colle-la dans n’importe quel visualiseur OpenAPI, ou donne-la à ton agent IA.

Configure ton shell une fois pour toutes :

Fenêtre de terminal
export KOMBINE_TOKEN='kmb_pat_…'
export API='https://api.kombine.dev/v1'
k() { curl -sS -H "Authorization: Bearer $KOMBINE_TOKEN" -H 'Content-Type: application/json' "$@"; }

Les exemples ci-dessous utilisent cette fonction k.

Il faut tasks : Lecture pour lister, Lecture et écriture pour modifier.

Lister les tâches. Les résultats arrivent par pages dans data, avec total, limit (200 par défaut, 500 max) et offset :

Fenêtre de terminal
k "$API/tasks?limit=500" | jq '.data[] | {title, status, priority, due_date}'

Il n’y a pas de filtre côté serveur par statut ou par date, alors filtre avec jq. Les tâches ouvertes dont l’échéance est aujourd’hui ou avant :

Fenêtre de terminal
today=$(date +%F)
k "$API/tasks?limit=500" | jq -r --arg d "$today" '
.data[] | select(.status != "DONE" and .is_archived == false and .due_date != null and .due_date[0:10] <= $d)
| "\(.priority // "-")\t\(.title)"'

Ajouter une tâche. C’est ton outil qui choisit l’id de la tâche (n’importe quel UUID), comme le font les applis. Ça rend les nouvelles tentatives sans risque : envoyer deux fois le même id ne peut pas créer deux tâches.

Fenêtre de terminal
k -X POST "$API/tasks" -d "$(jq -n --arg id "$(uuidgen | tr A-Z a-z)" '{
id: $id,
title: "Renew passport",
priority: "HIGH",
due_date: "2026-11-01T00:00:00Z",
due_date_has_time: false,
tags: ["errands"]
}')"
  • priority : LOW, MEDIUM ou HIGH (omets-le pour aucune priorité)
  • status : TODO (par défaut), IN_PROGRESS ou DONE
  • due_date_has_time: false signifie « à faire ce jour-là », sans heure précise

Modifier une tâche. PUT ne modifie que les champs que tu envoies. Pour en marquer une comme terminée :

Fenêtre de terminal
k -X PUT "$API/tasks/$TASK_ID" -d '{"status":"DONE"}'

Terminer une tâche via l’API compte exactement comme dans les applis : c’est enregistré pour tes statistiques, et une tâche récurrente passe à sa prochaine date.

Il faut sessions : Lecture et écriture. Enregistre une session faite ailleurs (une réunion, un footing, du temps suivi dans une autre appli) :

Fenêtre de terminal
k -X POST "$API/sessions" -d "$(jq -n --arg id "$(uuidgen | tr A-Z a-z)" '{
id: $id,
mode: "POMODORO",
started_at: "2026-10-23T07:00:00Z",
ended_at: "2026-10-23T07:25:00Z",
duration_ms: 1500000,
note: "Pairing on the importer"
}')"

mode vaut POMODORO, FLOW ou ADAPTIVE. Ajoute task_id ou activity_id pour l’associer. Liste tes activités avec k "$API/activities" | jq '.data[] | {id, name}'.

Il faut timer : Lecture. Regarde ce qui tourne sur n’importe lequel de tes appareils :

Fenêtre de terminal
k "$API/timer/state" | jq '{status, mode, is_break, started_at, elapsed_ms, task_id}'

Une réponse vide (204) signifie qu’aucun minuteur ne tourne.

Démarrer ou arrêter le minuteur depuis un script n’est pas recommandé. Une session n’est enregistrée que par l’appli qui a fait tourner le minuteur, donc un minuteur lancé via l’API ne laisse aucune session derrière lui. Pour enregistrer du temps, crée plutôt une session (voir Sessions de concentration ci-dessus).

Il faut stats : Lecture.

Fenêtre de terminal
k "$API/stats/all-time" | jq '{totalFocusSessions, hours: ((.totalFocusSeconds // 0) / 3600 | floor), longestStreakLength}'
k "$API/daily-snapshots?from=2026-10-01&to=2026-10-31" | jq '.snapshots[] | {date, sessions_completed, achieved}'

Les statistiques globales sont calculées en arrière-plan. Sur un compte tout neuf, stats/all-time répond 404 (« No stats available yet ») tant qu’elles n’ont pas été calculées une première fois.

Les erreurs sont en JSON, avec un error_code sur lequel tu peux te baser, par exemple :

{ "title": "Forbidden", "status": 403, "detail": "Personal access token does not permit this route", "error_code": 1014 }
Statut error_code Signification Que faire
400 5001, 5002 Un champ manque ou n’est pas valide ; errors indique lequel Corrige la requête
401 1013 Jeton expiré Crée un nouveau jeton
401 1011 Jeton révoqué Crée un nouveau jeton
401 1004 Jeton non reconnu Vérifie que tu l’as copié en entier
403 1014 Les permissions du jeton ne couvrent pas cette action Crée un jeton avec les bonnes permissions
409 4003 Cet id est déjà pris Tu peux l’ignorer lors d’une nouvelle tentative
409 4010 Cette external_ref est déjà utilisée Voir Workflows
429 6001 Trop de requêtes Attends Retry-After secondes

GET /v1/error-codes les liste tous (pas besoin de jeton).

Chaque jeton a droit à 60 requêtes par minute, avec de courtes rafales jusqu’à 20. Au-delà, tu reçois un 429 avec un en-tête Retry-After. Les autres jetons et tes applis ne sont pas concernés.