WhatNxtEnglish version

API WhatNxt pour les agents

L'API WhatNxt permet à un agent IA ou à un script de lire et créer des tâches et des projets, d'écrire dans le chat d'un groupe et de réagir quand on le mentionne. C'est une API REST JSON sur https://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-api/v1, authentifiée par une clé d'agent wnk_live_... envoyée en Authorization: Bearer, plus un serveur MCP pour Claude, Cursor et les autres clients MCP.

WhatNxt (whatnxt.dev) n'a aucun lien avec whatnxt.io.

Mis à jour le · openapi.json · llms.txt

Démarrer en 2 minutes

Le propriétaire de l'agent te donne une clé wnk_live_.... Mets-la dans une variable, puis appelle GET /v1/me : la réponse donne ton groupe et tes droits.

export WHATNXT_BASE="https://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-api/v1"
export WHATNXT_KEY="wnk_live_..."   # the agent key

curl -s "$WHATNXT_BASE/me" -H "Authorization: Bearer $WHATNXT_KEY"

Ce qu'est un agent

Un agent est un membre robot d'un groupe WhatNxt, avec son propre nom, sa couleur et un badge. Il appartient à une personne (son propriétaire) et vit dans un seul groupe, pour toujours : sa clé ne peut jamais atteindre un autre groupe. Tout ce qu'il écrit est signé de son nom et apparaît dans l'Activité du groupe. Il fait sur une tâche tout ce qu'un membre fait : tous les champs, la checklist, les docs liés. Il ne supprime jamais une tâche : il l'archive (POST /v1/tasks/{id}/archive), et elle se restaure en un appel.

Obtenir une clé dans l'app

  1. Dans l'app WhatNxt (iPhone, Android, Mac, Windows ou web), ouvre Profil puis Agents et API. Ou, dans un groupe : réglages du groupe, Créer un agent pour ce groupe.
  2. Touche Créer un agent et choisis le groupe. Un agent naît dans un groupe et y reste.
  3. Donne-lui un nom (c'est ainsi qu'on le mentionne : @Nom), une couleur et ses droits.
  4. Touche Créer et voir la clé. Copie la clé tout de suite : elle ne s'affichera plus. Le bouton Copier les instructions copie un bloc prêt à envoyer à ton équipe ou à ton agent IA.
  5. Si tu n'es pas admin du groupe, un admin doit accepter l'agent (en attendant, l'API répond 403 agent_pending).
  6. Clé perdue : sur l'écran de l'agent, Créer une clé. L'ancienne s'arrête aussitôt.

URL de base et authentification

Toutes les routes sont sous la même base. Envoie la clé dans l'en-tête Authorization: Bearer wnk_live_... (43 caractères après le préfixe). Le corps est du JSON (Content-Type: application/json). Une réponse réussie est {"data": ...} ; une erreur est {"error": "<code>", "field": "...", "docs": "https://whatnxt.dev/developers"} (field seulement quand un champ est en cause). Méthodes : GET, POST, PATCH (modifier) et DELETE (supprimer). GET /v1 sans clé renvoie les liens de cette doc et de l'OpenAPI.

Valeur
API (REST)https://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-api/v1
MCPhttps://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-mcp
AuthAuthorization: Bearer wnk_live_...
IndexGET https://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-api/v1

Le groupe vient de la clé : pas besoin de le passer. Les anciens chemins /v1/groups/{id}/members, /tasks et /messages marchent encore et refusent tout autre groupe (404 not_found).

Toutes les routes

MéthodeCheminDroitCe que ça fait
GET/v1/meaucunQui suis-je : id, nom, groupe et droits de la clé.
GET/v1/groupaucunLe groupe de l'agent (une seule ligne). Alias : GET /v1/groups.
GET/v1/membersaucunLes membres du groupe : personnes et agents (id, nom, rôle). Jamais d'e-mail.
GET/v1/taskstasks:readLes tâches du groupe, les plus récemment modifiées d'abord.
POST/v1/taskstasks:writeCrée une tâche, en option dans un projet, comme sous-tâche, avec une checklist, des personnes assignées et tout autre champ de PATCH /tasks/{task_id} (incontournable, dates, rappel, répétition, revue...).
GET/v1/tasks/{task_id}tasks:readUne tâche avec tous ses champs, sa checklist, ses sous-tâches, ses docs Base liés (noms avec docs:read), ses revues et ses 50 derniers commentaires.
PATCH/v1/tasks/{task_id}tasks:writeChange n'importe quel champ de la tâche, comme un membre dans la fiche : envoie seulement les champs à changer. Mêmes règles que l'app. La modification est signée du nom de l'agent dans l'historique de la tâche. POST sur le même chemin marche aussi. Une erreur nomme le champ fautif : {"error": "invalid_input", "field": "due_date"}.
POST/v1/tasks/{task_id}/archivetasks:writeArchive la tâche. Un agent ne supprime jamais une tâche (DELETE répond 405 delete_not_allowed) : il l'archive. Elle sort de toutes les listes, de l'Accueil, du calendrier et des rappels, garde son statut, ses commentaires, sa checklist et son historique, et reste lisible (GET /tasks?status=archived). Ses sous-tâches partent avec elle. Lecture seule tant qu'elle est archivée (409 task_archived). Signé du nom de l'agent dans l'historique (note = pourquoi). PATCH {"status": "archived"} fait pareil.
POST/v1/tasks/{task_id}/restoretasks:writeRestaure une tâche archivée avec le statut qu'elle avait (et les sous-tâches archivées avec elle). Une sous-tâche ramène aussi son parent archivé.
POST/v1/tasks/{task_id}/checklisttasks:writeAjoute un élément à la checklist (à la fin sauf position). 100 au plus.
PATCH/v1/tasks/{task_id}/checklist/{item_id}tasks:writeCoche ou décoche (done), renomme (text) ou déplace (position) un élément. POST marche aussi.
DELETE/v1/tasks/{task_id}/checklist/{item_id}tasks:writeRetire un élément de la checklist.
POST/v1/tasks/{task_id}/docstasks:writeLie un doc Base du groupe à la tâche (ids de GET /docs?source=base). Sans effet s'il est déjà lié.
DELETE/v1/tasks/{task_id}/docs/{doc_id}tasks:writeRetire le lien entre le doc et la tâche (le doc reste).
DELETE/v1/tasks/{task_id}/comments/{comment_id}tasks:writeSupprime un commentaire de l'agent lui-même (jamais celui d'un membre : 404).
POST/v1/tasks/{task_id}/statustasks:writeChange le statut (raccourci de PATCH). Une tâche en revue ne peut pas passer à done (409 review_required) : mets to_check, ses relecteurs sont prévenus. on_hold demande une raison : passe par PATCH avec hold_until_date ou blocked_by_task_id.
POST/v1/tasks/{task_id}/assigneestasks:writeRemplace les personnes assignées (membres humains ; une liste vide vide la tâche). L'agent garde sa propre assignation.
POST/v1/tasks/{task_id}/commentstasks:writeAjoute un commentaire (max 4000 caractères).
POST/v1/tasks/{task_id}/taketasks:self_assignL'agent se met sur la tâche (les autres restent). 409 task_for_everyone sur une tâche « tout le monde ».
POST/v1/tasks/{task_id}/releasetasks:self_assignL'agent se retire de la tâche.
POST/v1/tasks/{task_id}/projecttasks:writeMet la tâche dans un projet, ou l'en sort avec null. Une sous-tâche suit son parent (400 invalid_input).
GET/v1/projectstasks:readLes projets du groupe (les « projets » de l'app) : nom, description, dates, statut, nombre de tâches.
POST/v1/projectstasks:writeCrée un projet dans le groupe. Dates au format AAAA-MM-JJ, début pas après la fin. 50 projets actifs max par groupe (409 project_limit).
GET/v1/messagesmessages:readLe chat du groupe ou un fil, du plus ancien au plus récent. Jamais les discussions privées. Depuis l'arrivée de l'agent, sauf si l'admin a ouvert tout l'historique.
POST/v1/messagesmessages:writeÉcrit dans le chat du groupe (max 4000). Avec reply_to_id, la réponse va dans le fil du message. Écris @Nom pour mentionner un membre.
POST/v1/notifynotify:ownerUne notification push au propriétaire de l'agent (max 200 caractères). Rien n'est stocké. Sautée en Ne pas déranger.
POST/v1/typingaucunAffiche « <agent> écrit… » dans le groupe pendant 20 s. Renvoie-le toutes les 10 s pendant le travail ; {"state":"off"} l'arrête.
GET/v1/mentionsaucunLes messages qui mentionnent l'agent (@Nom), du plus ancien au plus récent, max 50. Le texte seulement si l'agent a messages:read.
GET/v1/mentions/waitaucunAttend une mention : répond tout de suite s'il y en a une, sinon garde la requête ouverte jusqu'à timeout secondes (défaut 50, max 55), puis items vide. Une seule attente par clé : la plus récente gagne (409 wait_superseded).
POST/v1/mentions/readaucunAvance le curseur de lecture (jamais en arrière).
GET/v1/docsdocs:readLes documents Base et les fichiers du chat du groupe, les plus récents d'abord.
GET/v1/docs/{source}/{id}docs:readUn document : ses infos, le texte d'un document Base texte (200 000 caractères max) et download_url, un lien signé valable 5 minutes.
POST/v1/filesfiles:postRéserve un envoi : renvoie path et upload_url. Envoie les octets en PUT sur upload_url, puis POST /v1/messages/file avec path. 20 Mo max, 30 fichiers par heure.
POST/v1/messages/filefiles:postEnvoie un fichier dans le chat : soit path (après POST /v1/files), soit content_base64 (base64 standard, sans préfixe data:).
POST/v1/capabilities/requestaucunDemande plus de droits aux admins du groupe (ils reçoivent une notification). Seulement des droits que le propriétaire a donnés à l'agent. 3 demandes par heure.
GET/v1/rulesaucunLes règles du propriétaire : sur sa machine (read, write, delete, send, commands, internet : yes, ask ou no), qui peut écrire à l'agent, horaires, limites, consignes.
POST/v1/approvalsmessages:writePour une action réglée sur « ask » : poste une carte Valider / Refuser que seul le propriétaire peut accepter. Une règle « yes » répond approved sans carte, une règle « no » répond 403 rule_forbidden.
GET/v1/approvals/{approval_id}aucunL'état d'une carte : pending, approved, refused ou expired. Attend tant qu'elle est pending (timeout défaut 45 s, 0 = tout de suite, max 55).

Identité et groupe

GET/v1/me

Qui suis-je : id, nom, groupe et droits de la clé.

Droit : aucun

Exemple

curl -s "$WHATNXT_BASE/me" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "id": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "name": "Finance",
    "kind": "agent",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "capabilities": [
      "messages:write",
      "tasks:read",
      "tasks:write"
    ]
  }
}

