Customer API

Emisión de documentos de control administrativo desde tu TMS o ERP. REST sobre HTTPS, JSON en ambos sentidos. Tres llamadas de escritura y una de consulta.

El modelo: un borrador que se rellena

El DeCA se constituye por partes: nace como un borrador incompleto, se rellena con tantas llamadas como necesites y se cierra al llamar a generar QR. Mientras está abierto está en modo borrador, y no tiene validez legal.

Máquina de estados
              POST /v1/decas
              (constituye, N veces)
                    ↺
                    │
   ──────────►  borrador  ──────────────►  emitido
   crear            ▲      generar_QR         │
                    │                         │
                    └────── regenerar ────────┘
                          (abre borrador nuevo,
                           sembrado con lo emitido)

Cada llamada de escritura corresponde a una transición: constituir se puede repetir, generar consume un número de tu serie legal y produce el PDF, y regenerar abre una corrección que queda registrada. Ninguna de las dos últimas ocurre como efecto de la primera.

La referencia es la tuya

Todas las llamadas identifican el documento por referenciaExterna: tu número de orden, expedición o pedido. No hay que guardar ningún identificador nuestro en tu base de datos.

Autenticación

Clave estática por cabecera, en las cuatro llamadas. Se emite al dar de alta la integración y es revocable en caliente, sin desplegar nada de tu lado.

Cabeceras
x-api-key: dk_live_a1b2c3d4e5f6g7h8i9j0
Content-Type: application/json
Entornobase_urlPrefijo de clave
Producciónhttps://decatransporte.app/apidk_live_
Pruebashttps://sandbox.decatransporte.app/apidk_test_

La clave identifica una cuenta y una empresa. Lo que emitas queda bajo esa empresa, con su serie de numeración propia, y solo esa cuenta lo consulta. La referenciaExterna es única dentro de esa empresa, no globalmente: dos clientes pueden usar el mismo OC-100425 sin cruzarse.

La clave emite documentos con validez legal

No la incrustes en clientes ni la subas a un repositorio. Si se compromete, se revoca al momento y se emite otra: las integraciones activas solo cambian el valor de la cabecera.

Constituir DeCA

POST/v1/decas

Abre el borrador si referenciaExterna es nueva; si ya hay uno abierto, funde los campos recibidos con los que hubiera. Es la misma llamada en los dos casos.

Entrada

campoTipoDescripción
referenciaExternareqstring ≤255Tu identificador del transporte. Único dentro de tu empresa.
…campos opcstringCualquier subconjunto de los 19 campos del documento, en cualquier orden y repartidos en cuantas llamadas quieras.
POST/v1/decasllamada 1 · entra el pedido
{
  "referenciaExterna": "OC-100425",
  "cargadorNombre":    "Segura SL",
  "cargadorNif":       "B12345678",
  "cargadorDomicilio": "Pol. Fuente del Jarro, 46988 Paterna",
  "origen":            "Valencia",
  "destino":           "Irún",
  "mercanciaNatura":   "Palés de cerámica",
  "mercanciaPeso":     "18500 kg"
}
Respuesta200 OK
{
  "id":                "3f9a2b1c-8d5e-4f2a-9c1b-7e6d5a4b3c2d",
  "referenciaExterna": "OC-100425",
  "estado":            "borrador",
  "faltan": ["transportistaNombre", "transportistaNif",
              "matriculaTractor", "fechaTransporte"]
}
POST/v1/decasllamada 2 · tráfico asigna vehículo
{ "referenciaExterna":  "OC-100425",
  "transportistaNombre": "Logística Ríos SL",
  "transportistaNif":    "B98765432",
  "matriculaTractor":    "4521 KLM",
  "matriculaRemolque":   "R-8830" }

// → 200 { "estado":"borrador", "faltan":["fechaTransporte"] }
// Los campos de la llamada 1 siguen ahí. Esto suma, no reemplaza.
faltan es informativo

faltan enumera los obligatorios que quedan por rellenar. Aunque la lista quede vacía, el documento sigue en borrador: se emite cuando llamas a generar_QR, nunca solo.

Campos que no están en el contrato

Si tu sistema envía centroCoste o numeroExpedicion, la llamada no falla: se guardan y se ignoran.

códigoCuándo
200Borrador abierto o actualizado
400JSON mal formado, falta referenciaExterna o un campo supera el límite
409El documento ya está emitido: abre una corrección con regenerar

Generar QR

POST/v1/decas/{referenciaExterna}/generar_QR

Cierra el borrador. Valida los once obligatorios, asigna el siguiente número de la serie de tu empresa y genera el PDF con su código QR de verificación incrustado.

Entrada

La referenciaExterna en la ruta y la clave en la cabecera. Sin cuerpo.

POST/v1/decas/OC-100425/generar_QR202 Accepted
{ "id": "3f9a2b1c-8d5e-4f2a-9c1b-7e6d5a4b3c2d",
  "referenciaExterna": "OC-100425",
  "estado": "emitiendo" }
Una sola puerta de escritura

