Guia do integrador

Integre catraca, leitor ou totem à API do E-Fit Core — decisão de acesso em tempo real, modo offline e registro de check-ins.

A API de controle de acesso do E-Fit Core está disponível para todas as academias a partir do plano Pro (gestao).

Visão geral

O E-Fit Core separa identificação de decisão:

  • Identificação é do equipamento. Biometria física, facial local, cartão RFID ou digitação de matrícula/CPF acontecem no equipamento do fabricante. O template biométrico nunca sai do equipamento — o E-Fit Core não recebe nem armazena templates biométricos locais de terceiros;
  • Decisão é do E-Fit Core. O equipamento envia o identificador à API e recebe em milissegundos liberado: true/false, com o comando de pulso e o motivo. As regras (status do aluno, exames, inadimplência e fluxos Wellhub/TotalPass) ficam centralizadas no painel da academia.

A URL base de produção é:

https://api.efitcore.com.br

Autenticação

Toda chamada à API utiliza uma chave de API informada no header X-Api-Key:

X-Api-Key: <sua-chave>
  • A chave é gerada pelo proprietário da conta no painel em Catracas e Dispositivos → Chaves de API (ou em Minha conta → Integrações);
  • Cada chave possui um escopo:
    • access: para decisão de acesso online, sincronização de allowlist offline e replay de giros (use este escopo para catracas e leitores);
    • checkin: para envio direto de check-ins de agregadores.
  • A chave completa é exibida uma única vez no momento da geração (o E-Fit Core armazena apenas o hash criptográfico). Se a chave for perdida, revogue-a e crie uma nova;
  • Chamadas sem chave ou com chave revogada recebem HTTP 401; chaves com escopo incompatível recebem HTTP 403.

Decisão de acesso (online)

POST /access/decision — escopo access. Executada a cada tentativa de giro ou leitura.

curl -X POST https://api.efitcore.com.br/access/decision \
  -H "X-Api-Key: $CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "identificador": "1234567890123",
    "dispositivoId": "b7e9c9a2-4f3b-4c92-9df7-285b01859182",
    "sentido": "entrada"
  }'

Payload:

Campo Tipo Obrigatório Descrição
identificador string Sim Matrícula do aluno, CPF (11 dígitos limpos), gympassId (13 dígitos), token TotalPass ou token TOTP dinâmico do App E-Fit
dispositivoId string (UUID) Não ID do dispositivo cadastrado no painel (Catracas e Dispositivos) — alimenta o monitoramento e a trilha por ponto de acesso
sentido string Não "entrada" (padrão) ou "saida". Catracas de saída devem enviar "saida"

Regra de segurança para catracas de saída (sentido: "saida")

Por questão de segurança física, evacuação e prevenção contra retenção de pessoas, a saída é sempre liberada. Nenhuma pendência financeira, bloqueio administrativo ou suspensão de plano nega a passagem de saída. O giro é registrado normalmente na trilha interna de auditoria com o motivo "Liberado — saída".

Resposta de sucesso (acesso liberado):

{
  "liberado": true,
  "motivo": "Liberado",
  "aluno": {
    "id": "e8d672a1-0df8-4f11-9457-3a4fcba8b72e",
    "nome": "Maria Silva"
  },
  "rele": {
    "ip": "192.168.1.50",
    "porta": 5000,
    "canal": 1,
    "pulsoMs": 1000,
    "protocolo": "tcp_pulse"
  }
}

[!NOTE] O objeto rele é retornado apenas se o dispositivo possuir relé de acionamento configurado no painel da academia.

Proteção de privacidade e LGPD na negação

Para impedir que a catraca seja explorada como um meio de consulta pública de dados financeiros ou cadastrais de terceiros, qualquer motivo de recusa sensível (inadimplência na régua, cadastro pendente, aluno bloqueado, matrícula cancelada ou PAR-Q pendente) é genericizado na resposta pública da API:

{
  "liberado": false,
  "motivo": "Acesso negado — consulte a recepção",
  "aluno": null
}

O motivo detalhado ("Mensalidade em atraso — acesso bloqueado", "PAR-Q pendente", etc.) fica preservado na trilha interna de auditoria do painel da academia (Acesso → Eventos), acessível exclusivamente à recepção e à gerência.

Motivos de negação retornados na API:

motivo Situação
Acesso negado — consulte a recepção Matrícula bloqueada por inadimplência, aluno inativo, cadastro pendente ou PAR-Q pendente
Aluno não encontrado Identificador não cadastrado na unidade
Assinatura do E-Fit Core inativa — acesso não pode ser decidido A conta E-Fit Core da academia está suspensa
Dispositivo desconhecido ou desativado (HTTP 400) dispositivoId inválido ou desativado

Modo offline

Sem internet a catraca continua decidindo — pela lista local. O ciclo tem três passos, na ordem em que você implementa:

1. Sincronizar a allowlist

GET /access/sync?dispositivoId=<uuid> — escopo access.