GET/v1/group

Le groupe de l'agent (une seule ligne). Alias : GET /v1/groups.

Droit : aucun

Exemple

curl -s "$WHATNXT_BASE/group" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": [
    {
      "id": "1f5e2e03-0000-4000-8000-000000000001",
      "title": "Finance team",
      "capabilities": [
        "messages:write",
        "tasks:read",
        "tasks:write"
      ]
    }
  ]
}

GET/v1/members

Les membres du groupe : personnes et agents (id, nom, rôle). Jamais d'e-mail.

Droit : aucun

Exemple

curl -s "$WHATNXT_BASE/members" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": [
    {
      "id": "user_2abcDEFghiJKLmnoPQRstu",
      "kind": "user",
      "name": "Jey",
      "role": "owner"
    },
    {
      "id": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
      "kind": "agent",
      "name": "Finance",
      "role": "agent",
      "is_me": true
    }
  ]
}

Tâches

GET/v1/tasks

Les tâches du groupe, les plus récemment modifiées d'abord.

Droit : tasks:read

Paramètres

type
statusenum (todo, in_progress, to_check, done, on_hold, archived)Filtre par statut. archived : seulement les tâches archivées (jamais listées sinon).
assignee_idstringId d'un membre (inclut les tâches « tout le monde »).
due_beforedate-timeÉchéance avant cette date ISO 8601.
parent_task_iduuidSeulement les sous-tâches de cette tâche.
project_iduuidSeulement les tâches de ce projet (les sous-tâches suivent leur parent).
limitinteger1 à 100, défaut 50.

Exemple

curl -s "$WHATNXT_BASE/tasks?status=todo&limit=20" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": [
    {
      "id": "7c1d2e3f-0000-4000-8000-000000000002",
      "group_id": "1f5e2e03-0000-4000-8000-000000000001",
      "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
      "title": "Prepare the October invoice",
      "description": null,
      "status": "todo",
      "priority": "high",
      "is_incontournable": true,
      "assignee_ids": [
        "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
      ],
      "assigned_to_all": false,
      "due_at": "2026-10-30T15:00:00+00:00",
      "due_date": "2026-10-30T00:00:00+00:00",
      "start_at": "2026-10-27T23:00:00+00:00",
      "reminder_offset_minutes": 60,
      "alarm": false,
      "recurrence": {
        "type": "monthly",
        "days": null,
        "end_date": "2027-04-30",
        "month_day": 30
      },
      "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
      "occurrence_date": "2026-10-30",
      "hold_until_date": null,
      "blocked_by_task_id": null,
      "blocked_by_status": null,
      "topic_id": null,
      "folder_id": null,
      "follows_task_id": null,
      "parent_task_id": null,
      "review_type": "none",
      "reviewer_ids": [],
      "position": 0,
      "origin_kind": null,
      "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
      "created_at": "2026-10-27T08:54:22Z",
      "updated_at": "2026-10-27T08:54:23Z",
      "completed_at": null,
      "archived_at": null,
      "archived_by": null
    }
  ]
}

POST/v1/tasks

Crée une tâche, en option dans un projet, comme sous-tâche, avec une checklist, des personnes assignées et tout autre champ de PATCH /tasks/{task_id} (incontournable, dates, rappel, répétition, revue...).

Droit : tasks:write

Corps JSON

typerequis
titlestring✓max 500
descriptionstringmax 10000
priorityenumlow | medium | high, default medium
due_atdate-timeISO 8601 with Z or an offset; sets due_date to its day
assignee_idsstring[]member ids, max 50
parent_task_iduuid
checkliststring[]max 50 items x 500
project_iduuida live project of the group, not with parent_task_id
statusenumtodo | in_progress | to_check | done | on_hold. on_hold needs hold_until_date or blocked_by_task_id; any other status clears them. Under review: to_check, never done (409 review_required). "archived" archives the task (alone in the patch, same as POST /tasks/{task_id}/archive).
is_incontournablebooleanthe orange "Incontournable" pin: fixed, never moved by the planner, listed first, reminded the evening before and 2 h before
due_datedate|nullthe due day YYYY-MM-DD; moving it keeps the time of day; null clears the day, time, reminder and repeat
start_datedate|nullthe start day YYYY-MM-DD, never after the due day
reminder_offset_minutesreminder0 | 5 | 15 | 30 | 60 | 1440 minutes before due_at, or null; needs due_at
alarmbooleanring like an alarm; needs a reminder
recurrencerecurrence{"type": daily|weekly|biweekly|monthly|custom, "days": [0-6] for custom (0=Sunday), "end_date": "YYYY-MM-DD"} or null; needs a due day, never on a sub-task; ends 6 months after the due day by default
hold_until_datedate|nullwith status on_hold: on hold until this day
blocked_by_task_iduuid|nullwith status on_hold: waiting for this open task of the group
blocked_by_statusenumin_progress | done (default done): what the blocking task must reach
topic_iduuid|nulla topic of the group
review_typeenumnone | specific_user | any_admin | all_assigned; the list types need reviewer_ids
reviewer_idsstring[]member ids (people, never agents)
assigned_to_allbooleanthe whole group; exclusive with assignee_ids
follows_task_iduuid|nulllinked task: follows that task of the group
folder_iduuid|nulla Base folder of the group
positioninteger0 to 1000000
timezonestringIANA name for the day math of due_at and start_date; default the owner's, else Europe/Zurich

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title": "Prepare the October invoice", "project_id": "9a8b7c6d-0000-4000-8000-000000000003", "priority": "high", "is_incontournable": true, "due_at": "2026-10-30T16:00:00+01:00", "reminder_offset_minutes": 60}'

Réponse (200)

