{
    "openapi": "3.1.0",
    "info": {
        "title": "decadocument · API del documento de control (DeCA)",
        "version": "1.0.0",
        "description": "Emisión y gestión del documento de control del transporte de mercancías por carretera (Orden FOM/2861/2012 y Resolución DGTCF de 5/6/2026)."
    },
    "servers": [
        {
            "url": "https://decadocument.com/api/v1"
        }
    ],
    "security": [
        {
            "bearer": []
        }
    ],
    "paths": {
        "/decas": {
            "get": {
                "summary": "Listar documentos",
                "parameters": [
                    {
                        "name": "desde",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "hasta",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "estado",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "EMITIDO",
                                "ANULADO",
                                "SUSTITUIDO"
                            ]
                        }
                    },
                    {
                        "name": "referencia_externa",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "matricula",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "por_pagina",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "maximum": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Lista paginada"
                    },
                    "401": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "summary": "Emitir un DeCA",
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 120
                        },
                        "description": "Repetir la petición con la misma clave devuelve el mismo resultado sin duplicar."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/NuevoDeca"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Documento",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Deca"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/decas/{id}": {
            "get": {
                "summary": "Consultar un DeCA",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Documento",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Deca"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/decas/{id}/pdf": {
            "get": {
                "summary": "PDF vigente",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "PDF",
                        "content": {
                            "application/pdf": {}
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/decas/{id}/vehiculo": {
            "post": {
                "summary": "Cambio de vehículo durante el servicio (misma URL)",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 120
                        },
                        "description": "Repetir la petición con la misma clave devuelve el mismo resultado sin duplicar."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "motivo"
                                ],
                                "properties": {
                                    "matricula_tractor": {
                                        "type": "string"
                                    },
                                    "matricula_remolque": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "autorizacion_especial": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    },
                                    "motivo": {
                                        "type": "string",
                                        "minLength": 5,
                                        "maxLength": 500
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Documento",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Deca"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/decas/{id}/rectificar": {
            "post": {
                "summary": "Rectificar: documento nuevo (URL nueva) que sustituye al original",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 120
                        },
                        "description": "Repetir la petición con la misma clave devuelve el mismo resultado sin duplicar."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "allOf": [
                                    {
                                        "$ref": "#/components/schemas/NuevoDeca"
                                    },
                                    {
                                        "type": "object",
                                        "required": [
                                            "motivo"
                                        ],
                                        "properties": {
                                            "motivo": {
                                                "type": "string",
                                                "minLength": 5,
                                                "maxLength": 500
                                            }
                                        }
                                    }
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Documento",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Deca"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/decas/{id}/anular": {
            "post": {
                "summary": "Anular (misma URL; el PDF indica que no tiene validez)",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 120
                        },
                        "description": "Repetir la petición con la misma clave devuelve el mismo resultado sin duplicar."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "motivo"
                                ],
                                "properties": {
                                    "motivo": {
                                        "type": "string",
                                        "minLength": 5,
                                        "maxLength": 500
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Documento",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Deca"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/transportistas": {
            "get": {
                "summary": "Listar transportistas",
                "responses": {
                    "200": {
                        "description": "Lista"
                    }
                }
            },
            "post": {
                "summary": "Alta o actualización por NIF",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Transportista"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Actualizado"
                    },
                    "201": {
                        "description": "Creado"
                    },
                    "422": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearer": {
                "type": "http",
                "scheme": "bearer",
                "description": "Token de la empresa (Empresa → Integraciones)."
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "properties": {
                    "message": {
                        "type": "string"
                    },
                    "errors": {
                        "type": "object"
                    }
                }
            },
            "Transportista": {
                "type": "object",
                "required": [
                    "nif",
                    "nombre"
                ],
                "properties": {
                    "nif": {
                        "type": "string"
                    },
                    "nombre": {
                        "type": "string"
                    },
                    "email": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "telefono": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "Envio": {
                "type": "object",
                "required": [
                    "origen",
                    "destino",
                    "naturaleza",
                    "peso"
                ],
                "properties": {
                    "origen": {
                        "type": "string"
                    },
                    "destino": {
                        "type": "string"
                    },
                    "naturaleza": {
                        "type": "string"
                    },
                    "peso": {
                        "type": "number"
                    },
                    "peso_unidad": {
                        "type": "string",
                        "default": "kg"
                    },
                    "bultos": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "referencia": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "NuevoDeca": {
                "type": "object",
                "required": [
                    "fecha_transporte",
                    "envios",
                    "matricula_tractor"
                ],
                "properties": {
                    "fecha_transporte": {
                        "type": "string",
                        "format": "date",
                        "description": "No anterior a hoy (hora peninsular)"
                    },
                    "carrier_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "O bien «transportista»"
                    },
                    "transportista": {
                        "$ref": "#/components/schemas/Transportista"
                    },
                    "envios": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 50,
                        "items": {
                            "$ref": "#/components/schemas/Envio"
                        }
                    },
                    "matricula_tractor": {
                        "type": "string"
                    },
                    "matricula_remolque": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "autorizacion_especial": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "observaciones": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "referencia_externa": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Tu nº de albarán, pedido o expedición"
                    }
                }
            },
            "Deca": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "estado": {
                        "type": "string",
                        "enum": [
                            "EMITIDO",
                            "ANULADO",
                            "SUSTITUIDO"
                        ]
                    },
                    "url": {
                        "type": "string",
                        "description": "URL del QR: descarga directa del PDF. Es la que se envía al conductor."
                    },
                    "pdf_url": {
                        "type": "string"
                    },
                    "referencia_externa": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "fecha_transporte": {
                        "type": "string",
                        "format": "date"
                    },
                    "cargador": {
                        "type": "object"
                    },
                    "transportista": {
                        "type": "object"
                    },
                    "envios": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Envio"
                        }
                    },
                    "vehiculo": {
                        "type": "object"
                    },
                    "observaciones": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "sustituye_a": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "sustituido_por": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "version": {
                        "type": "integer"
                    },
                    "emitido_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "conservar_hasta": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            }
        }
    }
}