Escaneo del albarán
El operario escanea el albarán que ya imprimes. El QR se decodifica y lo extraído se muestra para que lo confirme: un valor que nadie tecleó no llega al documento sin que alguien lo mire.
Resolución de 5 de junio de 2026 · BOE-A-2026-12784
Deca2U genera el DeCA de cada expedición, publica su QR en una URL descargable sin credenciales y lo conserva el tiempo que marca la ley. Tus sistemas de despacho no cambian: ni un campo, ni el albarán, ni el QR que ya imprimes.
5 de octubre de 2026 Sin periodo transitorio y sin fase sin sanción.
https://doc.deca2u.com/Cx4Kq8Lm2Nv6Pw0Ry3Ts7A/kogBvj2nt_Rxpc9jTj6klA.pdf
Artículo 6
La norma enumera el contenido por letras, y esa lista es exactamente lo que el documento imprime. Las dos condicionales sólo aparecen cuando corresponde: pedirlas como obligatorias es el error más habitual, y produce documentos que un inspector lee como incompletos.
Cómo llega el dato
No son fases ni niveles: son alternativas, y una planta puede usar las tres el mismo día. Lo que sale por el otro lado es el mismo documento, con el mismo QR y la misma trazabilidad.
El operario escanea el albarán que ya imprimes. El QR se decodifica y lo extraído se muestra para que lo confirme: un valor que nadie tecleó no llega al documento sin que alguien lo mire.
Para la báscula, el puerto y el punto sin conectividad. Pocos campos por pantalla y objetivos grandes, porque quien lo usa lleva guantes y está al sol.
La que consume nuestra propia aplicación de captura, así que existe desde el primer día y no es una promesa. Tu ERP publica el despacho y recibe la URL.
Lo que cuesta hacer bien
Cada centro guarda un bloque de identificadores en el dispositivo. Sin línea compone la URL, imprime el QR y entrega la copia; el registro sube cuando vuelve la red. El camión sale igual.
El PDF se genera de forma determinista, así que el archivo que se lleva en la cabina es idéntico byte a byte al que responde la URL. Una divergencia levanta una alerta, no pasa desapercibida.
La URL pública se cierra siete días naturales después del servicio y el archivo se destruye a los doce meses de la fecha de transporte. Conservarlo de más incumple tanto como perderlo.
La URL devuelve el archivo directamente, sobre TLS, sin login, sin página intermedia y sin botón. Cualquier cosa que devuelva HTML incumple la Resolución.
Ni un campo, ni el diseño, ni su QR actual. Deca2U emite el suyo en un justificante aparte, que es lo que permite arrancar sin tocar un sistema de planta.
Aunque el despacho llegue dos veces por dos vías distintas. Si un QR ya se entregó, resuelve: ese código está en una cabina y tiene que seguir funcionando.
Referencia
REST sobre JSON. Autenticación por clave en cabecera para un sistema de despacho, o
token de tu directorio para una persona. Todas las rutas cuelgan de
/v1 y actúan siempre sobre el cliente que trae la credencial: ninguna
acepta el inquilino como parámetro.
Un sistema de despacho presenta su clave en x-api-key. La clave
pertenece a un cliente y sólo puede actuar sobre él: el inquilino nunca viaja en
el cuerpo ni en la URL, porque ambos los escribe quien llama.
Una persona presenta un token de su propio directorio en
Authorization: Bearer. Lo que puede hacer lo decide el rol que su
administrador le asignó, nunca una reivindicación del token.
La llamada que integra el 90 % de los casos. Devuelve el identificador, la URL pública y la huella del PDF publicado.
curl -X POST https://api.deca2u.com/v1/documents \
-H "x-api-key: $DECA2U_KEY" \
-H "Content-Type: application/json" \
-d '{
"siteId": "M477",
"externalRef": "M477-52900",
"data": {
"contractualShipper": {
"name": "CEMEX España Operaciones, S.L.U.",
"taxId": "B12345678",
"address": "Hernández de Tejada 1, 28027 Madrid"
},
"effectiveCarrier": { "name": "Transportes Ruiz, S.L.", "taxId": "B81234567" },
"location": { "origin": "Planta de Bailén", "destination": "Obra Alcobendas" },
"goods": { "description": "Hormigón HA-25", "quantity": 8, "unit": "m3" },
"transportDate": "2026-07-15",
"vehicle": { "tractorPlate": "1234ABC", "articulated": false }
}
}'
const response = await fetch('https://api.deca2u.com/v1/documents', {
method: 'POST',
headers: {
'x-api-key': process.env.DECA2U_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
siteId: 'M477',
externalRef: 'M477-52900',
data: {
contractualShipper: {
name: 'CEMEX España Operaciones, S.L.U.',
taxId: 'B12345678',
address: 'Hernández de Tejada 1, 28027 Madrid',
},
effectiveCarrier: { name: 'Transportes Ruiz, S.L.', taxId: 'B81234567' },
location: { origin: 'Planta de Bailén', destination: 'Obra Alcobendas' },
goods: { description: 'Hormigón HA-25', quantity: 8, unit: 'm3' },
transportDate: '2026-07-15',
vehicle: { tractorPlate: '1234ABC', articulated: false },
},
}),
});
if (!response.ok) throw new Error(`Deca2U respondió ${response.status}`);
const { id, url } = await response.json();
import os
import requests
response = requests.post(
"https://api.deca2u.com/v1/documents",
headers={"x-api-key": os.environ["DECA2U_KEY"]},
json={
"siteId": "M477",
"externalRef": "M477-52900",
"data": {
"contractualShipper": {
"name": "CEMEX España Operaciones, S.L.U.",
"taxId": "B12345678",
"address": "Hernández de Tejada 1, 28027 Madrid",
},
"effectiveCarrier": {"name": "Transportes Ruiz, S.L.", "taxId": "B81234567"},
"location": {"origin": "Planta de Bailén", "destination": "Obra Alcobendas"},
"goods": {"description": "Hormigón HA-25", "quantity": 8, "unit": "m3"},
"transportDate": "2026-07-15",
"vehicle": {"tractorPlate": "1234ABC", "articulated": False},
},
},
timeout=10,
)
response.raise_for_status()
issued = response.json()
using System.Net.Http.Json;
var http = new HttpClient { BaseAddress = new Uri("https://api.deca2u.com/") };
http.DefaultRequestHeaders.Add("x-api-key", Environment.GetEnvironmentVariable("DECA2U_KEY"));
var response = await http.PostAsJsonAsync("v1/documents", new
{
siteId = "M477",
externalRef = "M477-52900",
data = new
{
contractualShipper = new
{
name = "CEMEX España Operaciones, S.L.U.",
taxId = "B12345678",
address = "Hernández de Tejada 1, 28027 Madrid",
},
effectiveCarrier = new { name = "Transportes Ruiz, S.L.", taxId = "B81234567" },
location = new { origin = "Planta de Bailén", destination = "Obra Alcobendas" },
goods = new { description = "Hormigón HA-25", quantity = 8, unit = "m3" },
transportDate = "2026-07-15",
vehicle = new { tractorPlate = "1234ABC", articulated = false },
},
});
response.EnsureSuccessStatusCode();
var issued = await response.Content.ReadFromJsonAsync<Issued>();
var body = """
{
"siteId": "M477",
"externalRef": "M477-52900",
"data": {
"contractualShipper": {
"name": "CEMEX España Operaciones, S.L.U.",
"taxId": "B12345678",
"address": "Hernández de Tejada 1, 28027 Madrid"
},
"effectiveCarrier": { "name": "Transportes Ruiz, S.L.", "taxId": "B81234567" },
"location": { "origin": "Planta de Bailén", "destination": "Obra Alcobendas" },
"goods": { "description": "Hormigón HA-25", "quantity": 8, "unit": "m3" },
"transportDate": "2026-07-15",
"vehicle": { "tractorPlate": "1234ABC", "articulated": false }
}
}
""";
var request = HttpRequest.newBuilder(URI.create("https://api.deca2u.com/v1/documents"))
.header("x-api-key", System.getenv("DECA2U_KEY"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
var response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
<?php
$payload = [
'siteId' => 'M477',
'externalRef' => 'M477-52900',
'data' => [
'contractualShipper' => [
'name' => 'CEMEX España Operaciones, S.L.U.',
'taxId' => 'B12345678',
'address' => 'Hernández de Tejada 1, 28027 Madrid',
],
'effectiveCarrier' => ['name' => 'Transportes Ruiz, S.L.', 'taxId' => 'B81234567'],
'location' => ['origin' => 'Planta de Bailén', 'destination' => 'Obra Alcobendas'],
'goods' => ['description' => 'Hormigón HA-25', 'quantity' => 8, 'unit' => 'm3'],
'transportDate' => '2026-07-15',
'vehicle' => ['tractorPlate' => '1234ABC', 'articulated' => false],
],
];
$curl = curl_init('https://api.deca2u.com/v1/documents');
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('DECA2U_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
]);
$issued = json_decode(curl_exec($curl), true);
Respuesta 201:
{
"id": "kogBvj2nt_Rxpc9jTj6klA",
"url": "https://doc.deca2u.com/Cx4Kq8Lm2Nv6Pw0Ry3Ts7A/kogBvj2nt_Rxpc9jTj6klA.pdf",
"publishedAt": "2026-07-15T06:31:02.144Z",
"publicUntil": "2026-07-22T23:59:59.000Z",
"pdfHash": "9f2c…",
"externalRef": "M477-52900"
}
Si la expedición ya tenía documento responde 200 con
alreadyIssuedAs y la URL existente, en vez de emitir un segundo. Si
falta alguna letra obligatoria responde 422 y enumera cuáles: un
documento incompleto no es un DeCA y no se publica.
Emite y publica. Acepta un identificador de un bloque del centro si el dispositivo ya imprimió el QR.
Comprueba un conjunto de datos y devuelve las letras que faltan, sin emitir nada.
Los documentos que el llamante puede leer, con from y to opcionales. Un transportista recibe sólo aquellos en los que figura como porteador efectivo.
Un documento y su historial de correcciones.
Lo emitido por un centro, del más reciente al más antiguo.
Sección 5 de la Resolución. Corregir conserva la URL que el conductor ya lleva y deja rastro en el propio documento; reemitir crea uno nuevo y marca el anterior como sustituido, porque hay cambios que no son una corrección.
Corrige. Exige el motivo, y responde 409 si el cambio requiere reemisión.
Reemite con URL y QR propios.
Registra un cambio de vehículo sobre un transporte en curso.
Deja constancia de por dónde se entregó la copia — print,
share, download o link — sin identificar al
conductor, que no es dato de este documento.
Un identificador son 128 bits, se asigna una vez y no se reutiliza. Cada centro recibe un bloque para poder imprimir sin conectividad.
Entrega un bloque nuevo al dispositivo que lo pide.
Lo que el centro tiene vivo, y qué dispositivo lo lleva.
Retira un bloque perdido. Lo no usado queda inválido para siempre.
Transportistas y vehículos, que el albarán no trae. Se cargan en bloque porque llegan como hoja de cálculo, y una carga a medias es peor que una que falla.
Igual para /v1/master-data/vehicles.
La dirección que resuelve el QR. Devuelve 200 con
application/pdf, sin credenciales y sobre TLS 1.2 o superior.
Devuelve 410 cuando la ventana pública se ha cerrado —siete días
naturales tras el servicio— y 404 para cualquier otra cosa, sin
distinguir un identificador mal formado de uno que no existe.
curl -O https://doc.deca2u.com/Cx4Kq8Lm2Nv6Pw0Ry3Ts7A/kogBvj2nt_Rxpc9jTj6klA.pdf