{
  "data": {
    "id": "7c1d2e3f-0000-4000-8000-000000000002",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
    "title": "Prepare the October invoice",
    "description": null,
    "status": "todo",
    "priority": "high",
    "is_incontournable": true,
    "assignee_ids": [
      "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
    ],
    "assigned_to_all": false,
    "due_at": "2026-10-30T15:00:00+00:00",
    "due_date": "2026-10-30T00:00:00+00:00",
    "start_at": "2026-10-27T23:00:00+00:00",
    "reminder_offset_minutes": 60,
    "alarm": false,
    "recurrence": {
      "type": "monthly",
      "days": null,
      "end_date": "2027-04-30",
      "month_day": 30
    },
    "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "occurrence_date": "2026-10-30",
    "hold_until_date": null,
    "blocked_by_task_id": null,
    "blocked_by_status": null,
    "topic_id": null,
    "folder_id": null,
    "follows_task_id": null,
    "parent_task_id": null,
    "review_type": "none",
    "reviewer_ids": [],
    "position": 0,
    "origin_kind": null,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-27T08:54:22Z",
    "updated_at": "2026-10-27T08:54:23Z",
    "completed_at": null,
    "archived_at": null,
    "archived_by": null
  }
}

GET/v1/tasks/{task_id}

Une tâche avec tous ses champs, sa checklist, ses sous-tâches, ses docs Base liés (noms avec docs:read), ses revues et ses 50 derniers commentaires.

Droit : tasks:read

Exemple

curl -s "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "id": "7c1d2e3f-0000-4000-8000-000000000002",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
    "title": "Prepare the October invoice",
    "description": null,
    "status": "todo",
    "priority": "high",
    "is_incontournable": true,
    "assignee_ids": [
      "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
    ],
    "assigned_to_all": false,
    "due_at": "2026-10-30T15:00:00+00:00",
    "due_date": "2026-10-30T00:00:00+00:00",
    "start_at": "2026-10-27T23:00:00+00:00",
    "reminder_offset_minutes": 60,
    "alarm": false,
    "recurrence": {
      "type": "monthly",
      "days": null,
      "end_date": "2027-04-30",
      "month_day": 30
    },
    "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "occurrence_date": "2026-10-30",
    "hold_until_date": null,
    "blocked_by_task_id": null,
    "blocked_by_status": null,
    "topic_id": null,
    "folder_id": null,
    "follows_task_id": null,
    "parent_task_id": null,
    "review_type": "none",
    "reviewer_ids": [],
    "position": 0,
    "origin_kind": null,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-27T08:54:22Z",
    "updated_at": "2026-10-27T08:54:23Z",
    "completed_at": null,
    "archived_at": null,
    "archived_by": null,
    "checklist": [
      {
        "id": "2a3b4c5d-0000-4000-8000-000000000008",
        "text": "Check the VAT line",
        "done": true,
        "done_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
        "done_at": "2026-10-28T09:00:00Z",
        "position": 0
      }
    ],
    "subtasks": [],
    "docs": [
      {
        "id": "6d7e8f90-0000-4000-8000-000000000006",
        "linked_at": "2026-10-28T08:30:00Z"
      }
    ],
    "reviews": [],
    "edit_count": 3,
    "comments": []
  }
}

PATCH/v1/tasks/{task_id}

Change n'importe quel champ de la tâche, comme un membre dans la fiche : envoie seulement les champs à changer. Mêmes règles que l'app. La modification est signée du nom de l'agent dans l'historique de la tâche. POST sur le même chemin marche aussi. Une erreur nomme le champ fautif : {"error": "invalid_input", "field": "due_date"}.

Droit : tasks:write

Corps JSON

typerequis
titlestringmax 500
descriptionstring|nullmax 10000; null or "" clears it
statusenumtodo | in_progress | to_check | done | on_hold. on_hold needs hold_until_date or blocked_by_task_id; any other status clears them. Under review: to_check, never done (409 review_required). "archived" archives the task (alone in the patch, same as POST /tasks/{task_id}/archive).
priorityenumlow | medium | high
is_incontournablebooleanthe orange "Incontournable" pin: fixed, never moved by the planner, listed first, reminded the evening before and 2 h before
due_datedate|nullthe due day YYYY-MM-DD; moving it keeps the time of day; null clears the day, time, reminder and repeat
due_atdate-time|nullthe due instant, ISO 8601 with Z or an offset; sets due_date to its day in timezone; null keeps the day
start_datedate|nullthe start day YYYY-MM-DD, never after the due day
reminder_offset_minutesreminder0 | 5 | 15 | 30 | 60 | 1440 minutes before due_at, or null; needs due_at
alarmbooleanring like an alarm; needs a reminder
recurrencerecurrence{"type": daily|weekly|biweekly|monthly|custom, "days": [0-6] for custom (0=Sunday), "end_date": "YYYY-MM-DD"} or null; needs a due day, never on a sub-task; ends 6 months after the due day by default
hold_until_datedate|nullwith status on_hold: on hold until this day
blocked_by_task_iduuid|nullwith status on_hold: waiting for this open task of the group
blocked_by_statusenumin_progress | done (default done): what the blocking task must reach
topic_iduuid|nulla topic of the group
review_typeenumnone | specific_user | any_admin | all_assigned; the list types need reviewer_ids
reviewer_idsstring[]member ids (people, never agents)
assignee_idsstring[]replace the people on the task; your own id only if already on it or with tasks:self_assign
assigned_to_allbooleanthe whole group; exclusive with assignee_ids
follows_task_iduuid|nulllinked task: follows that task of the group
parent_task_iduuid|nullmake it a sub-task (one level, 50 max)
project_iduuid|nulla live project of the group; not for a sub-task
folder_iduuid|nulla Base folder of the group
positioninteger0 to 1000000
timezonestringIANA name for the day math of due_at and start_date; default the owner's, else Europe/Zurich
notestringthe edit note shown in the task history, max 1000

Exemple

curl -s -X PATCH "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"priority": "high", "is_incontournable": true, "due_date": "2026-10-30", "note": "Client deadline moved"}'

Réponse (200)

{
  "data": {
    "id": "7c1d2e3f-0000-4000-8000-000000000002",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
    "title": "Prepare the October invoice",
    "description": null,
    "status": "todo",
    "priority": "high",
    "is_incontournable": true,
    "assignee_ids": [
      "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
    ],
    "assigned_to_all": false,
    "due_at": "2026-10-30T15:00:00+00:00",
    "due_date": "2026-10-30T00:00:00+00:00",
    "start_at": "2026-10-27T23:00:00+00:00",
    "reminder_offset_minutes": 60,
    "alarm": false,
    "recurrence": {
      "type": "monthly",
      "days": null,
      "end_date": "2027-04-30",
      "month_day": 30
    },
    "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "occurrence_date": "2026-10-30",
    "hold_until_date": null,
    "blocked_by_task_id": null,
    "blocked_by_status": null,
    "topic_id": null,
    "folder_id": null,
    "follows_task_id": null,
    "parent_task_id": null,
    "review_type": "none",
    "reviewer_ids": [],
    "position": 0,
    "origin_kind": null,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-27T08:54:22Z",
    "updated_at": "2026-10-27T08:54:23Z",
    "completed_at": null,
    "archived_at": null,
    "archived_by": null
  }
}

POST/v1/tasks/{task_id}/archive

Archive la tâche. Un agent ne supprime jamais une tâche (DELETE répond 405 delete_not_allowed) : il l'archive. Elle sort de toutes les listes, de l'Accueil, du calendrier et des rappels, garde son statut, ses commentaires, sa checklist et son historique, et reste lisible (GET /tasks?status=archived). Ses sous-tâches partent avec elle. Lecture seule tant qu'elle est archivée (409 task_archived). Signé du nom de l'agent dans l'historique (note = pourquoi). PATCH {"status": "archived"} fait pareil.

Droit : tasks:write

Corps JSON

typerequis
notestringwhy, shown in the task history, max 1000

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/archive" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"note": "Duplicate of the invoice task"}'

Réponse (200)

