DeCA Profesional
es
EntrarCrear DeCA

API v1 · REST · JSON

API de DeCA Profesional

Genera el Documento Electrónico de Control (DeCA) directamente desde tu ERP o TMS: envías los datos del transporte y recibes al momento el documento, su PDF con QR y la URL de verificación.

URL base: https://decaprofesional.es/api/v1

Para qué sirve

La API está pensada para empresas de transporte y cargadores que ya gestionan sus pedidos o expediciones en un ERP o TMS y quieren que el DeCA se genere solo, sin volver a teclear datos.

  1. 1. Tu ERP / TMS

    Envía el pedido o expedición por HTTPS (JSON, Bearer + Idempotency-Key).

  2. 2. API DeCA

    Valida los datos obligatorios y genera el DeCA.

  3. 3. Recibes

    La referencia, el PDF con QR y la URL pública de verificación.

El acceso a la API es un complemento de pago del plan Business (49,95 €/mes + IVA) para integraciones ERP/TMS. Los DeCA creados por la API cuentan en el mismo cupo mensual del plan que los creados desde el panel.

Primeros pasos

  1. Solicita el acceso escribiendo a integraciones@praetoriaabogados.es o activa el complemento API desde Plan y facturación si ya tienes el plan Business.
  2. Recibe tus credenciales: te enviamos una clave por integración (por ejemplo, una para tu ERP), con los permisos que necesite. La clave completa solo se muestra una vez.
  3. Prueba la conexión con GET /api/v1/me.
  4. Valida un DeCA con POST /api/v1/decas/validate: no crea nada ni consume cupo.
  5. Crea tu primer DeCA con POST /api/v1/decas y guarda la URL de verificación.
Probar la conexión
curl https://decaprofesional.es/api/v1/me \
  -H "Authorization: Bearer $DECA_API_KEY"

Autenticación

Cada petición lleva la clave de la integración en la cabecera Authorization. Solo HTTPS; no envíes nunca la clave en la URL ni la incluyas en código que se ejecute en el navegador.

Cabecera
Authorization: Bearer fvd_live_<id-de-la-clave>_<secreto>

La empresa siempre es la de la credencial: ningún campo de la petición (NIF, identificadores) cambia de empresa. Si pierdes una clave no se puede recuperar: pide una nueva o su rotación. Todo lo que tu credencial no puede ver responde 404.

Endpoints

GET/api/v1/me

Comprueba la credencial: integración, empresa, permisos, límites y uso del mes.

El primer endpoint que debes llamar para verificar la conexión.

POST/api/v1/decas/validatedeca:create

Valida un DeCA sin crearlo: mismas reglas que la creación.

No crea ningún DeCA, no genera PDF y no consume el cupo del plan.

POST/api/v1/decasdeca:createIdempotency-Key obligatoria

Crea un DeCA y devuelve la URL de verificación, la referencia y el PDF.

Responde 201 (o 200 si es un reintento con la misma Idempotency-Key).

GET/api/v1/decasdeca:read

Lista los DeCA, del más reciente al más antiguo, con paginación por cursor.

Filtros: limit (1–100, por defecto 25), cursor, externalId, status (active | annulled), createdFrom, createdTo (AAAA-MM-DD o ISO 8601 UTC).

GET/api/v1/decas/{id}deca:read

El DeCA completo: estado, periodo del servicio, URL de verificación, PDF y datos.

GET/api/v1/decas/{id}/statusdeca:read

Estado ligero (versión, disponibilidad, URL de verificación) para consultas periódicas.

GET/api/v1/decas/{id}/versionsdeca:read

Historial de versiones: motivo del cambio, origen (api / user) y URL y PDF de cada una.

GET/api/v1/decas/{id}/pdfdeca:read

Descarga el PDF (versión vigente o ?version=N).

Cabeceras X-Pdf-Sha256 (huella del PDF) y X-Deca-Status (active | annulled).

POST/api/v1/decas/{id}/correctionsdeca:correctIdempotency-Key obligatoria

