L’API de tokidu
Llegeix els teus projectes i tasques, crea tasques des d’un formulari o un script i tanca-les des d’una altra app. L’API passa per la mateixa porta que el web: un token mai fa res que no pugui fer el seu compte.
És del pla Max: la pot fer servir qui té Max i qui treballa en un projecte que comparteix algú amb Max, i només arriba a aquests projectes.
- Adreça base
https://tokidu.com/api/v1- Capçalera
Authorization: Bearer tkd_…- Límits
- 1000 peticions per hora i compte · 60 per minut i token
- Referència completa
- /api/v1/openapi.json
Començar
- A Compte → Integracions, crea un token i marca «Veure els teus projectes i tasques» (i «Crear i canviar tasques», si ha d’escriure).
- Copia’l, perquè només es mostra una vegada, i guarda’l com una contrasenya. Als exemples va a la variable
TOKIDU_TOKEN. - Prova’l demanant el teu compte:
curl https://tokidu.com/api/v1/me \
-H "Authorization: Bearer $TOKIDU_TOKEN"Crida-la des d’un servidor o un script, no des d’una pàgina web: l’API no admet CORS i no mira les galetes.
Tokens i àmbits
En crear un token tries què pot fer, a quins projectes arriba i quan caduca:
read, «Veure els teus projectes i tasques»: llegir els projectes, les tasques i «El següent».write, «Crear i canviar tasques»: crear projectes i tasques, canviar-les, acabar-les, reobrir-les i esborrar-les, com al web.- Projectes: tots els que veus o només els que marquis. Si en deixes de veure un, el token deixa d’arribar-hi.
- Caducitat: als 30, 90 o 365 dies. Si no tries, a l’any.
El token de Madrugo (integrations:read) només llegeix «El següent» per a Madrugo, de tots els projectes que veus: no obre aquesta API i no es pot limitar a uns quants projectes.
Pots tenir 10 tokens actius. Revoca’ls d’un en un o tots alhora, i mira a cadascun els últims canvis: guardem quins canvis s’han fet amb cada token, sense el contingut, durant 90 dies.
Límits
- 1000 peticions per hora per a tot el teu compte i 60 per minut per a cada token.
- Cada resposta porta
RateLimit-Limit,RateLimit-RemainingiRateLimit-Reset: el límit, el que queda i quan es renova. - Si te’n passes, la resposta és 429
demasiadas_peticionesambRetry-After: espera aquests segons i torna a provar. - El cos d’una petició pot ocupar 64 KiB com a molt.
Crear tasques sense duplicar-les
Crear una tasca exigeix la capçalera Idempotency-Key: d’1 a 100 caràcters, diferent per a cada tasca que vols crear (per exemple, l’id de la fila, del correu o del formulari d’on surt).
Si repeteixes la petició amb la mateixa clau, per exemple després d’un tall de xarxa, no se’n crea una altra: et torna la que ja existeix, amb 200 i Idempotent-Replayed: true.
Si la tasca d’aquesta clau es va esborrar, no torna: la resposta és 410 tarea_borrada. La mateixa clau en un altre projecte crea una altra tasca.
Errors
Un error respon amb el seu codi HTTP i el camp error del cos; amb 422, també field, el camp que no és vàlid.
- 401
token_invalido - Falta el token, no existeix, està revocat o ha caducat (no es diu quin cas és).
- 403
ambito - Al token li falta l’àmbit que demana la ruta.
- 403
proyecto_fuera_del_token - El token està limitat a altres projectes.
- 403
max_necesario - És del pla Max i qui comparteix el projecte no el té (o tu, en crear un projecte).
- 403
solo_lectura - En aquest projecte només pots veure, no canviar.
- 403
en_pausa - El projecte està en pausa: qui el comparteix ja no té el pla Equip, així que només es pot veure.
- 404
proyecto_inexistente - El projecte no existeix o no el veus.
- 404
tarea_inexistente - La tasca no existeix o no la veus.
- 404
ruta_inexistente - Aquesta ruta no és de l'API: revisa el mètode i l'adreça.
- 404
webhook_inexistente - Aquest avís no existeix o no el va crear aquest token.
- 409
id_ocupado - Aquesta
Idempotency-Keycorrespon a una tasca que no veus: fes-ne servir una altra. - 409
horas_de_otros - No es pot esborrar perquè té hores d’altres persones, com al web.
- 409
adjuntos_de_otros - No es pot esborrar perquè té fitxers d’altres persones, com al web.
- 409
entrada_facturada - No es pot esborrar perquè té hores ja facturades, com a la web.
- 409
ciclo - Aquesta espera tancaria un cercle: una tasca acabaria esperant-se a si mateixa.
- 409
webhooks_completo - Ja tens 20 avisos: esborra'n algun per crear-ne un altre.
- 410
tarea_borrada - Aquesta
Idempotency-Keyés d’una tasca que es va esborrar: no es torna a crear. Per crear-ne una altra, fes servir una altra clau. - 413
cuerpo_grande - El cos passa de 64 KiB.
- 415
json_necesario - El cos ha d’anar en JSON, amb
Content-Type: application/json. - 422
peticion_invalida - Un camp no és vàlid:
fielddiu quin. - 422
url_no_valida - L'adreça d'un avís no és vàlida:
reasondiu per què (https,puerto,usuario,local,tokidu,dnsoip_privada). - 428
idempotencia_necesaria - Per crear una tasca falta la capçalera
Idempotency-Key. - 429
demasiadas_peticiones - Has passat del límit: espera el que digui
Retry-After. - 429
demasiados_intentos - Has comprovat moltes adreces d'avisos seguides: espera el que digui
Retry-After. - 503
ocupado - El projecte estava ocupat amb un altre canvi: repeteix la petició passat el que digui
Retry-After. - 503
no_disponible - El servei no ha pogut respondre ara: repeteix la petició passat el que digui
Retry-After.
Referència
Totes les rutes van darrere de l’adreça base i responen en JSON. Els ids de projectes i tasques són els que torna la mateixa API.
GET /api/v1/me
El teu compte, el token (nom, àmbits, projectes i caducitat) i el que et queda de l’hora.
Àmbit: qualsevol
GET /api/v1/projects
Els projectes que veus de qui té Max: nom, color, qui el comparteix, el teu paper, semàfor, final previst, foto del pla i avanç.
Àmbit: read
GET /api/v1/projects/{id}
Un projecte, amb els seus sprints.
Àmbit: read
GET /api/v1/projects/{id}/tasks
Les tasques d’un projecte, sense notes: què esperen, si estan bloquejades i quan es preveu que acabin. Filtra amb status (open, done o all) i updatedSince, i passa de pàgina amb cursor.
Àmbit: read
curl "https://tokidu.com/api/v1/projects/$PROJECT_ID/tasks?status=open" \
-H "Authorization: Bearer $TOKIDU_TOKEN"GET /api/v1/tasks/{id}
Una tasca amb les seves notes, què espera i «Per què aquesta data?».
Àmbit: read
GET /api/v1/next
«El següent»: el que és teu i ja es pot començar.
Àmbit: read
POST /api/v1/projects
Crea un projecte: name i, si vols, color. Només si tens Max.
Àmbit: write
POST /api/v1/projects/{id}/tasks
Crea una tasca: title i, si vols, notes, priority, due, assignee, sprintId, estimateMin i after. Exigeix Idempotency-Key.
Àmbit: write
curl https://tokidu.com/api/v1/projects/$PROJECT_ID/tasks \
-H "Authorization: Bearer $TOKIDU_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: form-42" \
-d '{"title":"Trucar a la Marta","due":"2026-10-20"}'PATCH /api/v1/tasks/{id}
Canvia només els camps que enviïs. Respon amb la tasca, les que es desbloquegen i, si una altra persona ha canviat el mateix alhora, el que s’ha quedat.
Àmbit: write
curl -X PATCH https://tokidu.com/api/v1/tasks/$TASK_ID \
-H "Authorization: Bearer $TOKIDU_TOKEN" \
-H "Content-Type: application/json" \
-d '{"due":"2026-10-24"}'POST /api/v1/tasks/{id}/done
Marca la tasca com a feta i respon amb les que es desbloquegen.
Àmbit: write
curl -X POST https://tokidu.com/api/v1/tasks/$TASK_ID/done \
-H "Authorization: Bearer $TOKIDU_TOKEN"POST /api/v1/tasks/{id}/reopen
Torna a obrir una tasca feta.
Àmbit: write
PUT /api/v1/tasks/{id}/after/{otherId}
Fa que la tasca esperi una altra del mateix projecte.
Àmbit: write
DELETE /api/v1/tasks/{id}/after/{otherId}
Treu aquesta espera.
Àmbit: write
DELETE /api/v1/tasks/{id}
Esborra la tasca, com al web.
Àmbit: write
GET /api/v1/webhooks
Els avisos a altres apps que ha creat aquest token: adreça, esdeveniments, projectes i estat (mai el secret).
Àmbit: webhooks
POST /api/v1/webhooks
Registra una adreça https per rebre avisos signats: url, events i, si vols, projects (només teus). Respon amb el secret, una sola vegada.
Àmbit: webhooks
DELETE /api/v1/webhooks/{id}
Esborra un dels avisos que ha creat aquest token i deixa d’enviar-lo.
Àmbit: webhooks
Avisos a altres apps (webhooks)
Quan passa alguna cosa als teus projectes, tokidu envia un POST signat a l'adreça que diguis. Es creen a Compte → Integracions, o per l'API amb un token amb l'àmbit webhooks (el que fan servir Zapier o Make). Només el titular amb Max, i només dels seus projectes; fins a 20 per compte.
Què pots escoltar
task.created· Es crea una tascatask.done· S’acaba una tascatask.reopened· Es reobre una tascatask.unblocked· Es desbloqueja una tascatask.assigned· S’assigna una tascatask.deleted· S’esborra una tascaproject.status· Canvia el semàfor d’un projecte
Cada avís porta el tipus, un id del fet, l'hora, el projecte i, si és d'una tasca, el títol, l'estat, el responsable, la data límit i l'enllaç. Mai notes, enllaços, fitxers, correus ni hores.
Comprovar la signatura
Segueix Standard Webhooks: capçaleres webhook-id, webhook-timestamp (segons) i webhook-signature (v1, i un HMAC-SHA256 en base64 de id.timestamp.cos, amb la clau que va darrere de whsec_). Comprova-la amb el cos tal com arriba i rebutja els de més de 5 minuts. A Node:
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyTokidu(secret, headers, body, toleranceSeconds = 300) {
const id = headers["webhook-id"], ts = headers["webhook-timestamp"], sigs = headers["webhook-signature"];
if (!id || !ts || !sigs) return false;
if (Math.abs(Date.now() / 1000 - Number(ts)) > toleranceSeconds) return false;
const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
const expected = createHmac("sha256", key).update(`${id}.${ts}.${body}`).digest();
return sigs.split(" ").some((s) => {
const [version, sig] = s.split(",");
const given = Buffer.from(sig ?? "", "base64");
return version === "v1" && given.length === expected.length && timingSafeEqual(given, expected);
});
}Enviaments i reintents
Qualsevol 2xx és bo; les redireccions no se segueixen. Si falla, es reintenta a 1 min, 5 min, 30 min, 2 h, 6 h, 12 h i 24 h. Amb 20 lliuraments fallits seguits, o 3 dies sense un 2xx, l'avís s'apaga i t'enviem un correu.
Només adreces https:// públiques, al port 443 o 8443, sense usuari ni contrasenya: res de localhost, xarxes internes ni IP privades (també es comprova en enviar).
OpenAPI
Tots els camps de cada petició i de cada resposta, en format OpenAPI, per generar un client o importar-los a la teva eina: /api/v1/openapi.json.