CryptaukPassGuard

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 groupeClé personnelle
Sert àalimenter un groupe en tâches depuis un logicielagir sur les tâches d'une personne, à sa place
Créée pourun groupe dont vous êtes créateur ou administrateurvotre propre compte
Crée des tâchespartagées avec le groupe — et, en plus, avec d'autres groupes que son créateur administreà vous ; vous pouvez les partager
Littoutes les tâches partagées avec le groupevos 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, supprimeles tâches créées par une clé de ce groupeles tâches dont vous êtes propriétaire
Prend en charge, terminenon : c'est un geste humainoui, 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.

Demander une clé

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.

Requête
curl https://cryptauk.com/api/ext/v1/me \
  -H "Authorization: Bearer $CRYPTAUK_API_KEY"
Réponse
{
  "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

ChampSens
idIdentifiant Cryptauk. Un grand entier : il tient dans un Number JavaScript, mais stockez-le sur 64 bits ou en texte.
name, description, priorityLe 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.
isDoneTerminée ou non.
externalRefVotre référence, fournie à la création (voir « Éviter les doublons »). null si aucune.
createdViaNom de la clé API qui a créé la tâche ; null si elle a été créée dans une application Cryptauk.
ownerLe propriétaire : lui seul en modifie le contenu.
sharedGroupsTous les groupes de la tâche, [{ id, name }], le principal en tête : une tâche peut en avoir plusieurs.
sharedGroupLe groupe principal seul, conservé pour compatibilité.
sharedUserLa personne avec qui la tâche est partagée directement — exclusif des groupes.
imageCountNombre d'images jointes (voir « Images jointes »).
claimedBy, claimedAtQui a dit « je m'en occupe », et quand. null : personne.
doneBy, doneAtQui l'a terminée, et quand.
createdAt, updatedAtDates 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.

RouteCléEffet
GET /metoutesdécrit la clé
GET /taskstoutesliste les tâches (filtres : voir « Synchroniser »)
GET /tasks/:idtoutesune tâche
POST /taskstoutescrée une tâche : 201, ou 200 si l'externalRef existait déjà
PATCH /tasks/:idtoutesmodifie name, description, priority — et isDone avec une clé personnelle, sur une tâche non partagée
DELETE /tasks/:idtoutessupprime : 204
POST /tasks/:id/claimpersonnelle« je m'en occupe »
POST /tasks/:id/releasepersonnelle« je me désiste », ou débloquer une tâche (propriétaire)
POST /tasks/:id/donepersonnelle« c'est fait » — seulement par celui qui l'a prise
POST /tasks/:id/reopenpersonnellerouvrir une tâche terminée (propriétaire)
PUT /tasks/:id/sharepersonnellepartager avec sharedGroupId ou sharedUserId, ou {} pour arrêter (propriétaire)
GET /groupspersonnellevos groupes : [{ id, name }]
GET /contactspersonnelleles personnes avec qui vous pouvez partager directement
Créer une tâche
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, ou 404 s'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.
Exemple : corps de POST /tasks, avec la clé de l'équipe
{
  "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_scope hors de sa portée. S'il faut préciser, 400 categoryId_required ou sharedGroupIds_required ;
  • elle ne repartage pas et ne partage jamais avec une personne seule ; GET /groups ne 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ètreEffet
done=0, done=1seulement 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|allclé 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 :

  1. un premier appel, sans updatedSince ;
  2. retenez le updatedAt le plus récent reçu ;
  3. appel suivant avec updatedSince égal à cette valeur ;
  4. 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.
Si quelqu'un l'a prise avant vous : 409
{
  "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.

RouteEffet
GET /tasks/:id/imagesla liste, sans le contenu
POST /tasks/:id/imagesajoute { "data": "<base64>", "name": "facultatif" }
GET /tasks/:id/images/:imageIdle contenu brut, avec son Content-Type
DELETE /tasks/:id/images/:imageIdsupprime : 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_type sinon) ;
  • 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 updatedAt de la tâche, et imageCount dit combien elle en porte.

Erreurs

Le corps est toujours { "error": "<code>" }, parfois accompagné de champs utiles comme claimedBy.

HTTPCodeQuand
400invalid_name, name_too_long, invalid_priority, invalid_externalRef…corps invalide
400empty_updatePATCH sans aucun champ
400invalid_updatedSince, invalid_limit, invalid_scopeparamètre invalide
400not_allowed_for_group_keypartage demandé avec une clé de groupe
400invalid_additionalGroupIds, too_many_shared_groupsliste de groupes invalide ; plus de 10 groupes
400not_shared, invalid_shareprise en charge d'une tâche non partagée ; partage incohérent
400invalid_categoryId, categoryId_required, sharedGroupIds_requiredcatégorie mal formée ; clé restreinte : préciser la catégorie ou le groupe de la tâche
400invalid_data, invalid_imageIdimage absente ou base64 invalide ; identifiant d'image
401invalid_api_keyclé absente, inconnue ou révoquée
403not_allowed_for_group_keyaction réservée aux clés personnelles
403not_created_by_integrationclé de groupe : modifier une tâche créée par un membre
403out_of_key_scopeclé restreinte : catégorie ou groupe hors des siens, partage avec une personne, repartage
403owner_only, not_claimeraction réservée au propriétaire, ou au preneur
403not_image_authorsupprimer une image qu'on n'a pas ajoutée, sur une tâche qui n'est pas la sienne
404not_foundtâche inexistante ou hors de portée de la clé — indiscernables, volontairement
409already_claimedprise par quelqu'un d'autre (avec claimedBy)
409already_done, not_claimed, use_claim_flowdéjà terminée ; terminer sans avoir pris ; cocher une tâche partagée
409too_many_images10 images au plus par tâche
413image_too_largeimage de plus de 5 Mo
415unsupported_image_typeni PNG, ni JPEG, ni WebP, ni GIF
429too_many_requestslimite de débit atteinte
500internal_errorerreur serveur : réessayez plus tard

Limites de débit

  • 120 requêtes par minute et par clé. Au-delà : 429. Les en-têtes RateLimit-* 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 createdVia dit 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.