API des tâches
Publiez des tâches dans Cryptauk depuis vos propres logiciels — un outil métier, une supervision, un script — et suivez qui s'en occupe et quand c'est fait.
Une clé API donne accès aux tâches, jamais au coffre : ni mots de passe, ni notes, ni fichiers. Elle vivra sur un autre serveur, dans un fichier de configuration : si elle fuit un jour, seules des tâches seront exposées.
Deux sortes de clés
| Clé de groupe | Clé personnelle | |
|---|---|---|
| Sert à | alimenter un groupe en tâches depuis un logiciel | agir sur les tâches d'une personne, à sa place |
| Créée pour | un groupe dont vous êtes créateur ou administrateur | votre propre compte |
| Crée des tâches | partagées avec le groupe — et, en plus, avec d'autres groupes que son créateur administre | à vous ; vous pouvez les partager |
| Lit | toutes les tâches partagées avec le groupe | vos tâches, et celles qu'on vous a confiées — ou, si elle est restreinte, seulement vos tâches de certaines catégories et les tâches communes de certains groupes |
| Modifie, supprime | les tâches créées par une clé de ce groupe | les tâches dont vous êtes propriétaire |
| Prend en charge, termine | non : c'est un geste humain | oui, comme dans l'application |
Une clé n'a jamais plus de droits que la personne qui l'a créée. Une clé de groupe cesse de fonctionner si son créateur quitte le groupe ou n'en est plus administrateur ; une clé personnelle, si le compte est désactivé.
Obtenir une clé
Pour l'instant, les clés sont délivrées par l'équipe Cryptauk. Écrivez-nous en précisant le logiciel à brancher, et s'il s'agit d'une clé personnelle ou d'une clé de groupe — dans ce cas, le nom du groupe, dont vous devez être créateur ou administrateur.
Pour une clé personnelle, précisez si elle doit couvrir toutes vos tâches, ou seulement certaines catégories de vos tâches et/ou les tâches communes de certains groupes (voir « Clé personnelle restreinte »).
Une clé ressemble à ckt_ suivi de 43 caractères. Elle ne vous est communiquée qu'une seule fois : Cryptauk n'en conserve qu'une empreinte et ne peut pas la retrouver. Perdue, elle se remplace par une nouvelle, et l'ancienne est révoquée.
La personne n'a pas de compte Cryptauk ? Le créateur ou un administrateur du groupe peut lui créer, depuis l'application, un compte tâches — sans coffre ni connexion — avec sa propre clé personnelle. Votre logiciel s'en sert pour agir en son nom. Si elle s'inscrit un jour avec la même adresse, son compte devient complet et la clé continue de fonctionner.
S'authentifier
Toutes les requêtes vont vers https://cryptauk.com/api/ext/v1, en JSON et en UTF-8. La clé se passe dans l'en-tête Authorization — ou dans X-Api-Key si votre outil ne permet pas le premier.
Commencez par GET /me, qui décrit la clé : le moyen le plus simple de vérifier une installation.
curl https://cryptauk.com/api/ext/v1/me \
-H "Authorization: Bearer $CRYPTAUK_API_KEY"
{
"type": "group",
"label": "Mon logiciel",
"user": {
"id": 2,
"name": "Camille"
},
"group": {
"id": 281474976710668,
"name": "Équipe technique"
},
"restrictedToCategories": null,
"restrictedToGroups": null
}
Une clé absente, mal formée, inconnue, révoquée, ou dont le créateur a perdu ses droits reçoit toujours la même réponse : 401 avec { "error": "invalid_api_key" }. Rien n'indique laquelle de ces raisons s'applique.
restrictedToCategories, restrictedToGroups : pour une clé personnelle restreinte, ses catégories de tâches et ses groupes ; null sinon.
L'objet tâche
| Champ | Sens |
|---|---|
id | Identifiant Cryptauk. Un grand entier : il tient dans un Number JavaScript, mais stockez-le sur 64 bits ou en texte. |
name, description, priority | Le contenu. priority va de 0 à 255 ; plus grand = plus urgent. |
category | { id, name } : la catégorie de tâches du propriétaire. Seulement avec sa clé personnelle ; null sinon. |
isDone | Terminée ou non. |
externalRef | Votre référence, fournie à la création (voir « Éviter les doublons »). null si aucune. |
createdVia | Nom de la clé API qui a créé la tâche ; null si elle a été créée dans une application Cryptauk. |
owner | Le propriétaire : lui seul en modifie le contenu. |
sharedGroups | Tous les groupes de la tâche, [{ id, name }], le principal en tête : une tâche peut en avoir plusieurs. |
sharedGroup | Le groupe principal seul, conservé pour compatibilité. |
sharedUser | La personne avec qui la tâche est partagée directement — exclusif des groupes. |
imageCount | Nombre d'images jointes (voir « Images jointes »). |
claimedBy, claimedAt | Qui a dit « je m'en occupe », et quand. null : personne. |
doneBy, doneAt | Qui l'a terminée, et quand. |
createdAt, updatedAt | Dates ISO 8601 en UTC. updatedAt change à chaque modification, prise en charge ou fin. |
{
"id": 562949953421340,
"name": "Remplacer la batterie de la centrale",
"description": "Site de Lyon, accès par le quai B",
"priority": 2,
"category": null,
"isDone": false,
"externalRef": "mysoftware:job:1234",
"createdVia": "Mon logiciel",
"owner": {
"id": 2,
"name": "Camille"
},
"sharedGroup": {
"id": 281474976710668,
"name": "Équipe technique"
},
"sharedGroups": [
{
"id": 281474976710668,
"name": "Équipe technique"
}
],
"sharedUser": null,
"imageCount": 1,
"claimedBy": {
"id": 281474976710664,
"name": "Alex"
},
"claimedAt": "2026-10-12T09:41:07.000Z",
"doneBy": null,
"doneAt": null,
"createdAt": "2026-10-12T09:12:55.000Z",
"updatedAt": "2026-10-12T09:41:07.000Z"
}
Les noms de personnes sont ceux choisis dans Cryptauk, ou à défaut leur adresse e-mail. Tolérez les champs inconnus : la v1 peut en gagner, elle n'en perdra ni n'en renommera aucun.
Les routes
Les chemins sont relatifs à https://cryptauk.com/api/ext/v1. Les routes marquées « personnelle » répondent 403 not_allowed_for_group_key à une clé de groupe.
| Route | Clé | Effet |
|---|---|---|
GET /me | toutes | décrit la clé |
GET /tasks | toutes | liste les tâches (filtres : voir « Synchroniser ») |
GET /tasks/:id | toutes | une tâche |
POST /tasks | toutes | crée une tâche : 201, ou 200 si l'externalRef existait déjà |
PATCH /tasks/:id | toutes | modifie name, description, priority — et isDone avec une clé personnelle, sur une tâche non partagée |
DELETE /tasks/:id | toutes | supprime : 204 |
POST /tasks/:id/claim | personnelle | « je m'en occupe » |
POST /tasks/:id/release | personnelle | « je me désiste », ou débloquer une tâche (propriétaire) |
POST /tasks/:id/done | personnelle | « c'est fait » — seulement par celui qui l'a prise |
POST /tasks/:id/reopen | personnelle | rouvrir une tâche terminée (propriétaire) |
PUT /tasks/:id/share | personnelle | partager avec sharedGroupId ou sharedUserId, ou {} pour arrêter (propriétaire) |
GET /groups | personnelle | vos groupes : [{ id, name }] |
GET /contacts | personnelle | les personnes avec qui vous pouvez partager directement |
curl -X POST https://cryptauk.com/api/ext/v1/tasks \
-H "Authorization: Bearer $CRYPTAUK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Remplacer la batterie de la centrale",
"description": "Site de Lyon, accès par le quai B",
"priority": 2,
"externalRef": "mysoftware:job:1234"
}'
name est obligatoire (255 caractères au plus), description en accepte 10 000, externalRef 200. Avec une clé personnelle, ajoutez sharedGroupIds (un ou plusieurs groupes) ou sharedUserId pour partager d'emblée ; Une clé personnelle peut aussi passer categoryId, l'une de ses catégories de tâches. une clé de groupe partage d'office avec son groupe, et peut en ajouter d'autres (voir « Plusieurs groupes »). PATCH est partiel : n'envoyez que ce qui change.
Plusieurs groupes
Une clé de groupe peut publier une tâche aussi pour d'autres groupes, avec additionalGroupIds. Exemple : la clé d'une équipe publie une tâche que l'équipe communication doit voir aussi.
- accepté seulement si le créateur de la clé est créateur ou administrateur de chacun de ces groupes : une clé n'a jamais plus de droits que lui (
403 owner_only, ou404s'il n'en est pas membre) ; - la tâche est une seule : visible de tous ces groupes, et le premier qui la prend, d'un groupe ou d'un autre, la verrouille pour tous ;
- le groupe de la clé reste le groupe principal ; 10 groupes au plus en tout.
{
"name": "Valider le visuel de l'affiche",
"externalRef": "mysoftware:com:42",
"additionalGroupIds": [281474976710700]
}
Clé personnelle restreinte
Une clé personnelle couvre par défaut toutes les tâches de la personne — un choix aussi valable qu'un autre. Elle peut aussi être restreinte, à la création ou plus tard sans changer la clé : à des catégories de ses tâches (ses tâches perso rangées là) et/ou à des groupes dont elle est membre (leurs tâches communes). Exemple : une catégorie par structure pour ses tâches perso, plus le groupe de la structure pour pouvoir y prendre les tâches communes.
- elle voit ses tâches perso de ces catégories, sous-catégories comprises (même créées plus tard), et les tâches communes de ces groupes ; toute autre tâche répond
404, comme si elle n'existait pas ; - sur une tâche commune, elle agit comme la personne dans l'application :
claim,release,done— le premier qui prend verrouille pour tout le groupe ; - elle crée dans ses catégories (
categoryId) et/ou pour ses groupes (sharedGroupIds) —403 out_of_key_scopehors de sa portée. S'il faut préciser,400 categoryId_requiredousharedGroupIds_required; - elle ne repartage pas et ne partage jamais avec une personne seule ;
GET /groupsne renvoie que ses groupes ; - si ses catégories et ses groupes disparaissent tous, elle ne voit plus rien. Elle ne redevient jamais illimitée.
GET /me renvoie restrictedToCategories et restrictedToGroups, ou null pour une clé sans restriction.
Éviter les doublons : externalRef
Un appel réseau peut échouer après que le serveur l'a traité : la réponse se perd, votre logiciel réessaie et, sans précaution, la tâche serait créée deux fois.
Passez toujours une externalRef qui identifie l'objet chez vous, par exemple mysoftware:job:1234 :
- aucune tâche ne porte cette référence : elle est créée, réponse
201; - une tâche la porte déjà : rien n'est créé, la tâche existante est renvoyée avec
200.
C'est vrai même pour des appels simultanés, et même après le renouvellement de la clé. La référence permet aussi de retrouver une tâche sans stocker son identifiant : GET /tasks?externalRef=mysoftware:job:1234.
Synchroniser
GET /tasks accepte ces paramètres :
| Paramètre | Effet |
|---|---|
done=0, done=1 | seulement les tâches en cours, ou terminées |
externalRef=… | la tâche qui porte cette référence |
updatedSince=… | les tâches modifiées depuis cette date ISO, incluse |
limit=… | de 1 à 1000, 200 par défaut |
scope=mine|shared|all | clé personnelle : vos tâches, les partagées, ou tout (par défaut) |
Les résultats sont triés par updatedAt croissant. Pour suivre l'avancement sans tout relire :
- un premier appel, sans
updatedSince; - retenez le
updatedAtle plus récent reçu ; - appel suivant avec
updatedSinceégal à cette valeur ; - dédoublonnez par
id: la borne est incluse, la dernière tâche revient une fois de plus.
Si vous recevez exactement limit tâches, il en reste peut-être : rappelez aussitôt avec la nouvelle borne. Réutilisez la date que nous avons renvoyée plutôt que l'heure de votre serveur : aucun décalage d'horloge ne peut alors vous faire rater une tâche.
Une tâche supprimée disparaît simplement des réponses : la synchronisation ne la signale pas. Pour le détecter, interrogez-la par externalRef (réponse []), ou relisez de temps en temps la liste complète.
Prise en charge
Une tâche partagée doit être prise avant d'être terminée : deux personnes ne travaillent pas dessus en même temps. Ce parcours est réservé aux clés personnelles.
claim: la tâche libre devient « prise par vous » ;done: celui qui l'a prise la termine ;release: le preneur se désiste, ou le propriétaire débloque la tâche ;reopen: le propriétaire rouvre une tâche terminée, qui redevient libre.
{
"error": "already_claimed",
"claimedBy": { "id": 281474976710664, "name": "Alex" }
}
Un seul preneur à la fois, garanti par le serveur même si deux personnes appuient au même instant. Affichez « Alex s'en occupe déjà » et ne réessayez pas en boucle. Une tâche non partagée n'a pas ce parcours : elle se coche directement avec PATCH et { "isDone": true }.
Images jointes
Une tâche peut porter des images — captures d'écran, photos : 10 au plus, 5 Mo chacune. Toute clé qui voit la tâche peut les lister, les lire et en ajouter.
| Route | Effet |
|---|---|
GET /tasks/:id/images | la liste, sans le contenu |
POST /tasks/:id/images | ajoute { "data": "<base64>", "name": "facultatif" } |
GET /tasks/:id/images/:imageId | le contenu brut, avec son Content-Type |
DELETE /tasks/:id/images/:imageId | supprime : l'auteur de l'image ou le propriétaire de la tâche ; une clé de groupe, ce qu'une clé de son groupe a ajouté |
- le type est déterminé par les premiers octets : PNG, JPEG, WebP ou GIF (
415 unsupported_image_typesinon) ; - 5 Mo au plus une fois décodée (
413 image_too_large) : redimensionnez avant l'envoi ; 10 images par tâche (409 too_many_images) ; - les images sont en clair, comme les tâches : n'y joignez rien qui contienne un mot de passe ;
- ajouter ou supprimer une image fait avancer le
updatedAtde la tâche, etimageCountdit combien elle en porte.
Erreurs
Le corps est toujours { "error": "<code>" }, parfois accompagné de champs utiles comme claimedBy.
| HTTP | Code | Quand |
|---|---|---|
| 400 | invalid_name, name_too_long, invalid_priority, invalid_externalRef… | corps invalide |
| 400 | empty_update | PATCH sans aucun champ |
| 400 | invalid_updatedSince, invalid_limit, invalid_scope | paramètre invalide |
| 400 | not_allowed_for_group_key | partage demandé avec une clé de groupe |
| 400 | invalid_additionalGroupIds, too_many_shared_groups | liste de groupes invalide ; plus de 10 groupes |
| 400 | not_shared, invalid_share | prise en charge d'une tâche non partagée ; partage incohérent |
| 400 | invalid_categoryId, categoryId_required, sharedGroupIds_required | catégorie mal formée ; clé restreinte : préciser la catégorie ou le groupe de la tâche |
| 400 | invalid_data, invalid_imageId | image absente ou base64 invalide ; identifiant d'image |
| 401 | invalid_api_key | clé absente, inconnue ou révoquée |
| 403 | not_allowed_for_group_key | action réservée aux clés personnelles |
| 403 | not_created_by_integration | clé de groupe : modifier une tâche créée par un membre |
| 403 | out_of_key_scope | clé restreinte : catégorie ou groupe hors des siens, partage avec une personne, repartage |
| 403 | owner_only, not_claimer | action réservée au propriétaire, ou au preneur |
| 403 | not_image_author | supprimer une image qu'on n'a pas ajoutée, sur une tâche qui n'est pas la sienne |
| 404 | not_found | tâche inexistante ou hors de portée de la clé — indiscernables, volontairement |
| 409 | already_claimed | prise par quelqu'un d'autre (avec claimedBy) |
| 409 | already_done, not_claimed, use_claim_flow | déjà terminée ; terminer sans avoir pris ; cocher une tâche partagée |
| 409 | too_many_images | 10 images au plus par tâche |
| 413 | image_too_large | image de plus de 5 Mo |
| 415 | unsupported_image_type | ni PNG, ni JPEG, ni WebP, ni GIF |
| 429 | too_many_requests | limite de débit atteinte |
| 500 | internal_error | erreur serveur : réessayez plus tard |
Limites de débit
- 120 requêtes par minute et par clé. Au-delà :
429. Les en-têtesRateLimit-*indiquent le quota restant. - 30 échecs d'authentification par quart d'heure et par adresse IP, puis l'adresse est bloquée jusqu'à la fin du quart d'heure. Une intégration bien configurée n'en approche jamais.
Sur un 429 ou une erreur 5xx, attendez avant de réessayer, en doublant l'attente à chaque échec.
Sécurité
- Gardez la clé côté serveur, dans une variable d'environnement ou un coffre de secrets. Jamais dans du code versionné, une application mobile ou une page web : l'API n'envoie volontairement aucun en-tête CORS, un navigateur ne pourra pas l'appeler.
- Une clé par logiciel, avec un nom explicite : on en révoque une sans couper les autres, et
createdViadit d'où vient chaque tâche. - Faites révoquer sans attendre une clé exposée : l'effet est immédiat.
- Les tâches ne sont pas chiffrées. N'y mettez aucun secret — code d'alarme, mot de passe : c'est le rôle du coffre Cryptauk, que cette API n'ouvre pas.
Exemple complet (Node.js)
Un logiciel d'interventions qui publie chaque intervention comme tâche de groupe, puis remonte qui s'en occupe et ce qui est fait.
const BASE = 'https://cryptauk.com/api/ext/v1';
const CLE = process.env.CRYPTAUK_API_KEY; // clé de groupe : jamais dans le code
async function cryptauk(methode, chemin, corps) {
const r = await fetch(BASE + chemin, {
method: methode,
headers: { Authorization: `Bearer ${CLE}`, 'Content-Type': 'application/json' },
body: corps ? JSON.stringify(corps) : undefined,
});
if (r.status === 204) return null;
const json = await r.json();
if (!r.ok) throw Object.assign(new Error(json.error), { status: r.status, body: json });
return json;
}
// Une intervention créée chez vous devient une tâche du groupe.
// Rejouer cet appel ne crée pas de doublon, grâce à externalRef.
function publier(intervention) {
return cryptauk('POST', '/tasks', {
name: `${intervention.type} — ${intervention.site}`,
description: intervention.consignes,
priority: intervention.urgente ? 3 : 1,
externalRef: `mysoftware:job:${intervention.id}`,
});
}
// Régulièrement : qui s'en occupe, qu'est-ce qui est fait ?
let depuis = null; // à conserver entre deux redémarrages
async function synchroniser() {
for (;;) {
const q = depuis ? `?updatedSince=${encodeURIComponent(depuis)}&limit=500` : '?limit=500';
const taches = await cryptauk('GET', `/tasks${q}`);
for (const t of taches) {
if (!t.externalRef?.startsWith('mysoftware:job:')) continue; // tâche créée à la main
await mettreAJourIntervention(t.externalRef.split(':')[2], {
prisePar: t.claimedBy?.name ?? null,
terminee: t.isDone,
});
}
if (taches.length) depuis = taches[taches.length - 1].updatedAt;
if (taches.length < 500) break; // sinon il en reste : on enchaîne
}
}
Versions
/api/ext/v1 est un contrat stable. Peuvent s'ajouter : des champs, des routes, des paramètres facultatifs, des codes d'erreur. Jamais : un champ retiré ou renommé, un type changé, un sens modifié.
Un changement incompatible ferait l'objet d'une /api/ext/v2, la v1 restant servie le temps de migrer.