Sua primeira etiqueta
Neste guia você emite uma etiqueta completa pela API, do começo ao fim, no sandbox. Nada aqui gera cobrança nem etiqueta válida nas transportadoras, então pode testar à vontade.
O caminho tem seis passos:
| Passo | Chamada | O que acontece |
|---|---|---|
| 1. Cotar | POST /api/v0/calculator | Preço, prazo e caixa ideal de cada serviço |
| 2. Criar a etiqueta | POST /api/v0/cart | A etiqueta nasce com status pending |
| 3. Pagar | POST /api/v0/checkout | Debita o saldo da carteira e libera a etiqueta |
| 4. Imprimir | POST /api/v0/tag/print | Devolve a URL do PDF |
| 5. Consultar | GET /api/v0/order/info/{id} | Status e código de rastreio |
| 6. Acompanhar | POST /api/v0/webhook | A SuperFrete avisa você a cada mudança |
Antes de começar
Você precisa de quatro coisas no sandbox:
- Uma conta em sandbox.superfrete.com, com o cadastro completo e um número de celular salvo no perfil. Sem celular, a criação da etiqueta falha com
user.phone is required.. - Um token de sandbox. Siga o passo a passo em Primeiros passos.
- Saldo na carteira de testes, para pagar a etiqueta. O Pix é simulado: veja Adicione saldo no sandbox.
- Um
User-Agentno formatoNomeDaAplicacao/versão (email@dominio.com).
Deixe o token e o User-Agent em variáveis de ambiente para copiar os exemplos sem editar:
export SUPERFRETE_TOKEN="cole-o-token-de-sandbox-aqui"
export SUPERFRETE_UA="MinhaLoja/1.0 (dev@minhaloja.com.br)"
export SUPERFRETE_API="https://sandbox.superfrete.com"
1. Cote o frete
Informe os CEPs de origem e destino, os serviços que quer comparar e os produtos do pedido. Com products, a API calcula a menor caixa que acomoda tudo.
curl --request POST \
--url "$SUPERFRETE_API/api/v0/calculator" \
--header "Authorization: Bearer $SUPERFRETE_TOKEN" \
--header "User-Agent: $SUPERFRETE_UA" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"from": { "postal_code": "01153000" },
"to": { "postal_code": "20020050" },
"services": "1,2,17",
"options": { "own_hand": false, "receipt": false, "insurance_value": 0, "use_insurance_value": false },
"products": [
{ "quantity": 2, "weight": 0.3, "height": 4, "width": 12, "length": 17 }
]
}'
A resposta é uma lista, com um item por serviço. Escolha um e anote duas coisas: o id do serviço e a caixa em packages[0].
[
{
"id": 1,
"name": "PAC",
"price": 18.61,
"delivery_time": 5,
"packages": [
{
"format": "box",
"dimensions": { "height": "8", "width": "16", "length": "24" },
"weight": "0.6"
}
],
"has_error": false
}
]
No próximo passo, envie em volumes a caixa devolvida aqui (packages[0]), e não as medidas de cada produto. Assim a etiqueta sai exatamente com as medidas que foram cotadas.
Se um serviço vier com has_error: true, ele não atende aquele envio. O motivo está no campo error.
2. Crie a etiqueta
Envie remetente, destinatário, o serviço escolhido, a caixa e o conteúdo do pacote. Neste exemplo usamos declaração de conteúdo, que é o caminho mais simples para testar: basta enviar a lista de products.
curl --request POST \
--url "$SUPERFRETE_API/api/v0/cart" \
--header "Authorization: Bearer $SUPERFRETE_TOKEN" \
--header "User-Agent: $SUPERFRETE_UA" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"from": {
"name": "Loja Exemplo",
"address": "Rua Vitorino Carmilo",
"number": "100",
"district": "Barra Funda",
"city": "São Paulo",
"state_abbr": "SP",
"postal_code": "01153000"
},
"to": {
"name": "Maria Silva",
"address": "Rua Primeiro de Março",
"number": "50",
"district": "Centro",
"city": "Rio de Janeiro",
"state_abbr": "RJ",
"postal_code": "20020050",
"email": "maria@example.com",
"document": "12345678909"
},
"service": 1,
"products": [
{ "name": "Camiseta", "quantity": 2, "unitary_value": 59.9 }
],
"volumes": { "height": 8, "width": 16, "length": 24, "weight": 0.6 },
"options": {
"insurance_value": null,
"receipt": false,
"own_hand": false
},
"platform": "MinhaLoja"
}'
{
"id": "r8p3dhqjn4I0tBpnvkpU",
"price": 18.61,
"status": "pending"
}
Guarde o id: é ele que você usa em todos os passos seguintes. A etiqueta também já aparece em Etiquetas no painel do sandbox, aguardando pagamento.
Os cuidados com nome do remetente, state_abbr, bairro e documento estão em Cálculo de frete e etiquetas.
3. Pague com o saldo
curl --request POST \
--url "$SUPERFRETE_API/api/v0/checkout" \
--header "Authorization: Bearer $SUPERFRETE_TOKEN" \
--header "User-Agent: $SUPERFRETE_UA" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{ "orders": ["r8p3dhqjn4I0tBpnvkpU"] }'
{
"success": true,
"purchase": {
"status": "paid",
"orders": [
{
"id": "r8p3dhqjn4I0tBpnvkpU",
"price": 18.61,
"service_id": 1,
"tracking": "AA123456785BR",
"print": { "url": "" }
}
]
}
}
Se faltar saldo, a API responde 409 com Sem saldo na carteira!. Recarregue a carteira de testes e chame de novo.
4. Imprima
curl --request POST \
--url "$SUPERFRETE_API/api/v0/tag/print" \
--header "Authorization: Bearer $SUPERFRETE_TOKEN" \
--header "User-Agent: $SUPERFRETE_UA" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{ "orders": ["r8p3dhqjn4I0tBpnvkpU"] }'
{ "url": "https://sandbox.superfrete.com/_etiqueta/pdf/eyJvcmRlcl9pZCI6..." }
Abra a URL para ver o PDF. Você pode enviar vários IDs em orders para receber todas as etiquetas em um arquivo só.
5. Consulte o pedido
curl --request GET \
--url "$SUPERFRETE_API/api/v0/order/info/r8p3dhqjn4I0tBpnvkpU" \
--header "Authorization: Bearer $SUPERFRETE_TOKEN" \
--header "User-Agent: $SUPERFRETE_UA" \
--header "Accept: application/json"
A partir do status released, o campo tracking traz o código de rastreio. Os status possíveis estão em Status da etiqueta.
6. Acompanhe por webhook
Em vez de consultar o pedido de tempos em tempos, peça para a SuperFrete avisar você. Para testar, gere uma URL pública temporária em um serviço como webhook.site e cadastre um Webhook App:
curl --request POST \
--url "$SUPERFRETE_API/api/v0/webhook" \
--header "Authorization: Bearer $SUPERFRETE_TOKEN" \
--header "User-Agent: $SUPERFRETE_UA" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
"name": "Teste sandbox",
"url": "https://webhook.site/sua-url-unica",
"events": ["order.created", "order.released", "order.generated", "order.posted", "order.delivered", "order.cancelled"]
}'
Guarde o secret_token da resposta: é com ele que você valida a assinatura de cada notificação. Agora repita os passos 2 e 3 com uma etiqueta nova e veja os eventos chegarem.
No sandbox, nenhum pacote é postado nem entregue de verdade. Por isso os eventos de criação, pagamento e geração da etiqueta chegam, mas order.posted e order.delivered normalmente não.
Como validar a assinatura e responder do jeito certo está no guia de webhooks.
Tudo junto, em Node.js
O script abaixo faz os passos 1 a 5 em sequência. Rode com Node.js 18 ou mais recente:
- Node.js
const API = process.env.SUPERFRETE_API ?? 'https://sandbox.superfrete.com';
const headers = {
Authorization: `Bearer ${process.env.SUPERFRETE_TOKEN}`,
'User-Agent': process.env.SUPERFRETE_UA ?? 'MinhaLoja/1.0 (dev@minhaloja.com.br)',
'Content-Type': 'application/json',
Accept: 'application/json',
};
async function call(method, path, body) {
const response = await fetch(`${API}${path}`, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
});
const data = await response.json();
if (!response.ok) throw new Error(`${method} ${path} -> ${response.status}: ${JSON.stringify(data)}`);
return data;
}
// 1. Cotar
const quotes = await call('POST', '/api/v0/calculator', {
from: { postal_code: '01153000' },
to: { postal_code: '20020050' },
services: '1,2,17',
options: { own_hand: false, receipt: false, insurance_value: 0, use_insurance_value: false },
products: [{ quantity: 2, weight: 0.3, height: 4, width: 12, length: 17 }],
});
const quote = quotes.find((q) => !q.has_error);
const box = quote.packages[0];
console.log(`Serviço ${quote.name}: R$ ${quote.price} em ${quote.delivery_time} dias úteis`);
// 2. Criar a etiqueta com a caixa da cotação
const shipment = await call('POST', '/api/v0/cart', {
from: {
name: 'Loja Exemplo', address: 'Rua Vitorino Carmilo', number: '100',
district: 'Barra Funda', city: 'São Paulo', state_abbr: 'SP', postal_code: '01153000',
},
to: {
name: 'Maria Silva', address: 'Rua Primeiro de Março', number: '50', district: 'Centro',
city: 'Rio de Janeiro', state_abbr: 'RJ', postal_code: '20020050',
email: 'maria@example.com', document: '12345678909',
},
service: quote.id,
products: [{ name: 'Camiseta', quantity: 2, unitary_value: 59.9 }],
volumes: {
height: Number(box.dimensions.height),
width: Number(box.dimensions.width),
length: Number(box.dimensions.length),
weight: Number(box.weight),
},
options: { insurance_value: null, receipt: false, own_hand: false },
platform: 'MinhaLoja',
});
console.log(`Etiqueta ${shipment.id} criada (${shipment.status})`);
// 3. Pagar com o saldo
await call('POST', '/api/v0/checkout', { orders: [shipment.id] });
// 4. Imprimir
const { url } = await call('POST', '/api/v0/tag/print', { orders: [shipment.id] });
console.log(`PDF: ${url}`);
// 5. Consultar
const order = await call('GET', `/api/v0/order/info/${shipment.id}`);
console.log(`Status: ${order.status}, rastreio: ${order.tracking ?? 'ainda não disponível'}`);
Indo para produção
Quando o fluxo estiver redondo no sandbox:
- Gere um token na página de integrações de produção.
- Troque a URL base para
https://api.superfrete.com. - Recarregue a carteira de produção com Pix em Perfil > Carteira, ou pague as etiquetas pelo painel.
- Cadastre o Webhook App de produção. Webhooks do sandbox e de produção são independentes.
- Revise as regras de cada transportadora antes de liberar Jadlog, Loggi ou J&T.
Ficou com alguma dúvida? Escreva para integracao@superfrete.com ou fale com a gente pelo chat.