{
  "openapi": "3.1.0",
  "info": {
    "title": "Anonimatum API pública",
    "description": "API de Anonimatum: anonimización de documentos, patrones, wordsets, lotes, IA y herramientas PDF.\n\nAutenticación:\n- `X-API-Key`: API key de producto (usuario + grupo), generada en Intranet.\n- `Authorization: Bearer`: JWT de sesión de usuario.\n\nRutas de cliente vía Gateway: `/api/pdf/**` (rewrite al backend) y `/api/public/**` (contrato estable).\n",
    "contact": {
      "name": "Politeia Soft",
      "url": "https://politeiasoft.com",
      "email": "support@politeiasoft.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://politeiasoft.com"
    },
    "version": "1.9.0",
    "x-contract-version": "2.0.0"
  },
  "servers": [
    {
      "url": "https://api.anonimatum.com",
      "description": "Producción"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "BearerAuth": []
    }
  ],
  "paths": {
    "/api/public/ai/anonymize": {
      "post": {
        "tags": [
          "Inteligencia Artificial"
        ],
        "summary": "Anonimizar documento con IA",
        "description": "Mismos parámetros que /ai/anonymize. Valida y registra uso de IA del grupo.",
        "operationId": "anonymizeWithAi",
        "parameters": [
          {
            "name": "aiOptions",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zones",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "backgroundColor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "textContent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "censorHeightPadPx",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/ai/options": {
      "get": {
        "tags": [
          "Inteligencia Artificial"
        ],
        "summary": "Opciones de anonimización con IA",
        "description": "Lista las opciones disponibles del motor de IA (mismas que /ai/options).",
        "operationId": "getAiOptions",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/ai/preview": {
      "post": {
        "tags": [
          "Inteligencia Artificial"
        ],
        "summary": "Preview de anonimización con IA",
        "description": "Mismos parámetros que /ai/preview. Requiere X-API-Key o JWT.",
        "operationId": "generateAiPreview",
        "parameters": [
          {
            "name": "aiOptions",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "backgroundColor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "textContent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "censorHeightPadPx",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "customWords",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "patterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ocrPreprocess",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/batch-jobs": {
      "get": {
        "tags": [
          "Lotes (API pública)"
        ],
        "summary": "Listar trabajos del usuario",
        "operationId": "listJobs",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": {}
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Lotes (API pública)"
        ],
        "summary": "Encolar lote de documentos",
        "operationId": "uploadBatch",
        "parameters": [
          {
            "name": "config",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "configs",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "signatureHints",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "files": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    }
                  }
                },
                "required": [
                  "files"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {}
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/batch-jobs/{id}": {
      "delete": {
        "tags": [
          "Lotes (API pública)"
        ],
        "summary": "Eliminar trabajo",
        "operationId": "deleteJob",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/batch-jobs/{id}/output": {
      "get": {
        "tags": [
          "Lotes (API pública)"
        ],
        "summary": "Descargar PDF de un trabajo",
        "operationId": "downloadJobOutput",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/batch-jobs/{id}/output-bundle": {
      "get": {
        "tags": [
          "Lotes (API pública)"
        ],
        "summary": "Descargar bundle ZIP de un trabajo pseudo",
        "description": "El mapa nunca va en claro: con la cabecera X-Map-Password se incluye cifrado (<documento>_pseudo-map.enc, mismo formato que /pseudo/export?format=enc); sin ella, solo LEEME-mapa.txt.",
        "operationId": "downloadJobOutputBundle",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "X-Map-Password",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/batch-jobs/download-completed": {
      "get": {
        "tags": [
          "Lotes (API pública)"
        ],
        "summary": "Descargar ZIP de trabajos completados",
        "description": "X-Map-Password (opcional) cifra los mapas pseudo incluidos. Un trabajo cuyo mapa no está en la bóveda y llega sin contraseña se conserva en la cola para no perder el mapa.",
        "operationId": "downloadCompleted",
        "parameters": [
          {
            "name": "X-Map-Password",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/cases": {
      "get": {
        "tags": [
          "Expedientes (API pública)"
        ],
        "summary": "Listar los expedientes visibles para la clave",
        "description": "Del usuario de la clave o compartidos con su grupo, con recuentos por estado.",
        "operationId": "list_2",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CaseSummary"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/cases/{id}": {
      "get": {
        "tags": [
          "Expedientes (API pública)"
        ],
        "summary": "Estado de un expediente y de cada documento",
        "description": "UPLOADED, QUEUED, PROCESSING, DONE o FAILED por documento.",
        "operationId": "get",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/cases/{id}/download": {
      "get": {
        "tags": [
          "Expedientes (API pública)"
        ],
        "summary": "Descargar el expediente anonimizado en un ZIP",
        "description": "Documentos terminados e índice CSV/PDF sin datos personales; mapas pseudo solo como LEEME. 204 si no hay documentos terminados.",
        "operationId": "download",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/dashboard": {
      "get": {
        "tags": [
          "Plan y uso"
        ],
        "summary": "Dashboard del plan/uso del grupo",
        "operationId": "getDashboard",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/anonymize": {
      "post": {
        "tags": [
          "Documentos clásicos (API pública)"
        ],
        "summary": "Anonimizar (compatibilidad)",
        "operationId": "anonymize_1",
        "parameters": [
          {
            "name": "patterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "redactionZones",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/anonymize-by-ids": {
      "post": {
        "tags": [
          "Anonimización de Documentos"
        ],
        "summary": "Anonimizar PDF con Patrones y Wordsets por ID",
        "description": "**Funcionalidad Principal:**\nAnonimiza documentos PDF utilizando patrones regex y wordsets existentes en la base de datos,\nidentificados por sus IDs, junto con palabras sueltas opcionales.\n\n**Ventajas de este Endpoint:**\n- Reutiliza patrones y wordsets existentes\n- Mejor rendimiento al evitar recrear patrones\n- Gestión centralizada de patrones\n- Control de acceso basado en permisos de usuario\n\n**Casos de Uso:**\n- Anonimización de contratos y documentos legales\n- Protección de datos médicos en informes\n- Ocultación de información comercial confidencial\n- Preparación de documentos para auditorías\n- Procesamiento automatizado con patrones predefinidos\n\n**Proceso de Anonimización:**\n1. El PDF se analiza página por página\n2. Se cargan los patrones regex desde la base de datos usando los IDs\n3. Se cargan las palabras de los wordsets usando los IDs\n4. Se combinan con las palabras sueltas proporcionadas\n5. Se aplican todos los patrones y palabras para detectar información sensible\n6. Las coincidencias se marcan para anonimización\n7. Se genera un PDF con las zonas sensibles ocultadas\n\n**Cómo Enviar los Parámetros en Swagger:**\n- **patterns**: Escribe la palabra directamente sin comillas → `registro`\n- **wordSetIds**: Array JSON → `[2]` o `[1, 2, 3]`\n- **additionalWords**: Array JSON → `[\"palabra1\", \"palabra2\"]` o `[]`\n- **backgroundColor**: String → `black`\n- **textContent**: String → `none`\n- **highQuality**: Boolean → `false`\n",
        "operationId": "anonymizePdfByIds",
        "parameters": [
          {
            "name": "patternIds",
            "in": "query",
            "description": "IDs de patrones regex existentes en formato JSON",
            "required": false,
            "schema": {
              "type": "string",
              "default": "[]"
            },
            "example": [
              1,
              2,
              3
            ]
          },
          {
            "name": "wordSetIds",
            "in": "query",
            "description": "IDs de wordsets existentes en formato JSON",
            "required": false,
            "schema": {
              "type": "string",
              "default": "[]"
            },
            "example": [
              1,
              2,
              3
            ]
          },
          {
            "name": "additionalWords",
            "in": "query",
            "description": "Palabras sueltas adicionales en formato JSON",
            "required": false,
            "schema": {
              "type": "string",
              "default": "[]"
            },
            "example": [
              "palabra1",
              "palabra2"
            ]
          },
          {
            "name": "backgroundColor",
            "in": "query",
            "description": "Color de fondo para anonimización",
            "required": false,
            "schema": {
              "type": "string",
              "default": "black"
            },
            "example": "black"
          },
          {
            "name": "textContent",
            "in": "query",
            "description": "Contenido de texto para zonas anonimizadas",
            "required": false,
            "schema": {
              "type": "string",
              "default": "none"
            },
            "example": "none"
          },
          {
            "name": "highQuality",
            "in": "query",
            "description": "Procesamiento de alta calidad",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Archivo PDF a anonimizar"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PDF anonimizado exitosamente",
            "content": {
              "application/pdf": {
                "schema": {
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Solicitud inválida - Verificar IDs de patrones/wordsets",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Token JWT o API Key inválida",
            "content": {
              "application/json": {}
            }
          },
          "403": {
            "description": "Sin permisos para acceder a los patrones/wordsets especificados",
            "content": {
              "application/json": {}
            }
          },
          "404": {
            "description": "Patrones o wordsets no encontrados",
            "content": {
              "application/json": {}
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/anonymize-complete": {
      "post": {
        "tags": [
          "Documentos clásicos (API pública)"
        ],
        "summary": "Anonimización completa (patrones + zonas)",
        "operationId": "anonymizeComplete",
        "parameters": [
          {
            "name": "patterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "redactionZones",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          {
            "name": "wordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/anonymize-complete-inverse": {
      "post": {
        "tags": [
          "Documentos clásicos (API pública)"
        ],
        "summary": "Anonimización completa inversa",
        "operationId": "anonymizeCompleteInverse",
        "parameters": [
          {
            "name": "patterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "redactionZones",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          {
            "name": "wordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "excludePatterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "excludeWordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          {
            "name": "excludeWordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/anonymize-patterns": {
      "post": {
        "tags": [
          "Anonimización de Documentos"
        ],
        "summary": "Anonimizar PDF con Patrones Regex Directos",
        "description": "**Funcionalidad Principal:**\nAnonimiza documentos PDF utilizando patrones regex personalizados para detectar y ocultar información sensible.\n\n**Casos de Uso:**\n- Anonimización de contratos y documentos legales\n- Protección de datos médicos en informes\n- Ocultación de información comercial confidencial\n- Preparación de documentos para auditorías\n\n**Proceso de Anonimización:**\n1. El PDF se analiza página por página\n2. Se aplican los patrones regex especificados\n3. Las coincidencias se marcan para anonimización\n4. Se genera un PDF con las zonas sensibles ocultadas\n\n**Patrones Regex Comunes:**\n- DNI español: `\\d{8}[A-Z]`\n- Email: `[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}`\n- Teléfono: `\\+?[0-9]{9,15}`\n- Tarjeta crédito: `\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}[-\\s]?\\d{4}`\n\n**Cómo Enviar los Parámetros en Swagger:**\n- **patterns**: Array JSON con patrones regex → `[\"\\\\d{8}[A-Z]\", \"registro\"]`\n- **wordSetIds**: Array JSON con IDs → `[1, 2, 3]`\n- **backgroundColor**: String → `black`\n- **textContent**: String → `none`\n- **highQuality**: Boolean → `false`\n",
        "operationId": "anonymizePdfWithPatterns",
        "parameters": [
          {
            "name": "patterns",
            "in": "query",
            "description": "Patrones regex en formato JSON",
            "required": false,
            "schema": {
              "type": "string",
              "default": "[]"
            },
            "example": [
              "\\d{8}[A-Z]"
            ]
          },
          {
            "name": "wordSetIds",
            "in": "query",
            "description": "IDs de wordsets a aplicar",
            "required": false,
            "schema": {
              "type": "string",
              "default": "[]"
            },
            "example": [
              1,
              2,
              3
            ]
          },
          {
            "name": "backgroundColor",
            "in": "query",
            "description": "Color de fondo para anonimización",
            "required": false,
            "schema": {
              "type": "string",
              "default": "black"
            },
            "example": "black"
          },
          {
            "name": "textContent",
            "in": "query",
            "description": "Contenido de texto para zonas anonimizadas",
            "required": false,
            "schema": {
              "type": "string",
              "default": "none"
            },
            "example": "none"
          },
          {
            "name": "highQuality",
            "in": "query",
            "description": "Procesamiento de alta calidad",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Archivo PDF a anonimizar"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PDF anonimizado exitosamente",
            "content": {
              "application/pdf": {
                "schema": {
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Solicitud inválida",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Token JWT o API Key inválida",
            "content": {
              "application/json": {}
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/anonymize-specific-zones": {
      "post": {
        "tags": [
          "Documentos clásicos (API pública)"
        ],
        "summary": "Anonimizar zonas específicas (IA / coordenadas)",
        "operationId": "anonymizeSpecificZones",
        "parameters": [
          {
            "name": "zones",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "backgroundColor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "textContent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "censorHeightPadPx",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "aiOptions",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "customWords",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "patterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "pageOrientations",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ocrPreprocess",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "autoOcr",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "excludePatterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "excludeWordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          {
            "name": "excludeWordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/anonymize-whitelist": {
      "post": {
        "tags": [
          "Documentos clásicos (API pública)"
        ],
        "summary": "Anonimización por lista blanca",
        "operationId": "anonymizeWhitelist",
        "parameters": [
          {
            "name": "redactionZones",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "whitelistPatterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "whitelistWordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          {
            "name": "whitelistWordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "detectPattern",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "backgroundColor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "textContent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "censorHeightPadPx",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "whitelistSuppressions",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/anonymize-zones": {
      "post": {
        "tags": [
          "Documentos clásicos (API pública)"
        ],
        "summary": "Anonimizar solo zonas",
        "operationId": "anonymizeZones",
        "parameters": [
          {
            "name": "redactionZones",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/preview": {
      "post": {
        "tags": [
          "Documentos clásicos (API pública)"
        ],
        "summary": "Preview de anonimización",
        "operationId": "preview_2",
        "parameters": [
          {
            "name": "patterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "redactionZones",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "[]"
            }
          },
          {
            "name": "wordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "wordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "excludePatterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "excludeWordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          {
            "name": "excludeWordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "ocrPreprocess",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "autoOcr",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "backgroundColor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "textContent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "censorHeightPadPx",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {}
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/preview-inverse": {
      "post": {
        "tags": [
          "Documentos clásicos (API pública)"
        ],
        "summary": "Preview inversa (lista blanca)",
        "operationId": "previewInverse",
        "parameters": [
          {
            "name": "redactionZones",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "[]"
            }
          },
          {
            "name": "whitelistPatterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "whitelistWordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          {
            "name": "whitelistWordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "ocrPreprocess",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "autoOcr",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "backgroundColor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "textContent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "censorHeightPadPx",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {}
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/documents/result/searchable": {
      "post": {
        "tags": [
          "Documentos clásicos (API pública)"
        ],
        "summary": "Resultado buscable (OCR sobre PDF anonimizado)",
        "operationId": "resultSearchable",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/figure-patterns": {
      "get": {
        "tags": [
          "Patrones de figura (API pública)"
        ],
        "summary": "Listar patrones de figura del usuario",
        "operationId": "list_1",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FigurePatternResponseDTO"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Patrones de figura (API pública)"
        ],
        "summary": "Crear patrón de figura",
        "operationId": "create_1",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFigurePatternDTO"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/FigurePatternResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/figure-patterns/{id}": {
      "get": {
        "tags": [
          "Patrones de figura (API pública)"
        ],
        "summary": "Obtener patrón de figura por ID",
        "operationId": "getById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/FigurePatternResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Patrones de figura (API pública)"
        ],
        "summary": "Actualizar patrón de figura",
        "operationId": "update_1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFigurePatternDTO"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/FigurePatternResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Patrones de figura (API pública)"
        ],
        "summary": "Eliminar patrón de figura",
        "operationId": "delete_1",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/figure-patterns/{id}/zones": {
      "get": {
        "tags": [
          "Patrones de figura (API pública)"
        ],
        "summary": "Zonas del patrón como RedactionZoneDTO",
        "operationId": "getZones",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RedactionZoneDTO"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/formats/email/analyze": {
      "post": {
        "tags": [
          "Formatos (API pública)"
        ],
        "summary": "Analizar un correo (.eml/.msg)",
        "description": "Cabeceras, cuerpo y adjuntos. Sin cupo.",
        "operationId": "analyzeEmail",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/Analysis"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/formats/email/anonymize": {
      "post": {
        "tags": [
          "Formatos (API pública)"
        ],
        "summary": "Anonimizar un correo (.eml/.msg) con sus adjuntos",
        "description": "ZIP (base64) con el correo en PDF, los adjuntos anonimizados y, con includeEml, el .eml.",
        "operationId": "anonymizeEmail",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "options": {
                    "$ref": "#/components/schemas/FormatOptionsForm"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/Result"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/formats/tiff/from-pdf": {
      "post": {
        "tags": [
          "Formatos (API pública)"
        ],
        "summary": "PDF anonimizado → TIFF multipágina",
        "description": "Cupo de herramientas PDF.",
        "operationId": "tiffFromPdf",
        "parameters": [
          {
            "name": "dpi",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "colorMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/formats/word/editable": {
      "post": {
        "tags": [
          "Formatos (API pública)"
        ],
        "summary": "Word editable (.docx/.odt)",
        "description": "Documento con los datos sustituidos en el propio texto, verificado contra fugas.",
        "operationId": "wordEditable",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "options": {
                    "$ref": "#/components/schemas/FormatOptionsForm"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/Response"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/patterns": {
      "get": {
        "tags": [
          "Gestión de Patrones"
        ],
        "summary": "Obtener Todos los Patrones",
        "description": "**Biblioteca Completa de Patrones:**\nLista paginada de todos los patrones regex disponibles para el usuario.\n\n**Información Incluida:**\n- 🆔 ID único del patrón\n- Nombre y descripción\n- Expresión regex\n- Estadísticas de uso\n- Estado activo/inactivo\n- Fecha de creación y modificación\n",
        "operationId": "getAllPatterns",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Número de página (empezando en 1)",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          },
          {
            "name": "size",
            "in": "query",
            "description": "Elementos por página",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {}
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Gestión de Patrones"
        ],
        "summary": "Crear Nuevo Patrón",
        "description": "**Creación de Patrón Personalizado:**\nPermite crear un nuevo patrón regex personalizado para detección de información sensible.\n\n**Campos Requeridos:**\n- Nombre descriptivo\n- Expresión regex válida\n- Descripción del propósito\n- Tipo/categoría del patrón\n",
        "operationId": "createPattern",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatternRequestDTO"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/Patterns"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/patterns/{id}": {
      "get": {
        "tags": [
          "Gestión de Patrones"
        ],
        "summary": "Obtener Patrón por ID",
        "description": "**Detalles Completos del Patrón:**\nObtiene toda la información de un patrón específico incluyendo metadatos y estadísticas.\n",
        "operationId": "getPatternById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "🆔 ID único del patrón",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/Patterns"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Gestión de Patrones"
        ],
        "summary": "Actualizar Patrón Existente",
        "description": "**Modificación de Patrón:**\nPermite actualizar un patrón existente modificando cualquiera de sus propiedades.\n",
        "operationId": "updatePattern",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "🆔 ID del patrón a actualizar",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatternRequestDTO"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/Patterns"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Gestión de Patrones"
        ],
        "summary": "Eliminar Patrón",
        "description": "**Eliminación de Patrón:**\nElimina permanentemente un patrón de la biblioteca del usuario.\n\n**Advertencia:**Esta acción no se puede deshacer.\n",
        "operationId": "deletePattern",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "🆔 ID del patrón a eliminar",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/analyze-text-layer": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "Analizar capa de texto del PDF",
        "operationId": "analyzeTextLayer",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfTextLayerAnalysisResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/compress": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "Comprimir un PDF",
        "description": "Recomprime las imágenes embebidas a JPEG y reduce su resolución efectiva sin tocar el texto vectorial. `level`: `low` (calidad 0.85, máx. 200 ppp), `medium` (0.7, 150 ppp, por defecto) o `high` (0.5, 100 ppp). Si el resultado no es más pequeño se devuelve el original. Cabeceras `X-Original-Size` y `X-Compressed-Size` en bytes.",
        "operationId": "compressPdf",
        "parameters": [
          {
            "name": "level",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "medium"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/convert-to-pdf": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "Convertir documento/imagen a PDF",
        "operationId": "convertToPdf",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/images-to-pdf": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "Imágenes a PDF",
        "operationId": "imagesToPdf",
        "parameters": [
          {
            "name": "files",
            "in": "query",
            "required": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "binary"
              }
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/merge": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "Fusionar PDFs",
        "operationId": "mergePdfs",
        "parameters": [
          {
            "name": "files",
            "in": "query",
            "required": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "format": "binary"
              }
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/metadata": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "Editar los metadatos de un PDF",
        "description": "`metadata`: JSON con los campos de /metadata/read; un campo null o vacío se borra. `custom` null conserva los personalizados y un objeto los sustituye (un valor null o vacío no se escribe). `removeAll=true` borra antes Info, XMP y personalizados. El XMP se elimina siempre para que no contradiga los valores nuevos.",
        "operationId": "editMetadata",
        "parameters": [
          {
            "name": "metadata",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "removeAll",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/metadata/read": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "Leer los metadatos de un PDF",
        "description": "Devuelve título, autor, asunto, palabras clave, creador, productor, fechas de creación y modificación (ISO-8601 o null) y los campos personalizados (`custom`). No consume cupo.",
        "operationId": "readMetadata",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfMetadataDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/page-numbers": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "Numerar las páginas de un PDF",
        "description": "`position`: `bottom-center` (por defecto), `bottom-right`, `bottom-left`, `top-center`, `top-right` o `top-left`, sobre la página tal como se ve (respeta el giro). `format`: plantilla con `{n}` (número de página + `startNumber` - 1) y `{total}` (páginas del documento), p. ej. \"Página {n} de {total}\"; por defecto `{n}`. `startNumber`: número que corresponde a la página 1 (1). `fontSize`: 6–48 (11). `margin`: distancia al borde en puntos (24). `pages`: páginas a numerar (\"2-10\"); vacía = todas.",
        "operationId": "addPageNumbers",
        "parameters": [
          {
            "name": "position",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "bottom-center"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "{n}"
            }
          },
          {
            "name": "startNumber",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          },
          {
            "name": "fontSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 11
            }
          },
          {
            "name": "margin",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "format": "float",
              "default": 24
            }
          },
          {
            "name": "pages",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/pdf-to-images": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "Convertir páginas de un PDF a imágenes",
        "description": "`format`: `jpg` (por defecto) o `png`. `dpi`: 72–300 (por defecto 150). `pages`: expresión opcional (\"1-3,5\"); vacía = todas. Una sola página devuelve la imagen (`pagina-N.jpg`); varias, un ZIP `paginas-imagenes.zip` con `pagina-001.jpg`, `pagina-002.jpg`...",
        "operationId": "pdfToImages",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "jpg"
            }
          },
          {
            "name": "dpi",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 150
            }
          },
          {
            "name": "pages",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/pdf-to-searchable-pdf": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "PDF a PDF buscable (OCR)",
        "operationId": "pdfToSearchablePdf",
        "parameters": [
          {
            "name": "pages",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int32"
              }
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pdf-tools/split": {
      "post": {
        "tags": [
          "PDF tools (API pública)"
        ],
        "summary": "Extraer páginas de un PDF",
        "operationId": "splitPdf",
        "parameters": [
          {
            "name": "pages",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/permissions": {
      "get": {
        "tags": [
          "Plan y uso"
        ],
        "summary": "Permisos del grupo de la API key",
        "operationId": "getPermissions",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/plan": {
      "get": {
        "tags": [
          "Plan y uso"
        ],
        "summary": "Plan del grupo asociado a la API key",
        "description": "Devuelve el plan/límites del grupo Anonimatum vinculado a la API key.",
        "operationId": "getPlan",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/anonymize": {
      "post": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Pseudoanonimizar documento",
        "description": "outputMode: RASTER_TEXT (defecto) o VECTOR. Devuelve verification, vaultStored y contextId.",
        "operationId": "anonymize",
        "parameters": [
          {
            "name": "profileId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pseudoMethod",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "seed",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "patterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "wordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "aiOptions",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "customWords",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "excludePatterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "excludeWordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "excludeWordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "exclusionWords",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "excludeOfficeOccurrences",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "selectedOriginals",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "replacementOverrides",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "redactionZones",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ocrPreprocess",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "autoOcr",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "outputMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "methodsByType",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/PseudoAnonymizeResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/config/defaults": {
      "get": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Defaults de configuración",
        "operationId": "configDefaults",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/contexts": {
      "get": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Contextos de la bóveda visibles para el usuario",
        "operationId": "listContexts",
        "parameters": [
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PseudoContextSummaryDTO"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/contexts/{contextId}": {
      "delete": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Borrar un contexto de la bóveda",
        "operationId": "deleteContext",
        "parameters": [
          {
            "name": "contextId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/deanonymize": {
      "post": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Desanonimizar con mapa o con contextId de la bóveda",
        "operationId": "deanonymize",
        "parameters": [
          {
            "name": "X-Map-Password",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "password",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "contextId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "map": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/export/{contextId}": {
      "get": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Exportar mapa de contexto",
        "operationId": "exportMap",
        "parameters": [
          {
            "name": "contextId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "json"
            }
          },
          {
            "name": "X-Map-Password",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "password",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/lookup/{contextId}": {
      "get": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Lookup valor original desde pseudo",
        "operationId": "lookup",
        "parameters": [
          {
            "name": "contextId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "value",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/PseudoLookupResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/preview": {
      "post": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Preview de pseudoanonimización",
        "description": "methodsByType: JSON {\"<EntityType>\":\"<modo>\"}; language: es|en|ca|gl|eu|ro.",
        "operationId": "preview_1",
        "parameters": [
          {
            "name": "profileId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pseudoMethod",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "seed",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "patterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "wordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "aiOptions",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "customWords",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "excludePatterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "excludeWordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "excludeWordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "selectedOriginals",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "replacementOverrides",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "redactionZones",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ocrPreprocess",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "autoOcr",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "outputMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "methodsByType",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/PseudoPreviewResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/preview-document": {
      "post": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Previsualizar una página pseudoanonimizada (application/pdf)",
        "description": "Mismos parámetros que /anonymize más page (1-based). Sin bóveda ni cuota. Solo PDF/imagen.",
        "operationId": "previewDocument",
        "parameters": [
          {
            "name": "profileId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pseudoMethod",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "seed",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "patterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "wordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "aiOptions",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "customWords",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "excludePatterns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": ""
            }
          },
          {
            "name": "excludeWordSetIds",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "excludeWordSetMatchMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "full"
            }
          },
          {
            "name": "highQuality",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "selectedOriginals",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "replacementOverrides",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "redactionZones",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ocrPreprocess",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "autoOcr",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "outputMode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "methodsByType",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "byte"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/profiles": {
      "get": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Listar perfiles de pseudoanonimización",
        "operationId": "listProfiles",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PseudoProfileSummaryDTO"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/pseudo/profiles/{id}": {
      "get": {
        "tags": [
          "Pseudoanonimización (API pública)"
        ],
        "summary": "Detalle de perfil",
        "operationId": "getProfile",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/PseudoProfileDetailDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/sheets/analyze": {
      "post": {
        "tags": [
          "Hojas de cálculo por columnas (API pública)"
        ],
        "summary": "Analizar las columnas de una hoja de cálculo (xlsx, xls, ods, csv)",
        "description": "Cabecera, muestra y tipo sugerido por columna. Sin cupo.",
        "operationId": "analyze",
        "parameters": [
          {
            "name": "hasHeader",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "name": "sampleRows",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 10
            }
          },
          {
            "name": "useAi",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/Analysis"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/sheets/preview": {
      "post": {
        "tags": [
          "Hojas de cálculo por columnas (API pública)"
        ],
        "summary": "Vista previa del tratamiento por columnas",
        "description": "Sin cupo.",
        "operationId": "preview",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "options": {
                    "$ref": "#/components/schemas/SheetOptionsForm"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/Preview"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/sheets/process": {
      "post": {
        "tags": [
          "Hojas de cálculo por columnas (API pública)"
        ],
        "summary": "Tratar una hoja de cálculo por columnas",
        "description": "Mismo formato de salida; cupo: 1 página por cada 50 filas de datos.",
        "operationId": "process",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "options": {
                    "$ref": "#/components/schemas/SheetOptionsForm"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/SheetProcessResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/usage/current": {
      "get": {
        "tags": [
          "Plan y uso"
        ],
        "summary": "Uso del mes actual del grupo",
        "description": "Documentos/páginas consumidos en el mes en curso para el grupo de la API key.",
        "operationId": "getCurrentUsage",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/usage/history": {
      "get": {
        "tags": [
          "Plan y uso"
        ],
        "summary": "Historial de uso del grupo",
        "operationId": "getUsageHistory",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/usage/remaining": {
      "get": {
        "tags": [
          "Plan y uso"
        ],
        "summary": "Uso restante del mes",
        "operationId": "getRemainingUsage",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/usage/validate-operation": {
      "post": {
        "tags": [
          "Plan y uso"
        ],
        "summary": "Validar si una operación está permitida",
        "operationId": "validateOperation",
        "parameters": [
          {
            "name": "operationType",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/OperationValidationDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/webhooks": {
      "get": {
        "tags": [
          "Webhooks (API pública)"
        ],
        "summary": "Webhooks de esta API key",
        "operationId": "list",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookView"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Webhooks (API pública)"
        ],
        "summary": "Crear webhook",
        "description": "Eventos: batch.completed, batch.failed, publication.completed, publication.failed. Devuelve el secreto de firma una sola vez. Firma: X-Anonimatum-Signature t=<unix>,v1=<hex HMAC-SHA256(secreto, t.cuerpo)>; rechaza marcas de más de 5 minutos.",
        "operationId": "create",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookView"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/webhooks/{id}": {
      "put": {
        "tags": [
          "Webhooks (API pública)"
        ],
        "summary": "Cambiar webhook",
        "operationId": "update",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookView"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Webhooks (API pública)"
        ],
        "summary": "Borrar webhook",
        "operationId": "delete",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/webhooks/{id}/deliveries": {
      "get": {
        "tags": [
          "Webhooks (API pública)"
        ],
        "summary": "Registro de entregas",
        "operationId": "deliveries",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookDeliveryView"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/webhooks/{id}/rotate-secret": {
      "post": {
        "tags": [
          "Webhooks (API pública)"
        ],
        "summary": "Nuevo secreto de firma",
        "operationId": "rotate",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookView"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/webhooks/{id}/test": {
      "post": {
        "tags": [
          "Webhooks (API pública)"
        ],
        "summary": "Enviar prueba",
        "operationId": "test",
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryView"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/wordsets": {
      "get": {
        "tags": [
          "Gestión de Wordsets"
        ],
        "summary": "Obtener Todos los Wordsets",
        "description": "**Biblioteca Completa de Wordsets:**\nLista todos los diccionarios de palabras disponibles para el usuario.\n\n**Información Incluida:**\n- 🆔 ID único del wordset\n- Nombre y descripción\n- Número de palabras\n- Categoría/tipo\n- Estado activo\n- Última actualización\n",
        "operationId": "getAllWordSets",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WordSetResponseDTO"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Gestión de Wordsets"
        ],
        "summary": "Crear Nuevo Wordset",
        "description": "**Creación de Diccionario:**\nPermite crear un nuevo wordset personalizado con una lista de palabras.\n\n**Campos Requeridos:**\n- Nombre descriptivo\n- Descripción del propósito\n- Lista inicial de palabras\n- Categoría del wordset\n",
        "operationId": "createWordSet",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WordSetRequestDTO"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/WordSetResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/wordsets/{id}": {
      "get": {
        "tags": [
          "Gestión de Wordsets"
        ],
        "summary": "Obtener Wordset por ID",
        "description": "**Detalles Completos del Wordset:**\nObtiene toda la información de un wordset incluyendo la lista completa de palabras.\n",
        "operationId": "getWordSetById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "🆔 ID único del wordset",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/WordSetResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "put": {
        "tags": [
          "Gestión de Wordsets"
        ],
        "summary": "Actualizar Wordset",
        "description": "**Modificación de Wordset:**\nPermite actualizar un wordset existente incluyendo su lista de palabras.\n",
        "operationId": "updateWordSet",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "🆔 ID del wordset a actualizar",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WordSetRequestDTO"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/WordSetResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Gestión de Wordsets"
        ],
        "summary": "Eliminar Wordset",
        "description": "**Eliminación de Wordset:**\nElimina permanentemente un wordset y todas sus palabras asociadas.\n\n**Advertencia:**Esta acción no se puede deshacer.\n",
        "operationId": "deleteWordSet",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "🆔 ID del wordset a eliminar",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/api/public/wordsets/{id}/words": {
      "get": {
        "tags": [
          "Gestión de Wordsets"
        ],
        "summary": "Obtener Palabras de Wordset",
        "description": "**Lista de Palabras:**\nObtiene todas las palabras de un wordset específico con paginación.\n",
        "operationId": "getWordSetWords",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "🆔 ID del wordset",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "Número de página",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 1
            }
          },
          {
            "name": "size",
            "in": "query",
            "description": "Elementos por página",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 50
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Búsqueda por subcadena (opcional)",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {}
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "Gestión de Wordsets"
        ],
        "summary": "Agregar Palabra a Wordset",
        "description": "**Gestión de Palabras Individual:**\nAgrega una nueva palabra a un wordset existente.\n",
        "operationId": "addWordToSet",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "🆔 ID del wordset",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "word",
            "in": "query",
            "description": "Palabra a agregar",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/WordSetResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "tags": [
          "Gestión de Wordsets"
        ],
        "summary": "Eliminar Palabra de Wordset",
        "description": "**Gestión de Palabras Individual:**\nElimina una palabra específica de un wordset.\n",
        "operationId": "removeWordFromSet",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "🆔 ID del wordset",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "word",
            "in": "query",
            "description": "Palabra a eliminar",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/WordSetResponseDTO"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "Analysis": {
        "type": "object",
        "properties": {
          "format": {
            "type": "string"
          },
          "hasHeader": {
            "type": "boolean"
          },
          "rowsPerPage": {
            "type": "integer",
            "format": "int32"
          },
          "estimatedPages": {
            "type": "integer",
            "format": "int32"
          },
          "limits": {
            "type": "object",
            "additionalProperties": {
              "type": "number"
            }
          },
          "sheets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SheetInfo"
            }
          }
        }
      },
      "AttachmentOutcome": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string"
          },
          "filename": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "output": {
            "type": "string"
          }
        }
      },
      "CaseDetail": {
        "type": "object",
        "properties": {
          "summary": {
            "$ref": "#/components/schemas/CaseSummary"
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseDocumentDTO"
            }
          }
        }
      },
      "CaseDocumentDTO": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "fileName": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string"
          },
          "mode": {
            "type": "string"
          },
          "pages": {
            "type": "integer",
            "format": "int32"
          },
          "error": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "processedAt": {
            "type": "string",
            "format": "date-time"
          },
          "resultAvailable": {
            "type": "boolean"
          },
          "uploadedByUserId": {
            "type": "integer",
            "format": "int64"
          },
          "mine": {
            "type": "boolean"
          },
          "appliedTemplateId": {
            "type": "string"
          }
        }
      },
      "CaseSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "templateId": {
            "type": "string"
          },
          "templateName": {
            "type": "string"
          },
          "sharedMapId": {
            "type": "integer",
            "format": "int64"
          },
          "sharedMapName": {
            "type": "string"
          },
          "groupAccess": {
            "type": "boolean"
          },
          "creatorUserId": {
            "type": "integer",
            "format": "int64"
          },
          "mine": {
            "type": "boolean"
          },
          "canEdit": {
            "type": "boolean"
          },
          "documentCount": {
            "type": "integer",
            "format": "int32"
          },
          "doneCount": {
            "type": "integer",
            "format": "int32"
          },
          "failedCount": {
            "type": "integer",
            "format": "int32"
          },
          "pendingCount": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ColumnInfo": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "format": "int32"
          },
          "letter": {
            "type": "string"
          },
          "header": {
            "type": "string"
          },
          "samples": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "nonEmpty": {
            "type": "integer",
            "format": "int32"
          },
          "suggestedType": {
            "type": "string"
          },
          "confidence": {
            "type": "number",
            "format": "double"
          },
          "suggestedAction": {
            "type": "string"
          }
        }
      },
      "CreateFigurePatternDTO": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "groupCode": {
            "type": "string"
          },
          "zones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FigurePatternZoneDTO"
            }
          }
        }
      },
      "DocumentPseudoParams": {
        "type": "object",
        "properties": {
          "dateOffsetDays": {
            "type": "integer",
            "format": "int32"
          },
          "amountFactor": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "FigurePatternResponseDTO": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string"
          },
          "userCode": {
            "type": "string"
          },
          "groupCode": {
            "type": "string"
          },
          "zones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FigurePatternZoneDTO"
            }
          }
        }
      },
      "FigurePatternZoneDTO": {
        "type": "object",
        "properties": {
          "pageNumber": {
            "type": "integer",
            "format": "int32"
          },
          "type": {
            "type": "string"
          },
          "x": {
            "type": "number",
            "format": "float"
          },
          "y": {
            "type": "number",
            "format": "float"
          },
          "width": {
            "type": "number",
            "format": "float"
          },
          "height": {
            "type": "number",
            "format": "float"
          },
          "pointsJson": {
            "type": "string"
          }
        }
      },
      "FormatOptionsForm": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string"
          },
          "censorText": {
            "type": "string"
          },
          "patterns": {
            "type": "string"
          },
          "wordSetIds": {
            "type": "string"
          },
          "wordSetMatchMode": {
            "type": "string"
          },
          "excludePatterns": {
            "type": "string"
          },
          "excludeWordSetIds": {
            "type": "string"
          },
          "aiOptions": {
            "type": "string"
          },
          "customWords": {
            "type": "string"
          },
          "selectedOriginals": {
            "type": "string"
          },
          "excludeOfficeOccurrences": {
            "type": "string"
          },
          "profileId": {
            "type": "string"
          },
          "pseudoMethod": {
            "type": "string"
          },
          "seed": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "methodsByType": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "replacementOverrides": {
            "type": "string"
          },
          "imageRedaction": {
            "type": "string"
          },
          "backgroundColor": {
            "type": "string"
          },
          "textContent": {
            "type": "string"
          },
          "highQuality": {
            "type": "boolean"
          },
          "ocrPreprocess": {
            "type": "boolean"
          },
          "autoOcr": {
            "type": "boolean"
          },
          "includeEml": {
            "type": "boolean"
          }
        }
      },
      "LastDelivery": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string"
          },
          "httpStatus": {
            "type": "integer",
            "format": "int32"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "OperationValidationDTO": {
        "type": "object",
        "properties": {
          "allowed": {
            "type": "boolean"
          },
          "reason": {
            "type": "string"
          }
        }
      },
      "PatternRequestDTO": {
        "type": "object",
        "description": "Datos del nuevo patrón",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "pattern": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "active": {
            "type": "boolean"
          },
          "sensitivity": {
            "type": "number",
            "format": "double"
          },
          "patternIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            }
          },
          "wordSetId": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "Patterns": {
        "type": "object",
        "properties": {
          "fechaCreacion": {
            "type": "string",
            "format": "date-time"
          },
          "fechaModificacion": {
            "type": "string",
            "format": "date-time"
          },
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "pattern": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "userCode": {
            "type": "string"
          },
          "groupCode": {
            "type": "string"
          },
          "wordSetId": {
            "type": "integer",
            "format": "int64"
          },
          "tcreado": {
            "type": "string"
          },
          "tmodificado": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PdfMetadataDTO": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "author": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "keywords": {
            "type": "string"
          },
          "creator": {
            "type": "string"
          },
          "producer": {
            "type": "string"
          },
          "creationDate": {
            "type": "string"
          },
          "modificationDate": {
            "type": "string"
          },
          "custom": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        }
      },
      "PdfTextLayerAnalysisResult": {
        "type": "object",
        "properties": {
          "needsOcr": {
            "type": "boolean"
          },
          "pageCount": {
            "type": "integer",
            "format": "int32"
          },
          "extractedCharCount": {
            "type": "integer",
            "format": "int64"
          },
          "avgCharsPerPage": {
            "type": "number",
            "format": "double"
          },
          "imageHeavy": {
            "type": "boolean"
          },
          "hasFonts": {
            "type": "boolean"
          },
          "reason": {
            "type": "string"
          },
          "pagesNeedingOcr": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            }
          }
        }
      },
      "Preview": {
        "type": "object",
        "properties": {
          "sheets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SheetPreview"
            }
          }
        }
      },
      "PreviewCell": {
        "type": "object",
        "properties": {
          "column": {
            "type": "integer",
            "format": "int32"
          },
          "original": {
            "type": "string"
          },
          "result": {
            "type": "string"
          }
        }
      },
      "PreviewRow": {
        "type": "object",
        "properties": {
          "row": {
            "type": "integer",
            "format": "int32"
          },
          "cells": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PreviewCell"
            }
          }
        }
      },
      "PseudoAnonymizationConfig": {
        "type": "object",
        "properties": {
          "seed": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "profileId": {
            "type": "string"
          },
          "defaults": {
            "$ref": "#/components/schemas/PseudoEntityConfig"
          },
          "entities": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/PseudoEntityConfig"
            }
          },
          "documentDateOffsetDays": {
            "type": "integer",
            "format": "int32"
          },
          "documentAmountFactor": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "PseudoAnonymizeResponseDTO": {
        "type": "object",
        "properties": {
          "contextId": {
            "type": "string"
          },
          "downloadFilename": {
            "type": "string"
          },
          "mediaType": {
            "type": "string"
          },
          "documentBase64": {
            "type": "string"
          },
          "pseudoMap": {
            "$ref": "#/components/schemas/PseudoMapExportDTO"
          },
          "entityCount": {
            "type": "integer",
            "format": "int32"
          },
          "irreversibleCount": {
            "type": "integer",
            "format": "int32"
          },
          "outputMode": {
            "type": "string"
          },
          "verification": {
            "$ref": "#/components/schemas/PseudoOutputVerification"
          },
          "vaultStored": {
            "type": "boolean"
          },
          "projectId": {
            "type": "string"
          },
          "sharedMapId": {
            "type": "integer",
            "format": "int64"
          },
          "sharedMapNewEntries": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "PseudoContextSummaryDTO": {
        "type": "object",
        "properties": {
          "contextId": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "documentName": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "entityCount": {
            "type": "integer",
            "format": "int32"
          },
          "ownerUserId": {
            "type": "integer",
            "format": "int64"
          },
          "canDeanonymize": {
            "type": "boolean"
          }
        }
      },
      "PseudoEntityConfig": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "CONSISTENT_SUBSTITUTION",
              "PARTIAL_MASKING",
              "TOKENIZATION",
              "REVERSIBLE_ID_TABLE",
              "IRREVERSIBLE_HASH",
              "RELATIVE_DATE_SHIFT",
              "PROPORTIONAL_AMOUNT",
              "STRUCTURED_ADDRESS_SUBSTITUTION"
            ]
          },
          "visiblePrefix": {
            "type": "integer",
            "format": "int32"
          },
          "visibleSuffix": {
            "type": "integer",
            "format": "int32"
          },
          "tokenPrefix": {
            "type": "string"
          },
          "hashFormat": {
            "type": "string",
            "enum": [
              "HEX",
              "BASE64"
            ]
          },
          "hashSalt": {
            "type": "string"
          },
          "offsetDays": {
            "type": "integer",
            "format": "int32"
          },
          "amountFactor": {
            "type": "number",
            "format": "double"
          },
          "substitutionConstraints": {
            "$ref": "#/components/schemas/SubstitutionConstraints"
          },
          "language": {
            "type": "string",
            "writeOnly": true
          },
          "preserveApproxLength": {
            "type": "boolean",
            "writeOnly": true
          },
          "preserveGender": {
            "type": "boolean",
            "writeOnly": true
          },
          "preserveInitial": {
            "type": "boolean",
            "writeOnly": true
          },
          "maxLengthDelta": {
            "type": "integer",
            "format": "int32",
            "writeOnly": true
          }
        }
      },
      "PseudoEntityPreviewDTO": {
        "type": "object",
        "properties": {
          "previewId": {
            "type": "string"
          },
          "original": {
            "type": "string"
          },
          "entityType": {
            "type": "string",
            "enum": [
              "NOMBRE",
              "NOMBRE_MASCULINO",
              "NOMBRE_FEMENINO",
              "APELLIDO",
              "EMAIL",
              "TELEFONO",
              "DNI",
              "NIE",
              "CIF",
              "IBAN",
              "CIUDAD",
              "DIRECCION",
              "EMPRESA",
              "MATRICULA",
              "FECHA",
              "IMPORTE",
              "PERSONA_COMPLETA",
              "CUSTOM",
              "DESCONOCIDO"
            ]
          },
          "replacement": {
            "type": "string"
          },
          "recoverable": {
            "type": "boolean"
          },
          "mode": {
            "type": "string",
            "enum": [
              "CONSISTENT_SUBSTITUTION",
              "PARTIAL_MASKING",
              "TOKENIZATION",
              "REVERSIBLE_ID_TABLE",
              "IRREVERSIBLE_HASH",
              "RELATIVE_DATE_SHIFT",
              "PROPORTIONAL_AMOUNT",
              "STRUCTURED_ADDRESS_SUBSTITUTION"
            ]
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "x": {
            "type": "number",
            "format": "float"
          },
          "y": {
            "type": "number",
            "format": "float"
          },
          "width": {
            "type": "number",
            "format": "float"
          },
          "height": {
            "type": "number",
            "format": "float"
          },
          "pageWidth": {
            "type": "number",
            "format": "float"
          },
          "pageHeight": {
            "type": "number",
            "format": "float"
          },
          "textRotation": {
            "type": "number",
            "format": "float"
          }
        }
      },
      "PseudoLookupResponseDTO": {
        "type": "object",
        "properties": {
          "pseudoValue": {
            "type": "string"
          },
          "originalValue": {
            "type": "string"
          },
          "found": {
            "type": "boolean"
          }
        }
      },
      "PseudoMapEntryExportDTO": {
        "type": "object",
        "properties": {
          "original": {
            "type": "string"
          },
          "replacement": {
            "type": "string"
          },
          "entityType": {
            "type": "string"
          },
          "mode": {
            "type": "string"
          },
          "recoverable": {
            "type": "boolean"
          }
        }
      },
      "PseudoMapExportDTO": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string"
          },
          "contextId": {
            "type": "string"
          },
          "seed": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "profileId": {
            "type": "string"
          },
          "documentParams": {
            "$ref": "#/components/schemas/DocumentPseudoParams"
          },
          "forward": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "reverse": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PseudoMapEntryExportDTO"
            }
          }
        }
      },
      "PseudoOutputVerification": {
        "type": "object",
        "properties": {
          "leaks": {
            "type": "integer",
            "format": "int32"
          },
          "textLayer": {
            "type": "boolean"
          },
          "pages": {
            "type": "integer",
            "format": "int32"
          },
          "verified": {
            "type": "boolean"
          }
        }
      },
      "PseudoPreviewResponseDTO": {
        "type": "object",
        "properties": {
          "entities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PseudoEntityPreviewDTO"
            }
          },
          "countsBySource": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            }
          },
          "entityCount": {
            "type": "integer",
            "format": "int32"
          },
          "irreversibleCount": {
            "type": "integer",
            "format": "int32"
          },
          "profileId": {
            "type": "string"
          },
          "seed": {
            "type": "string"
          },
          "visualRedactionZones": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          }
        }
      },
      "PseudoProfileDetailDTO": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "sector": {
            "type": "string"
          },
          "config": {
            "$ref": "#/components/schemas/PseudoAnonymizationConfig"
          }
        }
      },
      "PseudoProfileSummaryDTO": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "sector": {
            "type": "string"
          }
        }
      },
      "RedactionZoneDTO": {
        "type": "object",
        "properties": {
          "x": {
            "type": "number",
            "format": "float"
          },
          "y": {
            "type": "number",
            "format": "float"
          },
          "width": {
            "type": "number",
            "format": "float"
          },
          "height": {
            "type": "number",
            "format": "float"
          },
          "viewerWidth": {
            "type": "number",
            "format": "float"
          },
          "viewerHeight": {
            "type": "number",
            "format": "float"
          },
          "viewerScale": {
            "type": "number",
            "format": "float"
          },
          "pageNumber": {
            "type": "integer",
            "format": "int32"
          },
          "textRotation": {
            "type": "number",
            "format": "float"
          },
          "protectionZone": {
            "type": "boolean"
          }
        }
      },
      "Response": {
        "type": "object",
        "properties": {
          "downloadFilename": {
            "type": "string"
          },
          "mediaType": {
            "type": "string"
          },
          "documentBase64": {
            "type": "string"
          },
          "pagesCharged": {
            "type": "integer",
            "format": "int32"
          },
          "entityCount": {
            "type": "integer",
            "format": "int32"
          },
          "replacements": {
            "type": "integer",
            "format": "int32"
          },
          "imagesRedacted": {
            "type": "integer",
            "format": "int32"
          },
          "imagesNotAnalyzed": {
            "type": "integer",
            "format": "int32"
          },
          "commentsRemoved": {
            "type": "integer",
            "format": "int32"
          },
          "revisionsResolved": {
            "type": "integer",
            "format": "int32"
          },
          "contextId": {
            "type": "string"
          },
          "vaultStored": {
            "type": "boolean"
          },
          "pseudoMap": {
            "$ref": "#/components/schemas/PseudoMapExportDTO"
          },
          "verification": {
            "$ref": "#/components/schemas/Verification"
          }
        }
      },
      "Result": {
        "type": "object",
        "properties": {
          "downloadFilename": {
            "type": "string"
          },
          "mediaType": {
            "type": "string"
          },
          "documentBase64": {
            "type": "string"
          },
          "pagesCharged": {
            "type": "integer",
            "format": "int32"
          },
          "entityCount": {
            "type": "integer",
            "format": "int32"
          },
          "emlIncluded": {
            "type": "boolean"
          },
          "contextId": {
            "type": "string"
          },
          "vaultStored": {
            "type": "boolean"
          },
          "pseudoMap": {
            "$ref": "#/components/schemas/PseudoMapExportDTO"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AttachmentOutcome"
            }
          }
        }
      },
      "SheetInfo": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string"
          },
          "dataRowCount": {
            "type": "integer",
            "format": "int32"
          },
          "columnCount": {
            "type": "integer",
            "format": "int32"
          },
          "columns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ColumnInfo"
            }
          }
        }
      },
      "SheetOptionsForm": {
        "type": "object",
        "properties": {
          "columns": {
            "type": "string"
          },
          "hasHeader": {
            "type": "boolean"
          },
          "censorText": {
            "type": "string"
          },
          "previewRows": {
            "type": "integer",
            "format": "int32"
          },
          "profileId": {
            "type": "string"
          },
          "pseudoMethod": {
            "type": "string"
          },
          "seed": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "methodsByType": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "patterns": {
            "type": "string"
          },
          "wordSetIds": {
            "type": "string"
          },
          "wordSetMatchMode": {
            "type": "string"
          },
          "aiOptions": {
            "type": "string"
          },
          "customWords": {
            "type": "string"
          },
          "sharedMapId": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "SheetPreview": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string"
          },
          "columns": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            }
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PreviewRow"
            }
          }
        }
      },
      "SheetProcessResponse": {
        "type": "object",
        "properties": {
          "downloadFilename": {
            "type": "string"
          },
          "mediaType": {
            "type": "string"
          },
          "documentBase64": {
            "type": "string"
          },
          "pagesCharged": {
            "type": "integer",
            "format": "int32"
          },
          "rowsProcessed": {
            "type": "integer",
            "format": "int32"
          },
          "cellsChanged": {
            "type": "integer",
            "format": "int32"
          },
          "entityCount": {
            "type": "integer",
            "format": "int32"
          },
          "contextId": {
            "type": "string"
          },
          "vaultStored": {
            "type": "boolean"
          },
          "sharedMapId": {
            "type": "integer",
            "format": "int64"
          },
          "sharedMapNewEntries": {
            "type": "integer",
            "format": "int32"
          },
          "pseudoMap": {
            "$ref": "#/components/schemas/PseudoMapExportDTO"
          }
        }
      },
      "SubstitutionConstraints": {
        "type": "object",
        "properties": {
          "preserveGender": {
            "type": "boolean"
          },
          "preserveInitial": {
            "type": "boolean"
          },
          "preserveApproxLength": {
            "type": "boolean"
          },
          "maxLengthDelta": {
            "type": "integer",
            "format": "int32"
          },
          "language": {
            "type": "string"
          }
        }
      },
      "Verification": {
        "type": "object",
        "properties": {
          "verified": {
            "type": "boolean"
          },
          "leaks": {
            "type": "integer",
            "format": "int32"
          },
          "checkedValues": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "WebhookDeliveryView": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "eventId": {
            "type": "string"
          },
          "eventType": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "attempts": {
            "type": "integer",
            "format": "int32"
          },
          "lastHttpStatus": {
            "type": "integer",
            "format": "int32"
          },
          "lastError": {
            "type": "string"
          },
          "durationMs": {
            "type": "integer",
            "format": "int64"
          },
          "lastAttemptAt": {
            "type": "string",
            "format": "date-time"
          },
          "nextAttemptAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "enabled": {
            "type": "boolean"
          }
        }
      },
      "WebhookView": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "url": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "enabled": {
            "type": "boolean"
          },
          "secretHint": {
            "type": "string"
          },
          "createdByApiKey": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastDelivery": {
            "$ref": "#/components/schemas/LastDelivery"
          },
          "secret": {
            "type": "string"
          }
        }
      },
      "WordSetRequestDTO": {
        "type": "object",
        "description": "Datos del nuevo wordset",
        "properties": {
          "wordSetIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            }
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "words": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "active": {
            "type": "boolean"
          }
        }
      },
      "WordSetResponseDTO": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string"
          },
          "userCode": {
            "type": "string"
          },
          "groupCode": {
            "type": "string"
          },
          "words": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "description": "API Key asociada a usuario + grupo Anonimatum (Intranet).",
        "name": "X-API-Key",
        "in": "header"
      },
      "BearerAuth": {
        "type": "http",
        "description": "Token JWT de sesión de usuario.",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "x-generated-from": "AnonimatumBack v/1-9-0 @ 39b3de2"
}
