Comandos de dispositivos
Os endpoints de comandos de dispositivos enviam um comando para um dispositivo gerido. Necessitam 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 sobre exatamente um dispositivo, identificado pelo respetivo assetId, que é o pathName devolvido por GET /assets. Não existe um endpoint em lote. Para enviar comandos para vários dispositivos, faça uma chamada por dispositivo dentro do limite de taxa. Os endpoints fazem o mesmo que as ferramentas de comando do MCP.
A chave necessita de DEVICES_COMMAND e DEVICES_READ. change-policy também necessita de POLICIES_READ. Os comandos destrutivos necessitam, em vez disso, 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 tem de estar inscrito (estado ACTIVE, INACTIVE ou SYNCHRONIZING). Alguns comandos funcionam apenas num tipo de dispositivo, tal como indicado em cada descrição abaixo: dispositivos Android Management (geridos pela Google) ou dispositivos geridos pelo agente Nomid (AOSP). Qualquer outro dispositivo recebe 409. Uma mensagem é uma notificação push para o agente Nomid e necessita de um token push registado.
Endpoints
| Método | Endpoint | Descrição |
|---|---|---|
| POST | /assets/{assetId}/commands/lock | Bloqueie o ecrã do dispositivo de imediato. Apenas dispositivos Android Management. Sem corpo de pedido. |
| POST | /assets/{assetId}/commands/lost-mode | Bloqueie o dispositivo e apresente uma mensagem, com detalhes de contacto opcionais, no respetivo ecrã de bloqueio. Apenas dispositivos Android Management. |
| POST | /assets/{assetId}/commands/found | Termine o modo perdido. Nada acontece e nenhum erro é devolvido se o dispositivo não estiver no modo perdido. Apenas dispositivos Android Management. Sem corpo de pedido. |
| POST | /assets/{assetId}/commands/message | Apresente uma notificação push em texto simples no dispositivo. |
| POST | /assets/{assetId}/commands/status-report | Pedir ao dispositivo para enviar um relatório de estado atualizado agora. O relatório chega mais tarde: leia-o com GET /assets/ASSET_ID. Sem corpo de pedido. |
| POST | /assets/{assetId}/commands/location-update | Pedir ao dispositivo para comunicar a sua localização atual agora. A localização chega mais tarde: leia-a com GET /assets/ASSET_ID. Sem corpo de pedido. |
| POST | /assets/{assetId}/commands/sync-policy | Enviar novamente a política atual para o dispositivo. Apenas dispositivos geridos pelo agente Nomid (AOSP): os dispositivos Android Management recebem alterações de política automaticamente e respondem com 409. Sem corpo de pedido. |
| POST | /assets/{assetId}/commands/reboot | Reiniciar o dispositivo agora. Quem o estiver a utilizar é interrompido e o trabalho não guardado pode ser perdido. Sem corpo de pedido. |
| POST | /assets/{assetId}/commands/shutdown | Desligar o dispositivo agora. Não é possível voltar a ligá-lo remotamente. Apenas dispositivos geridos pelo agente Nomid (AOSP). Sem corpo de pedido. |
| POST | /assets/{assetId}/commands/launch-app | Abrir uma aplicação instalada no dispositivo pelo nome do pacote. Apenas dispositivos geridos pelo agente Nomid (AOSP). |
| POST | /assets/{assetId}/commands/clear-app-data | Eliminar todos os dados das aplicações indicadas (contas, definições e ficheiros), como se tivessem acabado de ser instaladas. A ação não pode ser revertida. Apenas dispositivos Android Management. |
| POST | /assets/{assetId}/commands/change-policy | Mover o dispositivo para outra política da empresa. O dispositivo aplica as aplicações, restrições e definições da nova política, e tudo o que apenas a política atual tinha é 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. Os campos desconhecidos são rejeitados e os campos de texto obrigatórios não podem estar em branco.
Comandos destrutivos
Quatro comandos apagam dados, removem ou substituem o bloqueio de ecrã ou terminam a gestão do dispositivo. Com uma chave de API, são executados assim que o pedido é aceite. Não existe qualquer etapa de aprovação no portal.
Necessitam de uma chave de API com DEVICES_COMMAND_DESTRUCTIVE e DEVICES_READ. A empresa também deve ativar os comandos destrutivos no acesso de agentes de IA no portal. Essa definição está desativada por predefinição e exige que os comandos de dispositivos também estejam ativados. Sem ela, o pedido devolve o código 403 com o código forbidden.
| Método | Endpoint | Descrição |
|---|---|---|
| POST | /assets/{assetId}/commands/wipe | Remover o dispositivo da gestão e apagar os respetivos dados geridos. Um dispositivo pertencente à empresa é reposto para os valores de fábrica: todas as aplicações e dados contidos nele são apagados. Num dispositivo de propriedade pessoal com um perfil de trabalho, apenas o perfil de trabalho e as respetivas aplicações e dados são removidos; as aplicações e dados pessoais são mantidos. Irreversível. Sem corpo de pedido. |
| POST | /assets/{assetId}/commands/reset-screen-lock | Remover o bloqueio de ecrã do dispositivo (PIN, padrão ou palavra-passe), para que possa ser desbloqueado sem nenhum. Apenas dispositivos Android Management. Sem corpo de pedido. |
| POST | /assets/{assetId}/commands/change-screen-lock-password | Definir uma nova palavra-passe de bloqueio de ecrã. O dispositivo bloqueia e apenas a nova palavra-passe o desbloqueia. Apenas dispositivos Android Management. |
| POST | /assets/{assetId}/commands/relinquish-ownership | Libertar um dispositivo pertencente à empresa para o respetivo utilizador. O perfil de trabalho e os respetivos dados são removidos, e o dispositivo deixa de ser gerido. Irreversível. Sem corpo de pedido. |
change-screen-lock-password recebe a nova palavra-passe em newPassword. O Nomid nunca a armazena, devolve ou regista em logs.
Corpos de pedido
Corpo do pedido de modo perdido
| Campo | Obrigatório | Descrição |
|---|---|---|
| message | Sim | Texto apresentado no ecrã de bloqueio. Até 4096 carateres. |
| phoneNumber | Não | Número de telefone de contacto apresentado no ecrã de bloqueio. Até 4096 carateres. |
| Não | Endereço de e-mail de contacto apresentado no ecrã de bloqueio. Tem de ser um endereço de e-mail válido, até 320 carateres. | |
| streetAddress | Não | Morada de contacto apresentada no ecrã de bloqueio. Até 4096 carateres. |
| organization | Não | Nome da organização apresentado no ecrã de bloqueio. Até 4096 carateres. |
Corpo do pedido da mensagem
| Campo | Obrigatório | Descrição |
|---|---|---|
| title | Sim | Título da notificação. Até 60 carateres. |
| body | Sim | Texto da notificação. Até 500 caracteres. |
Corpo do pedido para iniciar aplicação
| Campo | Obrigatório | Descrição |
|---|---|---|
| packageName | Sim | Nome do pacote da aplicação instalada a abrir, por exemplo com.example.app. |
Corpo do pedido para limpar dados da aplicação
| Campo | Obrigatório | Descrição |
|---|---|---|
| packageNames | Sim | Matriz de 1 a 20 nomes de pacotes, por exemplo com.example.app, cujos dados são limpos. |
Corpo do pedido para alterar a política
| Campo | Obrigatório | Descrição |
|---|---|---|
| policyId | Sim | A nova política, pelo respetivo policyId (o pathName devolvido por GET /policies). |
Corpo do pedido para alterar a palavra-passe de bloqueio de ecrã
| Campo | Obrigatório | Descrição |
|---|---|---|
| newPassword | Sim | A nova palavra-passe de bloqueio de ecrã, com 4 a 128 carateres, sem espaços no início ou no fim. Nunca é armazenada, devolvida ou registada. |
Exemplo: enviar uma mensagem
Substitua o id do ativo por um pathName de GET /assets e guarde a chave numa 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 o pedido foi concluído. Para uma mensagem, SUCCESS significa que o push foi aceite para entrega, não que o utilizador o tenha visto. 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 de perda devolvem IN_PROGRESS enquanto o dispositivo ainda não tiver confirmado o comando. O histórico de comandos mostra SUCCESS assim que o fizer. O endpoint de bloqueio não aceita corpo.
Exemplo: apagar 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"
} A eliminação de dados de um dispositivo Android Management responde com IN_PROGRESS sem createdAt. Consulte o histórico de comandos para acompanhar a operação.
Respostas e o que fazer
As regras de repetição são importantes. Tentar novamente um comando cujo resultado é desconhecido pode fazer com que seja entregue duas vezes.
| Estado | Significado | O que fazer |
|---|---|---|
| 200 | O comando foi criado e colocado na fila. | Leia o campo status. Fica em IN_PROGRESS até que o dispositivo confirme o comando, por isso consulte o histórico de comandos para verificar SUCCESS. Alguns comandos, como reiniciar, apagar dados ou renunciar à propriedade num dispositivo Android Management, respondem com IN_PROGRESS sem createdAt. |
| 202 | UNCONFIRMED. O Nomid não consegue determinar se o comando chegou ao dispositivo, por exemplo, porque o fornecedor excedeu 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, nunca tem createdAt. | Não reenvie. Verifique primeiro o histórico de comandos do dispositivo e pergunte ao utilizador antes de enviar novamente. Para uma mensagem, o histórico pode mostrar ERROR mesmo que a notificação tenha sido apresentada. O comando pode apenas aparecer depois de o dispositivo o confirmar. |
| 400 | O corpo do pedido falhou a 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á em falta, é inválida ou expirou. | Envie uma chave válida no cabeçalho X-API-Key. |
| 403 | A chave não tem a permissão de que o comando necessita ou, no caso de um comando destrutivo, a empresa não ativou comandos destrutivos. | Utilize uma chave criada com DEVICES_COMMAND e DEVICES_READ, mais POLICIES_READ para change-policy, ou com DEVICES_COMMAND_DESTRUCTIVE e DEVICES_READ para um comando destrutivo. Para comandos destrutivos, verifique também a definição da empresa em «Acesso do agente de IA» no portal. |
| 404 | Não existe nenhum ativo com este id na empresa da chave. Um ativo de outra empresa também devolve 404. Nos endpoints lock, lost-mode, found e message, o corpo está vazio. Nos outros endpoints, trata-se de problem details com o código not_found, e change-policy também o devolve no caso de uma política desconhecida. | Verifique o id do ativo através de GET /assets e, para change-policy, o id da política através de GET /policies. |
| 409 | O dispositivo não pode aceitar este comando: não tem um dispositivo gerido, tem um estado não elegível ou um tipo de dispositivo não suportado ou, no caso de uma mensagem, não tem nenhum token de push válido. change-policy também devolve 409 quando o dispositivo já utiliza essa política. É também devolvido quando o fornecedor comunica que o dispositivo já não é gerido. O Nomid marca então o dispositivo como eliminado. | Tentar novamente falha da mesma forma até que o estado do dispositivo mude. Não tente novamente num ciclo contínuo. |
| 422 | O fornecedor avaliou o pedido e recusou-o para este dispositivo ou mensagem, ou comunicou que o comando já falhou. | Não tente novamente com os mesmos argumentos. |
| 429 | O limite de frequência de comandos foi excedido. Um cabeçalho Retry-After indica os segundos até à reposição da janela. | Aguarde pelo tempo indicado em Retry-After e tente novamente. |
| 500 | Erro inesperado. Fora dos endpoints lock, lost-mode, found e message, o corpo tem o código internal_error e retryable como false. Não é possível determinar se o comando chegou ao dispositivo. | Não reenvie de imediato. Verifique primeiro o ativo e o respetivo histórico de comandos. |
| 502 | O Android Management rejeitou o comando por um motivo alheio a este dispositivo. O membro retryable indica se deve tentar novamente. As mensagens nunca devolvem 502. | Se retryable for true (o fornecedor está a aplicar limitação de pedidos ou comunicou um conflito temporário), tente novamente após um breve intervalo. Se for false, a configuração de Android Management da empresa tem um problema: não tente novamente e contacte o suporte. |
| 503 | Não enviado. O pedido falhou no interior do Nomid antes de qualquer envio. retryable é sempre true. | É seguro tentar novamente. Nada foi entregue, pelo que uma nova tentativa não pode duplicar o comando. |
Corpos de erro
Os erros dos endpoints de comandos utilizam application/problem+json (RFC 9457). Nos endpoints lock, lost-mode, found e message, 401 e 429 devolvem 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, todos os erros exceto 401 contêm 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 incluem retryable. Uma resposta 202 não é um erro: transporta 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 pedidos
Os comandos estão limitados a 10 por minuto por chave de API, incluindo comandos destrutivos. O mesmo orçamento é partilhado com as ferramentas de comandos MCP, com alterações de políticas (cada chamada de proposta e aplicação) e com códigos QR de aprovisionamento, através de REST ou MCP. Em REST, os pedidos que ultrapassem o limite recebem HTTP 429 com um cabeçalho Retry-After.
Nos endpoints lock, lost-mode, found e message, apenas as chaves com DEVICES_COMMAND gastam este orçamento, e um pedido com um corpo inválido ou um ID de recurso desconhecido continua a contar, porque o limite é aplicado antes de o pedido ser validado. Os outros endpoints de comandos, chamadas de alteração de políticas e pedidos de códigos QR de aprovisionamento só o gastam após o pedido passar nas verificações de permissões e na validação de argumentos.
Registo de auditoria
Cada comando é registado no histórico de comandos do dispositivo no portal Nomid e atribuído à chave de API que o enviou, não a uma pessoa. O registo mostra api-key, o ID da chave e o prefixo da chave. O histórico devolvido por GET /assets/ASSET_ID/commands e pela ferramenta MCP list_device_commands contém apenas type, status, createdAt, feedbackAt e outcome, e não quem enviou o comando.