Aelby WeekMes clés d'API

L'API d'Aelby Week

L'application est API-first : l'interface consomme exactement l'API décrite ici. Tout ce que tu peux faire à l'écran, un programme peut le faire : lire ton planning, y poser, déplacer ou supprimer des blocs, sur les semaines réelles comme sur la semaine type.

Authentification

Génère une clé dans Paramètres → Clés d'API, puis envoie-la à chaque requête :

Authorization: Bearer awk_xxxxxxxxxxxx

Chaque clé donne accès au planning de son propriétaire, et à rien d'autre. La gestion des clés elle-même n'est accessible qu'en session (l'application), jamais avec une clé.

Conventions

  • Les semaines sont repérées par leur numéro ISO 8601 (année + semaine, lundi premier jour) : la « semaine 35 de 2026 ».
  • Les jours vont de 0 (lundi) à 6 (dimanche) ; les heures sont des minutes depuis minuit (9h30 = 570). Aucune date absolue, aucun fuseau sur les blocs.
  • Deux types de blocs, pas plus : slot (créneau avec début et fin) et task (tâche du jour, cochable, sans heure).
{
  "id": "3f2c…",              // UUID (fourni ou généré)
  "day": 1,                   // 0 = lundi … 6 = dimanche
  "kind": "slot",             // "slot" (créneau) ou "task" (tâche du jour)
  "title": "Dev Aelby Bar",
  "start_min": 540,           // minutes depuis minuit (9h00), créneaux uniquement
  "end_min": 660,             // 11h00, créneaux uniquement
  "done": false,              // tâches uniquement
  "color": null,              // null = auto, ou "peche" | "soleil" | "sauge" | "ciel" | "lilas" | "rose"
  "important": false,         // rouge plein dans l'app, et ses rappels armés (la couleur reste dessous)
  "reminders": null,          // null = tous ; créneau : "veille" | "4h" | "1h" ; tâche : "veille" | "matin"
  "origin": "manual",         // "template" si hérité de la semaine type
  "position": 0               // ordre des tâches dans la bande du jour
}

Règle du chevauchement, comme dans l'app : un créneau créé ou déplacé sur d'autres les tranche. Chacun se referme autour de lui : il se rogne, se coupe en deux s'il tombe en plein milieu, et ne s'efface que s'il ne restait rien de lui. La réponse dit tout : replaced(effacés), cropped (rognés, dans leur nouvel état), added (morceaux nés de la coupe), de quoi proposer une annulation exacte. Ajoute ?replace=0 pour ne rien trancher : les créneaux cohabitent alors, côte à côte.

Semaines réelles

Une semaine = lignes stockées (passé figé, blocs détachés, ajouts) + occurrences projetées en direct depuis la semaine type (linked: true, id du bloc du calque). Lire est sans effet.

  • GET/api/v1/weeks/current

    La semaine en cours (?tz=Europe/Paris par défaut). Réponse : { week, blocks }.

  • GET/api/v1/weeks/{année}/{semaine}

    Une semaine par son numéro ISO, ex. /weeks/2026/35.

  • POST/api/v1/weeks/{année}/{semaine}/blocks

    Créer un bloc dans cette semaine. Réponse : { week, block, replaced, cropped, added }.

  • PATCH/api/v1/blocks/{id}

    Modifier un bloc stocké (day, title, start_min, end_min, done, color, important, reminders, position, details, full_title). Réponse : { block, replaced, cropped, added }.

  • DELETE/api/v1/blocks/{id}

    Supprimer un bloc stocké. Réponse : { deleted, block }.

  • PATCH/api/v1/weeks/{année}/{semaine}/blocks/{id}

    Modifier une occurrence projetée : la détache du calque pour cette semaine (nouvel id).

  • DELETE/api/v1/weeks/{année}/{semaine}/blocks/{id}

    Masquer une occurrence projetée pour cette semaine : le calque est intact ailleurs.

  • POST/api/v1/weeks/{année}/{semaine}/blocks/{id}/restore

    Réattacher une occurrence masquée (l'inverse du DELETE d'occurrence).

Semaine type

Le calque vivant : projeté en direct sur tout le futur, à la minute près. Le modifier change toutes les occurrences à venir ; le passé, lui, est figé pour toujours.

  • GET/api/v1/template

    Tous les blocs de la semaine type.

  • POST/api/v1/template/blocks

    Créer un bloc dans la semaine type.

  • PATCH/api/v1/template/blocks/{id}

    Modifier un bloc de la semaine type.

  • DELETE/api/v1/template/blocks/{id}

    Supprimer un bloc de la semaine type.