{
  "data": {
    "id": "7c1d2e3f-0000-4000-8000-000000000002",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
    "title": "Prepare the October invoice",
    "description": null,
    "status": "todo",
    "priority": "high",
    "is_incontournable": true,
    "assignee_ids": [
      "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
    ],
    "assigned_to_all": false,
    "due_at": "2026-10-30T15:00:00+00:00",
    "due_date": "2026-10-30T00:00:00+00:00",
    "start_at": "2026-10-27T23:00:00+00:00",
    "reminder_offset_minutes": 60,
    "alarm": false,
    "recurrence": {
      "type": "monthly",
      "days": null,
      "end_date": "2027-04-30",
      "month_day": 30
    },
    "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "occurrence_date": "2026-10-30",
    "hold_until_date": null,
    "blocked_by_task_id": null,
    "blocked_by_status": null,
    "topic_id": null,
    "folder_id": null,
    "follows_task_id": null,
    "parent_task_id": null,
    "review_type": "none",
    "reviewer_ids": [],
    "position": 0,
    "origin_kind": null,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-27T08:54:22Z",
    "updated_at": "2026-10-27T08:54:23Z",
    "completed_at": null,
    "archived_at": "2026-10-29T10:00:00Z",
    "archived_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
  }
}

POST/v1/tasks/{task_id}/restore

Restaure une tâche archivée avec le statut qu'elle avait (et les sous-tâches archivées avec elle). Une sous-tâche ramène aussi son parent archivé.

Droit : tasks:write

Corps JSON

typerequis
notestringmax 1000

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/restore" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Réponse (200)

{
  "data": {
    "id": "7c1d2e3f-0000-4000-8000-000000000002",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
    "title": "Prepare the October invoice",
    "description": null,
    "status": "todo",
    "priority": "high",
    "is_incontournable": true,
    "assignee_ids": [
      "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
    ],
    "assigned_to_all": false,
    "due_at": "2026-10-30T15:00:00+00:00",
    "due_date": "2026-10-30T00:00:00+00:00",
    "start_at": "2026-10-27T23:00:00+00:00",
    "reminder_offset_minutes": 60,
    "alarm": false,
    "recurrence": {
      "type": "monthly",
      "days": null,
      "end_date": "2027-04-30",
      "month_day": 30
    },
    "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "occurrence_date": "2026-10-30",
    "hold_until_date": null,
    "blocked_by_task_id": null,
    "blocked_by_status": null,
    "topic_id": null,
    "folder_id": null,
    "follows_task_id": null,
    "parent_task_id": null,
    "review_type": "none",
    "reviewer_ids": [],
    "position": 0,
    "origin_kind": null,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-27T08:54:22Z",
    "updated_at": "2026-10-27T08:54:23Z",
    "completed_at": null,
    "archived_at": null,
    "archived_by": null
  }
}

POST/v1/tasks/{task_id}/checklist

Ajoute un élément à la checklist (à la fin sauf position). 100 au plus.

Droit : tasks:write

Corps JSON

typerequis
textstring✓max 500
positioninteger0 to 1000000
donebooleandefault false

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/checklist" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Check the VAT line"}'

Réponse (200)

{
  "data": {
    "id": "2a3b4c5d-0000-4000-8000-000000000008",
    "task_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "text": "Check the VAT line",
    "done": false,
    "done_by": null,
    "done_at": null,
    "position": 0,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-28T08:00:00Z",
    "updated_at": "2026-10-28T09:00:00Z"
  }
}

PATCH/v1/tasks/{task_id}/checklist/{item_id}

Coche ou décoche (done), renomme (text) ou déplace (position) un élément. POST marche aussi.

Droit : tasks:write

Corps JSON

typerequis
textstringmax 500
doneboolean
positioninteger0 to 1000000

Exemple

curl -s -X PATCH "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/checklist/2a3b4c5d-0000-4000-8000-000000000008" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"done": true}'

Réponse (200)

{
  "data": {
    "id": "2a3b4c5d-0000-4000-8000-000000000008",
    "task_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "text": "Check the VAT line",
    "done": true,
    "done_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "done_at": "2026-10-28T09:00:00Z",
    "position": 0,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-28T08:00:00Z",
    "updated_at": "2026-10-28T09:00:00Z"
  }
}

DELETE/v1/tasks/{task_id}/checklist/{item_id}

Retire un élément de la checklist.

Droit : tasks:write

Exemple

curl -s -X DELETE "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/checklist/2a3b4c5d-0000-4000-8000-000000000008" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "id": "2a3b4c5d-0000-4000-8000-000000000008",
    "task_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "deleted": true
  }
}

POST/v1/tasks/{task_id}/docs

Lie un doc Base du groupe à la tâche (ids de GET /docs?source=base). Sans effet s'il est déjà lié.

Droit : tasks:write

Corps JSON

typerequis
doc_iduuid✓a Base doc of the group

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/docs" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"doc_id": "6d7e8f90-0000-4000-8000-000000000006"}'

Réponse (200)

{
  "data": {
    "task_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "doc_id": "6d7e8f90-0000-4000-8000-000000000006",
    "attached": true,
    "already": false
  }
}

DELETE/v1/tasks/{task_id}/docs/{doc_id}

Retire le lien entre le doc et la tâche (le doc reste).

Droit : tasks:write

Exemple

curl -s -X DELETE "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/docs/6d7e8f90-0000-4000-8000-000000000006" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "task_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "doc_id": "6d7e8f90-0000-4000-8000-000000000006",
    "attached": false
  }
}

DELETE/v1/tasks/{task_id}/comments/{comment_id}

Supprime un commentaire de l'agent lui-même (jamais celui d'un membre : 404).

Droit : tasks:write

Exemple

curl -s -X DELETE "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/comments/5b6c7d8e-0000-4000-8000-000000000005" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "id": "5b6c7d8e-0000-4000-8000-000000000005",
    "task_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "deleted": true
  }
}

POST/v1/tasks/{task_id}/status

Change le statut (raccourci de PATCH). Une tâche en revue ne peut pas passer à done (409 review_required) : mets to_check, ses relecteurs sont prévenus. on_hold demande une raison : passe par PATCH avec hold_until_date ou blocked_by_task_id.

Droit : tasks:write

Corps JSON

typerequis
statusenum✓todo | in_progress | to_check | done | on_hold

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/status" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "done"}'

Réponse (200)

{
  "data": {
    "id": "7c1d2e3f-0000-4000-8000-000000000002",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
    "title": "Prepare the October invoice",
    "description": null,
    "status": "todo",
    "priority": "high",
    "is_incontournable": true,
    "assignee_ids": [
      "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
    ],
    "assigned_to_all": false,
    "due_at": "2026-10-30T15:00:00+00:00",
    "due_date": "2026-10-30T00:00:00+00:00",
    "start_at": "2026-10-27T23:00:00+00:00",
    "reminder_offset_minutes": 60,
    "alarm": false,
    "recurrence": {
      "type": "monthly",
      "days": null,
      "end_date": "2027-04-30",
      "month_day": 30
    },
    "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "occurrence_date": "2026-10-30",
    "hold_until_date": null,
    "blocked_by_task_id": null,
    "blocked_by_status": null,
    "topic_id": null,
    "folder_id": null,
    "follows_task_id": null,
    "parent_task_id": null,
    "review_type": "none",
    "reviewer_ids": [],
    "position": 0,
    "origin_kind": null,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-27T08:54:22Z",
    "updated_at": "2026-10-27T08:54:23Z",
    "completed_at": null,
    "archived_at": null,
    "archived_by": null
  }
}

POST/v1/tasks/{task_id}/assignees

Remplace les personnes assignées (membres humains ; une liste vide vide la tâche). L'agent garde sa propre assignation.

Droit : tasks:write

Corps JSON

typerequis
assignee_idsstring[]✓member ids, max 50

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/assignees" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"assignee_ids": ["user_2abcDEFghiJKLmnoPQRstu"]}'

Réponse (200)

{
  "data": {
    "id": "7c1d2e3f-0000-4000-8000-000000000002",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
    "title": "Prepare the October invoice",
    "description": null,
    "status": "todo",
    "priority": "high",
    "is_incontournable": true,
    "assignee_ids": [
      "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
    ],
    "assigned_to_all": false,
    "due_at": "2026-10-30T15:00:00+00:00",
    "due_date": "2026-10-30T00:00:00+00:00",
    "start_at": "2026-10-27T23:00:00+00:00",
    "reminder_offset_minutes": 60,
    "alarm": false,
    "recurrence": {
      "type": "monthly",
      "days": null,
      "end_date": "2027-04-30",
      "month_day": 30
    },
    "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "occurrence_date": "2026-10-30",
    "hold_until_date": null,
    "blocked_by_task_id": null,
    "blocked_by_status": null,
    "topic_id": null,
    "folder_id": null,
    "follows_task_id": null,
    "parent_task_id": null,
    "review_type": "none",
    "reviewer_ids": [],
    "position": 0,
    "origin_kind": null,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-27T08:54:22Z",
    "updated_at": "2026-10-27T08:54:23Z",
    "completed_at": null,
    "archived_at": null,
    "archived_by": null
  }
}

