REST · OpenAPI 3
A API do DeCA, gratuita e documentada
Emita, modifique, conclua e anule o DeCA a partir do seu TMS, ERP ou script. A web e o bot de WhatsApp utilizam exatamente a mesma API.
Comece em três passos
Desenvolva com uma chave de teste e mude para a de produção quando tudo funcionar.
Crie uma chave de teste
Registe-se gratuitamente e, como proprietário, vá a Empresa › Chaves de API. As chaves de teste começam por deca_test_ e só são mostradas uma vez.
Valide o seu primeiro DeCA
Envie o conteúdo para /api/v1/decas/validate. Passa pelas mesmas verificações que na emissão, sem guardar nada.
Emita e passe para produção
Chame /api/v1/decas e guarde o url que devolve: é o link do QR. Depois crie uma chave deca_live_ para DeCA válidos.
Exemplo: validar e emitir um DeCA
# 1. Check it without issuing anything
curl -X POST https://api.deca.routyn.com/api/v1/decas/validate \
-H "Authorization: Bearer $DECA_API_KEY" \
-H "Content-Type: application/json" \
-d @deca.json
# 2. Issue it (a retry with the same external_ref returns the same DeCA)
curl -X POST https://api.deca.routyn.com/api/v1/decas \
-H "Authorization: Bearer $DECA_API_KEY" \
-H "Content-Type: application/json" \
-d @deca.json
# deca.json
{
"external_ref": "TRIP-2026-1012-A",
"data": {
"shipper_name": "Logística Ibérica S.L.",
"shipper_tax_id": "B12345678",
"shipper_address": "Calle Mayor 10, 28013 Madrid",
"carrier_name": "Transportes Ejemplo S.A.",
"carrier_tax_id": "A87654321",
"vehicle_plate": "1234 KLM",
"transport_date": "2026-10-12",
"lines": [
{
"origin": "Polígono Industrial Las Mercedes, 28022 Madrid",
"destination": "Puerto de Valencia, 46024 Valencia",
"goods": "Palés de bebidas",
"weight_kg": 12400
}
]
}
}import os, requests
API = "https://api.deca.routyn.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['DECA_API_KEY']}"}
body = {
"external_ref": "TRIP-2026-1012-A",
"data": {
"shipper_name": "Logística Ibérica S.L.",
"shipper_tax_id": "B12345678",
"shipper_address": "Calle Mayor 10, 28013 Madrid",
"carrier_name": "Transportes Ejemplo S.A.",
"carrier_tax_id": "A87654321",
"vehicle_plate": "1234 KLM",
"transport_date": "2026-10-12",
"lines": [
{
"origin": "Polígono Industrial Las Mercedes, 28022 Madrid",
"destination": "Puerto de Valencia, 46024 Valencia",
"goods": "Palés de bebidas",
"weight_kg": 12400
}
]
}
}
check = requests.post(f"{API}/decas/validate", headers=HEADERS, json=body, timeout=30)
if not check.ok:
problem = check.json() # application/problem+json
raise RuntimeError(f"{problem['code']}: {problem['detail']}")
resp = requests.post(f"{API}/decas", headers=HEADERS, json=body, timeout=30)
resp.raise_for_status()
deca = resp.json()
print(deca["id"], deca["url"]) # url = the QR linkconst API = "https://api.deca.routyn.com/api/v1";
const headers = {
Authorization: `Bearer ${process.env.DECA_API_KEY}`,
"Content-Type": "application/json",
};
const body = JSON.stringify({
"external_ref": "TRIP-2026-1012-A",
"data": {
"shipper_name": "Logística Ibérica S.L.",
"shipper_tax_id": "B12345678",
"shipper_address": "Calle Mayor 10, 28013 Madrid",
"carrier_name": "Transportes Ejemplo S.A.",
"carrier_tax_id": "A87654321",
"vehicle_plate": "1234 KLM",
"transport_date": "2026-10-12",
"lines": [
{
"origin": "Polígono Industrial Las Mercedes, 28022 Madrid",
"destination": "Puerto de Valencia, 46024 Valencia",
"goods": "Palés de bebidas",
"weight_kg": 12400
}
]
}
});
const check = await fetch(`${API}/decas/validate`, { method: "POST", headers, body });
if (!check.ok) {
const problem = await check.json(); // application/problem+json
throw new Error(`${problem.code}: ${problem.detail}`);
}
const res = await fetch(`${API}/decas`, { method: "POST", headers, body });
const deca = await res.json();
console.log(deca.id, deca.url); // url = the QR linkEm vez de enviar o conteúdo em data, pode enviar os ids dos seus dados mestre (carrier_id, shipper_id, vehicle_id, trailer_id…) com transport_date e lines.
O que convém saber
Autenticação
Envie a chave como token Bearer. Uma chave atua em nome da sua empresa com acesso aos DeCA e aos dados mestre, mas não pode gerir utilizadores nem chaves.
Authorization: Bearer deca_live_…Repetições seguras
Repetir um external_ref devolve o DeCA já emitido com 200 em vez de 201. Sem external_ref, utilize Idempotency-Key: o mesmo corpo em 24 horas devolve a primeira resposta.
Idempotency-Key: 3f1e9b2c-…Chaves de teste
Os DeCA emitidos com deca_test_ levam a marca «PRUEBA · SIN VALIDEZ» (teste, sem validade), são listados à parte e eliminados ao fim de 7 dias.
Organizações
Se a sua empresa tiver várias, indique em qual trabalha. Sem o cabeçalho, a chamada vai para a organização «Principal».
Deca-Organization: <id>Limites
Até 120 pedidos por minuto e por chave. Se ultrapassar, recebe 429 rate_limited com o cabeçalho Retry-After.
Retry-After: 12Erros
Todos os erros são application/problem+json com um campo code estável. Decida com base em code, nunca no texto de detail.
"code": "tractor_requires_trailer"Listas
As listagens aceitam limit (1 a 200, 50 por omissão) e offset, e devolvem items, total, limit e offset.
?limit=100&offset=200Webhooks assinados
Crie um endpoint em Empresa › Webhooks e receba um POST por cada evento, incluindo os dos DeCA emitidos pela web ou por WhatsApp. Cada chamada leva os cabeçalhos DeCA-Event-Id, DeCA-Event-Type e DeCA-Signature.
deca.issuedDeCA emitidodeca.modifiedNova versão, mesmo QRdeca.completedServiço concluídodeca.cancelledDeCA anuladodraft.completedA outra empresa preencheu os seus dadosdeca.importedDeCA de outro emissor importado
Responda com 2xx em menos de 10 segundos. Caso contrário, repetimos ao fim de 1 min, 5 min, 30 min, 2 h, 6 h, 12 h e 24 h, com o mesmo DeCA-Event-Id para que não o processe duas vezes.
Verificar a assinatura
import hashlib, hmac, time
def verify(raw_body: bytes, signature: str, secret: str, tolerance: int = 300) -> bool:
"""signature = the DeCA-Signature header; secret = the endpoint's whsec_... secret."""
parts = dict(p.split("=", 1) for p in signature.split(","))
if abs(time.time() - int(parts["t"])) > tolerance:
return False
expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts["v1"])Endpoints principais
Uma seleção. A referência completa, com cada campo e cada erro, está no Swagger e no ReDoc.
DeCA
- POST
/api/v1/decas/validateVerificar sem emitir - POST
/api/v1/decasEmitir, com dados ou com ids dos seus dados mestre - GET
/api/v1/decasListar e filtrar - PATCH
/api/v1/decas/{id}Modificar com motivo, mesmo QR - POST
/api/v1/decas/{id}/completeConcluir - POST
/api/v1/decas/{id}/cancelAnular (PDF ANULADO) - GET
/api/v1/decas/{id}/pdfPDF de qualquer versão - POST
/api/v1/decas/{id}/send-to-driverEnviar por e-mail ao motorista
Rascunhos e pedidos de dados
- POST
/api/v1/draftsGuardar um rascunho - POST
/api/v1/drafts/{id}/data-requestsPedir dados a outra empresa - POST
/api/v1/drafts/{id}/issueEmitir o rascunho - POST
/api/v1/decas/{id}/duplicateDuplicar como rascunho - GET
/api/v1/decas/recent-routesRotas mais utilizadas - POST
/api/v1/decas/vehicle-changeAlterar o veículo dos DeCA em curso
Dados mestre
- GET
/api/v1/carriersTambém shippers, customers, drivers, vehicles e trailers - POST
/api/v1/carriers/importImportar a partir do Excel (com /template e /export) - GET
/api/v1/locationsLocalizações guardadas - GET
/api/v1/organizationsOrganizações da empresa
DeCA recebidos
- POST
/api/v1/imported-decasImportar um PDF ou o link de um QR - GET
/api/v1/imported-decasListar os importados - GET
/api/v1/imported-decas/{id}/pdfDescarregar o PDF
Suporte da API
A documentação é aberta a todos. A ajuda personalizada com a integração é para clientes do Routyn, através do seu centro de ajuda
Já planeia com o Routyn?
O Routyn, o software líder de otimização de rotas de veículos, já está ligado ao DeCA: os seus clientes recebem cada DeCA no Routyn Drive sem escrever uma linha de código.
A sua primeira chave, num minuto
Crie a conta da sua empresa, gere uma chave de teste e emita o seu primeiro DeCA a partir do seu sistema.