Para desarrolladores

API de DeCA gratis

Crea, modifica y consulta DeCA desde tu ERP, tu TMS o tu web. Recibe webhooks firmados cuando cambian. Importa cientos de golpe con un CSV. Incluida en todos los planes, también en el gratis: cada DeCA cuenta para el cupo del mes, igual que si lo hicieras en la web.

Crear mi claveOpenAPI 3.1 (JSON)Agentes de IA (MCP)n8n, Make y Zapier

Empezar en 3 pasos

  1. Crea una clave en Integraciones (lo hace quien administra la cuenta). Empieza por dg_live_ y solo se enseña una vez.

  2. Pruébala en el entorno de pruebas: abre una cuenta en deca-demo.transportistastop10.com y crea allí una clave dg_test_. Base: https://deca-demo.transportistastop10.com/api/v1. Nada de lo que hagas allí vale ni se mezcla con datos reales.

  3. Crea tu primer DeCA:

    curl -X POST https://deca.transportistastop10.com/api/v1/decas \
      -H "Authorization: Bearer dg_live_…" \
      -H "Content-Type: application/json" \
      -d '{
        "ref_externa": "PED-1001",
        "referencia": "Albarán 1001",
        "fecha_transporte": "2026-10-07",
        "cargador_nombre": "Frutas Huerta S.L.",
        "cargador_nif": "B12345674",
        "cargador_domicilio": "Calle Mayor 1, 03001 Alicante",
        "matricula": "1234BCD",
        "matricula_remolque": "R5678BCF",
        "conductor_nombre": "Juan Pérez",
        "conductor_tel": "600123456",
        "envios": [
            {
                "origen": "Alicante",
                "destino": "Valencia",
                "naturaleza": "Fruta en cajas",
                "peso": 12000,
                "unidad": "kg"
            }
        ]
    }'

    No hace falta dar de alta antes clientes, direcciones ni vehículos: si eres el transportista, tu lado se rellena con tu empresa. La respuesta (201) trae el DeCA con la URL del PDF y del QR:

    {
        "deca": {
            "id": 4821,
            "numero": "2026-000123",
            "estado": "emitido",
            "version": 1,
            "emisor_rol": "transportista",
            "ref_externa": "PED-1001",
            "canal": "api",
            "cargador_nombre": "Frutas Huerta S.L.",
            "…": "(todos los campos de entrada)",
            "envios": [
                {
                    "origen": "Alicante",
                    "destino": "Valencia",
                    "naturaleza": "Fruta en cajas",
                    "peso": 12000,
                    "unidad": "kg",
                    "nota": null
                }
            ],
            "urls": {
                "pdf": "https://deca.transportistastop10.com/d/Xy7….pdf",
                "qr_png": "https://deca.transportistastop10.com/d/Xy7….png",
                "conductor": "https://deca.transportistastop10.com/c/Xy7…",
                "completar": null,
                "ficha": "https://deca.transportistastop10.com/deca/4821"
            },
            "pdf_sha256": "9f2c…",
            "pdf_bytes": 108544,
            "emitido_at": "2026-10-06 09:14:03",
            "modificado_at": "2026-10-06 09:14:03",
            "fin_servicio_at": null,
            "created_at": "2026-10-06 09:14:02",
            "sustituye_a": null,
            "sustituido_por": null,
            "archivado": false,
            "descargas": 0
        },
        "avisos": []
    }

Autenticación, formato y límites