Esta llamada no admite datos. Todo lo que sale en el PDF ha entrado por POST /v1/decas.

202 y no 200: la generación es asíncrona y tarda unos segundos. Sondea la consulta hasta que el estado sea emitido, o pide que te configuremos un webhook de aviso.

Faltan obligatorios422 Unprocessable Entity
{ "error": "campos_obligatorios",
  "detalle": "no se puede emitir sin todos los apartados del art. 6",
  "faltan": ["fechaTransporte"] }

Un 422 no toca nada: el borrador sigue abierto y con su contenido intacto. Completa lo que falte y vuelve a llamar.

Si la llamas dos veces

Después de la primera llamada ya no queda borrador que emitir. La segunda encuentra el documento en curso o terminado y te lo devuelve.

Cuándo llega la segundaQué encuentraRespuesta
El worker sigue trabajandoemitiendo202 · mismo id, mismo trabajo
Ya terminóemitido200 · referencia y pdfUrl
La generación fallóerror202 · reintenta, sin consumir número

Ni segundo PDF, ni segundo número de serie, ni segunda versión. Para que exista una v2 hay que pasar por regenerar, que es una llamada distinta y exige un motivo.

Punto de no retorno

Generar consume un número de la serie legal de tu empresa y produce un documento con valor probatorio, archivado y verificable por QR. A partir de ahí no se edita: se corrige emitiendo una versión nueva, y la anterior se conserva accesible.

Regenerar

POST/v1/decas/{referenciaExterna}/regenerar

El documento emitido no se edita. Regenerar abre un borrador nuevo sembrado con los campos del documento vigente, ya enlazado al anterior: es la vía para un cambio de vehículo a mitad de ruta o un error en el peso.

Entrada

campoTipoDescripción
motivoreqstring ≤255Circunstancia que obliga a corregir. Sale impreso en la versión nueva.

Ningún campo del transporte: los cambios entran después por POST /v1/decas, la única puerta de escritura.

POST/v1/decas/OC-100425/regenerar
{ "motivo": "cambio de vehículo por avería en ruta" }

// → 200
{ "id":      "7d2e9f04-…",        // el DeCA nuevo, todavía sin emitir
  "estado":  "borrador",
  "version": 2,
  "regeneradoDe": "3f9a2b1c-…",  // el DeCA vigente hasta ahora
  "faltan":  [] }                 // viene completo: se sembró de uno emitido

El ciclo de corrección

Tres llamadas, repetibles cuantas veces haga falta
POST /v1/decas/OC-100425/regenerar   { motivo }              → 200 borrador, faltan:[]
POST /v1/decas                       { matriculaTractor }    → 200 borrador
POST /v1/decas/OC-100425/generar_QR                          → 202 → v2, referencia 47
  • La versión nueva hereda la referencia legal. Tu numeración no salta: sigue siendo el DeCA nº 47, corregido.
  • La anterior queda marcada como reemplazada y sigue descargable.
  • El QR del PDF nuevo apunta al anterior: la cadena v1 → v2 → v3 queda trazada.
  • Tu referenciaExterna no cambia nunca y siempre resuelve a la versión vigente.
Regenerar es una llamada aparte

Un POST sobre un documento emitido devuelve 409. La corrección solo se abre llamando a /regenerar, con su motivo.

Siempre corrige la versión vigente

No recibe el id del documento a corregir: una sola línea de sucesión, sin ramas.

El motivo es obligatorio

La circunstancia que obliga a corregir consta en el documento (art. 6.g) y sale impresa en la versión nueva.

códigoCuándo
200Borrador nuevo abierto, sembrado con la versión vigente
400Falta motivo
404Esa referenciaExterna no existe
409Ya hay un borrador abierto: no se corrigen dos versiones en paralelo

Consultar documento

GET/v1/decas/{referenciaExterna}

Válido en cualquier fase. En borrador devuelve lo acumulado y lo que falta; emitido, el número legal, el PDF vigente y la cadena de versiones.

Respuesta200 OK
{
  "id":                "7d2e9f04-…",
  "referenciaExterna": "OC-100425",
  "estado":            "emitido",
  "referencia":        47,          // nº de DeCA de tu empresa
  "version":           2,
  "emitidoEl":         "2026-08-18T14:31:07Z",
  "pdfUrl":            "https://f003.backblazeb2.com/…?X-Amz-Signature=…",
  "versiones": [
    { "version": 1, "emitidoEl": "2026-08-18T11:04:22Z",
      "reemplazado": true,  "motivo": null, "pdfUrl": "https://…" },
    { "version": 2, "emitidoEl": "2026-08-18T14:31:07Z",
      "reemplazado": false, "motivo": "cambio de vehículo por avería en ruta",
      "pdfUrl": "https://…" }
  ],
  "documento": { /* todos los campos tal y como se imprimieron */ }
}
Sobre pdfUrl

Es una URL firmada con caducidad. Si archivas el DeCA en tu gestor documental, descarga el fichero al recibirlo en lugar de guardar el enlace. La consulta emite un enlace nuevo cada vez que lo pidas.