Corrige un DeCA: crea una nueva versión con nueva URL, QR y PDF.

Responde 201 con la nueva versión (200 si es un reintento con la misma Idempotency-Key). Solo DeCA creados por la misma integración; las versiones anteriores se conservan.

POST/api/v1/decas/{id}/annulmentdeca:annul

Anula un DeCA. Es definitivo; repetir la llamada devuelve 200 sin cambios.

Solo DeCA creados por la misma integración.

Crear un DeCA

El cuerpo describe el transporte: fechas, vehículo, cargador contractual (shipper), transportista efectivo (carrier) y de 1 a 20 envíos. Los países van siempre en código ISO de dos letras (ES, FR, PT…). Los campos desconocidos se rechazan.

CampoObligatorioDescripción
externalIdRecomendadoTu identificador (pedido, expedición). 1–100 caracteres: letras, números y . _ - /. Único entre los DeCA activos de la empresa.
loadDate, unloadDateSíAAAA-MM-DD. La descarga no puede ser anterior a la carga.
vehicle.tractorPlateSíMatrícula (se normaliza: mayúsculas, sin espacios ni guiones). trailerPlate opcional.
shipper, carrierSíEmpresa (name, taxId, address; country, postalCode, city opcionales) o "self".
shipments[]SíloadLocation y unloadLocation (nombre, dirección, código postal, ciudad, provincia opcional, país ISO), goods, weight (número = kg, o texto como "22 palés"), recipient opcional.
referenceNoHasta 120 caracteres; se imprime en el DeCA.
notesNoHasta 1000 caracteres, una sola línea.
serviceTypeNogoods (por defecto) o passenger (transporte de viajeros).
cURL
curl -X POST https://decaprofesional.es/api/v1/decas \
  -H "Authorization: Bearer $DECA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d @deca.json
deca.json
{
  "externalId": "TR-45882",
  "reference": "Pedido 88231",
  "loadDate": "2026-10-06",
  "unloadDate": "2026-10-07",
  "vehicle": {
    "tractorPlate": "1234 KLM",
    "trailerPlate": "R-5678-BBC"
  },
  "shipper": {
    "name": "CERÁMICAS DEL MEDITERRÁNEO S.A.",
    "taxId": "A12345674",
    "country": "ES",
    "address": "Carretera de Alcora km 3",
    "postalCode": "12006",
    "city": "Castellón de la Plana"
  },
  "carrier": "self",
  "shipments": [
    {
      "loadLocation": {
        "name": "Planta 1",
        "address": "Carretera de Alcora km 3",
        "postalCode": "12006",
        "city": "Castellón de la Plana",
        "province": "Castellón",
        "country": "ES"
      },
      "unloadLocation": {
        "name": "Entrepôt Lyon Sud",
        "address": "12 Rue du Port",
        "postalCode": "69007",
        "city": "Lyon",
        "country": "FR"
      },
      "goods": "Azulejo cerámico en palés",
      "weight": 18400,
      "recipient": "Céramique Rhône SARL"
    }
  ]
}

Respuesta 201 Created con la cabecera Location: /api/v1/decas/{id}:

