Ir al contenido

Crear la app y la key

Tu sistema habla con el motor como una app cliente con una o más API keys. Esta página amplía el paso 1 del Inicio rápido: qué elegir al emitir una key, cómo restringirla, cómo rotarla sin cortar el servicio y qué pasa con lo pendiente cuando una key deja de valer. El modelo completo está en Apps, instancias y scopes.

Las apps y las keys las crea un operador con rol superadmin en el panel. Una app nunca crea otra app ni emite sus propias keys: /v1 no tiene rutas para eso. Un operador con rol operador ve las apps y sus keys, pero no puede crearlas, rotarlas ni revocarlas.

En Clientes, elige Nueva app:

Campo Qué es
Nombre Único en el motor. Lo verás en el panel y en whoami.
Descripción Opcional.
Cupo de instancias Opcional. Sin cupo propio, la app usa el de Ajustes → Límites (3 de fábrica).

La app nace activo. Lo mismo se puede hacer con la API de administración (POST /admin/api/clientes, sesión de operador con CSRF): está en API de administración.

En la ficha de la app, elige Emitir key:

Campo Qué es
Nombre Para reconocerla: «CRM producción», «worker de webhooks».
Entorno Producción (mw_live_…) o Prueba (mw_test_…).
Scopes Al menos uno. Los permisos de la key: la tabla completa.
Instancias Opcional. Si eliges alguna, la key solo alcanza a esas. Vacío: todas las de la app.
Vencimiento Sin vencimiento, en 30 días, en 90 días o en un año.

El diálogo Key emitida muestra el token completo una sola vez. El motor guarda solo su prefijo y su HMAC: no puede volver a mostrártelo. Si lo pierdes, rota la key.

mw_live_1a2b3c4d_<43 caracteres base64url>
└──── prefijo ─┘ └──────── secreto ────────┘

El prefijo (mw_live_1a2b3c4d) es lo único que vuelve a aparecer: en el panel, en whoami y en la auditoría. Sirve para saber qué key es sin exponer el secreto. Guarda el token completo en el gestor de secretos de tu app; nunca en el repositorio, en un log ni en un ticket.

El entorno solo cambia el prefijo (mw_live_ o mw_test_) y la etiqueta. Una key de prueba habla con el mismo motor, las mismas instancias y el mismo WhatsApp real: no hay un modo de prueba que simule envíos.

Cada ruta de /v1 pide un scope; sin él, la respuesta es 403 («Tu API key no tiene el scope …»). Elige los mínimos que necesita cada parte de tu sistema: el worker que solo recibe webhooks no necesita messages:send.

Grupo Scope Qué permite
Instancias instances:read Ver sus instancias, su estado y su diagnóstico.
instances:create Crear instancias.
instances:manage Cambiar el nombre y la configuración, reconectar, desconectar, pausar y reanudar.
instances:pair Vincular números (QR, código y passkey).
instances:logout Desvincular o archivar instancias.
Mensajes messages:send Enviar mensajes (y leer el estado de esos comandos).
messages:read Leer los mensajes guardados, sus recibos y el resultado de encuestas e interactivos.
presence:write Mandar la presencia y seguir la de un contacto.
Eventos events:read Leer el ledger, los streams y las entregas.
subscriptions:manage Crear, cambiar, probar y rotar suscripciones de webhooks.
deliveries:replay Pedir el reenvío (replay) de eventos ya aceptados.
Multimedia media:read Descargar multimedia.
media:write Subir multimedia.
Llamadas calls:manage Ver y rechazar llamadas entrantes.
Chats chats:read Ver el estado de los chats (fijado, archivado, silenciado, no leído) y su sincronización.
chats:manage Fijar, archivar, silenciar, marcar, destacar y borrar chats.
labels:read Ver las etiquetas del número.
labels:manage Crear, editar, eliminar y asociar etiquetas.
Contactos contacts:read Ver los contactos del número y resolver identidades (LID↔PN) de una instancia.
contacts:lookup Preguntar al servidor si un número está en WhatsApp y el perfil público de otros, con la cuota diaria de la app.
Historial history:read Ver la política del historial y sus trabajos.
history:manage Pedir e importar historial y cancelar sus trabajos.
Grupos groups:read Consultar grupos y comunidades.
groups:write Administrar grupos y comunidades.
Canales newsletters:read Consultar canales y sus publicaciones.
newsletters:write Crear, seguir, silenciar, ver y reaccionar en canales. Publicar va con messages:send.
Status status:read Consultar los status recibidos y publicados mientras se retienen.
status:write Publicar status con la audiencia explícita.
Comercio catalog:read Consultar el catálogo y las colecciones de WhatsApp Business, con la cuota diaria de la app.
Perfil profile:read Consultar el perfil propio.
profile:write Cambiar el perfil propio.
Privacidad privacy:read Consultar la privacidad y la lista de bloqueados.
privacy:write Cambiar la privacidad y los bloqueos.