Campos del documento

Los nombres son los del contrato y no cambian dentro de v1. Los once obligatorios son los apartados del artículo 6 y son condición para generar, no para constituir.

Obligatorios para generar

campoFormatoEjemplo
cargadorNombrestringSegura SL
cargadorNifstringB12345678
cargadorDomiciliostringPol. Fuente del Jarro, Paterna
transportistaNombrestringLogística Ríos SL
transportistaNifstringB98765432
origenstringValencia
destinostringIrún
mercanciaNaturastringPalés de cerámica
mercanciaPesostring18500 kg
fechaTransporteAAAA-MM-DD2026-08-18
matriculaTractorstring4521 KLM

mercanciaPeso es texto, no número: la norma admite expresar la cantidad en otra magnitud. Manda la unidad dentro del valor.

Opcionales

campoDescripción
matriculaRemolqueSolo en conjunto articulado
bultosNúmero y clase de bultos
destinatarioNombreDestinatario de la mercancía
destinatarioDomicilioDomicilio de entrega
numeroAlbaranNº de tu albarán de origen, informativo
observacionesObservaciones generales del transporte
observacionesCargadorReservas del cargador (art. 6.h)
observacionesTransportistaReservas del transportista (art. 6.h)
Campos que gestionamos nosotros

id, referencia, version, pdfUrl y regeneradoDe se descartan si los mandas. Son resultado de la emisión, no entrada.

Estados y transiciones

estadoSignificaSiguiente
borradorBorrador abierto, admite camposgenerar_QR → emitiendo
emitiendoValidado, generándose el PDFautomático → emitido | error
emitidoPDF disponible, número asignadoregenerar → borrador
errorLa generación falló; vuelve detallegenerar_QR → reintenta

Qué admite cada estado

Estado actualPOST /decasgenerar_QRregenerar
(no existe)abre el borrador404404
borradorfunde camposemite409
emitiendo409202, mismo trabajo409
emitido409200, el ya emitidoabre borrador v+1

Dos invariantes al integrar: hay como mucho un borrador abierto por referencia (de ahí el 409 de regenerar sobre un borrador) y un documento en error no ha consumido número de serie, así que reintentar no deja huecos en tu numeración.

Reintentos

Las cuatro llamadas se pueden repetir. La unicidad la impone una restricción en base de datos, no una comprobación de la aplicación.

RepetirEfecto
POST /v1/decasFunde los mismos valores otra vez. No abre un segundo borrador.
POST …/generar_QRDevuelve el documento en curso o emitido. Ni segundo PDF ni segundo número.
POST …/regenerar409: ya hay un borrador abierto por la primera llamada.
GET …Sin efectos. Lectura pura.
Nunca reintentes con una referencia nueva

Ante un timeout o un 5xx, repite la misma llamada con la misma referenciaExterna, con espera creciente. Una referencia distinta es otro transporte y produce un documento duplicado.

Códigos de error

Formato único en todas las rutas. El texto de detalle es explicativo y puede cambiar: para tu lógica usa el código HTTP y el campo error, que sí es estable.

Forma del error
{ "error": "ya_emitido", "detalle": "usa /regenerar para abrir una corrección" }
HTTPerrorCausaAcción
400peticion_invalidaJSON mal formado o campo fuera de límiteCorregir; reintentar no ayuda
401no_autorizadoClave ausente, errónea o revocadaRevisar x-api-key
403cuenta_solo_consultaLa cuenta no puede emitirPedir clave con permiso de emisión
404no_encontradoEsa referenciaExterna no existeComprobar el valor exacto
409ya_emitidoConstituir sobre un documento emitidoLlamar a /regenerar
409borrador_abiertoRegenerar con un borrador ya abiertoCerrarlo con /generar_QR
422campos_obligatoriosFaltan apartados del art. 6Leer faltan y completar
429demasiadas_peticionesLímite de ritmoEsperar lo que indique Retry-After
5xxerror_internoFallo nuestroReintentar con espera creciente; es seguro

Límites y alcance

Límitevalor
Longitud de campo255 caracteres · 2000 en observaciones
Cuerpo de la petición64 KB
Ritmo por clave60 peticiones / minuto
Caducidad de un borrador abierto30 días sin actividad
Vigencia de pdfUrl7 días desde la consulta

Fuera de alcance en v1

  • Sin EDI ni SFTP. Solo HTTPS con JSON. Si tu operativa es de ficheros por lotes, escríbenos y lo vemos aparte.
  • Sin OCR por API. La extracción de campos desde una foto del albarán vive en el panel web. La API recibe los datos ya estructurados.
  • Sin firma electrónica cualificada. El DeCA no la exige.
  • Sin borrado de documentos emitidos. Se corrigen, no se eliminan.
  • Una empresa por clave. Si emites en nombre de varias sociedades, una clave por cada una.
Lo que hace falta de tu lado

Lanzar llamadas HTTP desde tu TMS y guardar el PDF que devolvemos. El documento se localiza siempre por una referencia que ya tienes, así que no hay que añadir campos a tu base de datos.