curl "https://api.efitcore.com.br/access/sync?dispositivoId=b7e9c9a2-…" \
  -H "X-Api-Key: $CHAVE"
{
  "geradoEm": "2026-07-17T12:00:00Z",
  "total": 412,
  "liberados": [
    {
      "alunoId": "…",
      "nome": "Maria Silva",
      "matricula": "A0412",
      "gympassId": "1234567890123",
      "totalpassId": null
    }
  ]
}
  • O snapshot é completo: substitua a lista local inteira a cada sync (não há delta na v1).
  • Polling sugerido: a cada 5 minutos.
  • Assinatura da academia suspensa ⇒ lista vazia (a catraca passa a negar).
  • Visita Wellhub de quem não tem ficha na academia exige modo online — o visitante não está na allowlist.
  • Enviar o dispositivoId alimenta a última sincronização exibida no painel — é por aí que começa o diagnóstico de "catraca fora do ar".

2. Decidir e enfileirar localmente

Sem rede, o controlador decide pela lista local e guarda cada giro numa fila local persistente (do integrador — precisa sobreviver a reboot). Nada chega ao E-Fit Core até o replay.

3. Replay dos eventos

POST /access/events — escopo access, lotes de até 500 eventos.

curl -X POST https://api.efitcore.com.br/access/events \
  -H "X-Api-Key: $CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "eventos": [
      {
        "eventoId": "9f2c1e08-3e42-4f3b-8571-01859182a40b",
        "identificador": "A0412",
        "dispositivoId": "b7e9c9a2-4f3b-4c92-9df7-285b01859182",
        "dataHora": "2026-10-16T08:31:12-03:00",
        "sentido": "entrada",
        "liberado": true,
        "motivo": "Liberado pela lista local"
      }
    ]
  }'
{ "registrados": 1, "checkInsCriados": 0, "duplicados": 0 }
  • dataHora é o horário original do giro, não o do replay — a trilha de auditoria e o relatório de frequência ficam corretos.
  • sentido é opcional: "entrada" (padrão) ou "saida".
  • eventoId é gerado pelo integrador (ex.: UUID criado na catraca) e é a chave de idempotência: se a resposta se perder na rede, reenvie o lote inteiro — eventos já registrados são contados em duplicados e ignorados, nunca duplicados.
  • Giros de aluno Wellhub liberados disparam o check-in no replay; o Wellhub aplica a janela de validade — giros muito antigos podem ser rejeitados na validação (o acesso físico já aconteceu; só o repasse é afetado).
  • Fail-open ou fail-closed (liberar ou travar quando estiver sem rede e o aluno não estiver na lista) é decisão da academia — configure no seu controlador.

Registro de check-ins

POST /checkins — escopo checkin. Canal complementar para registrar o check-in Wellhub de um aluno (ex.: app próprio da academia). Responde 202: a validação com o Wellhub é assíncrona.

curl -X POST https://api.efitcore.com.br/checkins \
  -H "X-Api-Key: $CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "alunoId": "1234567890123",
    "gymId": "<uuid-da-academia>",
    "dataHora": "2026-07-17T08:31:12-03:00",
    "origem": "app",
    "latitude": -23.561,
    "longitude": -46.655
  }'
{
  "checkInId": "…",
  "status": "accepted",
  "message": "Check-in aceito. Validação com o Wellhub em andamento."
}
  • alunoId é o gympassId (13 dígitos, visível no app Wellhub).
  • gymId deve ser o da academia dona da chave (senão 403).
  • origem: app, catraca ou manual.

Dispositivos

Cadastre cada equipamento no painel (Catracas e Dispositivos em /acesso): catraca, leitor ou totem. Enviar o dispositivoId nas chamadas dá trilha por equipamento e acende a última sincronização no painel. Um dispositivoId desconhecido ou desativado derruba a chamada com 400 — melhor descobrir na instalação do que perder trilha em produção.

Erros e limites

HTTP Quando
400 Payload inválido ou dispositivoId desconhecido/desativado
401 Chave ausente, inválida ou revogada
403 Escopo errado para a rota, ou gymId de outra academia
422 Campos fora do formato (ex.: alunoId sem 13 dígitos)
429 Rate limit — /access/*: 120 req/min por chave; /checkins: 20 req/min por chave

Em 429, aguarde alguns segundos e tente de novo (backoff exponencial simples resolve). Replays offline em lote contam como 1 requisição por lote — prefira lotes maiores a rajadas de chamadas.

Pseudocódigo do controlador

a cada 5 min:            allowlist = GET /access/sync?dispositivoId=X
                         substituir lista local

a cada giro:
  se online:             resposta = POST /access/decision
                         liberar catraca se resposta.liberado
  senão:                 decidir pela lista local
                         enfileirar {eventoId: uuid(), identificador,
                                     dataHora: agora(), liberado, motivo}

ao voltar a rede:        enquanto fila não vazia:
                           lote = até 500 eventos da fila
                           r = POST /access/events (lote)
                           se r ok: remover lote da fila
                           (reenvio é seguro — idempotente por eventoId)

Ambiente de testes

Use o staging antes de apontar para produção:

https://staging.api.efitcore.com.br

O staging é um ambiente separado (banco próprio, sem dados reais). Para obter uma chave de API de staging, escreva para contato@magsitech.com.br — criamos uma academia de teste e enviamos a chave.

Atualizado em 2026-10-16.