Saltar a contenido

Documentos (firma de PDF)

Hay tres endpoints de firma. Todos requieren token (Authorization: Bearer <token>) y que el dni indicado tenga un certificado principal cargado (ver Certificados). El archivo enviado en file debe tener Content-Type: application/pdf; cualquier otro tipo responde 400 BAD_REQUEST con "The file must be a PDF".

Endpoint Cómo se posiciona la firma Apariencia Parámetros de apariencia
sign-by-label Busca un texto (label) en el PDF Bloque simple: nombre, CQFP, cargo, empresa, motivo, fecha signatureWidth, signatureHeight, printCqfp, printJobTitle, printCompany, dateFormat, printLabelJobTitle, printLabelCompany, printLabelDate
sign-by-coord-simple Coordenadas explícitas (coordX, coordY, page) La misma apariencia simple que sign-by-label signatureWidth, signatureHeight, printCqfp, printJobTitle, printCompany, dateFormat, printLabelJobTitle, printLabelCompany, printLabelDate
sign-by-coord Coordenadas explícitas (coordX, coordY, page) Apariencia extendida en tabla (número de documento, ciudad/fecha, imagen opcional) documentTextNumberSize, signatureTextSpacing, documentTextNumberMultipliedLeading, cityAndDateTextSize, documentNumberTextFirst

sign-by-coord-simple existe para los casos que necesitan firmar en una posición exacta (sin buscar un texto en el PDF) pero con la apariencia simple de sign-by-label, sin tener que usar los parámetros adicionales de sign-by-coord (pensado para otro caso de uso).

En sign-by-label y sign-by-coord-simple, las líneas CQFP: <matrícula>, cargo y empresa solo se pintan si además de no estar desactivadas (printCqfp, printJobTitle, printCompany, todos true por defecto) el dato correspondiente no está vacío: tuition (ver Autenticación, campo opcional en signup), jobTitle o company del certificado. Si el dato está vacío, la línea se omite automáticamente sin necesidad de pasar el flag en false.

Además, printLabelJobTitle, printLabelCompany y printLabelDate (todos false por defecto) anteponen una etiqueta a esas líneas cuando están en true: "Cargo: ", "Empresa: " y "Fecha y hora: " respectivamente. Con el valor por defecto (false) el texto se pinta igual que antes, sin etiqueta.

Los tres devuelven un SignResponse:

{
  "fileBase64Encode": "<PDF firmado, codificado en Base64>",
  "status": "SUCCESS",
  "message": "Document signed successfully"
}

Ver ejemplos completos, incluyendo cómo decodificar la respuesta, en Casos de uso: firmar un documento por etiqueta, Casos de uso: firmar por coordenadas (apariencia simple) y en Casos de uso: firmar un documento por coordenadas.

POST /api/doc/sign-by-label

Busca una etiqueta de texto dentro del PDF (recorriendo todas las páginas) y coloca ahí el bloque de firma.

Parámetro Tipo Requerido Descripción
file multipart Sí PDF a firmar
dni string Sí DNI del firmante (dueño del certificado principal a usar)
label string Sí Texto exacto a buscar en el PDF para posicionar la firma
reason string Sí Motivo de la firma, se muestra en el sello
typeSigner int Sí 0 = no aplica, 1 = Suscriptor, 2 = Reemplazo
hasImageSignature boolean Sí Si true, usa la imagen de firma del usuario (/api/auth/{id}/upload-signature-img); si no hay imagen o es false, usa logo.png
useTsa boolean No Si true, agrega sello de tiempo (TSA)
tsaAlias string No Alias de TSA a usar; si se omite y useTsa=true, usa la TSA marcada como isDefault
signatureWidth float No Ancho del bloque de firma, en puntos (default 180)
signatureHeight float No Alto del bloque de firma, en puntos (default 100)
printCqfp boolean No Si false, omite la línea CQFP: <matrícula> del bloque de firma (default true, se pinta)
printJobTitle boolean No Si false, omite el cargo del firmante (default true, se pinta)
printCompany boolean No Si false, omite la empresa del firmante (default true, se pinta)
dateFormat string No Patrón DateTimeFormatter de Java para la fecha del bloque de firma (default yyyy-MM-dd HH:mm:ss, mostrada con sufijo " h"). Si se indica un patrón custom, no se agrega el sufijo " h". Un patrón inválido responde 500 INTERNAL_SERVER_ERROR
printLabelJobTitle boolean No Si true, antepone "Cargo: " a la línea del cargo (default false)
printLabelCompany boolean No Si true, antepone "Empresa: " a la línea de la empresa (default false)
printLabelDate boolean No Si true, antepone "Fecha y hora: " a la línea de la fecha (default false)

Importante: este endpoint no valida que el dni del token coincida con el dni enviado — cualquier usuario autenticado puede firmar en nombre de cualquier dni que tenga certificado principal cargado. Si no se encuentra la etiqueta en el PDF o no existe certificado principal para el dni, la firma falla con 500 INTERNAL_SERVER_ERROR.

curl -X POST http://localhost:8080/api/doc/sign-by-label \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
  -F "file=@contrato.pdf;type=application/pdf" \
  -F "dni=12345678" \
  -F "label=FIRMA_AQUI" \
  -F "reason=Aprobación de contrato" \
  -F "typeSigner=1" \
  -F "hasImageSignature=true" \
  -F "useTsa=true" \
  -F "tsaAlias=tsa-prd" \
  -F "signatureWidth=200" \
  -F "signatureHeight=110" \
  -F "printCqfp=false" \
  -F "printJobTitle=false" \
  -F "printCompany=false" \
  -F "dateFormat=dd/MM/yyyy HH:mm" \
  -F "printLabelJobTitle=true" \
  -F "printLabelCompany=true" \
  -F "printLabelDate=true"