MétodoRuta (sobre /api/v1)Para qué
GET/cuentaTu empresa, tu plan y el cupo del mes.
GET/decasLista de DeCA, del más nuevo al más viejo. Filtros: estado, desde, hasta (fecha del transporte), ref_externa, matricula, modificado_desde. Paginación: limite (máx. 100) y despues_de (el valor «siguiente» de la respuesta anterior).
POST/decasCrea un DeCA y, por defecto, lo emite (PDF, QR y URL). Con "emitir": false queda pendiente de los datos del otro lado y te devolvemos el enlace para que los complete (con "pedir_datos_email" se lo mandamos nosotros). Con "solo_validar": true no se guarda nada.
GET/decas/{id o número}Un DeCA con sus envíos y sus URL.
PATCH/decas/{id}Pendiente: cambia los datos (y con "emitir": true, lo emite). Emitido: modificación por el método 1 (misma URL y mismo QR); exige "motivo".
DELETE/decas/{id}Borra un DeCA PENDIENTE. Los emitidos no se borran: se conservan un año.
POST/decas/{id}/emitirEmite un DeCA pendiente.
POST/decas/{id}/sustituirMétodo 2: crea un DeCA nuevo (URL y QR nuevos) con los cambios y deja este como sustituido. Exige "motivo".
POST/decas/{id}/pedir-datosDevuelve el enlace para que el otro lado complete sus datos sin registrarse; con "email", se lo mandamos.
POST/decas/{id}/enviarManda el DeCA por email ("email") y te devuelve el texto para WhatsApp del conductor.
POST/decas/{id}/finMarca el fin del servicio.
POST/decas/{id}/archivarArchiva ("archivado": true) o saca del archivo (false).
GET/decas/{id}/pdfEl PDF (no cuenta como descarga pública).
GET/decas/{id}/qr.pngEl QR en PNG.
GET/decas/{id}/cambiosHistorial de modificaciones: versión, motivo, quién y qué cambió.
GET/decas/{id}/descargasCada vez que alguien abrió la URL pública o el QR (fecha, IP y navegador).
GET/agenda/empresas · /agenda/vehiculos · /agenda/lugaresTu agenda (se aprende sola de cada DeCA). Filtro: q.
POST/agenda/empresas · /agenda/vehiculos · /agenda/lugaresDa de alta (o actualiza) una empresa, un vehículo o un lugar. No hace falta para crear DeCA.
POST/fotosLee con IA la foto de un albarán, pedido o carta de porte (multipart «foto» o JSON «imagen_base64») y devuelve los datos del DeCA para revisarlos. No crea nada: después, POST /decas. Gasta una lectura del cupo de fotos (20 al mes en el plan gratis; ilimitadas en Pro). Tamaño máximo: 2 MB como fichero o unos 6 MB en base64; con 1.800 px de lado basta.
POST/importarImporta un CSV (cuerpo text/csv o multipart con el campo «csv»). ?validar=1 lo comprueba sin generar nada; ?emitir=0 los deja pendientes.
GET/webhooksTus webhooks.
POST/webhooksCrea un webhook: "url" (https), "eventos" (lista o ["*"]) y "descripcion". Devuelve el secreto UNA vez.
PATCH/webhooks/{id}Activa o pausa ("activo").
DELETE/webhooks/{id}Borra el webhook.
GET/webhooks/{id}/entregasLas últimas 100 entregas con su resultado.
POST/webhooks/{id}/probarManda un evento «ping» ahora mismo.

Campos del DeCA

Los datos del art. 6 de la Orden FOM/2861/2012. Te decimos en el error exactamente cuál falta.

CampoQué esLo pone
cargador_nombreCargador contractual · nombre o razón socialcargador
cargador_nifCargador contractual · NIFcargador
cargador_domicilioCargador contractual · domiciliocargador
transp_nombreTransportista efectivo · nombre o razón socialcargador
transp_nifTransportista efectivo · NIFcargador
fecha_transporteFecha del transportetransportista
tipo_vehiculoTipo de vehículotransportista
matriculaMatrícula (tractora o rígido)transportista
matricula_remolqueMatrícula del remolque o semirremolquetransportista
autorizacion_especialAutorización especial de circulacióntransportista
observacionesObservacionesambos
conductor_nombreConductortransportista
conductor_telTeléfono del conductortransportista
referenciaReferencia internaambos
envios[]origen, destino, naturaleza, peso, unidad (kg, t, m3, l, palets, bultos, unidades, contenedores) y nota. Uno o varios (hasta 48), con la misma pareja cargador-transportista.cargador
ref_externaTu referencia, única por cuenta (idempotencia).—

