Skip to main content
POST
/
api
/
contracts
/
preview
Preview Contract
curl --request POST \
  --url https://api.example.com/api/contracts/preview \
  --header 'Content-Type: application/json' \
  --data '
{
  "name": "<string>",
  "lastNameFather": "<string>",
  "lastNameMother": "<string>",
  "birthDate": "<string>",
  "sex": "<string>",
  "dni": "<string>",
  "email": "<string>",
  "address": "<string>",
  "province": "<string>",
  "district": "<string>",
  "department": "<string>",
  "salary": 123,
  "salaryInWords": "<string>",
  "position": "<string>",
  "entryDate": "<string>",
  "endDate": "<string>",
  "subDivisionOrParking": "<string>",
  "contractType": "<string>",
  "replacementFor": "<string>",
  "reasonForSubstitution": "<string>",
  "timeForCompany": "<string>",
  "workingCondition": "<string>",
  "probationaryPeriod": "<string>"
}
'
{
  "Content-Type": "<string>",
  "Content-Disposition": "<string>",
  "Content-Length": 123,
  "Body": {}
}

Overview

This endpoint generates a contract PDF for a single employee and returns it for preview or download. The PDF is returned inline, allowing it to be displayed directly in a browser or downloaded. Use this endpoint to:
  • Preview a contract before generating a batch
  • Download a single employee contract
  • Verify contract data and formatting

Request

Body Parameters

The request body contains a single employee object.
name
string
required
Employee’s first name (2-50 characters, letters only)
lastNameFather
string
required
Paternal last name (2-50 characters, letters only)
lastNameMother
string
required
Maternal last name (2-50 characters, letters only)
birthDate
string
required
Date of birth in format DD/MM/YYYY
sex
string
required
Gender of the employee
dni
string
required
National ID number - exactly 8 numeric digits
email
string
required
Valid email address
address
string
required
Street address (max 200 characters)
province
string
required
Province name (minimum 2 characters)
district
string
required
District name (minimum 2 characters)
department
string
required
Department name (minimum 2 characters)
salary
number
required
Salary amount (must be greater than 0)
salaryInWords
string
required
Salary written in words (5-100 characters)
position
string
required
Job position/title
entryDate
string
required
Employment start date in format DD/MM/YYYY
endDate
string
required
Contract end date in format DD/MM/YYYY
subDivisionOrParking
string
required
Subdivision or parking assignment
contractType
string
required
Type of contract. Must be one of: Planilla, Part Time, Subsidio
replacementFor
string
Required for Subsidio contracts only. Name of the person being replaced
reasonForSubstitution
string
Required for Subsidio contracts only. Reason for the substitution
timeForCompany
string
Required for Subsidio contracts only. Duration of employment with company
workingCondition
string
Required for Subsidio contracts only. Working conditions description
probationaryPeriod
string
Required for Subsidio contracts only. Probationary period duration

Response

Success Response

Content-Type
string
application/pdf
Content-Disposition
string
inline; filename="{dni}-{position}.pdf"The filename is based on the employee’s DNI and position.
Content-Length
number
Size of the PDF file in bytes
Body
binary
PDF file content

Error Responses

400 - Validation Error
Returned when the request body fails validation.
{
  "success": false,
  "message": "La solicitud no se pudo procesar",
  "errors": [
    {
      "field": "dni",
      "message": "DNI debe tener exactamente 8 dígitos numéricos."
    }
  ]
}
400 - Missing Required Fields for Subsidio
Returned when contract type is Subsidio but required fields are missing.
{
  "success": false,
  "message": "La solicitud no se pudo procesar",
  "errors": [
    {
      "field": "replacementFor",
      "message": "El campo 'SUPLENCIA DE' es obligatorio para contratos de Subsidio"
    },
    {
      "field": "reasonForSubstitution",
      "message": "El campo 'MOTIVO DE SUPLENCIA' es obligatorio para contratos de Subsidio"
    },
    {
      "field": "timeForCompany",
      "message": "El campo Tiempo en empresa es obligatorio"
    },
    {
      "field": "workingCondition",
      "message": "La condición laboral es obligatoria"
    },
    {
      "field": "probationaryPeriod",
      "message": "El periodo de prueba es obligatorio"
    }
  ]
}
500 - PDF Generation Error
Returned when there’s an error generating the PDF.
{
  "success": false,
  "message": "Error interno del servidor"
}

Examples

Preview Planilla Contract

