Skip to content

Usuário automático ​

Tipo
Como fazer
Para
Parceiro whitelabel, Desenvolvedor

A API de usuários cadastra, atualiza e remove os usuários de um tenant, com os grupos e as Mesas de cada um. O cadastro acompanha o seu sistema sem passar pelo HEC, e o usuário pode ser criado logo antes do login transparente.

Todas as chamadas desta página usam o Tenant Token. Para o mesmo cadastro feito na tela, veja Usuários do Tenant.

Conferir se o e-mail existe ​

bash
curl "https://api.horusbi.com.br/v1/tenant/users?email=ana.souza%40lojaexemplo.com.br" \
  -H "Authorization: Bearer $TENANT_TOKEN"
json
{
  "status": "success",
  "data": [
    {
      "id": 812,
      "login": "ana.souza@lojaexemplo.com.br",
      "nome": "Ana Souza",
      "ultimo_login": "2026-10-20T13:02:11.000Z",
      "groups": [3],
      "bi_desks": [7],
      "apps_deny": []
    }
  ]
}

data vazio quer dizer que o e-mail não está vinculado a este tenant. O filtro aceita email, login (o mesmo campo) ou id. Sem filtro, a chamada devolve todos os usuários ativos do tenant, inclusive as pessoas da equipe do Cliente que entram nele.

Criar o usuário ​

bash
curl -X POST https://api.horusbi.com.br/v1/tenant/users \
  -H "Authorization: Bearer $TENANT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "login": "ana.souza@lojaexemplo.com.br",
    "nome": "Ana Souza",
    "groups": [3]
  }'
json
{ "success": true, "id": 812 }

O usuário é da plataforma, e o tenant guarda só um vínculo com ele. Se o e-mail já existe em outro tenant, de qualquer Cliente, a API vincula esse mesmo usuário. Por isso password só vale para usuário criado agora (quem já existia continua com a senha dele), e nome muda o nome do usuário em todos os tenants dele.

Sem password, o usuário fica sem senha e entra só pelo login transparente. Use assim quando o seu sistema for a única porta de entrada.

Dar acesso aos Dashboards ​

Usuário sem grupo e sem Mesa entra no DataViz e não vê nada. Os campos de permissão valem na criação e na edição:

CampoRecebeEfeito
groupsIDs de GET /v1/tenant/groupsO usuário herda as Mesas, as tabelas liberadas e os filtros de linha do grupo
bi_desksIDs de Mesa, de GET /v1/tenantLibera a Mesa para o usuário direto, sem grupo
apps_denyIDs de AplicaçãoEsconde Aplicações específicas, mesmo dentro de uma Mesa liberada
tablesTabelas, com filtro de linhaLibera a tabela para o usuário direto, só com as linhas do filtro. Veja Filtrar as linhas

Prefira grupos. Com um grupo por perfil do seu sistema (Diretoria, Gerente, Vendedor), mudar o que um perfil vê é uma edição no HEC, sem reenviar a lista de Mesas de cada usuário. Grupos estão em Grupos e permissões, e o que um grupo libera, em Liberar acesso.

A API não dá o grupo de administrador. A chamada que tentar volta com HTTP 403, O grupo de administrador não pode ser atribuído pela API. e o código ADMIN_GROUP_NOT_ALLOWED. Quem vai administrar o tenant recebe esse grupo no HEC.

Filtrar as linhas de cada usuário ​

O filtro de linha fica na liberação de uma tabela, e a liberação pode ser de um grupo ou de um usuário. As duas vão no campo tables da mesma chamada que cria ou edita o grupo ou o usuário. Escolha pelo que o filtro descreve:

O filtro descreveOnde ficaExemplo
Algo que várias pessoas dividem: loja, filial, regiãoNo grupoOs gerentes da loja 12 veem só a loja 12
A própria pessoaNo usuárioCada um de 180 representantes vê só as próprias vendas

Com 180 representantes, um grupo por pessoa daria 180 grupos de um membro só. Nesse caso o filtro vai no próprio usuário, e um grupo único dá a Mesa a todos.

Dois casos. À esquerda, o grupo Loja 12 tem a Mesa 7 e a tabela Vendas com o filtro Loja = 12, e dá os dois a Carla e Bruno. À direita, o grupo Representantes dá só a Mesa 7 a Ana e Rui, e cada um tem a própria liberação de Vendas: Representante = 10 para Ana, Representante = 11 para Rui.Dois casos. À esquerda, o grupo Loja 12 tem a Mesa 7 e a tabela Vendas com o filtro Loja = 12, e dá os dois a Carla e Bruno. À direita, o grupo Representantes dá só a Mesa 7 a Ana e Rui, e cada um tem a própria liberação de Vendas: Representante = 10 para Ana, Representante = 11 para Rui.

