Começando
São dois endpoints: um para cotar e outro para confirmar o pedido. O ERP consulta antes de fechar o pedido, mostra valor e prazo ao cliente e grava a transportadora escolhida. A partir daí a Alladino cuida de etiqueta, rastreio e notificações — sem novas chamadas de API.
URL base
https://api.alladino.com.br/api/v1
O domínio responde por HTTPS com certificado Let's Encrypt válido; chamadas em HTTP são redirecionadas. Use sempre https:// — o ERP deve recusar conexão sem TLS.
Responsabilidades
| Quem | Faz o quê |
|---|---|
| ERP | Coleta peso e dimensões do pedido, valida o CEP, chama POST /cotacoes, exibe valor e prazo ao cliente e cria o pedido com a transportadora escolhida. |
| Alladino | Valida a entrada, consulta as transportadoras habilitadas para a conta, aplica a precificação e devolve a melhor opção. Fechado o pedido, o painel da Alladino gera a etiqueta em PDF, envia as notificações e mantém o rastreio. |
Fluxo em um olhar
Duas chamadas do seu lado. O resto acontece dentro da Alladino.
POST /cotacoes — quanto custa e em quantos dias
Você manda CEPs, peso e medidas, junto com o seu numero_pedido.
transportadora, valor, prazo_dias, cotacao_id e expira_em.O cliente vê o frete e fecha o pedido
Grave cotacao_id no pedido, junto com transportadora, valor e prazo. A cotação vale 60 minutos — passou disso, cote de novo.
POST /confirmacoes — o pedido saiu
Uma chamada curta com o mesmo numero_pedido da cotação, avisando que ele foi fechado. Só esse campo é obrigatório; quanto mais você mandar (destinatário, nota fiscal), menos precisamos buscar depois.
protocolo de recebimento.Etiqueta, notificações e rastreio
A etiqueta é gerada automaticamente no painel da Alladino, o cliente final é avisado a cada mudança de status e o rastreio fica atualizado. Nenhuma chamada de API a mais do seu lado.
Autenticação
Toda requisição precisa de uma API key da Alladino no header Authorization. A chave identifica o parceiro, define quais transportadoras serão consultadas e controla o limite de uso.
Authorization: Bearer alld_test_5f3c9a17b24e8d6091c7fa3b8e0d2c44
Content-Type: application/json
| Prefixo | Ambiente | Comportamento |
|---|---|---|
| alld_test_ | Sandbox | Para integrar e testar. Cotações reais, mas nenhum pedido é criado e nenhuma etiqueta é emitida. |
| alld_live_ | Produção | Liberado após o aceite da homologação. |
Guarde-a como variável de ambiente no servidor. Ela nunca deve ir para o front-end, para o repositório ou para o app do cliente. Se vazar, avise a equipe Alladino: revogamos e emitimos outra na hora, sem downtime da integração.
POST /cotacoes
Recebe os dados da encomenda e devolve a melhor opção de frete disponível para aquele trecho.
Corpo da requisição
| Campo | Tipo | Descrição | |
|---|---|---|---|
| numero_pedido | string | obrigatório | Identificador do pedido no seu sistema. Até 60 caracteres. Volta igual na resposta e é a chave que liga a cotação à confirmação — mande o mesmo valor em POST /confirmacoes. |
| cep_origem | string | obrigatório | CEP de saída, 8 dígitos. Pode enviar com hífen — normalizamos. |
| cep_destino | string | obrigatório | CEP de entrega, 8 dígitos. |
| peso_kg | number | obrigatório | Peso real da encomenda em quilos. De 0,1 a 30. |
| altura_cm | number | obrigatório | Altura do volume em centímetros, de 1 a 100. |
| largura_cm | number | obrigatório | Largura do volume em centímetros, de 1 a 100. |
| comprimento_cm | number | obrigatório | Comprimento do volume em centímetros, de 1 a 100. A ordem dos três lados não importa. |
| valor_declarado | number | opcional | Valor da mercadoria em reais, para seguro. Padrão 0. |
{
"numero_pedido": "PED-2026-001",
"cep_origem": "01310100",
"cep_destino": "20040020",
"peso_kg": 0.3,
"comprimento_cm": 16,
"largura_cm": 11,
"altura_cm": 7
}
Resposta 200 OK
{
"numero_pedido": "PED-2026-001",
"transportadora": "loggi",
"valor": 12.90,
"prazo_dias": 2,
// metadados — úteis para exibição e suporte
"modalidade": "Express",
"cotacao_id": "9f2c1e40-77a8-4b1d-9c3e-2f8a6b104d55",
"expira_em": "2026-09-01T15:46:12.385Z"
}
| Campo | Tipo | Descrição |
|---|---|---|
| numero_pedido | string | O mesmo identificador enviado na requisição. |
| transportadora | string | Código da transportadora escolhida. Grave no pedido — a Alladino usa esse código para despachar. |
| valor | number | Valor final do frete em reais, com duas casas. |
| prazo_dias | integer | Prazo de entrega em dias úteis. 0 significa entrega no mesmo dia. |
| modalidade | string | Express, Same Day ou Economic. |
| cotacao_id | string | UUID desta cotação. Guarde no pedido — é por ele que a equipe Alladino audita qualquer divergência. |
| expira_em | string | Data/hora ISO-8601 UTC até quando o valor é garantido (60 minutos). |
Os detalhes de como o preço foi formado são internos da Alladino: entram no cálculo e ficam no nosso histórico, mas não voltam na resposta. O ERP trabalha com as medidas que enviou e com o valor final.
Os quatro primeiros campos são o contrato estável. Podemos acrescentar metadados em versões futuras, então trate campos desconhecidos como ignoráveis em vez de falhar o parsing.
POST /confirmacoes
Avisa a Alladino que o orçamento virou pedido. A partir daí a etiqueta é gerada automaticamente no painel da Alladino — você não precisa pedir, baixar nem chamar mais nada.
Corpo da requisição
Só o numero_pedido é obrigatório. Todo o resto é opcional e existe para poupar consulta depois: quanto mais vier aqui, menos precisamos buscar no seu sistema para emitir a etiqueta.
| Campo | Tipo | Descrição | |
|---|---|---|---|
| numero_pedido | string | obrigatório | O mesmo identificador usado na cotação. É por ele que amarramos a confirmação ao orçamento. |
| cotacao_id | string | opcional | UUID devolvido pela cotação. Mais preciso que o numero_pedido quando houve mais de uma cotação para o mesmo pedido — mande os dois se tiver. |
| confirmado | boolean | opcional | Quando enviado, deve ser true. Só existe para deixar a intenção explícita no payload. |
| transportadora | string | opcional | O código da transportadora, se for diferente do que a cotação devolveu. |
| destinatario | object | opcional | Quem recebe: nome, documento, telefone, email e endereco (cep, logradouro, numero, complemento, bairro, cidade, uf). |
| nota_fiscal | object | opcional | Dados fiscais: numero, serie, chave. Se a NF ainda não saiu, mande depois — a etiqueta não depende dela. |
| observacao | string | opcional | Recado livre para a expedição. Até 500 caracteres. |
{
"numero_pedido": "PED-2026-001",
"confirmado": true,
// tudo abaixo é opcional
"cotacao_id": "9f2c1e40-77a8-4b1d-9c3e-2f8a6b104d55",
"destinatario": {
"nome": "Maria Souza",
"documento": "000.000.000-00",
"telefone": "11999990000",
"email": "maria@exemplo.com.br",
"endereco": {
"cep": "20040020",
"logradouro": "Av. Rio Branco",
"numero": "156",
"complemento": "sala 1201",
"bairro": "Centro",
"cidade": "Rio de Janeiro",
"uf": "RJ"
}
},
"nota_fiscal": { "numero": "123456", "serie": "1" },
"observacao": "Entregar em horário comercial"
}
Resposta 202 Accepted
{
"numero_pedido": "PED-2026-001",
"status": "recebido",
"protocolo": "3a71c0de-5f11-4a02-8e6d-9b7c1f204a88",
"recebido_em": "2026-09-02T14:03:51.204Z",
"mensagem": "Confirmação registrada. A etiqueta é gerada no painel da Alladino."
}
| Campo | Tipo | Descrição |
|---|---|---|
| status | string | recebido — a confirmação entrou na fila da expedição. |
| protocolo | string | UUID do recebimento. Guarde no pedido: é por ele que a equipe Alladino localiza a confirmação. |
| recebido_em | string | Data/hora ISO-8601 UTC em que a confirmação entrou. |
Se você não tiver certeza de que a confirmação chegou, mande de novo com o mesmo numero_pedido. Cada envio gera um protocolo próprio no histórico e a expedição trabalha com o mais completo — nada é duplicado na etiqueta.
400 VALIDACAO_FALHOU quando falta numero_pedido ou um campo veio no formato errado; 401 INVALIDO_CREDENTIALS para chave inválida; 405 para qualquer método diferente de POST.
Validações
A entrada é validada antes de qualquer consulta a transportadora, então erros de dados voltam em milissegundos. Valide também no seu lado para não gastar requisição.
| Campo | Mínimo | Máximo | Erro retornado |
|---|---|---|---|
| peso_kg | 0,1 kg | 30 kg | PESO_INVALIDO |
| altura_cm | 1 cm | 100 cm | DIMENSOES_INVALIDAS |
| largura_cm | 1 cm | 100 cm | DIMENSOES_INVALIDAS |
| comprimento_cm | 1 cm | 100 cm | DIMENSOES_INVALIDAS |
| altura + largura + comprimento | — | 200 cm | CAIXA_MUITO_GRANDE |
| cep_origem / cep_destino | 8 dígitos | 8 dígitos | VALIDACAO_FALHOU |
| numero_pedido | 1 caractere | 60 caracteres | VALIDACAO_FALHOU |
Os máximos seguem o limite de encomenda nacional dos Correios: nenhum lado acima de 100 cm, soma das três dimensões até 200 cm e peso até 30 kg. É o teto mais restritivo entre as transportadoras da rede, então um pacote aceito aqui é aceito por todas.
Erros
Todo erro devolve o mesmo formato. Use error.code na lógica do seu sistema e error.message para mostrar ao operador — a mensagem já vem escrita em português, pronta para exibição.
{
"error": {
"code": "PESO_INVALIDO",
"message": "Peso deve estar entre 0.1kg e 30kg"
}
}
| Código | HTTP | Significa | O que fazer |
|---|---|---|---|
| PESO_INVALIDO | 400 | Peso fora da faixa de 0,1 kg a 30 kg | Focar o campo de peso do pedido. |
| DIMENSOES_INVALIDAS | 400 | Altura, largura ou comprimento fora de 1 a 150 cm | Focar o campo de dimensões. A mensagem diz qual campo falhou. |
| CAIXA_MUITO_GRANDE | 400 | Soma das três dimensões acima de 200 cm | Dividir em mais volumes ou usar embalagem menor. |
| VALIDACAO_FALHOU | 400 | Campo obrigatório ausente, CEP inválido ou JSON malformado | A mensagem lista os campos. Corrigir e repetir. |
| INVALIDO_CREDENTIALS | 401 | API key ausente, inválida ou revogada | Conferir o header. Se persistir, solicitar nova chave. |
| LIMITE_EXCEDIDO | 429 | Passou de 1000 requisições na última hora | Aguardar e repetir com backoff. Considerar cache por CEP + faixa de peso. |
| INDISPONIVEL | 503 | Nenhuma transportadora atende o trecho, ou falha interna | Repetir em 60 segundos. Se insistir, exibir frete a combinar. |
Tratamento sugerido
se resposta.status != 200:
codigo = resposta.json().error.code
mensagem = resposta.json().error.message
mostrar_ao_operador(mensagem)
se codigo em ["PESO_INVALIDO"]: focar_campo("peso")
se codigo em ["DIMENSOES_INVALIDAS",
"CAIXA_MUITO_GRANDE"]: focar_campo("dimensoes")
se codigo em ["VALIDACAO_FALHOU"]: focar_campo("cep")
se codigo em ["LIMITE_EXCEDIDO",
"INDISPONIVEL"]: repetir_com_backoff()
Limites e validade
| Item | Valor | Observação |
|---|---|---|
| Rate limit | 1000 req/hora | Por API key, em janela deslizante. Cada resposta traz X-RateLimit-Limit e X-RateLimit-Remaining. |
| Validade da cotação | 60 minutos | Indicada em expira_em. Passado o prazo, cote de novo antes de fechar o pedido. |
| Tempo de resposta | ~1 a 3 s | Inclui o encaminhamento até o motor de cotação. Sobe quando os Correios são consultados em tempo real. Use timeout de 10 s. |
| Métodos aceitos | POST | Qualquer outro método devolve 405. |
Exemplos de código
Mesma chamada em quatro linguagens. Troque apenas a chave e o corpo.
export ALLADINO_URL="https://api.alladino.com.br/api/v1"
export ALLADINO_TOKEN="alld_test_sua_chave_aqui"
curl -X POST "$ALLADINO_URL/cotacoes" \
-H "Authorization: Bearer $ALLADINO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"numero_pedido": "TEST-001",
"cep_origem": "01310100",
"cep_destino": "20040020",
"peso_kg": 0.3,
"comprimento_cm": 16,
"largura_cm": 11,
"altura_cm": 7
}'
const resposta = await fetch(`${process.env.ALLADINO_URL}/cotacoes`, {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.ALLADINO_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
numero_pedido: pedido.codigo,
cep_origem: loja.cep,
cep_destino: pedido.cepEntrega,
peso_kg: pedido.pesoKg,
// medidas do volume, em centímetros
comprimento_cm: volume.comprimento,
largura_cm: volume.largura,
altura_cm: volume.altura,
}),
signal: AbortSignal.timeout(10000),
});
const dados = await resposta.json();
if (!resposta.ok) {
// dados.error.code | dados.error.message
throw new Error(dados.error.message);
}
// dados.transportadora, dados.valor, dados.prazo_dias
$ch = curl_init(getenv('ALLADINO_URL') . '/cotacoes');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('ALLADINO_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'numero_pedido' => $pedido['codigo'],
'cep_origem' => '01310100',
'cep_destino' => $pedido['cep'],
'peso_kg' => 0.3,
'comprimento_cm' => 16,
'largura_cm' => 11,
'altura_cm' => 7,
]),
]);
$corpo = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$dados = json_decode($corpo, true);
curl_close($ch);
if ($status !== 200) {
throw new \RuntimeException($dados['error']['message']);
}
import os, requests
resposta = requests.post(
f"{os.environ['ALLADINO_URL']}/cotacoes",
headers={
"Authorization": f"Bearer {os.environ['ALLADINO_TOKEN']}",
"Content-Type": "application/json",
},
json={
"numero_pedido": pedido.codigo,
"cep_origem": "01310100",
"cep_destino": pedido.cep_entrega,
"peso_kg": 0.3,
"comprimento_cm": 16,
"largura_cm": 11,
"altura_cm": 7,
},
timeout=10,
)
dados = resposta.json()
if resposta.status_code != 200:
raise RuntimeError(dados["error"]["message"])
frete = dados["valor"]
prazo = dados["prazo_dias"]