Les rappels

Un bloc important prévient sur les appareils abonnés (Web Push) : la veille au soir (un récap pour tout le lendemain), 4 h avant un créneau (au réveil si ça tombait la nuit), 1 h avant, et le matin même pour une tâche. Un bloc retouché après le moment de son rappel ne le reçoit pas ; chaque rappel ne part qu'une fois.

  • GET/api/v1/push

    La clé publique VAPID du serveur, les appareils abonnés, les réglages et ai (Coco improvise-t-il). Réponse : { public_key, devices, settings, ai }.

  • PATCH/api/v1/push

    Les réglages : { evening_min (16h–23h30, en minutes), evening_tasks, morning, coco_ai }.

  • POST/api/v1/push/devices

    Abonner un appareil : le corps de PushSubscription.toJSON(), plus label et replaces (facultatifs). Réponse : { device } ; 409 si cette adresse est abonnée à un autre compte avec d'autres clés.

  • DELETE/api/v1/push/devices/{id}

    Désabonner un appareil.

  • POST/api/v1/push/test

    Une notification d'essai, tout de suite : à un appareil ({ endpoint }) ou à tous. Réponse : { sent, failed }.

Divers

  • GET/api/v1/sync

    L'empreinte des données du compte : un jeton opaque qui change dès que quelque chose change, où que le geste ait eu lieu. Réponse : { rev, at }. Tant qu'elle ne bouge pas, il n'y a rien à relire : c'est ainsi que l'app reste à jour toute seule.

  • GET/api/v1/me

    L'utilisateur authentifié (pratique pour tester une clé).

  • GET/api/v1/keys

    Lister ses clés d'API (session uniquement).

  • POST/api/v1/keys

    Créer une clé : la valeur complète n'est renvoyée qu'une fois (session uniquement).

  • DELETE/api/v1/keys/{id}

    Révoquer une clé (session uniquement).

Applications reliées

Un bloc peut venir d'une autre application (source + source_id, ex. une tâche envoyée depuis Quilly). Cette application est prévenue (POST sur son adresse, « Authorization: Bearer <secret> ») chaque fois que le bloc est coché, déplacé, effacé ou restauré : { event: "block.updated" | "block.deleted", source_id, block: { id, done, day, year, week } }.

  • PUT/api/v1/hooks/{app}

    Dire où prévenir l'application {app} : { url (https), secret }.

  • DELETE/api/v1/hooks/{app}

    Ne plus la prévenir.

  • GET/api/v1/links?ids=…&source={app}

    L'état des blocs nommés (200 au plus) venus d'une application, pour se rattraper si une notification s'est perdue. Un bloc absent de la réponse n'existe plus. Réponse : { blocks: [{ id, source_id, done, day, year, week }] }.

Exemples

Lire la semaine en cours :

curl https://ton-app.vercel.app/api/v1/weeks/current \
  -H "Authorization: Bearer awk_xxxxxxxxxxxx"

Poser un rendez-vous jeudi de 10h à 11h30 (semaine 35 de 2026) :

curl -X POST https://ton-app.vercel.app/api/v1/weeks/2026/35/blocks \
  -H "Authorization: Bearer awk_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "day": 3, "kind": "slot", "title": "Rendez-vous client", "start_min": 600, "end_min": 690 }'

Cocher une tâche :

# l'id vient de la lecture de la semaine (GET /weeks/current)
curl -X PATCH https://ton-app.vercel.app/api/v1/blocks/3f2c… \
  -H "Authorization: Bearer awk_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "done": true }'

Marquer un créneau important, avec seulement le rappel d'1 h :

curl -X PATCH https://ton-app.vercel.app/api/v1/blocks/3f2c… \
  -H "Authorization: Bearer awk_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "important": true, "reminders": ["1h"] }'

Erreurs

Toujours le même format, avec un code HTTP parlant (401 non authentifié, 404 introuvable, 409 conflit d'id, 422 requête invalide) :

{ "error": { "code": "invalid_request", "message": "start_min doit être avant end_min." } }

Coco lui-même lit ton planning par cette API.

Aelby Week · API v1