Empezar
Autenticación
Dos credenciales. Una llave de API ejerce acciones; un token OAuth, que concede una persona, ejerce acciones y lee. Las dos llevan alcances con versión, así que una credencial sigue abriendo exactamente lo que abría el día que se emitió.
Última actualización
Llaves de API
Una llave pertenece al workspace, no a una persona: autentica una integración. Se manda como bearer:
Authorization: Bearer nk_…Nace con alcances y caducidad, y se muestra una sola vez, al crearla. Revocarla es un clic; deja de funcionar de inmediato. Ningún endpoint devuelve una llave: si la pierdes, emites otra.
Los alcances llevan la versión
Un alcance nombra una acción y una versión: crm.call_logged@1. Una versión nueva de una acción es un alcance nuevo, así que nada cambia bajo una credencial que no se emitió para ella.
miira.lead_create@1
crm.call_logged@1
crm.owner_assigned@1
crm.stage_moved@1OAuth (MCP y clientes de IA)
El servidor MCP usa OAuth 2.1 con registro dinámico de clientes y PKCE. El descubrimiento vive en la dirección estándar:
https://niiko.org/api/mcp
https://niiko.org/.well-known/oauth-authorization-serverLa autorización pasa siempre por una pantalla de niiko donde la persona elige un workspace y qué acciones y lecturas concede — ninguna marcada por defecto. El token resultante es una credencial de los endpoints de acciones y de lecturas, con esos alcances. El acceso se retira desde Configuración → Desarrolladores → Apps.
Dos permisos, no uno
Además de la credencial, cada acción y cada lectura necesitan que el dueño del workspace las haya encendido (Configuración → Conexiones, columna «API y MCP»). El motivo es deliberado: quien tiene una llave y quien es dueño del workspace suelen ser dos personas distintas, y cada una decide.
Lecturas: solo OAuth, con el rol de la persona
Una lectura se hace en nombre de la persona que autorizó la aplicación, y contesta con lo que esa persona ve en su propia pantalla. Una llave de API no tiene persona detrás, así que el endpoint de lecturas la rechaza con reads_need_a_person sin siquiera verificarla.
POST /api/v1/reads/kiipu.collections_get
Authorization: Bearer nk_…
403 { "status": "refused", "reason": "reads_need_a_person", "detail": { "message": "…" } }Después, tres comprobaciones en orden: el alcance del token (kiipu.collections_get@1), el rol de la persona (role_forbidden cuando su pantalla no lo muestra) y el interruptor del workspace (grant_off). Quien deja el workspace deja de leer, aunque su token siga vivo.
Por qué el 401 dice tan poco
Una credencial inexistente, revocada, caducada o sin el alcance contestan la misma unauthorized. Distinguirlas convertiría el endpoint en un oráculo para quien esté probando llaves. El estado exacto de tu llave está en tu panel.