Protocolo Push ZKTeco explicado: por que é essencial para o ponto eletrônico na nuvem
Os dispositivos ZKTeco suportam dois modos de conexão: pull (SDK) e push (nuvem). Saiba como o modo push elimina IPs estáticos, servidores locais e polling — e como receber dados de ponto em tempo real via API REST.
Introduction
Você comprou um dispositivo ZKTeco. Conectou à rede. Agora precisa dos dados de ponto na sua aplicação em nuvem. A pergunta é: o dispositivo envia os dados para você, ou você vai buscá-los no dispositivo?
Essa decisão arquitetural — push vs. pull — determina se sua integração funciona de forma confiável em escala ou quebra no momento em que você adiciona um segundo escritório. A maioria dos desenvolvedores começa pela abordagem pull (bibliotecas SDK), bate em um muro, e então descobre que o modo push existe. A essa altura, já perderam semanas.
Este artigo explica o que é o modo push, por que ele existe, como se compara à abordagem SDK, e como obter dados de ponto em tempo real sem tocar em protocolos brutos dos dispositivos.
Modo Pull: a abordagem SDK (e por que falha)
A forma tradicional de obter dados de um dispositivo ZKTeco é o modo pull. Seu servidor se conecta ao dispositivo na rede local, se autentica e solicita os registros. Bibliotecas como pyzk, node-zklib e zklib funcionam assim.
Parece simples no início. Escreve um script, conecta no IP do dispositivo, chama get_attendance(), pronto. Mas a simplicidade engana.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 340" fill="none" style="width:100%;max-width:800px;">
<text x="400" y="25" text-anchor="middle" fill="#94a3b8" font-size="17" font-weight="bold" font-family="system-ui">Modo Pull: o servidor se conecta ao dispositivo</text>
<rect x="40" y="70" width="180" height="80" rx="12" stroke="#f87171" stroke-width="2" fill="none"/>
<text x="130" y="105" text-anchor="middle" fill="#f87171" font-size="15" font-family="system-ui">💻 Seu servidor</text>
<text x="130" y="127" text-anchor="middle" fill="#f87171" font-size="14" font-family="system-ui">(precisa estar na LAN)</text>
<line x1="220" y1="110" x2="340" y2="110" stroke="#64748b" stroke-width="2" marker-end="url(#ppArrowPt)"/>
<text x="280" y="98" text-anchor="middle" fill="#64748b" font-size="13" font-family="system-ui">conexão + polling</text>
<rect x="340" y="70" width="180" height="80" rx="12" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="430" y="105" text-anchor="middle" fill="#22d3ee" font-size="15" font-family="system-ui">🖐 Dispositivo ZKTeco</text>
<text x="430" y="127" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">(IP estático necessário)</text>
<rect x="40" y="190" width="680" height="130" rx="10" stroke="#f87171" stroke-width="1.5" fill="none" stroke-dasharray="6,4"/>
<text x="60" y="215" fill="#f87171" font-size="15" font-weight="bold" font-family="system-ui">⚠ Limitações do modo Pull:</text>
<text x="60" y="240" fill="#94a3b8" font-size="14" font-family="system-ui">• O servidor precisa estar na mesma rede do dispositivo (sem apps na nuvem)</text>
<text x="60" y="262" fill="#94a3b8" font-size="14" font-family="system-ui">• O dispositivo precisa de IP estático — mudança DHCP quebra a conexão</text>
<text x="60" y="284" fill="#94a3b8" font-size="14" font-family="system-ui">• O polling gera atrasos (1-5 min) e desperdício de banda</text>
<text x="60" y="306" fill="#94a3b8" font-size="14" font-family="system-ui">• Cada dispositivo = uma conexão. 50 dispositivos = 50 threads fazendo polling</text>
<defs>
<marker id="ppArrowPt" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto"><polygon points="0 0, 10 3.5, 0 7" fill="#64748b"/></marker>
</defs>
</svg>
Veja o que dá errado em produção:
- Sua app roda na nuvem. AWS, Azure, Railway, DigitalOcean — nenhum desses consegue alcançar um dispositivo atrás de um roteador numa LAN corporativa. Você precisa de um servidor local rodando 24/7 como ponte.
- Os dispositivos mudam de IP. O TI reinicia o roteador, o lease DHCP expira, alguém desconecta o switch. Sua string de conexão agora está errada, e você não recebe dados até alguém notar.
- O polling não é tempo real. Você pergunta ao dispositivo "registros novos?" a cada 30 segundos. É banda desperdiçada em respostas vazias 95% do tempo.
- Não escala. Gerenciar conexões persistentes com 50+ dispositivos em múltiplos escritórios, cada um com sua configuração de rede? Isso é um trabalho de tempo integral.
O modo pull funciona para um dispositivo na LAN. No momento que você vai para multi-sites ou nuvem, você precisa do modo push.
Modo Push: o dispositivo se conecta a você
O modo push inverte a direção da conexão. O dispositivo inicia a conexão para um servidor na nuvem, não o contrário. O dispositivo não precisa de IP estático. Seu servidor não precisa estar na mesma rede. O dispositivo só precisa de acesso à internet.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 320" fill="none" style="width:100%;max-width:800px;">
<text x="400" y="25" text-anchor="middle" fill="#94a3b8" font-size="17" font-weight="bold" font-family="system-ui">Modo Push: o dispositivo se conecta à nuvem</text>
<rect x="20" y="60" width="170" height="65" rx="10" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="105" y="88" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">🖐 Escritório A</text>
<text x="105" y="108" text-anchor="middle" fill="#64748b" font-size="12" font-family="system-ui">(DHCP — qualquer IP)</text>
<rect x="20" y="145" width="170" height="65" rx="10" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="105" y="173" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">🖐 Escritório B</text>
<text x="105" y="193" text-anchor="middle" fill="#64748b" font-size="12" font-family="system-ui">(Rede diferente)</text>
<rect x="20" y="230" width="170" height="65" rx="10" stroke="#22d3ee" stroke-width="2" fill="none"/>
<text x="105" y="258" text-anchor="middle" fill="#22d3ee" font-size="14" font-family="system-ui">🖐 Escritório C</text>
<text x="105" y="278" text-anchor="middle" fill="#64748b" font-size="12" font-family="system-ui">(Atrás de NAT)</text>
<line x1="190" y1="92" x2="310" y2="160" stroke="#34d399" stroke-width="2" marker-end="url(#ppArrow2Pt)"/>
<line x1="190" y1="177" x2="310" y2="170" stroke="#34d399" stroke-width="2" marker-end="url(#ppArrow2Pt)"/>
<line x1="190" y1="262" x2="310" y2="180" stroke="#34d399" stroke-width="2" marker-end="url(#ppArrow2Pt)"/>
<text x="260" y="140" text-anchor="middle" fill="#34d399" font-size="13" font-family="system-ui">push</text>
<rect x="310" y="130" width="190" height="80" rx="12" stroke="#a78bfa" stroke-width="2" fill="none"/>
<text x="405" y="165" text-anchor="middle" fill="#a78bfa" font-size="15" font-family="system-ui">☁️ Motor de</text>
<text x="405" y="187" text-anchor="middle" fill="#a78bfa" font-size="15" font-family="system-ui">protocolo cloud</text>
<line x1="500" y1="170" x2="580" y2="170" stroke="#64748b" stroke-width="2" marker-end="url(#ppArrow2Pt)"/>
<text x="540" y="158" text-anchor="middle" fill="#64748b" font-size="13" font-family="system-ui">API REST</text>
<rect x="580" y="130" width="190" height="80" rx="12" stroke="#34d399" stroke-width="2" fill="none"/>
<text x="675" y="165" text-anchor="middle" fill="#34d399" font-size="15" font-family="system-ui">💻 Sua App</text>
<text x="675" y="187" text-anchor="middle" fill="#34d399" font-size="14" font-family="system-ui">(Qualquer lugar)</text>
<defs>
<marker id="ppArrow2Pt" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto"><polygon points="0 0, 10 3.5, 0 7" fill="#34d399"/></marker>
</defs>
</svg>
No modo push, o dispositivo faz o trabalho pesado. Ele se conecta de saída para a nuvem, envia dados de ponto em tempo real, recebe comandos (sincronizar hora, cadastrar funcionários, reiniciar), e reporta seu status — tudo sem que seu servidor precise iniciar uma conexão.
Por que o modo Push vence
| Fator | Pull (SDK) | Push (Nuvem) |
|-------|-----------|--------------|
| Rede necessária | Mesma LAN | Apenas internet |
| IP do dispositivo | Estático obrigatório | Qualquer (DHCP OK) |
| Latência | 30s–5min de polling | Tempo real (<1s) |
| Apps na nuvem | ❌ Ponte local necessária | ✅ Nativo |
| Multi-sites | ❌ VPN por site | ✅ Tudo converge para um ponto |
| Escalabilidade | 1 thread por dispositivo | Baseado em eventos, sem polling |
| Firewall | Portas de entrada abertas | Apenas saída |
A parte difícil: construir um servidor de protocolo push
Aqui é onde a maioria das equipes empaca. O modo push é melhor, mas implementar o servidor que recebe os dados push é complexo. O dispositivo fala um protocolo proprietário. Você precisa:
- Analisar corretamente o handshake de conexão do dispositivo
- Gerenciar autenticação e registro de dispositivos
- Processar registros de ponto do formato bruto
- Enfileirar e entregar comandos aos dispositivos
- Gerenciar o estado de conexão de dezenas de dispositivos simultaneamente
- Lidar com reconexões, timeouts e deduplicação de dados
Isso não é um projeto de fim de semana. Construir um servidor de protocolo push para produção levou meses de trabalho da nossa equipe e milhares de horas de testes com 80+ dispositivos em campo.
A abordagem middleware: protocolo na entrada, API REST na saída
PunchConnect fica entre seus dispositivos e sua aplicação. Os dispositivos enviam dados para o motor de protocolo do PunchConnect. Você consome endpoints REST API e webhooks limpos. Você nunca toca no protocolo bruto.
Obtendo dados de ponto em tempo real (exemplos de código)
Uma vez que seu dispositivo está configurado no painel do PunchConnect (leva cerca de 5 minutos), você interage exclusivamente com a API REST:
Buscar registros de ponto
# Obter os eventos de ponto de hojecurl -X GET "https://api.punchconnect.com/v1/attendance?from=2026-03-27T00:00:00Z" \-H "Authorization: Bearer SUA_CHAVE_API" \-H "Content-Type: application/json"
Python — Buscar e processar ponto
import requestsfrom datetime import datetime, timezoneAPI_KEY = "SUA_CHAVE_API"BASE_URL = "https://api.punchconnect.com/v1"def get_attendance(from_date: str = None):"""Busca registros de ponto do PunchConnect."""params = {}if from_date:params["from"] = from_dateresponse = requests.get(f"{BASE_URL}/attendance",headers={"Authorization": f"Bearer {API_KEY}"},params=params,)response.raise_for_status()return response.json()["data"]def sincronizar_com_seu_sistema(records):"""Envia os registros de ponto para seu sistema de RH."""for record in records:print(f"[{record['punch_time']}] "f"{record['employee_id']} — "f"{record['punch_type']} "f"({record['verify_mode']})")if __name__ == "__main__":today = datetime.now(timezone.utc).strftime("%Y-%m-%dT00:00:00Z")records = get_attendance(from_date=today)print(f"{len(records)} registros obtidos")sincronizar_com_seu_sistema(records)
JavaScript — Ouvir webhooks em tempo real
import express from "express";const app = express();app.use(express.json());app.post("/webhook/attendance", (req, res) => {const event = req.body;console.log(`Novo ponto: ${event.employee_id} às ${event.punch_time}`);console.log(` Tipo: ${event.punch_type} | Método: ${event.verify_mode}`);console.log(` Dispositivo: ${event.device_serial}`);res.status(200).json({ received: true });});app.listen(3000, () => {console.log("Listener de webhook ouvindo na porta 3000");});
Quais dispositivos ZKTeco suportam o modo push?
A maioria dos dispositivos ZKTeco modernos suportam o modo push. Qualquer dispositivo com firmware ZMM (a maioria dos fabricados após 2015) tem essa capacidade:
- Reconhecimento facial: SpeedFace V5L, SpeedFace-H5, ProFace X
- Impressão digital: UA860, K40, IN01-A, X7
- Multi-modal: SpeedFace V4L, MultiBio 800
- Controle de acesso: inBio 160/260, C3-100/200/400
Como verificar: Procure a configuração "Cloud Server" ou "ADMS Server" no menu de configuração de rede do seu dispositivo. Se estiver lá, seu dispositivo suporta modo push.
Modo push no Brasil: conformidade LGPD e CLT
Para implantações no Brasil, o modo push oferece vantagens importantes de conformidade:
- LGPD (Lei Geral de Proteção de Dados) — os dados biométricos transitam diretamente do dispositivo para a nuvem, sem servidor intermediário local que adicionaria um ponto de armazenamento extra sujeito às exigências da LGPD e da ANPD.
- Portaria 671 — o registro eletrônico de ponto precisa ser confiável e inviolável. O modo push em tempo real com PunchConnect fornece registros imediatos com timestamp do dispositivo, atendendo aos requisitos de integridade.
- CLT (Consolidação das Leis do Trabalho) — o controle de jornada é obrigatório para empresas com mais de 20 funcionários. O modo push garante que nenhum registro se perca, mesmo em caso de queda de internet.
Os modelos mais comuns no Brasil: ZKTeco K40 (relógio de ponto biométrico), SpeedFace V5L (facial), UA860 (digital + cartão). Todos suportam modo push.
Perguntas frequentes sobre o modo push
Preciso abrir portas no firewall para o modo push?
Não. O modo push usa conexões de saída do dispositivo, como um navegador web. Se seu dispositivo pode acessar a internet, ele pode enviar dados. Sem portas de entrada, sem IP estático, sem redirecionamento de portas.
Qual a latência real do modo push?
Menos de um segundo. Quando um funcionário bate o ponto no dispositivo, o evento chega ao PunchConnect e ativa seu webhook em menos de um segundo. Comparado com o polling SDK (30 segundos a 5 minutos), o modo push é praticamente instantâneo.
O que acontece se a internet cair?
O dispositivo armazena localmente. Os dispositivos ZKTeco guardam registros na memória interna (geralmente 50.000 a 100.000 registros). Quando a conectividade retorna, o dispositivo envia automaticamente todos os registros em buffer. O PunchConnect faz a deduplicação para que você nunca receba registros duplicados.
É possível enviar comandos para o dispositivo no modo push?
Sim. O PunchConnect enfileira os comandos (cadastrar funcionários, sincronizar hora, reiniciar, atualizar configurações) e os entrega ao dispositivo no próximo ciclo push. Você envia comandos pela API REST, o PunchConnect cuida da entrega.
O modo push é compatível com todos os modelos ZKTeco?
O modo push funciona com qualquer dispositivo ZKTeco que tenha a configuração "Cloud Server" ou "ADMS Server" — a grande maioria dos dispositivos fabricados após 2015. Dispositivos mais antigos (pré-2015) suportam apenas o modo pull, mas estão cada vez mais raros em implantações ativas.
Para começar
Se você está construindo uma integração biométrica e decidindo entre push e pull:
1. Comece com o modo push. É a arquitetura certa para qualquer aplicação na nuvem.
2. Não construa o servidor de protocolo sozinho — a menos que tenha meses de sobra e experiência profunda com protocolos ZKTeco.
3. Teste o PunchConnect grátis por 7 dias — cadastre seu dispositivo, obtenha sua chave API, e receba seu primeiro webhook de ponto em menos de 15 minutos. Sem cartão de crédito.
Se você já usa uma biblioteca SDK e está com problemas de escalabilidade, leia nossa comparação: Por que bibliotecas open-source ZKTeco não escalam. E se seu maior bloqueio é o IP estático, veja Ponto biométrico sem IP estático.
---
*PunchConnect é um middleware comprovado em produção que conecta dispositivos biométricos ZKTeco a qualquer sistema de software. Atualmente gerencia o ponto de 24.000+ funcionários em 50+ locais.*
Artigos relacionados
Por que bibliotecas open-source ZKTeco não escalam (e o que usar no lugar)
9 min read
TutorialComo Conectar ZKTeco ao Odoo: Integração via API Cloud (Sem VPN, Sem Software Local)
10 min read
GuideControle de Ponto Biométrico Sem IP Fixo: Como a API na Nuvem Resolve o Maior Problema das Empresas Brasileiras
11 min read