Con matricula_remolque el vehículo pasa a ser articulado. Si mandas solo tu lado con "emitir": false, el DeCA queda pendiente y urls.completar es el enlace para el otro lado.

Errores

{
    "error": {
        "codigo": "validacion",
        "mensaje": "Faltan datos o no son válidos: Falta la matrícula del vehículo.",
        "campos": {
            "matricula": "Falta la matrícula del vehículo."
        },
        "avisos": [],
        "request_id": "req_…"
    }
}
HTTPcodigoCuándo
400json_invalidoEl cuerpo no es JSON.
401no_autenticadoSin clave o clave no válida o revocada.
403solo_lecturaClave de solo lectura en una escritura.
404no_encontradoEse DeCA o webhook no es de tu cuenta.
409cuenta_incompleta · emitido · sin_cambios…La acción no cabe en el estado actual.
422validacion · falta_motivoFaltan datos (detalle en «campos»).
429demasiadas_peticiones · limite_planLímite por minuto, o cupo del mes del plan gratis agotado.

Webhooks

POST con JSON a tu URL (https) en cuanto pasa algo. Si no respondes 2xx en 10 s, reintentamos a 1 min, 5 min, 30 min, 2 h y 12 h. Cada entrega queda registrada en Integraciones.

EventoCuándo
deca.creadoSe ha creado un DeCA (también los pendientes de datos del otro lado).
deca.emitidoEl DeCA tiene ya su PDF, su QR y su URL.
deca.modificadoModificación por el método 1: mismo PDF y misma URL, nueva versión con motivo.
deca.sustituidoSustitución por el método 2: este DeCA queda sustituido por otro nuevo.
deca.completadoLa otra parte ha completado sus datos por el enlace y el DeCA se ha emitido.
deca.fin_servicioSe ha marcado el fin del servicio.
deca.descargadoAlguien ha abierto la URL pública o el QR del PDF (por ejemplo, en una inspección).
POST /tu-webhook
X-Deca-Evento: deca.emitido
X-Deca-Entrega: ev_…            (único: úsalo para no procesar dos veces)
X-Deca-Firma: t=1759651200,v1=5b1c…

{
    "id": "ev_…",
    "evento": "deca.emitido",
    "creado_at": "2026-10-06T11:16:12+02:00",
    "entorno": "produccion",
    "data": {
        "deca": "(el mismo objeto que GET /decas/{id})"
    }
}

Comprueba la firma: HMAC-SHA256 con tu secreto (whsec_…) de t + "." + cuerpo, y rechaza si t tiene más de 5 minutos.

// PHP
[$t, $v1] = array_map(fn($p) => explode('=', $p, 2)[1], explode(',', $_SERVER['HTTP_X_DECA_FIRMA']));
$cuerpo = file_get_contents('php://input');
$ok = abs(time() - (int)$t) < 300 && hash_equals(hash_hmac('sha256', $t . '.' . $cuerpo, $SECRETO), $v1);

// Node.js
const [t, v1] = req.headers['x-deca-firma'].split(',').map(p => p.split('=')[1]);
const ok = Math.abs(Date.now()/1000 - t) < 300 &&
  crypto.timingSafeEqual(Buffer.from(crypto.createHmac('sha256', SECRETO).update(t + '.' + cuerpoCrudo).digest('hex')), Buffer.from(v1));

# Python
t, v1 = [p.split('=', 1)[1] for p in request.headers['X-Deca-Firma'].split(',')]
ok = abs(time.time() - int(t)) < 300 and hmac.compare_digest(hmac.new(SECRETO.encode(), f"{t}.".encode() + cuerpo, 'sha256').hexdigest(), v1)

deca.descargado te avisa cuando alguien abre la URL pública o el QR: en ruta, suele ser una inspección.

Importación CSV