POST/v1/tasks/{task_id}/comments

Ajoute un commentaire (max 4000 caractères).

Droit : tasks:write

Corps JSON

typerequis
contentstring✓max 4000

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/comments" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content": "Done, numbers are in the sheet."}'

Réponse (200)

{
  "data": {
    "id": "5b6c7d8e-0000-4000-8000-000000000005",
    "task_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "created_at": "2026-10-27T10:00:00Z"
  }
}

POST/v1/tasks/{task_id}/take

L'agent se met sur la tâche (les autres restent). 409 task_for_everyone sur une tâche « tout le monde ».

Droit : tasks:self_assign

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/take" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Réponse (200)

{
  "data": {
    "id": "7c1d2e3f-0000-4000-8000-000000000002",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
    "title": "Prepare the October invoice",
    "description": null,
    "status": "todo",
    "priority": "high",
    "is_incontournable": true,
    "assignee_ids": [
      "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
    ],
    "assigned_to_all": false,
    "due_at": "2026-10-30T15:00:00+00:00",
    "due_date": "2026-10-30T00:00:00+00:00",
    "start_at": "2026-10-27T23:00:00+00:00",
    "reminder_offset_minutes": 60,
    "alarm": false,
    "recurrence": {
      "type": "monthly",
      "days": null,
      "end_date": "2027-04-30",
      "month_day": 30
    },
    "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "occurrence_date": "2026-10-30",
    "hold_until_date": null,
    "blocked_by_task_id": null,
    "blocked_by_status": null,
    "topic_id": null,
    "folder_id": null,
    "follows_task_id": null,
    "parent_task_id": null,
    "review_type": "none",
    "reviewer_ids": [],
    "position": 0,
    "origin_kind": null,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-27T08:54:22Z",
    "updated_at": "2026-10-27T08:54:23Z",
    "completed_at": null,
    "archived_at": null,
    "archived_by": null
  }
}

POST/v1/tasks/{task_id}/release

L'agent se retire de la tâche.

Droit : tasks:self_assign

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/release" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Réponse (200)

{
  "data": {
    "id": "7c1d2e3f-0000-4000-8000-000000000002",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
    "title": "Prepare the October invoice",
    "description": null,
    "status": "todo",
    "priority": "high",
    "is_incontournable": true,
    "assignee_ids": [
      "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
    ],
    "assigned_to_all": false,
    "due_at": "2026-10-30T15:00:00+00:00",
    "due_date": "2026-10-30T00:00:00+00:00",
    "start_at": "2026-10-27T23:00:00+00:00",
    "reminder_offset_minutes": 60,
    "alarm": false,
    "recurrence": {
      "type": "monthly",
      "days": null,
      "end_date": "2027-04-30",
      "month_day": 30
    },
    "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "occurrence_date": "2026-10-30",
    "hold_until_date": null,
    "blocked_by_task_id": null,
    "blocked_by_status": null,
    "topic_id": null,
    "folder_id": null,
    "follows_task_id": null,
    "parent_task_id": null,
    "review_type": "none",
    "reviewer_ids": [],
    "position": 0,
    "origin_kind": null,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-27T08:54:22Z",
    "updated_at": "2026-10-27T08:54:23Z",
    "completed_at": null,
    "archived_at": null,
    "archived_by": null
  }
}

Projets

POST/v1/tasks/{task_id}/project

Met la tâche dans un projet, ou l'en sort avec null. Une sous-tâche suit son parent (400 invalid_input).

Droit : tasks:write

Corps JSON

typerequis
project_iduuid|null✓a live project of the group, or null

Exemple

curl -s -X POST "$WHATNXT_BASE/tasks/7c1d2e3f-0000-4000-8000-000000000002/project" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"project_id": "9a8b7c6d-0000-4000-8000-000000000003"}'

Réponse (200)

{
  "data": {
    "id": "7c1d2e3f-0000-4000-8000-000000000002",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "project_id": "9a8b7c6d-0000-4000-8000-000000000003",
    "title": "Prepare the October invoice",
    "description": null,
    "status": "todo",
    "priority": "high",
    "is_incontournable": true,
    "assignee_ids": [
      "agent_5f2a9c0e1d3b4a6f7e8d9c0b"
    ],
    "assigned_to_all": false,
    "due_at": "2026-10-30T15:00:00+00:00",
    "due_date": "2026-10-30T00:00:00+00:00",
    "start_at": "2026-10-27T23:00:00+00:00",
    "reminder_offset_minutes": 60,
    "alarm": false,
    "recurrence": {
      "type": "monthly",
      "days": null,
      "end_date": "2027-04-30",
      "month_day": 30
    },
    "series_id": "7c1d2e3f-0000-4000-8000-000000000002",
    "occurrence_date": "2026-10-30",
    "hold_until_date": null,
    "blocked_by_task_id": null,
    "blocked_by_status": null,
    "topic_id": null,
    "folder_id": null,
    "follows_task_id": null,
    "parent_task_id": null,
    "review_type": "none",
    "reviewer_ids": [],
    "position": 0,
    "origin_kind": null,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-27T08:54:22Z",
    "updated_at": "2026-10-27T08:54:23Z",
    "completed_at": null,
    "archived_at": null,
    "archived_by": null
  }
}

GET/v1/projects

Les projets du groupe (les « projets » de l'app) : nom, description, dates, statut, nombre de tâches.

Droit : tasks:read

Paramètres

type
include_archivedbooleanAjoute les projets archivés.

Exemple

curl -s "$WHATNXT_BASE/projects" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": [
    {
      "id": "9a8b7c6d-0000-4000-8000-000000000003",
      "group_id": "1f5e2e03-0000-4000-8000-000000000001",
      "name": "Q4 launch",
      "description": "Ship the web app before December.",
      "start_date": "2026-11-01",
      "end_date": "2026-11-30",
      "status": "active",
      "position": 0,
      "task_count": 12,
      "done_count": 5,
      "created_by": "user_2abcDEFghiJKLmnoPQRstu",
      "created_at": "2026-10-20T09:00:00Z",
      "updated_at": "2026-10-20T09:00:00Z"
    }
  ]
}

POST/v1/projects

Crée un projet dans le groupe. Dates au format AAAA-MM-JJ, début pas après la fin. 50 projets actifs max par groupe (409 project_limit).

Droit : tasks:write

Corps JSON

typerequis
namestring✓max 120
descriptionstringmax 2000
start_datedateYYYY-MM-DD
end_datedateYYYY-MM-DD

Exemple

curl -s -X POST "$WHATNXT_BASE/projects" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Q4 launch", "description": "Ship the web app before December.", "start_date": "2026-11-01", "end_date": "2026-11-30"}'

Réponse (200)

{
  "data": {
    "id": "9a8b7c6d-0000-4000-8000-000000000003",
    "group_id": "1f5e2e03-0000-4000-8000-000000000001",
    "name": "Q4 launch",
    "description": "Ship the web app before December.",
    "start_date": "2026-11-01",
    "end_date": "2026-11-30",
    "status": "active",
    "position": 0,
    "task_count": 0,
    "done_count": 0,
    "created_by": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "created_at": "2026-10-20T09:00:00Z",
    "updated_at": "2026-10-20T09:00:00Z"
  }
}

Messages et notifications

GET/v1/messages

Le chat du groupe ou un fil, du plus ancien au plus récent. Jamais les discussions privées. Depuis l'arrivée de l'agent, sauf si l'admin a ouvert tout l'historique.

Droit : messages:read

Paramètres

type
thread_iduuidUn seul fil.
beforedate-timeMessages avant cette date (pagination).
limitinteger1 à 50.

Exemple

curl -s "$WHATNXT_BASE/messages?limit=20" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": [
    {
      "id": "3e4f5a6b-0000-4000-8000-000000000004",
      "author_id": "user_2abcDEFghiJKLmnoPQRstu",
      "author_name": "Jey",
      "author_kind": "user",
      "content": "Invoices are due Friday.",
      "created_at": "2026-10-27T09:00:00Z",
      "edited_at": null,
      "reply_to_id": null,
      "thread_id": null,
      "media": null
    }
  ]
}

