Acesso e Check-in
Registrar entrada e saída de alunos e monitorar a ocupação da academia.
Acesso e Check-in
Registre a passagem de alunos (catraca própria, totem, aplicativo ou recepção) e monitore a ocupação em tempo real.
| Endpoint | Escopo |
|---|---|
POST /api/v1/access/validate | access:write |
POST /api/v1/access/checkout | access:write |
GET /api/v1/access/occupancy | access:read |
GET /api/v1/checkins | access:read |
Validar entrada (check-in)
POST /api/v1/access/validateAplica todas as regras da empresa — mensalidade ativa, horário permitido pelo plano, bloqueio de acesso, créditos, parceiros (Wellhub/TotalPass) — e registra a passagem quando liberada.
Body (JSON)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
member_profile_id | string | Condicional | UUID do aluno. Obrigatório se não enviar member_code. |
member_code | string | Condicional | Código/QR gerado pelo app do aluno. Alternativa ao member_profile_id. |
method | string | Não | manual, qr, card, biometric, facial. Padrão manual. |
store_id | string | Condicional | UUID da unidade. Obrigatório para empresas com mais de uma unidade. |
Empresa com várias unidades
A chave de API não tem "unidade ativa" como a sessão do painel. Se a empresa tem mais de uma
unidade e você não enviar store_id, a requisição responde 400.
Exemplo de Requisição
curl -X POST "https://dashboard.octagym.ai/api/v1/access/validate" \
-H "Authorization: Bearer og_live_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{
"member_profile_id": "8f1c0f2e-9c1a-4a3f-9f0e-4b7f1d2a3c4d",
"method": "card",
"store_id": "3a2b1c0d-1111-2222-3333-444455556666"
}'Exemplo de Resposta
{
"allowed": true,
"duplicate": false,
"member_profile_id": "8f1c0f2e-9c1a-4a3f-9f0e-4b7f1d2a3c4d",
"reason": null
}Quando a entrada é negada, allowed vem false e reason explica o motivo (por exemplo
denied_inactive, denied_outside_plan_hours, denied_access_blocked).
Passagem duplicada
Uma segunda leitura do mesmo aluno dentro da janela de debounce devolve duplicate: true e
allowed: true sem contar de novo na ocupação — o webhook access.checkin também não é
reemitido. Trate como sucesso, não como erro.
Registrar saída (check-out)
POST /api/v1/access/checkoutFecha o check-in aberto e decrementa a ocupação. Use quando a academia não tem catraca de saída ou
quando ela está offline. Saída sem entrada correspondente é registrada como unpaired_exit (não
decrementa).
Body (JSON)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
member_profile_id | string | Sim | UUID do aluno |
method | string | Não | Padrão manual |
store_id | string | Condicional | Obrigatório para empresas com mais de uma unidade |
Exemplo de Resposta
{
"status": "checked_out",
"member_profile_id": "8f1c0f2e-9c1a-4a3f-9f0e-4b7f1d2a3c4d"
}Listar check-ins
GET /api/v1/checkinsMovimento de entrada da empresa por período. É o endpoint para sincronização incremental — BI, controle de frequência, folha de instrutor por presença.
Query Parameters
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
since | string | últimas 24h | Timestamp ISO 8601 inicial (inclusivo) |
until | string | — | Timestamp ISO 8601 final (exclusivo) |
store_id | string | — | Filtrar por unidade |
member_profile_id | string | — | Filtrar por aluno |
method | string | — | Filtrar por método de entrada |
page | integer | 1 | Número da página |
limit | integer | 20 | Itens por página (máximo 100) |
Os resultados vêm em ordem crescente de checkin_at, para que você avance o cursor pelo último
registro recebido.
Exemplo de Requisição
curl -X GET "https://dashboard.octagym.ai/api/v1/checkins?since=2026-03-22T00:00:00Z&limit=100" \
-H "Authorization: Bearer og_live_sua_chave_aqui"Exemplo de Resposta
{
"success": true,
"data": [
{
"id": "uuid-do-checkin",
"member_profile_id": "uuid-do-aluno",
"store_id": "uuid-da-unidade",
"checkin_at": "2026-03-22T07:32:00Z",
"checkout_at": null,
"method": "qr",
"device_id": "uuid-da-catraca",
"created_at": "2026-03-22T07:32:00Z"
}
],
"pagination": { "page": 1, "limit": 100, "total": 348, "pages": 4 }
}Sincronização incremental
let cursor = lastSyncedAt; // ISO 8601 salvo na última execução
while (true) {
const url = new URL('https://dashboard.octagym.ai/api/v1/checkins');
url.searchParams.set('since', cursor);
url.searchParams.set('limit', '100');
const response = await fetch(url, { headers: { Authorization: `Bearer ${API_KEY}` } });
const { data } = await response.json();
if (data.length === 0) break;
await processCheckins(data);
cursor = data[data.length - 1].checkin_at;
}Ocupação Atual
GET /api/v1/access/occupancyRetorna a contagem de pessoas presentes na academia no momento e a capacidade máxima configurada.
Exemplo de Requisição
curl -X GET "https://dashboard.octagym.ai/api/v1/access/occupancy" \
-H "Authorization: Bearer og_live_sua_chave_aqui" \
-H "Content-Type: application/json"const response = await fetch(
'https://dashboard.octagym.ai/api/v1/access/occupancy',
{
headers: {
'Authorization': 'Bearer og_live_sua_chave_aqui',
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
Exemplo de Resposta
{
"success": true,
"data": {
"current_count": 45,
"max_capacity": 120
}
}Campos da Resposta
| Campo | Tipo | Descrição |
|---|---|---|
current_count | int | Número de pessoas presentes no momento |
max_capacity | int | Capacidade máxima configurada |
Exemplos de Uso
Display de ocupação
const { data } = await response.json();
const percentage = Math.round((data.current_count / data.max_capacity) * 100);
let status;
if (percentage < 50) status = '🟢 Tranquilo';
else if (percentage < 80) status = '🟡 Moderado';
else status = '🔴 Lotado';
console.log(`${data.current_count}/${data.max_capacity} (${percentage}%) — ${status}`);
// 45/120 (38%) — 🟢 TranquiloPolling para atualização em tempo real
// Atualizar ocupação a cada 30 segundos
setInterval(async () => {
const response = await fetch('https://dashboard.octagym.ai/api/v1/access/occupancy', {
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
});
const { data } = await response.json();
updateDisplay(data.current_count, data.max_capacity);
}, 30000);Endpoints restritos ao dashboard
O gerenciamento de dispositivos (/api/v1/access/devices), o pareamento de catracas e os
registros de acesso brutos (/api/v1/access/logs) continuam exclusivos do painel: envolvem
credenciais de equipamento e configuração de hardware.
Suporte
- Email: suporte@octagym.ai
- Dashboard: dashboard.octagym.ai