Desde la web (Integraciones → Importar) o por la API (POST /importar). Cada fila es un envío; las filas con la misma ref_externa (o la misma referencia) forman un DeCA. Volver a subir el mismo fichero no duplica nada. Separador «;» o «,»; UTF-8 o el CSV de Excel.

Columnas: ref_externa;referencia;fecha_transporte;cargador;cargador_nif;cargador_domicilio;transportista;transportista_nif;origen;destino;mercancia;peso;unidad;tipo_vehiculo;matricula;remolque;autorizacion_especial;conductor;conductor_tel;observaciones — y opcional emisor_rol. Son las mismas que la exportación de «Mis DeCA», así que puedes exportar, cambiar y volver a importar. Descargar la plantilla.

curl -X POST "https://deca.transportistastop10.com/api/v1/importar?validar=1" -H "Authorization: Bearer dg_live_…" -H "Content-Type: text/csv" --data-binary @decas.csv

Agentes de IA (MCP)

Conecta Claude, Cursor o VS Code a tu cuenta y pídele en lenguaje normal «hazme el DeCA del porte de mañana a Valencia con el 1234BCD». El servidor MCP usa la misma clave que la API y sus mismos permisos: con una clave de solo lectura, el agente solo puede consultar.

Servidor: https://deca.transportistastop10.com/mcp (HTTP «streamable», JSON-RPC 2.0). Herramientas: ver_cuenta, listar_decas, ver_deca, historial_deca, descargas_deca, buscar_agenda y, con clave de escritura, leer_albaran (foto → datos), validar_deca, crear_deca, modificar_deca, sustituir_deca, emitir_deca, enviar_deca, pedir_datos y fin_servicio.

# Claude Code
claude mcp add --transport http deca-gratis https://deca.transportistastop10.com/mcp --header "Authorization: Bearer dg_live_…"

# Cursor (~/.cursor/mcp.json) · VS Code (.vscode/mcp.json, con "servers" y "type": "http")
{ "mcpServers": { "deca-gratis": { "url": "https://deca.transportistastop10.com/mcp",
    "headers": { "Authorization": "Bearer dg_live_…" } } } }

# Claude Desktop (claude_desktop_config.json), a través de mcp-remote
{ "mcpServers": { "deca-gratis": { "command": "npx",
    "args": ["mcp-remote", "https://deca.transportistastop10.com/mcp", "--header", "Authorization: Bearer dg_live_…"] } } }

Para probar sin riesgo, usa una clave dg_test_ con https://deca-demo.transportistastop10.com/mcp. Los conectores que solo admiten OAuth (como ChatGPT) todavía no.

n8n, Make y Zapier

Preguntas frecuentes

¿La API cuesta algo?

No. Va incluida en todos los planes, también en el gratis. Cada DeCA cuenta para el cupo del mes, igual que en la web (ilimitado hasta el 31-12-2026; después, 100 al mes en el plan gratis y sin límite en Pro).

¿Hay entorno de pruebas?

Sí: deca-demo.transportistastop10.com, con sus propias claves dg_test_. Los DeCA de allí no tienen validez y se pueden borrar en cualquier momento.

¿Tengo que dar de alta clientes o direcciones antes?

No. Mandas el DeCA con los datos y ya está. La agenda se aprende sola; si quieres, también la puedes rellenar por la API.

¿Funciona con SAP, Odoo, Dynamics, Sage o A3?

Sí: cualquier programa que pueda hacer una petición HTTP con JSON (o exportar un CSV) puede crear DeCA. No necesitas un conector especial.

¿Puedo hacer el DeCA hablando con una IA?

Sí: conecta nuestro servidor MCP a Claude, Cursor o VS Code con tu clave y pídeselo con tus palabras. El agente valida los datos antes de crear y nunca inventa un NIF ni una matrícula.

¿Y si el otro lado tiene que poner sus datos?

Crea el DeCA con "emitir": false: te devolvemos el enlace para que el cargador o el transportista complete lo suyo sin registrarse. Cuando lo hace, recibes el webhook deca.completado.