Comandos de dispositivo
Os endpoints de comando de dispositivo enviam um comando para um dispositivo gerenciado. Eles precisam de uma chave de API com a permissão DEVICES_COMMAND ou DEVICES_COMMAND_DESTRUCTIVE para os quatro comandos destrutivos.
Visão geral
Cada chamada atua em exatamente um dispositivo, identificado pelo seu assetId, que é o pathName retornado por GET /assets. Não há endpoint em massa. Para comandar vários dispositivos, faça uma chamada por dispositivo dentro do limite de taxa. Os endpoints fazem a mesma coisa que as ferramentas de comando MCP.
A chave precisa de DEVICES_COMMAND e DEVICES_READ. change-policy também precisa de POLICIES_READ. Em vez disso, os comandos destrutivos precisam de DEVICES_COMMAND_DESTRUCTIVE e DEVICES_READ. Envie a chave no cabeçalho X-API-Key. A API REST não aceita um cabeçalho Authorization.
O dispositivo deve estar inscrito (status ACTIVE, INACTIVE ou SYNCHRONIZING). Alguns comandos funcionam apenas em um tipo de dispositivo, conforme indicado em cada descrição abaixo: dispositivos Android Management (gerenciados pelo Google) ou dispositivos gerenciados pelo agente Nomid (AOSP). Qualquer outro dispositivo recebe 409. Uma mensagem é uma notificação push para o agente Nomid e precisa de um token push registrado.
Endpoints
| Método | Endpoint | Descrição |
|---|---|---|
| POST | /assets/{assetId}/commands/lock | Bloqueie a tela do dispositivo imediatamente. Apenas dispositivos Android Management. Nenhum corpo de requisição. |
| POST | /assets/{assetId}/commands/lost-mode | Bloqueie o dispositivo e exiba uma mensagem, com detalhes de contato opcionais, na tela de bloqueio. Apenas dispositivos Android Management. |
| POST | /assets/{assetId}/commands/found | Encerre o modo perdido. Nada acontece e nenhum erro é retornado se o dispositivo não estiver no modo perdido. Apenas dispositivos Android Management. Nenhum corpo de requisição. |
| POST | /assets/{assetId}/commands/message | Exiba uma notificação push em texto sem formatação no dispositivo. |
| POST | /assets/{assetId}/commands/status-report | Solicite ao dispositivo que envie um relatório de status atualizado agora. O relatório chega mais tarde: leia-o com GET /assets/ASSET_ID. Sem corpo da solicitação. |
| POST | /assets/{assetId}/commands/location-update | Solicite ao dispositivo que informe sua localização atual agora. A localização chega mais tarde: leia-a com GET /assets/ASSET_ID. Sem corpo da solicitação. |
| POST | /assets/{assetId}/commands/sync-policy | Envie a política atual para o dispositivo novamente. Apenas dispositivos gerenciados pelo agente Nomid (AOSP): dispositivos Android Management recebem alterações de política automaticamente e respondem com 409. Sem corpo da solicitação. |
| POST | /assets/{assetId}/commands/reboot | Reinicie o dispositivo agora. Quem estiver usando o dispositivo será interrompido e o trabalho não salvo poderá ser perdido. Sem corpo da solicitação. |
| POST | /assets/{assetId}/commands/shutdown | Desligue o dispositivo agora. Ele não pode ser ligado novamente de forma remota. Apenas dispositivos gerenciados pelo agente Nomid (AOSP). Sem corpo da solicitação. |
| POST | /assets/{assetId}/commands/launch-app | Abra um aplicativo instalado no dispositivo pelo nome do pacote. Apenas dispositivos gerenciados pelo agente Nomid (AOSP). |
| POST | /assets/{assetId}/commands/clear-app-data | Exclua todos os dados dos aplicativos especificados (contas, configurações e arquivos), como se tivessem acabado de ser instalados. Isso não pode ser desfeito. Apenas dispositivos Android Management. |
| POST | /assets/{assetId}/commands/change-policy | Mova o dispositivo para outra política da empresa. O dispositivo aplica os aplicativos, restrições e configurações da nova política, e tudo o que apenas a política atual possuía é removido. Também requer POLICIES_READ. |
Envie Content-Type: application/json com os endpoints lost-mode, message, launch-app, clear-app-data, change-policy e change-screen-lock-password. Os outros endpoints não aceitam corpo. Campos desconhecidos são rejeitados, e campos de texto obrigatórios não podem ficar em branco.
Comandos destrutivos
Quatro comandos apagam dados, removem ou substituem o bloqueio de tela ou encerram o gerenciamento do dispositivo. Com uma chave de API, eles são executados assim que a solicitação é aceita. Não há etapa de aprovação no portal.
Eles precisam de uma chave de API com DEVICES_COMMAND_DESTRUCTIVE e DEVICES_READ. A empresa também deve ativar comandos destrutivos no acesso de agente de IA no portal. Essa configuração fica desativada por padrão e exige que os comandos de dispositivo também estejam ativados. Sem isso, a solicitação retorna 403 com o código forbidden.
| Método | Endpoint | Descrição |
|---|---|---|
| POST | /assets/{assetId}/commands/wipe | Remova o dispositivo do gerenciamento e apague seus dados gerenciados. Um dispositivo de propriedade da empresa é restaurado para as configurações de fábrica: todos os aplicativos e dados nele são apagados. Em um dispositivo de propriedade pessoal com perfil de trabalho, apenas o perfil de trabalho e seus aplicativos e dados são removidos; os aplicativos e dados pessoais permanecem. Irreversível. Sem corpo da solicitação. |
| POST | /assets/{assetId}/commands/reset-screen-lock | Remova o bloqueio de tela do dispositivo (PIN, padrão ou senha), para que ele possa ser desbloqueado sem um. Apenas dispositivos Android Management. Sem corpo da solicitação. |
| POST | /assets/{assetId}/commands/change-screen-lock-password | Defina uma nova senha de bloqueio de tela. O dispositivo é bloqueado e apenas a nova senha o desbloqueia. Apenas dispositivos Android Management. |
| POST | /assets/{assetId}/commands/relinquish-ownership | Libere um dispositivo de propriedade da empresa para o seu usuário. O perfil de trabalho e seus dados são removidos, e o dispositivo não é mais gerenciado. Irreversível. Sem corpo da solicitação. |
change-screen-lock-password recebe a nova senha em newPassword. O Nomid nunca a armazena, retorna ou registra em logs.
Corpos de requisição
Corpo da requisição de modo perdido
| Campo | Obrigatório | Descrição |
|---|---|---|
| message | Sim | Texto exibido na tela de bloqueio. Até 4096 caracteres. |
| phoneNumber | Não | Número de telefone de contato exibido na tela de bloqueio. Até 4096 caracteres. |
| Não | Endereço de e-mail de contato exibido na tela de bloqueio. Deve ser um endereço de e-mail válido, de até 320 caracteres. | |
| streetAddress | Não | Endereço físico de contato exibido na tela de bloqueio. Até 4096 caracteres. |
| organization | Não | Nome da organização exibido na tela de bloqueio. Até 4096 caracteres. |
Corpo da requisição de mensagem
| Campo | Obrigatório | Descrição |
|---|---|---|
| title | Sim | Título da notificação. Até 60 caracteres. |
| body | Sim | Texto da notificação. Até 500 caracteres. |
Corpo da solicitação para iniciar aplicativo
| Campo | Obrigatório | Descrição |
|---|---|---|
| packageName | Sim | Nome do pacote do aplicativo instalado a ser aberto, por exemplo com.example.app. |
Corpo da solicitação para limpar dados de aplicativos
| Campo | Obrigatório | Descrição |
|---|---|---|
| packageNames | Sim | Matriz de 1 a 20 nomes de pacotes, por exemplo com.example.app, cujos dados serão limpos. |
Corpo da solicitação para alterar política
| Campo | Obrigatório | Descrição |
|---|---|---|
| policyId | Sim | A nova política, pelo seu policyId (o pathName retornado por GET /policies). |
Corpo da solicitação para alterar senha de bloqueio de tela
| Campo | Obrigatório | Descrição |
|---|---|---|
| newPassword | Sim | A nova senha de bloqueio de tela, de 4 a 128 caracteres, sem espaços no início ou no fim. Ela nunca é armazenada, retornada ou registrada. |
Exemplo: enviar uma mensagem
Substitua o ID do ativo por um pathName de GET /assets e mantenha a chave em uma variável de ambiente.
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"
} Uma resposta 200 significa que o comando foi criado. O campo status é o estado do comando quando a solicitação retornou. Para uma mensagem, SUCCESS significa que o push foi aceito para entrega, não que o usuário o visualizou. Acompanhe com GET /assets/ASSET_ID/commands.
Exemplo: bloquear um 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"
} O lock e o modo perdido retornam IN_PROGRESS enquanto o dispositivo ainda não tiver confirmado o comando. O histórico de comandos exibirá SUCCESS assim que ele o fizer. O endpoint de bloqueio não aceita corpo de requisição.
Exemplo: limpar um 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"
} Uma limpeza de um dispositivo Android Management responde IN_PROGRESS sem createdAt. Verifique o histórico de comandos para acompanhá-la.
Respostas e o que fazer
As regras de repetição são importantes. Repetir um comando cujo resultado é desconhecido pode entregá-lo duas vezes.
| Status | Significado | O que fazer |
|---|---|---|
| 200 | O comando foi criado e enfileirado. | Leia o campo status. Ele permanece como IN_PROGRESS até que o dispositivo confirme o comando, portanto, verifique o histórico de comandos para SUCCESS. Alguns comandos, como reinicialização, limpeza ou renúncia de propriedade em um dispositivo com Android Management, respondem IN_PROGRESS sem createdAt. |
| 202 | UNCONFIRMED. O Nomid não consegue determinar se o comando alcançou o dispositivo, por exemplo, porque o provedor expirou o tempo limite ou falhou do seu lado. O corpo é o objeto de resultado normal com status UNCONFIRMED e orientações em detail. Fora dos endpoints lock, lost-mode, found e message, ele nunca possui createdAt. | Não reenvie. Verifique primeiro o histórico de comandos do dispositivo e pergunte ao usuário antes de enviar novamente. Para uma mensagem, o histórico pode exibir ERROR mesmo que a notificação tenha sido mostrada. O comando pode aparecer apenas quando o dispositivo confirmar o recebimento. |
| 400 | O corpo da solicitação falhou na validação ou um parâmetro é inválido. | Corrija os campos listados no array errors ou em detail. Nenhum comando foi enviado. |
| 401 | A chave de API está ausente, é inválida ou expirou. | Envie uma chave válida no cabeçalho X-API-Key. |
| 403 | A chave não possui a permissão necessária para o comando ou, para um comando destrutivo, a empresa não habilitou comandos destrutivos. | Use uma chave criada com DEVICES_COMMAND e DEVICES_READ, além de POLICIES_READ para change-policy, ou com DEVICES_COMMAND_DESTRUCTIVE e DEVICES_READ para um comando destrutivo. Para comandos destrutivos, verifique também a configuração da empresa em AI agent access no portal. |
| 404 | Nenhum ativo com este ID existe na empresa da chave. Um ativo de outra empresa também retorna 404. Nos endpoints lock, lost-mode, found e message, o corpo fica vazio. Nos outros endpoints, trata-se de detalhes do problema com o código not_found, e change-policy também o retorna para uma política desconhecida. | Verifique o ID do ativo com GET /assets e, para change-policy, o ID da política com GET /policies. |
| 409 | O dispositivo não pode aceitar este comando: ele não possui um dispositivo gerenciado, tem um status inelegível ou um tipo de dispositivo não suportado, ou, para uma mensagem, não possui um token de push válido. change-policy também retorna 409 quando o dispositivo já usa essa política. Também é retornado quando o provedor relata que o dispositivo não é mais gerenciado. O Nomid marca o dispositivo como excluído em seguida. | Repetir a tentativa falhará da mesma forma até que o estado do dispositivo mude. Não repita em loop. |
| 422 | O provedor avaliou a solicitação e a recusou para este dispositivo ou mensagem, ou informou que o comando já falhou. | Não tente novamente com os mesmos argumentos. |
| 429 | O limite de taxa de comandos foi excedido. Um cabeçalho Retry-After informa os segundos até que a janela seja redefinida. | Aguarde o tempo indicado em Retry-After e tente novamente. |
| 500 | Erro inesperado. Fora dos endpoints lock, lost-mode, found e message, o corpo contém o código internal_error e retryable false. Se o comando alcançou o dispositivo é desconhecido. | Não reenvie imediatamente. Verifique primeiro o ativo e seu histórico de comandos. |
| 502 | O Android Management rejeitou o comando por um motivo que não está relacionado a este dispositivo. O membro retryable indica se você deve tentar novamente. Mensagens nunca retornam 502. | Se retryable for true (o provedor está limitando as requisições ou relatou um conflito temporário), tente novamente após um breve intervalo. Se for false, a configuração do Android Management da empresa tem um problema: não tente novamente e entre em contato com o suporte. |
| 503 | Não enviado. A solicitação falhou dentro do Nomid antes que algo fosse despachado. retryable é sempre true. | Seguro para tentar novamente. Nada foi entregue, portanto uma nova tentativa não duplicará o comando. |
Corpos de erro
Erros dos endpoints de comando usam application/problem+json (RFC 9457). Nos endpoints lock, lost-mode, found e message, 401 e 429 retornam um pequeno objeto JSON com error, message e status, 404 não tem corpo, e apenas 502 e 503 adicionam um membro booleano retryable. Nos outros endpoints, todo erro, exceto 401, são detalhes do problema com um membro code, como not_found, unsupported, forbidden, invalid_arguments ou rate_limited, e 429, 500, 502 e 503 também contêm retryable. Uma resposta 202 não é um erro: ela contém o objeto de resultado normal.
Exemplo de resposta 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."
} Exemplo de resposta 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
} Exemplo de resposta 404 de um endpoint diferente de lock, lost-mode, found e 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"
} Limite de taxa
Os comandos são limitados a 10 por minuto por chave de API, comandos destrutivos inclusos. O mesmo orçamento é compartilhado com as ferramentas de comando MCP, com alterações de política (cada chamada propose e apply) e com códigos QR de provisionamento, via REST ou MCP. Via REST, solicitações que ultrapassam o limite recebem HTTP 429 com um cabeçalho Retry-After.
Nos endpoints lock, lost-mode, found e message, apenas chaves com DEVICES_COMMAND consomem esse orçamento, e uma solicitação com um corpo inválido ou um ID de ativo desconhecido ainda é contabilizada, pois o limite é aplicado antes da validação da solicitação. Os outros endpoints de comando, chamadas de alteração de política e solicitações de código QR de provisionamento só o consomem depois que a solicitação passa pelas verificações de permissão e validação de argumentos.
Trilha de auditoria
Cada comando é registrado no histórico de comandos do dispositivo no portal Nomid e atribuído à chave de API que o enviou, não a uma pessoa. A entrada mostra api-key, o ID da chave e o prefixo da chave. O histórico retornado por GET /assets/ASSET_ID/commands e pela ferramenta MCP list_device_commands contém apenas type, status, createdAt, feedbackAt e outcome, não quem enviou o comando.