Tres reglas que no se ven en la tabla:

  • GET /v1/whoami y GET /v1/capabilities funcionan con cualquier key válida.
  • GET /v1/commands/{id} pide el scope del tipo del comando: el de un mensaje pide messages:send; el de un instance.reconnect, instances:manage.
  • Algunas rutas piden dos: mandar la invitación de un grupo pide groups:read y messages:send.

La tabla es el catálogo completo: el motor no tiene otros scopes (una prueba del motor compara esta tabla con su código). Para ver los que tiene tu key, usa GET /v1/whoami o GET /v1/capabilities.

Si eliges instancias al emitirla, la key queda restringida:

  • Solo ve y opera esas instancias. Las demás de la app responden 404, igual que una instancia que no existe.
  • Las listas (GET /v1/instances, las suscripciones, las entregas) solo traen lo suyo.
  • No puede crear instancias (403): una instancia nueva no entraría en su alcance. Créala con otra key o pídesela al operador.
  • Una suscripción creada con ella tiene que nombrar sus instancias.
  • Cada instancia elegida tiene que ser de la app y no estar archivada (si no, 422 en body.instancias).

Una instancia que se crea después no se suma sola a las keys restringidas. Una key sin restricción alcanza a todas, también a las nuevas.

Manda el token en cada pedido como Authorization: Bearer <token>. Si falta, la respuesta es 401 «Falta la API key»; si es inválida, venció, fue revocada o su app está suspendida, 401 con un mismo mensaje para todos los casos (el motor no dice cuál).

Al arrancar tu app, comprueba con GET /v1/whoami que la key es la que esperas y que tiene los scopes que vas a usar. Así un error de configuración aparece en el arranque y no en el primer envío:

Ventana de terminal
curl -s https://motor.ejemplo.com/v1/whoami \
-H "Authorization: Bearer TU_API_KEY" | jq '.key | {prefijo, entorno, scopes, instancias}'
200 OK · una key restringida
{
"cliente": { "id": "8a1d2c3e-0000-4000-8000-000000000001", "nombre": "Mi CRM" },
"key": {
"id": "8a1d2c3e-0000-4000-8000-000000000003",
"prefijo": "mw_test_5e6f7a8b",
"entorno": "prueba",
"scopes": ["events:read", "messages:send"],
"instancias": ["8a1d2c3e-0000-4000-8000-0000000000a1"]
}
}

GET /v1/capabilities completa el cuadro: la versión del contrato, el contrato de eventos (los transportes, cuántos streams puede abrir la app, los días de reanudación), el estado del proveedor y los scopes de la key.

Rotar (en el panel, o POST /admin/api/keys/{id}/rotar) emite una key nueva con el mismo nombre, entorno, scopes, instancias y vencimiento, y revoca la anterior en el mismo momento (motivo rotada). No hay una ventana en la que valgan las dos: desde la rotación, el token viejo recibe 401. Una key vencida no se rota (409).

Para cambiar de key sin cortar el servicio ni perder lo pendiente:

  1. Emite una segunda key con los mismos scopes e instancias.
  2. Despliega tu app con la nueva y confirma con whoami que la usa (el panel muestra el último uso de cada key).
  3. Espera a que salga lo que la vieja dejó en cola.
  4. Revoca la vieja.

Rota directamente cuando el token se filtró: ahí importa más cortarlo ya que lo pendiente.

Qué pasa Efecto en /v1 Efecto en lo pendiente
Revocar la key (irreversible) 401 al instante Sus comandos sin ejecutar fallan con credencial_revocada.
La key vence 401 desde la fecha Fallan con credencial_vencida.
Suspender la app 401 en todas sus keys al instante Fallan con app_suspendida. Reactivar la app devuelve el acceso.

Una key no se edita: para cambiar sus scopes o sus instancias, emite otra y revoca la anterior. El motivo de una revocación es texto libre y queda en la auditoría; si alguien pega un token ahí por error, el motor lo oculta antes de guardarlo. Las suscripciones de webhooks son de la app, no de la key: revocar una key no las toca.

Respuesta Causa Qué hacer
401 «Falta la API key» Sin Authorization o sin el prefijo Bearer . Manda Authorization: Bearer mw_….
401 «La API key no es válida…» Token mal copiado, revocado, vencido o app suspendida. Mira el prefijo y el estado de la key en el panel.
403 «…no tiene el scope…» La key no tiene el scope de esa ruta. Emite una key con el scope (las keys no se editan).
403 al crear una instancia La key está restringida a instancias. Usa una key sin restricción.
404 en una instancia que existe Es de otra app, o está fuera de las instancias de la key. Revisa instancias en whoami.
422 body.instancias al emitir Una instancia no es de la app o está archivada. Elige instancias vivas de esa app.

Con la key lista, vincula un número.