Respuesta 201
{
  "id": "cmg4x2k9a0001l508h3n7q2rz",
  "reference": "DECA-Q3VJ9KXA",
  "externalId": "TR-45882",
  "status": "active",
  "availability": "public",
  "version": 1,
  "createdAt": "2026-10-05T07:41:12.384Z",
  "updatedAt": "2026-10-05T07:41:12.384Z",
  "annulledAt": null,
  "serviceType": "goods",
  "servicePeriod": {
    "start": "2026-10-06",
    "end": "2026-10-07",
    "publicUntil": "2026-10-14"
  },
  "verification": {
    "url": "https://decaprofesional.es/d/q3vj9kxa7Rm2…",
    "note": "La URL cambia con cada corrección: imprime o envía siempre la última."
  },
  "pdf": {
    "href": "/api/v1/decas/cmg4x2k9a0001l508h3n7q2rz/pdf",
    "sha256": "9f2c4e…",
    "contentType": "application/pdf"
  },
  "data": {
    "reference": "Pedido 88231",
    "notes": null,
    "loadDate": "2026-10-06",
    "unloadDate": "2026-10-07",
    "vehicle": {
      "tractorPlate": "1234KLM",
      "trailerPlate": "R5678BBC"
    },
    "shipper": {
      "name": "CERÁMICAS DEL MEDITERRÁNEO S.A.",
      "taxId": "A12345674",
      "country": "ES",
      "address": "Carretera de Alcora km 3",
      "postalCode": "12006",
      "city": "Castellón de la Plana"
    },
    "carrier": {
      "name": "TRANSPORTES EJEMPLO S.L.",
      "taxId": "B12345674",
      "country": null,
      "address": "Polígono Industrial 5",
      "postalCode": "46540",
      "city": "El Puig"
    },
    "shipments": [
      {
        "loadLocation": {
          "name": "Planta 1",
          "address": "Carretera de Alcora km 3",
          "postalCode": "12006",
          "city": "Castellón de la Plana",
          "province": "Castellón",
          "country": "ES",
          "countryName": "España"
        },
        "unloadLocation": {
          "name": "Entrepôt Lyon Sud",
          "address": "12 Rue du Port",
          "postalCode": "69007",
          "city": "Lyon",
          "province": null,
          "country": "FR",
          "countryName": "Francia"
        },
        "goods": "Azulejo cerámico en palés",
        "weight": "18.400 kg",
        "recipient": "Céramique Rhône SARL",
        "loadDate": "2026-10-06",
        "unloadDate": "2026-10-07"
      }
    ],
    "totalWeight": "18.400 kg"
  },
  "warnings": [],
  "links": {
    "self": "/api/v1/decas/cmg4x2k9a0001l508h3n7q2rz",
    "status": "/api/v1/decas/cmg4x2k9a0001l508h3n7q2rz/status",
    "versions": "/api/v1/decas/cmg4x2k9a0001l508h3n7q2rz/versions",
    "pdf": "/api/v1/decas/cmg4x2k9a0001l508h3n7q2rz/pdf"
  }
}

warnings recoge avisos que no impiden crear el DeCA (por ejemplo, un NIF con un formato poco habitual). availability indica si la URL pública está disponible (public), ya caducó (expired) o el DeCA está anulado (annulled).

Idempotency-Key y externalId

Idempotency-Key (cabecera, obligatoria al crear y corregir): una cadena única por operación, por ejemplo un UUID (8–255 caracteres). Si repites la misma llamada con la misma clave y el mismo cuerpo —por un corte de red o un reintento—, recibes el mismo DeCA con 200 y la cabecera Idempotent-Replayed: true; nunca se crea un segundo documento. La misma clave con un cuerpo distinto responde 409 idempotency_conflict.

externalId (cuerpo): el identificador de tu objeto de negocio. Si ya existe un DeCA activo con ese externalId, la API responde 409 duplicate_external_id con el existingId. Puedes buscarlo con GET /api/v1/decas?externalId=…. Un DeCA anulado libera su externalId.

Validar sin crear

POST /api/v1/decas/validate acepta el mismo cuerpo que la creación y aplica exactamente las mismas reglas, pero no crea ningún DeCA, no genera PDF y no consume el cupo del plan. Úsalo para probar tu integración y para comprobar los datos antes de emitir.

Respuesta 200
{
  "valid": true,
  "warnings": []
}

“self”: tu propia empresa

En shipper o carrier puedes enviar el texto "self" en lugar de los datos de la empresa: se usan los datos de la empresa de la credencial tal como figuran en su ficha de DeCA Profesional. Si la ficha está incompleta, la respuesta es 422 con el detalle self_company_incomplete.

PDF, QR y URL de verificación

Cada DeCA tiene una URL pública de verificación (verification.url): es la que codifica el QR impreso en el PDF y la que se muestra en una inspección, sin necesidad de cuenta. El PDF se descarga con tu credencial en GET /api/v1/decas/{id}/pdf (o ?version=N); la cabecera X-Pdf-Sha256 permite comprobar su integridad. La URL pública está disponible durante el servicio y los 7 días siguientes (servicePeriod.publicUntil).

