Integre fretes, pedidos e webhooks com simplicidade
A API Vai Envios conecta lojas, ERPs e marketplaces aos fluxos de cotação, pedidos, etiquetas e rastreamento com autenticação Bearer Token e respostas JSON previsíveis.
O que é a API Vai Envios?
É uma API REST para automatizar a jornada logística da sua operação: consultar frete, receber pedidos de uma loja integrada, acompanhar o status operacional e notificar seu sistema com webhooks.
Você não precisa integrar via programação.
O plugin oficial Vai Envios para WooCommerce está em homologação temporária.
Estamos finalizando os últimos ajustes desta integração. Em breve ela será liberada com mais segurança, estabilidade e uma experiência melhor para sua loja.
- Aguardar a liberação do plugin
- Gerar sua API Key
- Colar no WooCommerce após a homologação
Primeira integração em 10 minutos
Roteiro recomendado: 2 min para gerar uma chave production, 2 min para validar /me, 3 min para cotar, 2 min para criar pedido com Idempotency-Key e 1 min para testar webhooks no painel.
Comece em 4 passos
Acesse Dashboard > Integrações > Chaves API e crie uma chave de produção.
A chave completa aparece apenas uma vez. Guarde em um cofre de segredos ou variável de produção.
Envie o header Authorization: Bearer SUA_CHAVE nas rotas REST v1 protegidas. A exceção documentada é GET /api/v1/health, que é pública.
Comece por GET /api/v1/me para validar usuário, produção e prefixo público.
Teste endpoints sem sair do painel
Abra Dashboard > Integrações, cole uma API key válida ou inválida, escolha /me, /cep, /cotar ou /pedidos e veja status HTTP, tempo e JSON retornado. O playground chama a API real com Authorization: Bearer.
Header obrigatório
As rotas protegidas da API REST v1 exigem uma API key ativa no padrão Bearer Token. GET /api/v1/health é público e não exige token; GET /api/v1/me exige Authorization: Bearer.
Requisição válida
Authorization: Bearer ve_live_sua_chave
Requisição inválida
Authorization: ve_live_xxxxx
X-API-Key: ve_live_xxxxx
Authorization: Bearer chave_revogada
Idempotency-Key
Em operações de criação, envie Idempotency-Key com um valor único do seu pedido externo. Se houver timeout ou retry, repetir a mesma chave evita pedido duplicado e pode retornar 409 quando existir conflito real de ownership/dados.
Idempotency-Key: shopify-100045
GET /api/v1/me retorna os dados da conta.401 sem token, prefixo inválido, chave revogada ou inativa em rotas protegidas.Público GET /api/v1/health retorna 200 sem Authorization.Faça sua primeira chamada em menos de 1 minuto
Substitua ve_live_sua_chave pela chave criada no dashboard.
curl https://vaienvios.com.br/api/v1/me \
-H "Authorization: Bearer ve_live_sua_chave"
Resposta esperada
{
"success": true,
"user_id": 123,
"environment": "production",
"api_key_prefix": "ve_live_abcd1234",
"account_complete": false,
"origin_postcode": "",
"cep_origem": "",
"sender": {
"name": "Maria Silva",
"document": "12345678909",
"phone": "11999999999",
"email": "maria@loja.com.br",
"address": {
"cep": "",
"street": "",
"number": "",
"complement": "",
"district": "",
"city": "",
"state": ""
}
},
"capabilities": {
"cotacoes_sem_saldo": true,
"emissao_exige_regra_financeira": false,
"woocommerce_ready": false
},
"data": {
"user_id": 123,
"environment": "production",
"api_key_prefix": "ve_live_abcd1234",
"account_complete": false,
"origin_postcode": "",
"cep_origem": "",
"sender": {
"name": "Maria Silva",
"document": "12345678909",
"phone": "11999999999",
"email": "maria@loja.com.br",
"address": {
"cep": "",
"street": "",
"number": "",
"complement": "",
"district": "",
"city": "",
"state": ""
}
},
"capabilities": {
"cotacoes_sem_saldo": true,
"emissao_exige_regra_financeira": false,
"woocommerce_ready": false
}
}
}
Mapa de endpoints REST v1
/api/v1/healthHealth check público; não exige token.
/api/v1/meValida a chave API atual; exige Bearer Token.
/api/v1/servicosLista serviços disponíveis: PAC e SEDEX.
/api/v1/cep/{cep}Consulta endereço básico de um CEP.
/api/v1/cotacoesCalcula opções de frete para origem, destino e pacote.
/api/v1/pedidosCria pedido idempotente de loja integrada.
/api/v1/pedidos/{pedido_uuid}Consulta status do pedido e status de envio.
/api/v1/pedidos/external/{external_order_id}Consulta pedido pelo ID da loja.
/api/v1/pedidos/{pedido_uuid}/etiquetaConsulta link de etiqueta e DACE quando disponíveis.
/api/v1/pedidos/{pedido_uuid}/emissaoConsulta status da emissão.
/api/v1/pedidos/{pedido_uuid}/confirmar-pagamentoConfirma pagamento informado pela plataforma integrada.
/api/v1/etiquetasValida pedido pago e solicita emissão de etiqueta no fluxo interno.
/api/v1/rastreio/{codigo}Consulta rastreio/pedido pertencente ao dono da API key.
POST /api/v1/cotacoes
Use este endpoint para mostrar opções de frete no checkout antes de criar o pedido.
Payload
{
"cep_origem": "06700000",
"cep_destino": "01001000",
"peso": 1.2,
"altura": 10,
"largura": 20,
"comprimento": 30,
"valor_declarado": 100.00
}
Resposta
{
"success": true,
"data": {
"quote_id": "q_1234567890abcdef12345678",
"environment": "production",
"currency": "BRL",
"servicos": [
{ "codigo": "SEDEX", "nome": "SEDEX", "prazo": 2, "valor": 29.90 },
{ "codigo": "PAC", "nome": "PAC", "prazo": 5, "valor": 22.40 }
]
},
"quote_id": "q_1234567890abcdef12345678",
"servicos": [
{ "codigo": "SEDEX", "nome": "SEDEX", "prazo": 2, "valor": 29.90 },
{ "codigo": "PAC", "nome": "PAC", "prazo": 5, "valor": 22.40 }
]
}
Erros comuns: 401 sem chave, 405 método incorreto, 422 CEP/dimensões inválidos.
POST /api/v1/pedidos
Cria um pedido de loja integrada. Se o mesmo external_order_id ou header Idempotency-Key já existir para o mesmo usuário da chave, a resposta retorna o registro existente de forma idempotente.
Payload sanitizado
{
"external_order_id": "WC-100045",
"platform": "woocommerce",
"buyer": {
"name": "Maria Silva",
"email": "maria@loja.com.br"
},
"recipient": {
"name": "Maria Silva",
"document": "12345678909",
"cep": "01001000",
"street": "Praça da Sé",
"number": "100",
"district": "Sé",
"city": "São Paulo",
"state": "SP"
},
"package": {
"weight": 1.2,
"height": 10,
"width": 20,
"length": 30
},
"shipping": {
"service": "SEDEX",
"amount_paid": 29.90
}
}
Resposta 201 Created
{
"success": true,
"order_id": 987,
"external_order_id": "WC-100045",
"status": "received",
"idempotent": false,
"data": {
"order_id": 987,
"pedido_uuid": "2f1f4c7a-6df1-4ef9-91d8-9df4f7a6f001",
"external_order_id": "WC-100045",
"platform": "woocommerce",
"status": "received",
"shipping_status": "pending",
"shipping_service": "SEDEX",
"quote_id": "q_1234567890abcdef12345678",
"shipping_amount_paid": 29.9,
"amount_paid": 29.9,
"idempotency_key": "shopify-100045"
}
}
Idempotency-Key em retries de criação para impedir duplicidade. A API também mantém fallback por external_order_id por usuário.GET /api/v1/me retorna account_complete: false e woocommerce_ready: false, a chave está válida e a conta está conectada, mas ainda falta completar os dados operacionais do remetente, especialmente CEP/endereço de origem, para operar no WooCommerce.Confirmar pagamento
curl -X POST https://vaienvios.com.br/api/v1/pedidos/2f1f4c7a-6df1-4ef9-91d8-9df4f7a6f001/confirmar-pagamento \
-H "Authorization: Bearer ve_live_sua_chave" \
-H "Content-Type: application/json" \
-d '{"payment_reference":"mp-123","amount_paid":29.90,"paid_at":"2026-06-10T12:00:00Z"}'
Resposta de confirmação
{
"success": true,
"data": {
"pedido_uuid": "2f1f4c7a-6df1-4ef9-91d8-9df4f7a6f001",
"status": "payment_confirmed",
"shipping_status": "ready_for_label",
"label_status": "ready_for_internal_generation"
}
}
Contratos públicos v1
Todos os endpoints protegidos usam Authorization: Bearer ve_live_sua_chave ou uma chave ve_live_..., recebem/enviam JSON e seguem o envelope de sucesso {"success": true, "data": {...}}. Erros seguem {"success": false, "error": {"code": "...", "message": "...", "http_status": 422}}. A API pública opera em produção: Cotação → Pedido congelado → Pagamento confirmado → Geração real da etiqueta nos Correios. Cotações e criação de pedido não geram etiqueta antes da confirmação de pagamento.
curl https://vaienvios.com.br/api/v1/me \
-H "Authorization: Bearer ve_live_sua_chave"
curl "https://vaienvios.com.br/api/v1/pedidos/external/WC-100045" \
-H "Authorization: Bearer ve_live_sua_chave"
curl "https://vaienvios.com.br/api/v1/pedidos/2f1f4c7a-6df1-4ef9-91d8-9df4f7a6f001/etiqueta" \
-H "Authorization: Bearer ve_live_sua_chave"
curl "https://vaienvios.com.br/api/v1/pedidos/2f1f4c7a-6df1-4ef9-91d8-9df4f7a6f001/emissao" \
-H "Authorization: Bearer ve_live_sua_chave"
POST /api/v1/etiquetas
Valida que o pedido pertence ao usuário da API key e que o frete já foi pago pelo comprador final antes de encaminhar a emissão para o fluxo interno atual.
{
"pedido_uuid": "9f8f1c62-0000-4000-9000-123456789abc"
}
Resposta 202 Accepted
{
"success": true,
"data": {
"pedido_uuid": "9f8f1c62-0000-4000-9000-123456789abc",
"external_order_id": "WC-100045",
"environment": "production",
"shipping_status": "ready_for_label",
"label_status": "ready_for_internal_generation",
"status_url": "https://vaienvios.com.br/api/v1/etiquetas/9f8f1c62-0000-4000-9000-123456789abc/status",
"label_url": null,
"dace_url": null,
"idempotency_key": "shopify-100045",
"message": "Pedido validado e preparado para fila interna de emissão."
}
}
Consulta do pedido após emissão/processamento
curl https://vaienvios.com.br/api/v1/pedidos/2f1f4c7a-6df1-4ef9-91d8-9df4f7a6f001 \
-H "Authorization: Bearer ve_live_sua_chave"
{
"success": true,
"data": {
"order_id": 987,
"pedido_uuid": "2f1f4c7a-6df1-4ef9-91d8-9df4f7a6f001",
"external_order_id": "WC-100045",
"platform": "woocommerce",
"status": "payment_confirmed",
"shipping_status": "ready_for_label",
"label_status": "ready_for_internal_generation",
"shipping_service": "SEDEX",
"quote_id": "q_1234567890abcdef12345678",
"shipping_amount_paid": 29.9,
"amount_paid": 29.9,
"idempotency_key": "shopify-100045",
"label_status": "ready_for_internal_generation",
"created_at": "2026-06-10 12:00:00",
"updated_at": "2026-06-10 12:01:00"
}
}
GET /api/v1/rastreio/{codigo}
Consulta somente pedidos ou etiquetas pertencentes ao dono da chave Bearer. A rota pública real é por caminho, /api/v1/rastreio/{codigo}; códigos de outras contas retornam 404.
curl "https://vaienvios.com.br/api/v1/rastreio/WC-100045" \
-H "Authorization: Bearer ve_live_sua_chave"
Erros comuns: 404 quando o código não existe ou pertence a outro usuário; 422 quando o código é inválido.
Receba eventos automaticamente
Webhook é um POST enviado pelo Vai Envios para o seu sistema quando um evento relevante acontece. Seu servidor recebe o JSON, valida a assinatura e responde HTTP 200 para confirmar recebimento.
Eventos preparados
Headers enviados
Content-Type: application/json
User-Agent: VaiEnvios-Webhooks/1.0
X-Vai-Envios-Event: order.received
X-Vai-Envios-Signature: sha256=assinatura_hmac_sha256
X-Vai-Envios-Webhook-Key: segredo_do_webhook
X-Vai-Envios-Delivery: id_da_entrega
Payload sanitizado
{
"event": "order.received",
"created_at": "2026-06-10T12:00:00Z",
"data": {
"order_id": 987,
"pedido_uuid": "2f1f4c7a-6df1-4ef9-91d8-9df4f7a6f001",
"external_order_id": "WC-100045",
"status": "received",
"shipping_status": "pending"
}
}
Validação da assinatura em PHP
$body = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_VAI_ENVIOS_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $body, getenv('VAI_ENVIOS_WEBHOOK_SECRET'));
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('invalid signature');
}
http_response_code(200);
echo 'ok';
Código pronto para copiar
cURL
curl -X POST https://vaienvios.com.br/api/v1/cotacoes \
-H "Authorization: Bearer ve_live_sua_chave" \
-H "Content-Type: application/json" \
-d '{
"cep_origem": "06700000",
"cep_destino": "01001000",
"peso": 1.2,
"altura": 10,
"largura": 20,
"comprimento": 30,
"valor_declarado": 100
}'
PHP
<?php
$payload = [
'cep_origem' => '06700000',
'cep_destino' => '01001000',
'peso' => 1.2,
'altura' => 10,
'largura' => 20,
'comprimento' => 30,
'valor_declarado' => 100,
];
$ch = curl_init('https://vaienvios.com.br/api/v1/cotacoes');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ve_live_sua_chave',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
print_r($data);
JavaScript
const response = await fetch('https://vaienvios.com.br/api/v1/cotacoes', {
method: 'POST',
headers: {
Authorization: 'Bearer ve_live_sua_chave',
'Content-Type': 'application/json'
},
body: JSON.stringify({
cep_origem: '06700000',
cep_destino: '01001000',
peso: 1.2,
altura: 10,
largura: 20,
comprimento: 30,
valor_declarado: 100
})
});
console.log(await response.json());
Node.js
import fetch from 'node-fetch';
const response = await fetch('https://vaienvios.com.br/api/v1/pedidos', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VAI_ENVIOS_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
external_order_id: 'WC-100045',
platform: 'woocommerce',
buyer: { name: 'Maria Silva', email: 'maria@loja.com.br' },
recipient: {
name: 'Maria Silva',
document: '12345678909',
cep: '01001000',
street: 'Praça da Sé',
number: '100',
district: 'Sé',
city: 'São Paulo',
state: 'SP'
},
package: { weight: 1.2, height: 10, width: 20, length: 30 },
shipping: { service: 'SEDEX', amount_paid: 29.9 }
})
});
console.log(await response.json());
Python
import os
import requests
payload = {
'cep_origem': '06700000',
'cep_destino': '01001000',
'peso': 1.2,
'altura': 10,
'largura': 20,
'comprimento': 30,
'valor_declarado': 100,
}
response = requests.post(
'https://vaienvios.com.br/api/v1/cotacoes',
headers={
'Authorization': f"Bearer {os.environ['VAI_ENVIOS_API_KEY']}",
'Content-Type': 'application/json',
},
json=payload,
timeout=15,
)
print(response.json())
Shopify
// Shopify app/backend: transforme um pedido Shopify em pedido Vai Envios.
const shopifyOrder = { id: 100045, email: 'cliente@loja.com' };
const response = await fetch('https://vaienvios.com.br/api/v1/pedidos', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VAI_ENVIOS_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': `shopify-${shopifyOrder.id}`
},
body: JSON.stringify({
external_order_id: `shopify-${shopifyOrder.id}`,
platform: 'shopify',
buyer: { name: 'Cliente Shopify', email: shopifyOrder.email },
recipient: { name: 'Cliente Shopify', document: '12345678909', cep: '01001000', street: 'Praça da Sé', number: '100', district: 'Sé', city: 'São Paulo', state: 'SP' },
package: { weight: 1.2, height: 10, width: 20, length: 30 },
shipping: { service: 'SEDEX', amount_paid: 29.9 }
})
});
console.log(await response.json());
Nuvemshop
// Nuvemshop/Tiendanube app backend: use o ID do pedido como idempotência.
$pedidoNuvemshopId = '987654321';
$payload = [
'external_order_id' => 'nuvemshop-' . $pedidoNuvemshopId,
'platform' => 'nuvemshop',
'buyer' => ['name' => 'Cliente Nuvemshop', 'email' => 'cliente@loja.com'],
'recipient' => ['name' => 'Cliente Nuvemshop', 'document' => '12345678909', 'cep' => '01001000', 'street' => 'Praça da Sé', 'number' => '100', 'district' => 'Sé', 'city' => 'São Paulo', 'state' => 'SP'],
'package' => ['weight' => 1.2, 'height' => 10, 'width' => 20, 'length' => 30],
'shipping' => ['service' => 'PAC', 'amount_paid' => 22.4],
];
// Envie com Authorization: Bearer e Idempotency-Key: nuvemshop-987654321
Códigos de erro e como resolver
Formato padrão
{
"success": false,
"error": {
"code": "invalid_field",
"message": "O campo package.weight deve ser maior que zero.",
"http_status": 422
}
}
Como tratar 429 Too Many Requests
Planeje sua integração para lidar com limites por IP, usuário e API key. Ao receber 429, aguarde antes de repetir a chamada e use backoff exponencial para evitar novas recusas.
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{
"success": false,
"error": {
"code": "rate_limit_exceeded",
"message": "Muitas requisições. Aguarde antes de tentar novamente.",
"http_status": 429
}
}
Teste endpoints pelo dashboard
A estrutura segura já existe no Dashboard > Integrações: informe sua API key, escolha o endpoint, edite o payload e veja HTTP status, tempo de resposta e JSON formatado.
Abrir playgroundPerguntas frequentes
Uso WooCommerce. Preciso programar?
Não. Baixe o plugin oficial, gere sua API Key e cole no WooCommerce. A integração por API é indicada para sistemas próprios ou personalizados.
Preciso ter saldo?
Nem sempre. Quando o comprador final estiver pagando o frete, o usuário da API pode operar sem saldo próprio. Saldo é necessário apenas quando o próprio usuário utilizar diretamente os serviços internos do Vai Envios.
Posso integrar com WooCommerce?
Sim. O caminho recomendado para lojistas é o plugin oficial; a API continua disponível para integrações customizadas.
Posso integrar com Nuvemshop?
Sim. A integração pode ser feita por backend intermediário usando Bearer Token.
Posso integrar com Shopify?
Sim. Nunca exponha a API key no tema ou no front-end; use seu app/backend.
Preciso de aprovação manual?
O fluxo atual permite criar chaves pelo dashboard. Para operar em produção, mantenha seus dados cadastrais e configurações logísticas atualizados.
Como gero minha chave?
Acesse sua conta, abra Dashboard > Integrações > Chaves API, informe um nome e copie a chave de produção completa no momento da criação.
Como recebo webhooks?
Cadastre uma URL pública HTTPS no Dashboard > Integrações > Webhooks, copie a secret, valide X-Vai-Envios-Signature e responda HTTP 200.
Promover etiqueta e rastreio detalhado para contrato público
Após esta reestruturação de documentação, o próximo passo recomendado é expor endpoints REST públicos e versionados para emissão de etiqueta, download de PDF e rastreamento detalhado por código, reaproveitando a infraestrutura interna existente sem quebrar o fluxo atual.