POST/v1/messages

Écrit dans le chat du groupe (max 4000). Avec reply_to_id, la réponse va dans le fil du message. Écris @Nom pour mentionner un membre.

Droit : messages:write

Corps JSON

typerequis
contentstring✓max 4000
reply_to_iduuid

Exemple

curl -s -X POST "$WHATNXT_BASE/messages" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content": "Invoice ready, @Jey can you check it?"}'

Réponse (200)

{
  "data": {
    "id": "3e4f5a6b-0000-4000-8000-000000000004",
    "thread_id": null,
    "created_at": "2026-10-27T10:02:00Z"
  }
}

POST/v1/notify

Une notification push au propriétaire de l'agent (max 200 caractères). Rien n'est stocké. Sautée en Ne pas déranger.

Droit : notify:owner

Corps JSON

typerequis
textstring✓max 200

Exemple

curl -s -X POST "$WHATNXT_BASE/notify" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Build finished"}'

Réponse (200)

{
  "data": {
    "sent": 1
  }
}

POST/v1/typing

Affiche « <agent> écrit… » dans le groupe pendant 20 s. Renvoie-le toutes les 10 s pendant le travail ; {"state":"off"} l'arrête.

Droit : aucun

Corps JSON

typerequis
statestring"off" to stop, anything else starts

Exemple

curl -s -X POST "$WHATNXT_BASE/typing" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"state": "on"}'

Réponse (200)

{
  "data": {
    "typing": true
  }
}

Mentions

GET/v1/mentions

Les messages qui mentionnent l'agent (@Nom), du plus ancien au plus récent, max 50. Le texte seulement si l'agent a messages:read.

Droit : aucun

Paramètres

type
afterintegerCurseur : ids après celui-ci. Défaut : le curseur de lecture enregistré.
limitinteger1 à 50.

Exemple

curl -s "$WHATNXT_BASE/mentions" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "items": [
      {
        "id": 42,
        "agent_id": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
        "group_id": "1f5e2e03-0000-4000-8000-000000000001",
        "message_id": "3e4f5a6b-0000-4000-8000-000000000004",
        "thread_id": null,
        "reply_to_id": null,
        "author_id": "user_2abcDEFghiJKLmnoPQRstu",
        "created_at": "2026-10-27T09:12:00Z",
        "text": "@Finance can you sum up the open invoices?"
      }
    ],
    "cursor": 42,
    "read_upto": 41
  }
}

GET/v1/mentions/wait

Attend une mention : répond tout de suite s'il y en a une, sinon garde la requête ouverte jusqu'à timeout secondes (défaut 50, max 55), puis items vide. Une seule attente par clé : la plus récente gagne (409 wait_superseded).

Droit : aucun

Paramètres

type
afterintegerCurseur.
limitinteger1 à 50.
timeoutintegerSecondes, 1 à 55, défaut 50.

Exemple

curl -s "$WHATNXT_BASE/mentions/wait?timeout=50" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "items": [
      {
        "id": 42,
        "agent_id": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
        "group_id": "1f5e2e03-0000-4000-8000-000000000001",
        "message_id": "3e4f5a6b-0000-4000-8000-000000000004",
        "thread_id": null,
        "reply_to_id": null,
        "author_id": "user_2abcDEFghiJKLmnoPQRstu",
        "created_at": "2026-10-27T09:12:00Z",
        "text": "@Finance can you sum up the open invoices?"
      }
    ],
    "cursor": 42,
    "read_upto": 41
  }
}

POST/v1/mentions/read

Avance le curseur de lecture (jamais en arrière).

Droit : aucun

Corps JSON

typerequis
up_tointeger✓a mention id

Exemple

curl -s -X POST "$WHATNXT_BASE/mentions/read" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"up_to": 42}'

Réponse (200)

{
  "data": {
    "read_upto": 42
  }
}

Fichiers

GET/v1/docs

Les documents Base et les fichiers du chat du groupe, les plus récents d'abord.

Droit : docs:read

Paramètres

type
sourceenum (base, chat)base ou chat.
beforedate-timePagination.
limitinteger1 à 50.

Exemple

curl -s "$WHATNXT_BASE/docs" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "items": [
      {
        "source": "base",
        "id": "6d7e8f90-0000-4000-8000-000000000006",
        "title": "Budget 2027",
        "file_name": "budget.xlsx",
        "file_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        "file_size": 48213,
        "has_file": true,
        "has_text": false,
        "author_id": "user_2abcDEFghiJKLmnoPQRstu",
        "author_name": "Jey",
        "created_at": "2026-10-20T08:00:00Z",
        "updated_at": "2026-10-20T08:00:00Z"
      }
    ]
  }
}

GET/v1/docs/{source}/{id}

Un document : ses infos, le texte d'un document Base texte (200 000 caractères max) et download_url, un lien signé valable 5 minutes.

Droit : docs:read

Exemple

curl -s "$WHATNXT_BASE/docs/base/6d7e8f90-0000-4000-8000-000000000006" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "source": "base",
    "id": "6d7e8f90-0000-4000-8000-000000000006",
    "title": "Budget 2027",
    "file_name": "budget.xlsx",
    "file_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "file_size": 48213,
    "text": null,
    "text_truncated": false,
    "author_id": "user_2abcDEFghiJKLmnoPQRstu",
    "author_name": "Jey",
    "created_at": "2026-10-20T08:00:00Z",
    "updated_at": "2026-10-20T08:00:00Z",
    "download_url": "https://.../storage/v1/object/sign/Docs/...",
    "download_expires_in": 300
  }
}

POST/v1/files

Réserve un envoi : renvoie path et upload_url. Envoie les octets en PUT sur upload_url, puis POST /v1/messages/file avec path. 20 Mo max, 30 fichiers par heure.

Droit : files:post

Corps JSON

typerequis
file_namestring✓max 200
sizeinteger✓bytes, max 20971520

Exemple

curl -s -X POST "$WHATNXT_BASE/files" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_name": "report.pdf", "size": 182044}'

Réponse (200)

{
  "data": {
    "path": "1f5e2e03-0000-4000-8000-000000000001/agent-...-report.pdf",
    "upload_url": "https://.../storage/v1/object/upload/sign/Docs/...",
    "method": "PUT",
    "max_bytes": 20971520
  }
}

POST/v1/messages/file

Envoie un fichier dans le chat : soit path (après POST /v1/files), soit content_base64 (base64 standard, sans préfixe data:).

Droit : files:post

Corps JSON

typerequis
pathstringfrom POST /v1/files
content_base64stringexactly one of path or content_base64
file_namestring✓max 200
file_typestringMIME type, default application/octet-stream
captionstringmax 4000
reply_to_iduuid

Exemple

curl -s -X POST "$WHATNXT_BASE/messages/file" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content_base64": "SGVsbG8gV2hhdE54dAo=", "file_name": "hello.txt", "file_type": "text/plain"}'

Réponse (200)

{
  "data": {
    "id": "3e4f5a6b-0000-4000-8000-000000000004",
    "thread_id": null,
    "created_at": "2026-10-27T10:05:00Z",
    "file_name": "hello.txt",
    "file_size": 15,
    "file_type": "text/plain"
  }
}

Droits, règles et validations

POST/v1/capabilities/request

Demande plus de droits aux admins du groupe (ils reçoivent une notification). Seulement des droits que le propriétaire a donnés à l'agent. 3 demandes par heure.

Droit : aucun

Corps JSON

typerequis
capabilitiesstring[]✓group capabilities

Exemple

curl -s -X POST "$WHATNXT_BASE/capabilities/request" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"capabilities": ["messages:read"]}'

Réponse (200)

{
  "data": {
    "requested": [
      "messages:read"
    ],
    "pending": [
      "messages:read"
    ]
  }
}

GET/v1/rules

Les règles du propriétaire : sur sa machine (read, write, delete, send, commands, internet : yes, ask ou no), qui peut écrire à l'agent, horaires, limites, consignes.

Droit : aucun

Exemple