PDF del DeCA que genera la API para el ejemplo de esta página: referencia DECA-Q3VJ9KXA, cargador, transportista, ruta Castellón–Lyon, mercancía y matrículas; en la segunda página, la verificación pública con el QR y su URL
El PDF que genera la API para el ejemplo de esta página (datos ficticios). El QR de la verificación pública codifica la misma URL que devuelve verification.url.
Descargar el PDF
curl https://decaprofesional.es/api/v1/decas/<id>/pdf \
  -H "Authorization: Bearer $DECA_API_KEY" -o deca.pdf

Correcciones

Una corrección sustituye todos los datos del DeCA y crea una nueva versión con nueva URL de verificación, nuevo QR y nuevo PDF. Las versiones anteriores se conservan (GET /versions). Imprime o envía siempre la última URL. El externalId no se puede cambiar y un DeCA anulado no se puede corregir. Responde 201 con el DeCA en su nueva versión (200 si es un reintento con la misma Idempotency-Key).

  1. 1. POST /decas

    Versión 1 con su URL de verificación.

  2. 2. POST /corrections

    Versión 2 con URL, QR y PDF nuevos; la anterior se conserva.

  3. 3. Imprime o envía

    Siempre la última URL.

  4. 4. POST /annulment

    Definitivo: la URL muestra que el DeCA está anulado.

POST /api/v1/decas/{id}/corrections (con Idempotency-Key)
{
  "changeReason": "Cambio de matrícula del remolque",
  "deca": "…el mismo cuerpo completo que al crear…"
}

Anulación

La anulación es definitiva: la URL pública pasa a mostrar que el documento está anulado y el QR sigue resolviendo a ese aviso. Repetir la llamada devuelve 200 sin cambios. El motivo es obligatorio (3–500 caracteres).

POST /api/v1/decas/{id}/annulment
{
  "reason": "Pedido cancelado por el cliente"
}

Permisos (scopes)

Cada credencial tiene solo los permisos que necesita su integración.

deca:createCrear DeCA (POST /decas) y validarlos (POST /decas/validate).
deca:readLeer y listar los DeCA creados por esta integración.
deca:read_companyAmpliar la lectura a todos los DeCA de la empresa. Nunca amplía la escritura.
deca:correctCorregir DeCA creados por esta integración.
deca:annulAnular DeCA creados por esta integración.

Límites

  • 60 peticiones por minuto por credencial (cabeceras X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset).
  • Un techo técnico diario de creación por credencial (5000 DeCA) y un bloqueo temporal tras varios intentos de autenticación fallidos.
  • Cuerpo de hasta 256 KB y hasta 20 envíos por DeCA.
  • El cupo mensual de DeCA es el de tu plan; GET /api/v1/me indica el uso y lo que queda.
  • Al superar un límite recibes 429 con Retry-After: espera y reintenta.

Errores

Todos los errores tienen el mismo formato. code es estable y es lo que debe leer tu integración; message es informativo. Si contactas con soporte, indica el requestId.