Os exemplos usam uma Aplicação publicada na Mesa 7 que lê a tabela Vendas, com as colunas Loja e Representante. A ordem das chamadas:

Sequência entre o seu backend e api.horusbi.com.br. Uma vez por tenant: GET /v1/tenant/tables devolve os IDs da tabela e das colunas. Por loja: POST /v1/tenant/groups com a Mesa e a tabela filtrada, que devolve o ID do grupo. Por pessoa: POST /v1/tenant/users com o grupo e, no caso do representante, a tabela com o filtro dele.Sequência entre o seu backend e api.horusbi.com.br. Uma vez por tenant: GET /v1/tenant/tables devolve os IDs da tabela e das colunas. Por loja: POST /v1/tenant/groups com a Mesa e a tabela filtrada, que devolve o ID do grupo. Por pessoa: POST /v1/tenant/users com o grupo e, no caso do representante, a tabela com o filtro dele.

Os IDs da tabela e da coluna ​

A liberação aponta para o ID da tabela e o ID da coluna do filtro. Os dois não mudam: busque uma vez por tenant e guarde.

bash
curl https://api.horusbi.com.br/v1/tenant/tables \
  -H "Authorization: Bearer $TENANT_TOKEN"
json
{
  "status": "success",
  "data": [
    {
      "id": 297,
      "nome": "Vendas",
      "columns": [
        { "id": 4358, "column_name": "LOJA", "data_type": "String", "label": "Loja" },
        { "id": 4361, "column_name": "REPRESENTANTE", "data_type": "String", "label": "Representante" }
      ]
    }
  ]
}

Aqui a tabela é a 297, a coluna Loja é a 4358 e a coluna Representante é a 4361. Os IDs mudam de um tenant para outro, mesmo quando os dois nascem do mesmo template; o que se repete é o nome. Ao criar um tenant, procure a tabela pelo nome e a coluna pelo column_name e guarde os IDs daquele tenant. Assim cada tenant novo custa uma chamada a mais, não uma por usuário.

O campo tables ​

Cada item libera uma tabela:

CampoRecebe
tableIdID da tabela, obrigatório
filtersLista de filtros de linha. Cada um tem column.column_id, operator e value
allow_exporttrue deixa exportar os dados da tabela
hidden_columnsIDs de coluna que a pessoa não vê
show_unlinkedfalse esconde as tabelas da Aplicação sem ligação com esta
expires_inData em que a liberação acaba (AAAA-MM-DD), ou null para não acabar

O filtro tem o mesmo formato que o HEC grava: { "column": { "column_id": 4358 }, "operator": "=", "value": "12" }. Os operadores são =, !=, >, >=, <, <=, LIKE, NOT LIKE, IN, NOT IN, BETWEEN, NOT BETWEEN, IS NULL e IS NOT NULL. IN recebe uma lista (["01", "02"]) e BETWEEN, dois valores.

A lista tables substitui as liberações que o grupo ou o usuário tem. Uma tabela que fica de fora perde a liberação, e "tables": [] tira todas. Num item de tabela que já estava liberada, o campo que não vai no corpo mantém o valor. Liberação feita por Datamart, no HEC ou em /v1/tenant/datamart, não muda com tables.

Filtro no grupo: um grupo por loja ​

Para cada loja, crie o grupo com a Mesa e a tabela filtrada:

bash
curl -X POST https://api.horusbi.com.br/v1/tenant/groups \
  -H "Authorization: Bearer $TENANT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "nome": "Loja 12",
    "bi_desks": [7],
    "tables": [
      {
        "tableId": 297,
        "allow_export": true,
        "filters": [{ "column": { "column_id": 4358 }, "operator": "=", "value": "12" }]
      }
    ]
  }'
json
{ "success": true, "id": 34 }

Guarde no seu sistema a relação entre a loja e o grupo 34. Cada gerente entra no grupo da loja dele ao ser criado, com "groups": [34] em Criar o usuário.

Filtro no usuário: um por representante ​

Crie o grupo Representantes uma vez, só com a Mesa ({"nome": "Representantes", "bi_desks": [7]}), e guarde o ID que volta, aqui 40. Depois, cada representante é criado no grupo e com o próprio filtro, numa chamada só:

bash
curl -X POST https://api.horusbi.com.br/v1/tenant/users \
  -H "Authorization: Bearer $TENANT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "login": "ana.souza@lojaexemplo.com.br",
    "nome": "Ana Souza",
    "groups": [40],
    "tables": [
      {
        "tableId": 297,
        "allow_export": false,
        "filters": [{ "column": { "column_id": 4361 }, "operator": "=", "value": "10" }]
      }
    ]
  }'
json
{ "success": true, "id": 812 }

Para os 180, repita a chamada com o login e o código de cada um. Quem já existe recebe a mesma lista por PUT /v1/tenant/users, que troca a liberação dele, então dá para mandar a cada login transparente o código que o seu sistema tem hoje.

Quando os filtros se somam ​

Os filtros que chegam a uma pessoa na mesma tabela valem juntos, todos ao mesmo tempo. Quem está nos grupos Loja 01 e Loja 02 vê as linhas que são das duas lojas ao mesmo tempo, ou seja, nenhuma. Para quem cuida de várias lojas, dê a liberação no usuário com o operador IN:

json
{ "column": { "column_id": 4358 }, "operator": "IN", "value": ["01", "02"] }

Liberação sem filtro não abre nada que outra liberação filtrou: no caso dos representantes, o grupo dá a Mesa sem liberar a tabela, e o filtro de cada um continua valendo.

O filtro vale para Vendas e para as tabelas ligadas a ela por relacionamento. Uma tabela da Aplicação sem ligação com Vendas aparece inteira, a menos que a liberação leve "show_unlinked": false (veja Tabelas sem ligação).

Para conferir, gere a URL de login transparente de um gerente ou representante e abra o Dashboard: os números têm de ser só os dele. No HEC, a Central de Permissões mostra quem acessa cada tabela.

Manter as permissões em sincronia ​

Cada lista enviada (groups, bi_desks, apps_deny, tables) substitui a anterior inteira. Mandar "groups": [3] para quem está nos grupos 3 e 5 tira o usuário do grupo 5. Campo que não vai no corpo fica como está.

Com isso dá para sincronizar a cada login: antes de gerar a URL, envie a lista completa de grupos que o perfil do usuário pede hoje.

bash
curl -X PUT https://api.horusbi.com.br/v1/tenant/users \
  -H "Authorization: Bearer $TENANT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"login": "ana.souza@lojaexemplo.com.br", "groups": [3, 4]}'

Duas exceções protegem o que a API não administra: o grupo de administrador não sai por omissão da lista, e os grupos do Cliente marcados como invisíveis para o tenant também não. Esses grupos invisíveis também não recebem membro pela API (MANAGED_BY_PROVIDER).

Remover quem saiu ​

bash
curl -X DELETE https://api.horusbi.com.br/v1/tenant/users/delete \
  -H "Authorization: Bearer $TENANT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"login": "ana.souza@lojaexemplo.com.br"}'

O vínculo com o tenant acaba, e a sessão aberta cai na próxima página que o usuário abrir. Nos outros tenants dele, nada muda. Se o seu cliente HTTP não manda corpo em DELETE, use POST /v1/tenant/users/delete com o mesmo corpo.

Se der errado ​

RespostacodeCausa
HTTP 404, "success": false, Usuário não encontradoUSER_NOT_FOUNDEm PUT ou DELETE, o e-mail não está vinculado a este tenant. Crie com POST
HTTP 409, "success": false, Login já está cadastradoUSER_LOGIN_TAKENO e-mail já está vinculado a este tenant. Use PUT para mudar permissões
HTTP 404, "success": false, Grupo 99 não encontradoGROUP_NOT_FOUNDID de grupo que não é deste tenant. Mesa, Aplicação e tabela dão DESK_NOT_FOUND, APP_NOT_FOUND e TABLE_NOT_FOUND
HTTP 403, "success": false, Este grupo é administrado pelo fornecedor da plataforma e não pode ser alterado pela API.MANAGED_BY_PROVIDERO grupo é um grupo padrão do Cliente marcado como invisível para o tenant, e a API não põe ninguém nele
HTTP 409, message com Limite de N usuário(s) atingido...USER_QUOTA_EXCEEDEDO tenant chegou à franquia de usuários contratada
HTTP 400, "success": false, Liberação de tabela inválida: ...TABLE_ACCESS_INVALIDUm item de tables tem coluna que não é da tabela, operador sem o valor que ele pede ou tabela de outro tenant. errors aponta o campo de cada problema

Operação de usuário que falha responde com o status da causa, "success": false, o motivo em message e o code. Até a versão de 28/10/2026 da API, esses erros voltavam com HTTP 200, e a franquia com HTTP 500 e o motivo só no campo error. A lista completa está nos códigos de erro da API.

Relacionado ​