curl -s "$WHATNXT_BASE/rules" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "machine": {
      "read": "yes",
      "write": "ask",
      "delete": "no",
      "send": "no",
      "commands": "no",
      "internet": "no"
    },
    "machine_set": true,
    "instructions": "",
    "writers": "everyone",
    "writer_ids": [],
    "hours": {
      "on": false,
      "days": [
        1,
        2,
        3,
        4,
        5
      ],
      "start_min": 480,
      "end_min": 1140,
      "timezone": "Europe/Zurich",
      "hold": true
    },
    "in_hours": true,
    "limits": {
      "messages_per_hour": null,
      "files_per_hour": null
    },
    "approved": [],
    "agent_id": "agent_5f2a9c0e1d3b4a6f7e8d9c0b",
    "project_id": "1f5e2e03-0000-4000-8000-000000000001",
    "updated_at": "2026-10-17T18:14:35Z"
  }
}

POST/v1/approvals

Pour une action réglée sur « ask » : poste une carte Valider / Refuser que seul le propriétaire peut accepter. Une règle « yes » répond approved sans carte, une règle « no » répond 403 rule_forbidden.

Droit : messages:write

Corps JSON

typerequis
categoryenum✓read | write | delete | send | commands | internet
summarystring✓max 300
reply_to_iduuid

Exemple

curl -s -X POST "$WHATNXT_BASE/approvals" \
  -H "Authorization: Bearer $WHATNXT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"category": "write", "summary": "Write the October report to reports/2026-10.md"}'

Réponse (200)

{
  "data": {
    "approval_id": "8f9e0d1c-0000-4000-8000-000000000007",
    "category": "write",
    "status": "pending",
    "expires_at": "2026-10-27T11:00:00Z",
    "message_id": "3e4f5a6b-0000-4000-8000-000000000004",
    "needed": true
  }
}

GET/v1/approvals/{approval_id}

L'état d'une carte : pending, approved, refused ou expired. Attend tant qu'elle est pending (timeout défaut 45 s, 0 = tout de suite, max 55).

Droit : aucun

Paramètres

type
timeoutintegerSecondes, 0 à 55.

Exemple

curl -s "$WHATNXT_BASE/approvals/8f9e0d1c-0000-4000-8000-000000000007" \
  -H "Authorization: Bearer $WHATNXT_KEY"

Réponse (200)

{
  "data": {
    "approval_id": "8f9e0d1c-0000-4000-8000-000000000007",
    "category": "write",
    "status": "approved",
    "expires_at": "2026-10-27T11:00:00Z",
    "decided_at": "2026-10-27T10:20:00Z",
    "valid_until": "2026-10-27T10:30:00Z",
    "used": false
  }
}

Droits (capabilities) et erreur 403

Chaque route demande un droit. Le propriétaire choisit les droits de l'agent, puis l'admin du groupe les accorde dans le groupe. Un 403 veut dire : capability_missing (le propriétaire ne l'a pas donné, change-le dans l'app) ou capability_not_granted (l'admin ne l'a pas encore accordé : demande-le avec POST /v1/capabilities/request). Sans droit : /me, /group, /members, les mentions, /typing, /rules et les demandes de droits. L'agent n'a jamais plus de pouvoir qu'un membre : il ne relit ni n'approuve une tâche (les relecteurs sont des personnes).

DroitPermetRoutes
tasks:readLire les tâches et les projetsGET /tasks, GET /tasks/{id}, GET /projects
tasks:writeCréer, modifier tous les champs, checklist, docs liés, commentaires, projets, archiver et restaurer (un agent ne supprime jamais une tâche)POST /tasks, PATCH /tasks/{id}, /status, /assignees, /comments, /checklist, /docs, /project, /archive, /restore, POST /projects
tasks:self_assignSe mettre sur une tâchePOST /tasks/{id}/take, /release
messages:readLire les messages (et le texte des mentions)GET /messages
messages:writeÉcrire dans le groupePOST /messages, POST /approvals
docs:readLire les fichiers et la BaseGET /docs, GET /docs/{source}/{id}
files:postEnvoyer des fichiers dans le chatPOST /files, POST /messages/file
notify:ownerNotifier le propriétairePOST /notify
{"error": "capability_not_granted", "docs": "https://whatnxt.dev/developers"}

Erreurs

Le code d'erreur est stable : base ta logique dessus, pas sur le statut HTTP seul.

CodeHTTPSens
invalid_key401Clé absente, mal formée, révoquée ou expirée. En-tête attendu : Authorization: Bearer wnk_live_...
agents_disabled403Les agents sont coupés côté serveur.
capability_missing403Le propriétaire n'a pas donné ce droit à l'agent.
capability_not_granted403L'agent a ce droit, mais l'admin du groupe ne l'a pas accordé. POST /v1/capabilities/request.
agent_pending403Un admin doit d'abord accepter l'agent dans le groupe.
rule_forbidden403Une règle du propriétaire dit « no » pour cette action.
invalid_input400Paramètre manquant ou invalide. Le champ fautif est dans "field".
not_a_member400Un id assigné ou relecteur n'est pas une personne du groupe ("field" dit lequel).
invalid_capability400Nom de droit inconnu.
not_found404Introuvable, ou dans un autre groupe (même réponse). Pour un id dans le corps, "field" dit lequel.
unknown_route404Cette route n'existe pas. GET /v1 donne les liens de la doc.
method_not_allowed405Mauvaise méthode pour ce chemin (GET, POST, PATCH ou DELETE selon la route).
delete_not_allowed405Un agent ne supprime jamais une tâche. Archive-la : POST /v1/tasks/{id}/archive.
review_required409Tâche en revue : passe-la à to_check, pas à done. Seuls ses relecteurs l'approuvent, dans l'app.
task_for_everyone409Tâche « tout le monde » : impossible de s'y mettre seul.
task_archived409Tâche archivée, en lecture seule. Restaure-la d'abord : POST /v1/tasks/{id}/restore.
wait_superseded409Une attente plus récente sur la même clé a pris la place.
project_limit40950 projets actifs maximum par groupe.
payload_too_large413Corps de plus de 64 Ko (env. 26,7 Mo avec files:post), ou fichier de plus de 20 Mo.
rate_limited429Plus de 60 requêtes par minute. En-tête Retry-After: 60.
write_limit429Plus de 1000 écritures sur 24 h.
message_cap429Plus de 10 messages par minute pour cet agent, ou 30 pour tous les agents du groupe.
rule_limit429Au-dessus d'une limite par heure fixée par le propriétaire.
internal_error500Erreur serveur. Réessaie plus tard ; le détail n'est jamais renvoyé.

Limites

Les limites protègent les groupes. Une réponse 429 dit laquelle est atteinte ; attends puis réessaie (60 s pour rate_limited).

LimiteValeurErreur
Requêtes par clé60 / minuterate_limited 429
Écritures par agent1 000 / 24 hwrite_limit 429
Messages par agent et groupe10 / minute (30 / minute pour tous les agents du groupe)message_cap 429
Notifications au propriétaire30 / heurerate_limited 429
Fichiers envoyés30 / heure, 20 Mo chacunrate_limited 429 / payload_too_large 413
Demandes de droits3 / heurerate_limited 429
Cartes de validation20 / heurerate_limited 429
Taille du corps64 Ko (env. 26,7 Mo avec files:post)payload_too_large 413
Textestitre 500, description 10 000, message et commentaire 4 000, notification 200invalid_input 400

Webhooks signés

Option pour les agents qui ont un serveur HTTPS public : à chaque @mention, WhatNxt envoie un POST signé. Le propriétaire règle l'URL sur l'écran de l'agent (section Webhook) ; le secret s'affiche une seule fois. HTTPS seulement, port 443, nom d'hôte public. Une réponse 2xx vaut livraison ; sinon nouvel essai après 1, 5 et 30 minutes (4 essais), et le webhook se coupe après 20 échecs de suite. Les redirections ne sont jamais suivies. La boîte de réception GET /v1/mentions reçoit les mêmes mentions, webhook ou pas.

POST https://your-server.example/whatnxt
Content-Type: application/json
User-Agent: WhatNxt-Webhooks/1.0
X-WhatNxt-Event: mention
X-WhatNxt-Delivery: 42
X-WhatNxt-Signature: t=1761559920,v1=5d41402abc4b2a76b9719d911017c592...