curl -X POST https://api.example.com/api/contracts/preview \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Juan",
    "lastNameFather": "García",
    "lastNameMother": "López",
    "birthDate": "15/06/1990",
    "sex": "Masculino",
    "dni": "12345678",
    "email": "[email protected]",
    "address": "Av. Principal 123",
    "province": "Lima",
    "district": "Miraflores",
    "department": "Lima",
    "salary": 3500,
    "salaryInWords": "tres mil quinientos soles",
    "position": "Desarrollador",
    "entryDate": "01/03/2026",
    "endDate": "31/12/2026",
    "subDivisionOrParking": "Tecnología",
    "contractType": "Planilla"
  }' \
  --output contract-preview.pdf

Preview Part Time Contract

curl -X POST https://api.example.com/api/contracts/preview \
  -H "Content-Type: application/json" \
  -d '{
    "name": "María",
    "lastNameFather": "Pérez",
    "lastNameMother": "Silva",
    "birthDate": "20/03/1992",
    "sex": "Femenino",
    "dni": "87654321",
    "email": "[email protected]",
    "address": "Calle Los Olivos 456",
    "province": "Lima",
    "district": "San Isidro",
    "department": "Lima",
    "salary": 2500,
    "salaryInWords": "dos mil quinientos soles",
    "position": "Asistente",
    "entryDate": "15/03/2026",
    "endDate": "15/09/2026",
    "subDivisionOrParking": "Administración",
    "contractType": "Part Time"
  }' \
  --output contract-preview.pdf

Preview Subsidio Contract

curl -X POST https://api.example.com/api/contracts/preview \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Carlos",
    "lastNameFather": "Rodríguez",
    "lastNameMother": "Torres",
    "birthDate": "10/08/1988",
    "sex": "Masculino",
    "dni": "45678912",
    "email": "[email protected]",
    "address": "Jr. Las Flores 789",
    "province": "Lima",
    "district": "Surco",
    "department": "Lima",
    "salary": 4000,
    "salaryInWords": "cuatro mil soles",
    "position": "Analista Senior",
    "entryDate": "01/04/2026",
    "endDate": "30/06/2026",
    "subDivisionOrParking": "Finanzas",
    "contractType": "Subsidio",
    "replacementFor": "Ana Martínez",
    "reasonForSubstitution": "Licencia por maternidad",
    "timeForCompany": "3 meses",
    "workingCondition": "Tiempo completo",
    "probationaryPeriod": "30 días"
  }' \
  --output contract-preview.pdf

Display PDF in Browser

<iframe 
  src="https://api.example.com/api/contracts/preview" 
  width="100%" 
  height="600px"
  style="border: none;">
</iframe>

JavaScript Example with Fetch API

const previewContract = async (employeeData) => {
  try {
    const response = await fetch('https://api.example.com/api/contracts/preview', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(employeeData)
    });

    if (!response.ok) {
      const error = await response.json();
      console.error('Validation errors:', error.errors);
      return;
    }

    // Get the PDF as a blob
    const blob = await response.blob();
    
    // Create a URL for the blob
    const url = window.URL.createObjectURL(blob);
    
    // Open in new window or display in iframe
    window.open(url, '_blank');
    
    // Or trigger download
    const a = document.createElement('a');
    a.href = url;
    a.download = 'contract-preview.pdf';
    a.click();
  } catch (error) {
    console.error('Error previewing contract:', error);
  }
};

// Usage
const employee = {
  name: "Juan",
  lastNameFather: "García",
  lastNameMother: "López",
  birthDate: "15/06/1990",
  sex: "Masculino",
  dni: "12345678",
  email: "[email protected]",
  address: "Av. Principal 123",
  province: "Lima",
  district: "Miraflores",
  department: "Lima",
  salary: 3500,
  salaryInWords: "tres mil quinientos soles",
  position: "Desarrollador",
  entryDate: "01/03/2026",
  endDate: "31/12/2026",
  subDivisionOrParking: "Tecnología",
  contractType: "Planilla"
};

previewContract(employee);

Implementation Notes

  • The PDF is generated using Puppeteer in headless mode
  • The Content-Disposition header is set to inline to allow browser preview
  • The filename format is {dni}-{position}.pdf
  • This endpoint does not validate the employee data using the EmployeeBatchSchema middleware, so validation may differ slightly from the batch endpoint
  • Each request launches a new Puppeteer browser instance which is closed after PDF generation
  • The PDF generation uses the same templates as the batch download endpoint

Contract Type Requirements

All Contract Types

  • All base fields are required (name, DNI, email, address, salary, dates, etc.)
  • Dates must be in DD/MM/YYYY format
  • DNI must be exactly 8 numeric digits
  • Salary must be greater than 0

Subsidio Contracts

In addition to base fields, these are mandatory:
  • replacementFor - Name of person being replaced
  • reasonForSubstitution - Reason for the substitution
  • timeForCompany - Duration with the company
  • workingCondition - Working conditions
  • probationaryPeriod - Probationary period duration

Build docs developers (and LLMs) love