Ejemplo 422
{
  "error": {
    "code": "validation",
    "message": "El DeCA no cumple los requisitos obligatorios.",
    "requestId": "req_7f3a9c…",
    "details": [
      {
        "path": "/shipments/0/unloadLocation/country",
        "code": "invalid_country",
        "message": "Usa un código de país ISO 3166-1 alfa-2 (p. ej. ES, FR, PT)"
      }
    ]
  }
}
HTTPcodeSignificado
400invalid_json, idempotency_key_required, invalid_queryPetición mal formada, falta la Idempotency-Key o un filtro no es válido.
401invalid_credentials, credential_revoked, credential_expiredClave desconocida o incorrecta (misma respuesta en ambos casos), revocada o caducada.
402business_plan_required, plan_allowance_exhaustedEl plan de la empresa no incluye la API, o se ha agotado el cupo de DeCA del plan.
403api_addon_required, company_inactive, ip_not_allowed, insufficient_scopeEl complemento API no está activo, la cuenta no está activa, IP no autorizada o permiso insuficiente.
404not_foundNo existe o no es visible para esta credencial (nunca se distingue).
409duplicate_external_id, idempotency_conflict, deca_annulled, version_conflictexternalId ya usado por un DeCA activo (incluye existingId), clave de idempotencia reutilizada con otro cuerpo, DeCA anulado o corrección simultánea.
413 / 415payload_too_large, unsupported_media_typeCuerpo de más de 256 KB, o no es application/json.
422validationDatos no válidos. details indica cada campo con un puntero JSON y un código (required, unknown_field, invalid_country, too_short, too_long, invalid_format, invalid_value, self_company_incomplete…).
429rate_limited, daily_create_ceiling, too_many_failed_attemptsLímite de peticiones superado. Respeta la cabecera Retry-After.
500generation_failed, internal_errorError al generar (incluye correlationId y retryable: reintenta con la misma Idempotency-Key) o error interno.
503service_unavailable, pdf_unavailableServicio o PDF temporalmente no disponible: reintenta.

Preguntas frecuentes

¿Dónde pongo la clave de la API?

No se introduce en DeCA Profesional: se configura en tu propio programa de gestión (ERP o TMS), normalmente lo hace tu informático o el proveedor de ese programa. Con ella, tu programa envía los datos del transporte a DeCA Profesional y recibe al momento el DeCA, su PDF con QR y la URL de verificación, sin que nadie tenga que rellenarlo en la web. Si no usas un ERP o TMS, o no tienes a nadie que haga la integración, no necesitas la API: puedes crear tus DeCA desde la web.

¿Hay un entorno de pruebas?

Usa POST /api/v1/decas/validate: aplica exactamente las mismas reglas que la creación, pero no crea ningún DeCA, no genera PDF y no consume el cupo del plan. Cuando la validación responda valid: true, el mismo cuerpo se creará sin errores.

¿Qué pasa si se corta la conexión mientras creo un DeCA?

Repite la misma llamada con la misma Idempotency-Key y el mismo cuerpo: si el DeCA ya se creó, recibes ese mismo DeCA (200 e Idempotent-Replayed: true); nunca se duplica.

¿Cómo evito crear dos DeCA para el mismo pedido?

Envía tu identificador de pedido o expedición en externalId. Si ya hay un DeCA activo con ese externalId, la API responde 409 duplicate_external_id con el existingId, y puedes consultarlo con GET /api/v1/decas?externalId=….

¿El QR cambia si corrijo el DeCA?

Sí. Cada corrección crea una versión nueva con nueva URL de verificación, nuevo QR y nuevo PDF. Guarda y comparte siempre la última verification.url; las versiones anteriores se conservan en GET /versions.

¿Puedo corregir o anular desde la API un DeCA creado en el panel?

No. La API solo corrige y anula los DeCA creados por la misma integración. Con el permiso deca:read_company puedes leer todos los DeCA de la empresa, pero nunca modificarlos.

¿Cuántos DeCA puedo crear?

Los de tu plan: los DeCA creados por la API y desde el panel comparten el mismo cupo mensual. GET /api/v1/me te indica cuántos llevas este mes y cuántos te quedan.

¿En qué formato van los países y las fechas?

Países en código ISO 3166-1 de dos letras (ES, FR, PT…) y fechas en AAAA-MM-DD. El PDF muestra el nombre del país en español.

¿Cuánto tiempo está disponible la URL pública?

Durante el servicio y los 7 días siguientes a la fecha de descarga (servicePeriod.publicUntil). Con tu credencial puedes descargar el PDF en cualquier momento.

Soporte para integraciones

¿Vas a conectar tu ERP o TMS?

Cuéntanos qué software usas y te ayudamos con el acceso, las credenciales y las primeras pruebas.

Escribir a integraciones@praetoriaabogados.es
API de DeCA Profesional para desarrolladores | DeCA Profesional