Depois que o pedido sai, a pergunta mais comum no atendimento de qualquer loja virtual é: “cadê a minha encomenda?”. Automatizar o rastreio reduz chamados, melhora a experiência do cliente e permite avisar sobre atrasos antes que ele reclame. Neste tutorial você vai aprender a rastrear encomendas dos Correios com Python usando a API Encomendas Correios da APIBrasil.
O que a API Encomendas Correios devolve
A API fica na categoria Serviços Digitais e custa R$ 0,04 por consulta em produção, conforme o catálogo. A partir do código de rastreio, ela devolve a lista objetos, e cada objeto traz:
| Campo | Descrição |
|---|---|
codObjeto | O código de rastreio |
dtPrevista | Data prevista de entrega |
bloqueioObjeto | Se o objeto está bloqueado |
eventos | Histórico de movimentações |
eventos[].descricao e detalhe | O que aconteceu com o objeto |
eventos[].dtHrCriado | Data e hora do evento |
eventos[].codigo e tipo | Código do evento, útil para automações |
eventos[].unidade | Unidade dos Correios, com tipo, cidade e UF |
Pré-requisitos
- Python 3.9 ou mais novo, com a biblioteca
requests(pip install requests). - Bearer Token da APIBrasil, em Credenciais no painel. Se ainda não tem, veja os primeiros passos.
Passo 1: a chamada
POST https://gateway.apibrasil.io/api/v2/consulta/rastreio/credits
Authorization: Bearer SEU_TOKEN
Content-Type: application/json
{
"tipo": "rastreio",
"code": "AN 100 867 266 BR",
"homolog": true
}
O campo do código se chama code, não codigo. O exemplo do catálogo mostra o código com espaços, mas vamos normalizar para o formato padrão de 13 caracteres (duas letras, nove números e duas letras).
Passo 2: entenda a resposta em homologação
Em homologação, esta API devolve um objeto simulado, com datas no ano 2099 e cidade fictícia, e deixa isso explícito no campo ambiente. É ótimo para desenvolver a tela sem gastar crédito, mas lembre que os eventos não são reais.

Passo 3: o script de rastreio
Crie o arquivo rastreio.py:
import os
import re
import sys
from datetime import datetime
import requests
URL = "https://gateway.apibrasil.io/api/v2/consulta/rastreio/credits"
def normalizar_codigo(codigo):
c = re.sub(r"\s", "", codigo).upper()
if not re.fullmatch(r"[A-Z]{2}\d{9}[A-Z]{2}", c):
raise ValueError(f"Código de rastreio inválido: {codigo}")
return c
def rastrear(codigo):
resp = requests.post(
URL,
json={
"tipo": "rastreio",
"code": normalizar_codigo(codigo),
"homolog": os.getenv("APIBRASIL_HOMOLOG", "true") == "true",
},
headers={"Authorization": f"Bearer {os.environ['APIBRASIL_TOKEN']}"},
timeout=120,
)
if resp.status_code == 402:
raise RuntimeError("Saldo insuficiente na APIBrasil")
resp.raise_for_status()
corpo = resp.json()
if corpo.get("error"):
raise RuntimeError(corpo.get("message", "Erro no rastreio"))
return corpo["data"].get("objetos", [])
def data_br(iso):
return datetime.fromisoformat(iso).strftime("%d/%m %H:%M")
if __name__ == "__main__":
for objeto in rastrear(sys.argv[1]):
previsao = objeto.get("dtPrevista")
prev = datetime.fromisoformat(previsao).strftime("%d/%m/%Y") if previsao else "-"
print(f"Objeto {objeto['codObjeto']} · previsão {prev}\n")
for ev in objeto.get("eventos", []):
unidade = ev.get("unidade", {})
end = unidade.get("endereco", {})
print(f"{data_br(ev['dtHrCriado'])} {ev['descricao']}")
print(f" {unidade.get('tipo', '')} · {end.get('cidade', '')}/{end.get('uf', '')}")
Passo 4: rode o rastreio
export APIBRASIL_TOKEN="seu_token_aqui"
python rastreio.py AN100867266BR

Passo 5: avise o cliente automaticamente
O verdadeiro ganho está em monitorar os pedidos e agir quando algo muda. A lógica é:
- Guarde no banco, para cada pedido, o código de rastreio e o
dtHrCriadodo último evento visto. - Uma tarefa agendada (cron, Celery, GitHub Actions) consulta os pedidos em trânsito algumas vezes por dia.
- Se o evento mais recente for novo, avise o cliente por e-mail, SMS ou WhatsApp.
- Quando a descrição indicar entrega, marque o pedido como entregue e pare de consultar.
def verificar_pedido(pedido):
objetos = rastrear(pedido.codigo)
if not objetos or not objetos[0].get("eventos"):
return
ultimo = objetos[0]["eventos"][0]
if ultimo["dtHrCriado"] != pedido.ultimo_evento:
pedido.ultimo_evento = ultimo["dtHrCriado"]
pedido.save()
notificar_cliente(pedido, ultimo["descricao"])
if "entregue" in ultimo["descricao"].lower():
pedido.status = "entregue"
pedido.save()
Para o aviso por SMS, veja o tutorial de envio de SMS com PHP. Para WhatsApp, veja como enviar mensagens de WhatsApp com Node.js.
Boas práticas
- Não consulte demais: cada consulta custa. Três ou quatro verificações por dia por pedido costumam bastar.
- Pare de consultar pedidos entregues e os que estão parados há muitos dias (esses vão para o atendimento).
- Confira a ordem dos eventos na sua conta antes de assumir que o primeiro é o mais recente. Se precisar, ordene por
dtHrCriado.
Perguntas frequentes
Funciona com qualquer código dos Correios?
A API recebe o código de rastreio do objeto. Códigos no padrão de 13 caracteres, como AN100867266BR, são os mais comuns em encomendas nacionais.
Por que a homologação mostra 2099 e cidade “CIDADE-NULA”?
Porque, nesta API, a homologação devolve dados simulados de propósito. Para ver eventos reais, rode em produção com um código verdadeiro.
Próximos passos
Combine o rastreio com o cálculo de distância entre CEPs para estimar prazos, ou veja como tratar erros e saldo em produção.
![]()