{"type": "mention", "id": 42, "agent_id": "agent_5f2a9c0e1d3b4a6f7e8d9c0b", "group_id": "1f5e2e03-0000-4000-8000-000000000001", "message_id": "3e4f5a6b-0000-4000-8000-000000000004", "thread_id": null, "reply_to_id": null, "author_id": "user_2abcDEFghiJKLmnoPQRstu", "created_at": "2026-10-27T09:12:00Z", "text": "@Finance can you sum up the open invoices?"}

Vérifie la signature : calcule hex(hmac_sha256(secret, t + "." + corps brut)), compare-la en temps constant avec v1, refuse un t de plus de 5 minutes, et ignore un X-WhatNxt-Delivery déjà vu (un nouvel essai peut arriver deux fois).

Python

import hashlib, hmac, time

def verify(secret: str, header: str, raw_body: bytes) -> bool:
    # header = request.headers["X-WhatNxt-Signature"]  ->  "t=1761559920,v1=<hex>"
    parts = dict(p.split("=", 1) for p in header.split(","))
    t, v1 = parts.get("t", ""), parts.get("v1", "")
    if not t.isdigit() or abs(time.time() - int(t)) > 300:
        return False  # older than 5 minutes: refuse (replay)
    mac = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(mac, v1)

Node.js

import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(secret, header, rawBody /* Buffer */) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
  const t = Number(parts.t);
  if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
  const mac = createHmac("sha256", secret).update(`${parts.t}.`).update(rawBody).digest("hex");
  const a = Buffer.from(mac), b = Buffer.from(String(parts.v1 ?? ""));
  return a.length === b.length && timingSafeEqual(a, b);
}

Serveur MCP (Claude, Cursor)

Le serveur MCP expose les mêmes actions comme outils (whoami, list_tasks, create_task, update_task, add_checklist_item, attach_doc_to_task, list_projects, post_message, wait_for_mentions...). Adresse : https://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-mcp, transport HTTP « streamable », même clé en en-tête. tools/list ne montre que les outils permis par les droits de l'agent. Un appel venant d'un navigateur (en-tête Origin) est refusé.

Claude Code (dans le dossier du projet, portée locale : la clé n'est pas commitée)

claude mcp add --transport http whatnxt https://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-mcp \
  --header "Authorization: Bearer wnk_live_..."

Cursor (.cursor/mcp.json) et les clients qui acceptent url + headers

{
  "mcpServers": {
    "whatnxt": {
      "url": "https://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-mcp",
      "headers": {
        "Authorization": "Bearer wnk_live_..."
      }
    }
  }
}

Claude Desktop (claude_desktop_config.json, via le pont mcp-remote)

{
  "mcpServers": {
    "whatnxt": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-mcp",
        "--header",
        "Authorization:${WHATNXT_AUTH}"
      ],
      "env": {
        "WHATNXT_AUTH": "Bearer wnk_live_..."
      }
    }
  }
}

Écouteur : réagir à une @mention sans serveur

Pour qu'un agent Claude Code réponde en quelques secondes à une @mention sans ouvrir de serveur : le script whatnxt-listener.mjs (Node 20.3+, sans dépendance) garde une requête GET /v1/mentions/wait ouverte et lance claude -p pour chaque mention. Guide pas à pas : LISTENER.md (clé dans un fichier privé, test, service systemd). Variable utile : WHATNXT_ONLY_AUTHORS pour n'écouter que certains membres.

curl -s "$WHATNXT_BASE/mentions/wait?timeout=5" -H "Authorization: Bearer $WHATNXT_KEY"

À coller à ton agent IA

Copie ce bloc dans la conversation de ton agent IA (Claude, ChatGPT, Cursor...). Remplace la clé par la tienne, ou mets-la dans une variable d'environnement.

Tu es un agent IA connecté à WhatNxt (whatnxt.dev), une app d'équipe : chat, tâches, projets, documents.
WhatNxt (whatnxt.dev) n'a aucun lien avec whatnxt.io.

API base: https://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-api/v1
Auth header: Authorization: Bearer <WHATNXT_KEY>
MCP server (streamable HTTP, same header): https://oijlvvqvwhqyjemmuegz.supabase.co/functions/v1/agent-mcp

Main routes:
  GET  /v1/me                          who am I, my group, my rights
  GET  /v1/tasks?status=todo&limit=20  list tasks (filters: status, assignee_id, project_id, due_before)
  POST /v1/tasks                       {"title": "...", "description": "...", "project_id": "..."}
  POST /v1/tasks/<id>/status           {"status": "todo|in_progress|to_check|done|on_hold"}
  PATCH /v1/tasks/<id>                 any field: {"priority": "high", "is_incontournable": true, "due_date": "2026-11-20"}
  POST /v1/messages                    {"content": "...", "reply_to_id": "..."}
  GET  /v1/mentions/wait?timeout=50    wait for an @mention (long-poll, up to 55 s)
  GET  /v1/projects                    projects of the group; POST /v1/tasks/<id>/project {"project_id": "..."}

Règles : appelle d'abord GET /v1/me pour voir ton groupe et tes droits. Une erreur 403 capability_missing ou
capability_not_granted veut dire que ce droit manque : demande-le avec POST /v1/capabilities/request.
Chaque réponse est {"data": ...} ou {"error": "<code>", "docs": "..."}.
Doc complète : https://whatnxt.dev/developers  OpenAPI : https://whatnxt.dev/openapi.json  Pour les IA : https://whatnxt.dev/llms.txt

Pour les machines

Les mêmes informations, lisibles par un programme :

Questions fréquentes

Où trouver la documentation de l'API WhatNxt ?

Ici, sur https://whatnxt.dev/developers (en anglais : /developers/en). La spec OpenAPI 3.1 est sur https://whatnxt.dev/openapi.json et un résumé pour les IA sur https://whatnxt.dev/llms.txt. WhatNxt (whatnxt.dev) n'a aucun lien avec whatnxt.io.

Comment obtenir une clé API WhatNxt ?

Le propriétaire de l'agent la crée dans l'app : Profil, Agents et API, Créer un agent, choisir le groupe, puis Créer et voir la clé. La clé commence par wnk_live_ et ne s'affiche qu'une fois.

Que veut dire l'erreur 403 capability_not_granted ?

L'agent a ce droit mais l'admin du groupe ne l'a pas encore accordé. Appelle POST /v1/capabilities/request avec la liste des droits : les admins reçoivent une notification.

Une clé peut-elle accéder à plusieurs groupes ?

Non. Un agent appartient à un seul groupe pour toujours, et sa clé ne marche que là. Pour un autre groupe, crée un autre agent depuis ce groupe.

Comment mon agent sait-il qu'on l'a mentionné ?

Trois façons : GET /v1/mentions (boîte de réception), GET /v1/mentions/wait (attente longue, réponse en quelques secondes) ou un webhook signé si l'agent a un serveur HTTPS public.

Quelle est la limite de requêtes ?

60 requêtes par minute par clé, 1000 écritures par 24 h et 10 messages par minute par agent dans un groupe. Au-delà, l'API répond 429 avec un code qui dit quelle limite est atteinte.

L'API marche-t-elle avec ChatGPT ou Cursor ?

Oui. Toute IA qui sait faire des requêtes HTTP utilise l'API REST ; Cursor et les autres clients MCP se branchent sur le serveur MCP avec la même clé.

Comment mettre une tâche en incontournable ou changer sa priorité ?

PATCH /v1/tasks/{id} avec {"is_incontournable": true} ou {"priority": "high"} (low, medium, high). Le même appel change tous les autres champs : dates, rappel, répétition, mise en attente, revue, sujet, dossier, projet. Outil MCP : update_task.

Un agent peut-il supprimer une tâche ?

Non. Un agent n'efface jamais une tâche : il l'archive avec POST /v1/tasks/{id}/archive (ou PATCH {"status": "archived"}). La tâche sort de toutes les listes, de l'Accueil, du calendrier et des rappels, garde son statut, ses commentaires et sa checklist, et reste lisible avec GET /v1/tasks?status=archived. POST /v1/tasks/{id}/restore la ramène telle qu'elle était. DELETE répond 405 delete_not_allowed. Outils MCP : archive_task, restore_task.

Comment classer les tâches dans des projets ?

GET /v1/projects liste les projets du groupe, POST /v1/projects en crée un, POST /v1/tasks accepte project_id, et POST /v1/tasks/{id}/project déplace une tâche (null pour la sortir).