---
title: "Cliente Python para a API do Wialon que funciona"
url: https://theassettrack.com/pt-br/blog/wialon-api-python-client/
description: "Um cliente Python moderno para a Remote API do Wialon: login, busca, eventos ao vivo com avl_evts e quais bibliotecas seguem vivas e quais morreram em 2013."
---

# Cliente Python para a API do Wialon que funciona

[Siarhei Havarunou](https://www.linkedin.com/in/sergey-govorunov/) – CEO

11 de setembro de 2026 · Atualizado 10 de outubro de 2026

Um cliente Python moderno para a Remote API do Wialon: login, busca, eventos ao vivo com avl_evts e quais bibliotecas seguem vivas e quais morreram em 2013.

A cada poucos meses alguém pergunta qual biblioteca Python usar com o Wialon. A resposta honesta é desconfortável: as duas bibliotecas com os nomes mais conhecidos — `python-wialon` e `php-wialon`, na organização wialon do GitHub — não são mexidas desde cerca de 2013. Elas ainda funcionam para chamadas básicas, mas são anteriores a metade da superfície da API e a todo o conhecimento operacional. Este guia entrega um cliente mínimo que você controla, em cerca de setenta linhas; depois, os cinco comportamentos que decidem se ele sobrevive ao contato com uma conta real; e por fim um mapa honesto do cenário de bibliotecas.

## O protocolo, para o cliente fazer sentido

O Wialon usa POST com formulário codificado, não REST com JSON: toda chamada vai para `wialon/ajax.html` com um campo `svc` que nomeia o serviço, um campo `params` com JSON e um campo `sid` assim que você tem uma sessão. Não há caminhos, verbos nem códigos de status para ler — um HTTP 200 com `{"error":7}` no corpo é a forma como a negação de acesso chega. (A mecânica completa está na [página de configuração do Postman](https://theassettrack.com/wialon-api/postman/).) Esse é o protocolo inteiro, e é por isso que um wrapper é um objeto de sessão em volta do `requests` e nada mais.

`import requests class Wialon: def __init__ (self, host = "https://hst-api.wialon.com", token = None): self.host = host self.base = host + "/wialon/ajax.html" self.sid = None self.token = token def call (self, svc, params = None, sid = True): data = { "svc": svc, "params": params or {}} if sid: data[ "sid" ] = self.sid r = requests.post(self.base, data = data, timeout = 30) r.raise_for_status() return r.json() def login (self): res = self.call("token/login", { "token": self.token}, sid = False) if "error" in res: raise RuntimeError (f "login failed: { res } ") self.sid = res[ "eid" ] return self.sid def events (self): # avl_evts is its own path, not an svc against ajax.html. r = requests.post(f " {self.host } /avl_evts", data = { "sid": self.sid}, timeout = 30) r.raise_for_status() return r.json()`

Setenta linhas é uma qualidade, não uma limitação: não há mágica para depurar às 3 da manhã quando uma sincronização trava. Gere o token na interface do Wialon com as flags de acesso mais estreitas que cubram suas leituras — a [página do token](https://theassettrack.com/wialon-api/token/) tem a tabela de flags — e mantenha-o fora do código, em uma variável de ambiente.

## Com qual host você está de fato falando

`hst-api.wialon.com` é o endpoint do Hosting, e só é o padrão correto se a sua conta vive no Wialon Hosting. Uma instalação do Wialon Local responde no domínio do próprio parceiro, e um token gerado em um host não significa nada no outro — a sessão é emitida pelo servidor que guarda a conta. Por isso `host` é um argumento do construtor acima e não uma constante do módulo: no dia em que você adicionar um segundo cliente em outro deployment, a única coisa que deve mudar é o valor que você passa.

Vale nomear desde já dois erros relacionados. O primeiro é deixar `hst-api.wialon.com` fixo em um cliente que você pretende vender a parceiros, o que limita silenciosamente o seu produto a um único deployment. O segundo é tratar o host da interface e o host da API como a mesma string; eles são relacionados, mas não intercambiáveis, e copiar uma URL do navegador para a configuração do cliente produz um 404 que parece uma falha de rede.

## Primeiro buscar, depois mensagens

Duas chamadas carregam a maior parte das integrações. `core/search_items` encontra coisas; `messages/load_interval` lê o histórico delas:

`w = Wialon(token = "...") w.login() units = w.call("core/search_items", { "spec": { "itemsType": "avl_unit", "propName": "sys_name", "propValueMask": "*", "sortType": "sys_name", }, "force": 1, "flags": 1, "from": 0, "to": 0, }) unit_id = units[ "items" ][ 0 ][ "id" ] msgs = w.call("messages/load_interval", { "itemId": unit_id, "timeFrom": 1726000000, "timeTo": 1726086400, "flags": 0, "flagsMask": 0x FF00, "loadCount": 10000, })`

Quatro detalhes dessa primeira chamada decidem o que você recebe. `itemsType` escolhe o catálogo: `avl_unit` para unidades, `avl_resource` para recursos, `avl_unit_group` para grupos, `user` para usuários. `propName` e `propValueMask` são o filtro, e `sys_name` com `*` é o idioma para “tudo o que tenho permissão de ver”. `sortType` dá uma ordem estável, o que importa mais do que parece: sem ele, ao paginar uma conta grande você pode ver a mesma unidade duas vezes e perder outra. E `flags` não é um booleano, e sim uma máscara de bits de data-flags: `1` retorna o conjunto base (id, nome, classe, unidades de medida), enquanto sensores, contadores e última posição são bits separados, cada um com custo no tamanho da resposta. A [referência de unidades](https://theassettrack.com/wialon-api/units/) traz a tabela completa; a regra a internalizar é pedir a máscara mais estreita que responda à sua pergunta, porque, em uma conta de três mil unidades, a diferença entre a flag `1` e uma máscara gulosa se mede em megabytes por consulta.

A paginação é a segunda coisa a acertar. `from` e `to` são índices de linha, não timestamps, e a resposta diz onde você está: `totalItemsCount` junto com `indexFrom` e `indexTo`. Pedir de `0` a `0` retorna uma única linha, o que serve para o exemplo acima e está errado para produção; percorra o índice em blocos de algumas centenas e pare quando `indexTo` chegar a `totalItemsCount`.

Duas armadilhas moram na segunda chamada. Primeiro, `flagsMask` seleciona quais tipos de mensagem voltam e `flags` diz quais deles você quer: o par documentado para mensagens de dados é a máscara `0xFF00` com flags `0x0000`, e pedir tudo em uma unidade movimentada devolve megabytes que você não queria. Segundo, `loadCount` limita o lote: itere avançando `timeFrom` em vez de aumentá-lo, ou uma única unidade de longa data estourará o [orçamento de cinco minutos dos relatórios](https://theassettrack.com/wialon-api/reports/) e devolverá zero linhas que parecem uma semana tranquila.

## Eventos ao vivo sem se matar de polling

Para quase tempo real, não consulte `load_interval` num temporizador. Inscreva a sessão com `core/update_data_flags` e depois faça polling de `avl_evts`, o canal de eventos do próprio Wialon. Atenção ao endereço: `avl_evts` não é um `svc` contra `wialon/ajax.html`, e sim um caminho próprio, `{host}/avl_evts?sid=<sid>`, e é por isso que o cliente precisa do segundo método acima em vez de outro `call()`:

`import time w.call("core/update_data_flags", { "spec": [{ "type": "type", "data": "avl_unit", "flags": 1, "mode": 0 }], }) while True: for e in w.events().get("events", []): handle(e) # your code: queue it, do not process inline time.sleep(1)`

Vale ler com atenção a entrada de `spec`. `type` diz como você seleciona os itens: `"type"` inscreve em uma classe inteira, e a alternativa seleciona uma coleção específica de ids, que é o que você vai querer quando a conta for grande o bastante para “todas as unidades” ser mais do que você precisa. `flags` é a mesma máscara de data-flags da busca, então os eventos que você recebe trazem apenas os campos que pediu. `mode` `0` substitui o que a sessão tinha inscrito, o que transforma a reinscrição após uma reconexão em uma única chamada idempotente, e não em uma diferença que você precise calcular.

Cada evento traz um id de item, um tipo e uma carga: uma mensagem nova, uma atualização do item, uma exclusão. A resposta também traz o relógio do próprio servidor, e usá-lo em vez do relógio do seu processo elimina toda uma classe de bugs do tipo “o evento chegou antes de acontecer” em máquinas com a hora desajustada.

Dois limites, ambos publicados, dão forma a esse laço: no máximo 10 requisições a `avl_evts` a cada 10 segundos por sessão, e dez requisições simultâneas à API por sessão no total. Um laço de um segundo já gasta todo o orçamento de eventos, então essa sessão não deve fazer mais nada — rode as extrações em uma segunda sessão. E o laço acima é enxuto de propósito: ele move os eventos para uma fila e volta ao polling. Processar em linha é como as integrações ficam para trás nos horários de pico e depois martelam a API para se recuperar, que é exatamente o modo de falha de que trata o artigo sobre [design de sync resiliente](https://theassettrack.com/blog/wialon-api-rate-limits-and-resilient-sync-design/). Se você precisa de push de verdade em vez de polling, leia [por que o Wialon não tem webhooks](https://theassettrack.com/pt-br/blog/wialon-webhooks-vs-polling/) antes de desenhar a arquitetura em torno dessa ausência.

## A sessão morre em silêncio, com relógio

Uma sessão do Wialon não é um bearer token de vida longa. Ela é encerrada após cinco minutos sem requisições, o que significa que uma integração que roda um job por hora mantém uma sessão morta por cinquenta e cinco minutos de cada sessenta e só descobre isso no pior momento. O laço de eventos acima nunca percebe, porque faz polling a cada segundo; um lote noturno percebe toda noite.

Há três defesas e você quer as três. Mantenha a sessão aquecida se o processo for de longa duração — qualquer chamada barata dentro da janela serve, e `avl_evts` é a convencional porque também é o que você já estava consultando. Trate o erro `1` como uma instrução para fazer login de novo exatamente uma vez e repetir a chamada, nunca como algo para tentar em laço. E renove o próprio token bem dentro da regra de cem dias de inatividade descrita na [página do token](https://theassettrack.com/wialon-api/token/), porque uma sessão expirada e um token excluído aparecem ambos como erro `1`, mas exigem correções completamente diferentes.

O padrão que falha em produção é a sessão compartilhada de longa duração: um login no início do processo, um `sid` entregue a todos os workers e nenhum caminho de reautenticação. Funciona até a primeira oscilação de rede, e então todos os workers falham ao mesmo tempo com o mesmo código, sem que nada na sua aplicação tenha mudado para explicar.

## Erros, classificados antes de repetir

O Wialon devolve erros como um HTTP 200 com um código no corpo, então o seu cliente precisa procurá-los explicitamente — `raise_for_status()` nunca vai disparar. Os códigos caem em quatro grupos, e o grupo decide o comportamento:

| Códigos | Classe | O que o cliente deve fazer |
| --- | --- | --- |
| 1, 1011 | Sessão perdida | Fazer login de novo uma vez, repetir a chamada uma vez e então desistir |
| 4 | Entrada inválida | Não repetir: é um bug nos seus parâmetros |
| 7 | Acesso negado | Não repetir: falta uma flag no token, ou o item não é seu |
| 10 | Limite de concorrência | Aguardar e repetir; você excedeu o teto por sessão |
| 1001 | Sem mensagens no intervalo | Não é um erro: é um resultado vazio para aquela janela |
| 1005 | Tempo de execução excedido | Dividir o intervalo e tentar as metades |

A distinção que mais poupa tempo é a entre `4` e `7`. O erro `4` significa que a requisição estava malformada para o serviço: um campo ausente, uma string onde deveria haver um número, um id que não pode ser interpretado. O erro `7` significa que a requisição estava bem formada e você não tem permissão para fazê-la, o que quase sempre se deve às flags de acesso do token e não a algo do item. Repetir qualquer um dos dois é puro desperdício, e repetir o erro `1` em laço é como um endereço de saída acaba bloqueado. A [referência de erros](https://theassettrack.com/wialon-api/errors/) traz a tabela completa e as strings de motivo que qualificam os códigos.

## Uma requisição em vez de quarenta

Quando você precisa da mesma chamada para muitos itens — ler um contador em cada unidade, atualizar um campo em uma frota inteira — `core/batch` as envia juntas:

`res = w.call("core/batch", { "params": [ { "svc": "core/search_item", "params": { "id": uid, "flags": 1 }} for uid in unit_ids ], "flags": 0, })`

`flags` `0` executa todos os comandos independentemente de falhas e devolve um resultado por comando; `flags` `1` para no primeiro erro, e depois disso os comandos restantes devolvem o erro `10`. Prefira `0` para leituras, para que um id ruim não custe os outros trinta e nove resultados, e `1` para escritas que não podem ser aplicadas pela metade.

Agrupar também é a correção mais barata para o teto de concorrência a seguir: quarenta chamadas em uma requisição ocupam uma vaga, não quarenta.

## A concorrência pertence à sessão, não ao seu pool

Três limites publicados governam o quanto você pode empurrar, e todos os três são por sessão, não por conta nem por IP: dez requisições simultâneas à API, três requisições pesadas simultâneas (o carregamento de mensagens e a execução de relatórios são os exemplos dados na documentação) e os dez `avl_evts` a cada dez segundos já mencionados. Um pool de vinte threads compartilhando uma sessão não vai duas vezes mais rápido que um de dez: ele começa a colecionar o erro `10`.

O formato que funciona é uma sessão por worker, com um token por worker e não um token por execução. Os tokens têm um teto por usuário, então gerar um novo a cada execução acaba esgotando a cota e o job passa a falhar até para se autenticar. E mantenha o laço de eventos em uma sessão própria: ele é barato, é constante, e compartilhá-lo com uma extração é como um backfill noturno deixa o seu feed em tempo real sem recursos.

## O que registrar em log, desde o primeiro dia

Quatro campos tornam qualquer incidente posterior tratável: o nome do serviço, os milissegundos decorridos, o código de erro, se houver, e os limites do intervalo para qualquer coisa que leia histórico. Adicione uma impressão digital curta do id da sessão — nunca o id em si — e você consegue distinguir “a sessão morreu” de “a chamada estava errada” com uma busca nos logs, e não com uma sessão de depuração. A única coisa que não se deve registrar é o token.

## O cenário de bibliotecas, mapeado com honestidade

- **`python-wialon` / `php-wialon` (organização wialon, ~2013).** Nomes conhecidos, projetos mortos. Servem como referência do formato das chamadas, não como dependências.
- **`py-aiowialon`, `wialon`, `wialon-sdk` (PyPI, de terceiros).** Wrappers assíncronos ou de conveniência, de atualização variável. Bons para scripts; audite o tratamento de sessão antes de confiar um deles à sincronização de produção: a renovação do token e o novo login nos erros 1/4 é onde costumam economizar.
- **Suas próprias setenta linhas (acima).** O que rodamos em produção atrás de uma fila. Você é dono da política de novas tentativas, do backoff e do log, que são as partes que de fato quebram.

O padrão nas três: o HTTP é trivial, a operação não. Sessões expiram, tokens são revogados após 100 dias de inatividade, chamadas pesadas são limitadas a três por vez por sessão. Quem é dono do seu código de cliente é dono desses comportamentos — garanta que seja você, não um pacote abandonado.

## Próximos passos

Com um cliente e uma fila em mãos, as próximas perguntas são de arquitetura: [um sync que sobrevive aos limites de taxa](https://theassettrack.com/blog/wialon-api-rate-limits-and-resilient-sync-design/), [levar os dados para o PostgreSQL](https://theassettrack.com/blog/wialon-to-postgresql-production-pipeline/) e [empurrá-los adiante para um ERP](https://theassettrack.com/pt-br/blog/wialon-integration-with-erp-architecture-and-pitfalls/). Se essa fila está começando a parecer um produto e não um script, é isso que a nossa [prática de integração](https://theassettrack.com/pt-br/wialon-integration/) constrói.

Trabalhe com a gente

Precisa disso rodando no seu próprio Wialon?

Construímos integrações do Wialon, pipelines de dados e aplicativos de frota white label. Vinte minutos de conversa costumam bastar para dizer se o seu caso é uma semana de trabalho ou um trimestre.

[Book a free call](https://cal.com/sergey.govorunov/call) ou mande uma mensagem

## Mais da Asset Track

- 11 de setembro de 2026 · Estratégia
 ### Como se tornar parceiro do Wialon (2026)
 O modelo de parceiro do Wialon explicado: planos de cobrança e margem, de onde vêm os leads, status e onde os novos parceiros travam.
 [Como se tornar parceiro do Wialon (2026)](https://theassettrack.com/pt-br/blog/how-to-become-wialon-partner/)
- 11 de setembro de 2026 · Estratégia
 ### Preços do Wialon: Hosting, Local, Platform, Lite
 Como os preços do Wialon funcionam nas quatro edições — Hosting, Local, Platform e Lite: planos de cobrança, descontos e as cinco variáveis da fatura.
 [Preços do Wialon: Hosting, Local, Platform, Lite](https://theassettrack.com/pt-br/blog/wialon-pricing-hosting-explained/)
- 11 de setembro de 2026 · Integração
 ### Wialon não tem webhooks: faça polling assim
 O Wialon não consegue enviar eventos para a sua URL. Três alternativas que funcionam: polling de avl_evts, ações de notificação e uma ponte com flespi.
 [Wialon não tem webhooks: faça polling assim](https://theassettrack.com/pt-br/blog/wialon-webhooks-vs-polling/)
- Atualizado 9 de setembro de 2026 · Análise
 ### Limites dos relatórios do Wialon e análise em SQL
 Quando os relatórios do Wialon não bastam, a análise em SQL abre dimensões próprias, comparações históricas e métricas com uma definição só.
 [Limites dos relatórios do Wialon e análise em SQL](https://theassettrack.com/pt-br/blog/wialon-reporting-limitations-and-sql-first-analytics/)
- Atualizado 9 de setembro de 2026 · Estratégia
 ### App de frota white label: fazer ou comprar
 Um modelo prático de fazer ou comprar para produtos de frota white label: custo em 18 meses, camadas de diferenciação e lançamento em etapas.
 [App de frota white label: fazer ou comprar](https://theassettrack.com/pt-br/blog/white-label-fleet-app-build-vs-buy/)
- Atualizado 11 de setembro de 2026 · Integração
 ### Integração do Wialon com ERP: arquitetura e armadilhas
 Guia prático de integração entre Wialon e ERP: contratos de dados, propriedade de campos, novas tentativas e conciliação noturna para um sync estável.
 [Integração do Wialon com ERP: arquitetura e armadilhas](https://theassettrack.com/pt-br/blog/wialon-integration-with-erp-architecture-and-pitfalls/)