POST /api/doc/sign-by-coord-simple

Firma en una posición explícita (x, y, página), igual que sign-by-coord, pero usando la misma apariencia simple de sign-by-label (nombre, CQFP opcional, cargo, empresa, motivo y fecha) en lugar de la apariencia extendida en tabla. Usar este endpoint cuando ya se conoce la posición exacta de la firma y no se necesitan los parámetros adicionales de sign-by-coord (número de documento, ciudad, alineaciones, etc.).

Parámetro Tipo Requerido Descripción
file multipart Sí PDF a firmar (application/pdf)
dni string Sí DNI del firmante (dueño del certificado principal a usar)
coordX, coordY string (numérico) Sí Coordenadas del bloque de firma en la página
page int Sí Número de página (1-indexado)
reason string Sí Motivo de la firma
typeSigner int Sí 0 = no aplica, 1 = Suscriptor, 2 = Reemplazo
hasImageSignature boolean Sí Igual que en sign-by-label
useTsa boolean No Igual que en sign-by-label
tsaAlias string No Igual que en sign-by-label
signatureWidth float No Ancho del bloque de firma, en puntos (default 180)
signatureHeight float No Alto del bloque de firma, en puntos (default 100)
printCqfp boolean No Si false, omite la línea CQFP: <matrícula> (default true)
printJobTitle boolean No Si false, omite el cargo del firmante (default true)
printCompany boolean No Si false, omite la empresa del firmante (default true)
dateFormat string No Igual que en sign-by-label
printLabelJobTitle boolean No Igual que en sign-by-label (default false)
printLabelCompany boolean No Igual que en sign-by-label (default false)
printLabelDate boolean No Igual que en sign-by-label (default false)

Al igual que sign-by-label, este endpoint no valida que el dni del token coincida con el dni enviado (a diferencia de sign-by-coord).

curl -X POST http://localhost:8080/api/doc/sign-by-coord-simple \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
  -F "file=@contrato.pdf;type=application/pdf" \
  -F "dni=12345678" \
  -F "coordX=120.5" \
  -F "coordY=680.0" \
  -F "page=1" \
  -F "reason=Aprobación de contrato" \
  -F "typeSigner=1" \
  -F "hasImageSignature=true" \
  -F "useTsa=false"

POST /api/doc/sign-by-coord

Firma en una posición explícita (x, y, página), con control fino sobre la apariencia del bloque de texto de la firma.

Parámetro Tipo Requerido Descripción
file multipart Sí PDF a firmar (application/pdf)
dni string Sí DNI del firmante; debe coincidir con el dni del token, si no responde 401 UNAUTHORIZED
coordX, coordY string (numérico) Sí Coordenadas del bloque de firma en la página
page int Sí Número de página (1-indexado)
reason string Sí Motivo de la firma
documentTextNumber string Sí Texto/código de documento a mostrar junto a la firma
documentTextNumberAlignment string Sí Alineación del texto anterior
city string No Ciudad a mostrar junto a la fecha; si se omite, no se pinta ni ciudad ni fecha
visibleSign boolean Sí Si el bloque de firma es visible en el PDF
hasImageSignature boolean No Igual que en sign-by-label
useTsa boolean No Igual que en sign-by-label
tsaAlias string No Igual que en sign-by-label
documentTextNumberSize float No Tamaño de fuente del texto de documento (default 10.0)
signatureTextSpacing float No Espaciado del texto de firma (default 30.0)
documentTextNumberMultipliedLeading float No Interlineado multiplicado (default 1.1)
cityAndDateTextSize float No Tamaño de fuente de ciudad/fecha (default 10)
documentNumberTextFirst boolean No Si el número de documento va antes que otros textos (default true)
curl -X POST http://localhost:8080/api/doc/sign-by-coord \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
  -F "file=@contrato.pdf;type=application/pdf" \
  -F "dni=12345678" \
  -F "coordX=120.5" \
  -F "coordY=680.0" \
  -F "page=1" \
  -F "reason=Aprobación de contrato" \
  -F "documentTextNumber=EXP-2026-001" \
  -F "documentTextNumberAlignment=LEFT" \
  -F "city=Lima" \
  -F "visibleSign=true" \
  -F "hasImageSignature=true" \
  -F "useTsa=false"

Comportamiento de useTsa / tsaAlias (ambos endpoints)

useTsa tsaAlias Resultado
false / ausente (cualquiera) No se agrega sello de tiempo
true vacío/ausente Usa la TSA activa marcada isDefault = true; si no existe ninguna, 400 BAD_REQUEST (No default TSA configuration found)
true <alias> Usa esa TSA; si el alias no existe o está eliminado, 400 BAD_REQUEST (TSA alias not found: <alias>)

Códigos de respuesta

Código Causa
200 OK Documento firmado correctamente
400 BAD_REQUEST Falta un campo requerido, archivo no es PDF, o error de negocio (TSA no encontrada, etc.)
401 UNAUTHORIZED Token inválido/vacío, o (sign-by-coord) el dni del token no coincide con el dni enviado
500 INTERNAL_SERVER_ERROR Error inesperado (etiqueta no encontrada, sin certificado principal para el dni, error de iText, etc.)