Comandos de dispositivos
Los endpoints de comandos de dispositivos envían un comando a un dispositivo administrado. Necesitan una clave API con el permiso DEVICES_COMMAND, o DEVICES_COMMAND_DESTRUCTIVE para los cuatro comandos destructivos.
Descripción general
Cada llamada actúa sobre exactamente un dispositivo, identificado por su assetId, que es el pathName devuelto por GET /assets. No hay un endpoint masivo. Para enviar comandos a varios dispositivos, realice una llamada por dispositivo dentro del límite de frecuencia. Los endpoints hacen lo mismo que las herramientas de comandos de MCP.
La clave necesita DEVICES_COMMAND y DEVICES_READ. change-policy también necesita POLICIES_READ. Los comandos destructivos necesitan DEVICES_COMMAND_DESTRUCTIVE y DEVICES_READ en su lugar. Envíe la clave en el encabezado X-API-Key. La API REST no acepta un encabezado Authorization.
El dispositivo debe estar inscrito (estado ACTIVE, INACTIVE o SYNCHRONIZING). Algunos comandos solo funcionan en un tipo de dispositivo, tal como indica cada descripción a continuación: dispositivos Android Management (administrados por Google) o dispositivos administrados por el agente de Nomid (AOSP). Cualquier otro dispositivo recibe 409. Un mensaje es una notificación push para el agente de Nomid y necesita un token push registrado.
Endpoints
| Método | Endpoint | Descripción |
|---|---|---|
| POST | /assets/{assetId}/commands/lock | Bloquea la pantalla del dispositivo de inmediato. Solo dispositivos Android Management. Sin cuerpo de solicitud. |
| POST | /assets/{assetId}/commands/lost-mode | Bloquea el dispositivo y muestra un mensaje, con detalles de contacto opcionales, en su pantalla de bloqueo. Solo dispositivos Android Management. |
| POST | /assets/{assetId}/commands/found | Finaliza el modo perdido. No ocurre nada y no se devuelve ningún error si el dispositivo no estaba en modo perdido. Solo dispositivos Android Management. Sin cuerpo de solicitud. |
| POST | /assets/{assetId}/commands/message | Muestra una notificación push de texto sin formato en el dispositivo. |
| POST | /assets/{assetId}/commands/status-report | Solicita al dispositivo que envíe un informe de estado actualizado ahora. El informe llega más tarde: léelo con GET /assets/ASSET_ID. Sin cuerpo de solicitud. |
| POST | /assets/{assetId}/commands/location-update | Solicita al dispositivo que informe su ubicación actual ahora. La ubicación llega más tarde: léela con GET /assets/ASSET_ID. Sin cuerpo de solicitud. |
| POST | /assets/{assetId}/commands/sync-policy | Vuelve a enviar al dispositivo su política actual. Solo dispositivos administrados por el agente de Nomid (AOSP): los dispositivos de Android Management reciben cambios de política automáticamente y responden 409. Sin cuerpo de solicitud. |
| POST | /assets/{assetId}/commands/reboot | Reinicia el dispositivo ahora. Quienquiera que lo esté usando será interrumpido y el trabajo no guardado podría perderse. Sin cuerpo de solicitud. |
| POST | /assets/{assetId}/commands/shutdown | Apaga el dispositivo ahora. No se puede volver a encender de forma remota. Solo dispositivos administrados por el agente de Nomid (AOSP). Sin cuerpo de solicitud. |
| POST | /assets/{assetId}/commands/launch-app | Abre una aplicación instalada en el dispositivo por el nombre del paquete. Solo dispositivos administrados por el agente de Nomid (AOSP). |
| POST | /assets/{assetId}/commands/clear-app-data | Elimina todos los datos de las aplicaciones especificadas (cuentas, ajustes y archivos), como si acabaran de ser instaladas. No se puede deshacer. Solo dispositivos de Android Management. |
| POST | /assets/{assetId}/commands/change-policy | Mueve el dispositivo a otra política de la empresa. El dispositivo aplica las aplicaciones, restricciones y ajustes de la nueva política, y se elimina todo lo que solo tenía la política actual. También requiere POLICIES_READ. |
Envíe Content-Type: application/json con los endpoints lost-mode, message, launch-app, clear-app-data, change-policy y change-screen-lock-password. Los demás endpoints no admiten cuerpo. Los campos desconocidos se rechazan y los campos de texto obligatorios no pueden estar vacíos.
Comandos destructivos
Cuatro comandos borran datos, eliminan o reemplazan el bloqueo de pantalla, o finalizan la gestión del dispositivo. Con una clave de API, se ejecutan tan pronto como se acepta la solicitud. No hay ningún paso de aprobación en el portal.
Requieren una clave de API con DEVICES_COMMAND_DESTRUCTIVE y DEVICES_READ. La empresa también debe habilitar los comandos destructivos en el acceso de agentes de IA en el portal. Esa configuración está desactivada de forma predeterminada y requiere que los comandos de dispositivo también estén activados. Sin ella, la solicitud devuelve 403 con el código forbidden.
| Método | Endpoint | Descripción |
|---|---|---|
| POST | /assets/{assetId}/commands/wipe | Elimina el dispositivo de la administración y borra sus datos administrados. Un dispositivo propiedad de la empresa se restablece a los valores de fábrica: se borran todas las aplicaciones y todos los datos en él. En un dispositivo de propiedad personal con perfil de trabajo, solo se eliminan el perfil de trabajo y sus aplicaciones y datos; las aplicaciones y los datos personales se conservan. Irreversible. Sin cuerpo de solicitud. |
| POST | /assets/{assetId}/commands/reset-screen-lock | Elimina el bloqueo de pantalla del dispositivo (PIN, patrón o contraseña), para que se pueda desbloquear sin uno. Solo dispositivos de Android Management. Sin cuerpo de solicitud. |
| POST | /assets/{assetId}/commands/change-screen-lock-password | Establece una nueva contraseña de bloqueo de pantalla. El dispositivo se bloquea y solo la nueva contraseña lo desbloquea. Solo dispositivos de Android Management. |
| POST | /assets/{assetId}/commands/relinquish-ownership | Libera un dispositivo propiedad de la empresa a su usuario. El perfil de trabajo y sus datos se eliminan, y el dispositivo deja de estar administrado. Irreversible. Sin cuerpo de solicitud. |
change-screen-lock-password recibe la nueva contraseña en newPassword. Nomid nunca la almacena, devuelve ni registra.
Cuerpos de solicitud
Cuerpo de solicitud de modo perdido
| Campo | Obligatorio | Descripción |
|---|---|---|
| message | Sí | Texto mostrado en la pantalla de bloqueo. Hasta 4096 caracteres. |
| phoneNumber | No | Número de teléfono de contacto mostrado en la pantalla de bloqueo. Hasta 4096 caracteres. |
| No | Dirección de correo electrónico de contacto mostrada en la pantalla de bloqueo. Debe ser una dirección de correo electrónico válida, de hasta 320 caracteres. | |
| streetAddress | No | Dirección física de contacto mostrada en la pantalla de bloqueo. Hasta 4096 caracteres. |
| organization | No | Nombre de la organización mostrado en la pantalla de bloqueo. Hasta 4096 caracteres. |
Cuerpo de solicitud de mensaje
| Campo | Obligatorio | Descripción |
|---|---|---|
| title | Sí | Título de la notificación. Hasta 60 caracteres. |
| body | Sí | Texto de notificación. Hasta 500 caracteres. |
Cuerpo de solicitud para iniciar aplicación
| Campo | Obligatorio | Descripción |
|---|---|---|
| packageName | Sí | Nombre del paquete de la aplicación instalada que se abrirá, por ejemplo com.example.app. |
Cuerpo de solicitud para borrar datos de la aplicación
| Campo | Obligatorio | Descripción |
|---|---|---|
| packageNames | Sí | Matriz de 1 a 20 nombres de paquetes, por ejemplo com.example.app, cuyos datos se borrarán. |
Cuerpo de solicitud para cambiar política
| Campo | Obligatorio | Descripción |
|---|---|---|
| policyId | Sí | La nueva política, por su policyId (el pathName devuelto por GET /policies). |
Cuerpo de solicitud para cambiar la contraseña de bloqueo de pantalla
| Campo | Obligatorio | Descripción |
|---|---|---|
| newPassword | Sí | La nueva contraseña de bloqueo de pantalla, de 4 a 128 caracteres, sin espacios iniciales ni finales. Nunca se almacena, devuelve ni registra. |
Ejemplo: enviar un mensaje
Reemplace el id del activo con un pathName de GET /assets, y mantenga la clave en una variable de entorno.
curl -X POST "https://api.nomid.tech/emm/api/v1/assets/k3x9m2pa/commands/message" \
-H "X-API-Key: $NOMID_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Please return this device", "body": "Bring it to the IT desk by 5 pm."}' {
"assetId": "k3x9m2pa",
"type": "NOTIFICATION_MESSAGE",
"status": "SUCCESS",
"createdAt": "2026-10-06T14:30:00Z"
} Una respuesta 200 significa que el comando fue creado. El campo status es el estado del comando cuando se devolvió la solicitud. Para un mensaje, SUCCESS significa que el push fue aceptado para su entrega, no que el usuario lo haya visto. Haga un seguimiento con GET /assets/ASSET_ID/commands.
Ejemplo: bloquear un dispositivo
curl -X POST "https://api.nomid.tech/emm/api/v1/assets/k3x9m2pa/commands/lock" \
-H "X-API-Key: $NOMID_API_KEY" {
"assetId": "k3x9m2pa",
"type": "LOCK",
"status": "IN_PROGRESS",
"createdAt": "2026-10-06T14:30:00Z"
} lock y el modo perdido devuelven IN_PROGRESS mientras el dispositivo aún no haya confirmado el comando. El historial de comandos muestra SUCCESS una vez que lo hace. El endpoint lock no acepta ningún cuerpo.
Ejemplo: borrar un dispositivo
curl -X POST "https://api.nomid.tech/emm/api/v1/assets/k3x9m2pa/commands/wipe" \
-H "X-API-Key: $NOMID_API_KEY" {
"assetId": "k3x9m2pa",
"type": "WIPE_COMPANY_DATA",
"status": "IN_PROGRESS"
} El borrado de un dispositivo de Android Management responde IN_PROGRESS sin createdAt. Consulte el historial de comandos para realizar el seguimiento.
Respuestas y qué hacer
Las reglas de reintento son importantes. Reintentar un comando cuyo resultado se desconoce puede hacer que se entregue dos veces.
| Estado | Significado | Qué hacer |
|---|---|---|
| 200 | El comando fue creado y puesto en cola. | Lea el campo status. Es IN_PROGRESS hasta que el dispositivo confirme el comando, así que revise el historial de comandos para ver si está en SUCCESS. Algunos comandos, como un reinicio, borrado o renuncia a la propiedad en un dispositivo con Android Management, responden IN_PROGRESS sin createdAt. |
| 202 | UNCONFIRMED. Nomid no puede saber si el comando llegó al dispositivo, por ejemplo porque el proveedor agotó el tiempo de espera o falló en su lado. El cuerpo es el objeto de resultado normal con status UNCONFIRMED y orientación en detail. Fuera de los endpoints lock, lost-mode, found y message, nunca tiene createdAt. | No vuelva a enviar. Revise primero el historial de comandos del dispositivo y consulte al usuario antes de enviar de nuevo. Para un mensaje, el historial puede mostrar ERROR incluso si se mostró la notificación. Es posible que el comando solo aparezca una vez que el dispositivo lo reconozca. |
| 400 | El cuerpo de la solicitud no superó la validación o un parámetro no es válido. | Corrija los campos enumerados en el array errors o en detail. No se envió ningún comando. |
| 401 | La clave de API falta, no es válida o ha caducado. | Envíe una clave válida en la cabecera X-API-Key. |
| 403 | La clave no tiene el permiso que necesita el comando o, para un comando destructivo, la empresa no ha activado los comandos destructivos. | Use una clave creada con DEVICES_COMMAND y DEVICES_READ, más POLICIES_READ para change-policy, o con DEVICES_COMMAND_DESTRUCTIVE y DEVICES_READ para un comando destructivo. Para comandos destructivos, revise también la configuración de la empresa en AI agent access en el portal. |
| 404 | No existe ningún activo con este id en la empresa de la clave. Un activo de otra empresa también devuelve 404. En los endpoints lock, lost-mode, found y message el cuerpo está vacío. En los otros endpoints es problem details con el código not_found, y change-policy también lo devuelve para una política desconocida. | Verifique el id del activo con GET /assets, y para change-policy el id de la política con GET /policies. |
| 409 | El dispositivo no puede aceptar este comando: no tiene un dispositivo administrado, tiene un estado no apto o un tipo de dispositivo no compatible o, en el caso de un mensaje, no tiene un token push válido. change-policy también devuelve 409 cuando el dispositivo ya utiliza esa política. También se devuelve cuando el proveedor informa que el dispositivo ya no está administrado. Nomid luego marca el dispositivo como eliminado. | Reintentar fallará de la misma manera hasta que cambie el estado del dispositivo. No reintente en bucle. |
| 422 | El proveedor evaluó la solicitud y la rechazó para este dispositivo o mensaje, o informó que el comando ya había fallado. | No vuelva a intentarlo con los mismos argumentos. |
| 429 | Se superó el límite de frecuencia de comandos. Un encabezado Retry-After indica los segundos hasta que la ventana se restablezca. | Espere el tiempo indicado en Retry-After y luego intente nuevamente. |
| 500 | Error inesperado. Fuera de los endpoints lock, lost-mode, found y message, el cuerpo tiene el código internal_error y retryable en false. Se desconoce si el comando llegó al dispositivo. | No vuelva a enviar de inmediato. Compruebe primero el activo y su historial de comandos. |
| 502 | Android Management rechazó el comando por un motivo ajeno a este dispositivo. El miembro retryable indica si se debe intentar nuevamente. Los mensajes nunca devuelven 502. | Si retryable es true (el proveedor está limitando la velocidad o informó un conflicto temporal), vuelva a intentarlo tras un breve retraso. Si es false, la configuración de Android Management de la empresa presenta un problema: no vuelva a intentarlo y contacte al soporte técnico. |
| 503 | No enviado. La solicitud falló dentro de Nomid antes de que se despachara nada. retryable siempre es true. | Es seguro reintentar. No se entregó nada, por lo que un reintento no duplicará el comando. |
Cuerpos de error
Los errores de los endpoints de comandos utilizan application/problem+json (RFC 9457). En los endpoints lock, lost-mode, found y message, 401 y 429 devuelven un objeto JSON pequeño con error, message y status, 404 no tiene cuerpo, y solo 502 y 503 agregan un miembro booleano retryable. En los demás endpoints, cada error excepto 401 corresponde a detalles del problema con un miembro code, como not_found, unsupported, forbidden, invalid_arguments o rate_limited, y 429, 500, 502 y 503 también incluyen retryable. Una respuesta 202 no es un error: incluye el objeto de resultado normal.
Ejemplo de respuesta 202
HTTP/1.1 202 Accepted
{
"assetId": "k3x9m2pa",
"type": "LOCK",
"status": "UNCONFIRMED",
"detail": "The command's outcome is unknown. Check the device's command history (list_device_commands or GET /api/v1/assets/{assetId}/commands) before retrying; it may only appear once the device acknowledges it."
} Ejemplo de respuesta 503
HTTP/1.1 503 Service Unavailable
Content-Type: application/problem+json
{
"type": "about:blank",
"title": "Service Unavailable",
"status": 503,
"detail": "Command was not sent; it is safe to retry.",
"instance": "/emm/api/v1/assets/k3x9m2pa/commands/message",
"retryable": true
} Ejemplo de respuesta 404 de un endpoint distinto de lock, lost-mode, found y message
HTTP/1.1 404 Not Found
Content-Type: application/problem+json
{
"type": "about:blank",
"title": "Not Found",
"status": 404,
"detail": "No device found with assetId: k3x9m2pa",
"instance": "/emm/api/v1/assets/k3x9m2pa/commands/reboot",
"code": "not_found"
} Límite de frecuencia
Los comandos están limitados a 10 por minuto por clave de API, comandos destructivos incluidos. Este mismo cupo se comparte con las herramientas de comandos de MCP, con los cambios de políticas (cada llamada propose y apply) y con los códigos QR de aprovisionamiento, ya sea mediante REST o MCP. Mediante REST, las solicitudes que superan el límite reciben HTTP 429 con un encabezado Retry-After.
En los endpoints lock, lost-mode, found y message, solo las claves con DEVICES_COMMAND consumen este cupo, y una solicitud con un cuerpo no válido o un ID de activo desconocido sigue contando, ya que el límite se aplica antes de que se valide la solicitud. Los demás endpoints de comandos, las llamadas de cambio de políticas y las solicitudes de códigos QR de aprovisionamiento solo lo consumen una vez que la solicitud ha superado las comprobaciones de permisos y la validación de argumentos.
Registro de auditoría
Cada comando se registra en el historial de comandos del dispositivo en el portal de Nomid y se atribuye a la clave de API que lo envió, no a una persona. La entrada muestra api-key, el ID de clave y el prefijo de clave. El historial devuelto por GET /assets/ASSET_ID/commands y por la herramienta MCP list_device_commands solo contiene type, status, createdAt, feedbackAt y outcome, no quién envió el comando.