# Nómina electrónica

> Las operaciones de Nómina electrónica de la API de Trevol: parámetros, cuerpo, respuestas y ejemplos de código.

Fuente: https://platform.trevol.si/docs/api/payrolls

Documento soporte de pago de nómina electrónica (102) y su nota de ajuste (103: Reemplazar o Eliminar). Un 102 por trabajador y por mes en producción (y en habilitación cuando la empresa ya pasó el set de pruebas). Sin PDF ni correo: `xml`, `zip` y `dian_response`. El trabajador solo sale al dueño de la llave.

Los ejemplos son peticiones con cURL. La llave va en `TREVOL_API_KEY`; los cuerpos de ejemplo son los de la especificación. Los errores comunes están en [Errores](/docs/errores).

## Emitir una nómina electrónica

`POST /v1/payrolls` · `createPayroll`

Emite el documento soporte de pago de **nómina electrónica** (102) de un trabajador para un periodo. Trevol valida todo el contrato (periodo, trabajador, devengados y deducciones) ANTES de reservar, calcula los totales, numera (prefijo de nómina de la empresa), firma y lo manda a la DIAN. **En producción hay un solo 102 por trabajador y por mes** (art. 1.5.3.2.2): otro es `409 duplicate_document` con `existing_id`; para cambiarlo usa `POST /v1/payroll_adjustments`. La empresa debe tener la nómina habilitada ante la DIAN (`company_not_enabled`, `payroll_not_enabled`): con una llave `live`, `habilitada`; con una `test`, también el set de pruebas (`GET /v1/company` → `capabilities.payroll`). En el set de pruebas de habilitación responde `202 validating` en las dos versiones y reintentar no lo reenvía. No hay PDF ni correo: `xml`, `zip` y `dian_response`. Se cobra por empleado. Los datos del trabajador solo salen al dueño de la llave: no van en los webhooks ni en el registro de peticiones, y la respuesta guardada para la idempotencia no los copia.

**Respuestas.** `201` la DIAN lo validó (`status: accepted`). `202` solo en la versión 2026-10-22: la DIAN no contestó (`processing`), otra petición lo está enviando (`sending`) o, en habilitación, el set de pruebas todavía lo valida (`validating`, en las dos versiones); trae `Location` y `Retry-After`, y el resultado llega por GET y por webhook: **no crees otro documento para la misma operación**. `422` `validation_error` (se revisó a fondo ANTES de reservar: no se gastó el número, y `errors[]` dice el campo), `dian_rejected` (con `document` y las reglas traducidas; corrige con `PUT` y el mismo número), `company_not_enabled` o `numbering_unavailable` (con `reason`). `402` `insufficient_balance` (producción sin saldo: queda `pending` con su número). `409` `external_id_in_use` o `duplicate_document` (con `existing_id`). `503` `dian_unavailable` en la 2026-10-21. Pide `Idempotency-Key`: repetir la misma devuelve lo mismo sin enviar nada.

**Parámetros**

| Nombre | En | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | cabecera | texto | sí | Obligatoria: 1 a 255 caracteres ASCII visibles, única por pedido (7 días). |

**Cuerpo** ([PayrollInput](/docs/api/objetos#PayrollInput), obligatorio)

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `external_id` | texto |  | Tu identificador del documento: único entre los documentos API de la empresa y el ambiente. En las nóminas es único entre las nóminas y sus ajustes (aparte de las facturas y los eventos). |
| `period` | [PayrollPeriod](/docs/api/objetos#PayrollPeriod) | sí | El periodo que se liquida y el tiempo laborado (`time_worked` se calcula si no se manda: años de 360 días y meses de 30). |
| `pay_period` | texto | sí | Periodo de nómina (tabla 5.5.1): "1" semanal, "2" decenal, "3" catorcenal, "4" quincenal, "5" mensual, "6" otro. |
| `currency` | texto |  | Moneda (ISO 4217). Por defecto COP; con otra va `exchange_rate`. |
| `exchange_rate` | decimal |  | Tasa de cambio a pesos. Obligatoria con una moneda distinta de COP y prohibida con COP. |
| `novelty` | [PayrollNovelty](/docs/api/objetos#PayrollNovelty) |  | El CUNE del documento con la novedad contractual, si la hay. Solo en la nómina. |
| `notes` | lista de texto |  | Máximo 20. |
| `employee` | [PayrollEmployee](/docs/api/objetos#PayrollEmployee) | sí | El trabajador. Sus datos solo salen en las respuestas a esta llave (la del empleador): nunca en webhooks, en el registro de peticiones ni en lo que se guarda de la idempotencia. |
| `payment` | [PayrollPayment](/docs/api/objetos#PayrollPayment) | sí |  |
| `payment_dates` | lista de fecha (AAAA-MM-DD) | sí | Las fechas de pago (1 a 31). Máximo 31. |
| `earnings` | [PayrollEarnings](/docs/api/objetos#PayrollEarnings) | sí |  |
| `deductions` | [PayrollDeductions](/docs/api/objetos#PayrollDeductions) | sí |  |
| `rounding` | decimal |  | Redondeo hasta 2.00; no suma a los totales. |
| `generation_place` | [PayrollPlace](/docs/api/objetos#PayrollPlace) |  | Dónde se generó el documento. Por defecto, el municipio de la empresa. |
| `employer` | [PayrollEmployer](/docs/api/objetos#PayrollEmployer) |  | Solo si la empresa es persona natural: sus apellidos y nombres (si la razón social no se separa bien en «apellido1 apellido2 nombre1»). |

**Respuestas**

| Estado | Qué pasó |
| --- | --- |
| 201 | El documento ([Payroll](/docs/api/objetos#Payroll)) |
| 202 | Versión 2026-10-22: la DIAN no contestó (`status: processing`; Trevol termina el documento y avisa por webhook; no crees otro documento para la misma venta, y si repites con la misma Idempotency-Key respondemos sin enviar) o el documento se está enviando (`status: sending`); también la contingencia (`status: contingency`). Lleva `Location` y, salvo la contingencia, `Retry-After: 30`. En 2026-10-21 la DIAN sin contestar es un 503 `dian_unavailable`. También `status: validating` (en las dos versiones): el set de pruebas de habilitación de nómina recibió el documento y todavía lo valida; reintentar con la misma Idempotency-Key, `POST …/send` o corregir responde lo mismo SIN reenviar (`PUT` en ese estado es 409 `invalid_state`). ([Payroll](/docs/api/objetos#Payroll)) |
| 402 | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |
| 409 | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |
| 422 | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |
| 429 | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |
| 503 | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |
| Error | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |

`POST /v1/payrolls` (`createPayroll`)

#### cURL

```bash
curl -X POST "https://api.trevol.si/v1/payrolls" \
  -H "Authorization: Bearer $TREVOL_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "external_id": "NOM-2026-09-001",
  "period": {
    "hire_date": "2024-03-01",
    "start": "2026-09-01",
    "end": "2026-09-30"
  },
  "pay_period": "5",
  "notes": [
    "Nómina de septiembre de 2026"
  ],
  "employee": {
    "type": "01",
    "subtype": "00",
    "high_risk_pension": false,
    "document_type": "13",
    "document_number": "1000000101",
    "first_surname": "PRUEBA",
    "second_surname": "NOMINA01",
    "first_name": "TRABAJADOR",
    "other_names": "DE PRUEBA",
    "workplace": {
      "country": "CO",
      "municipality_code": "76001",
      "address": "Calle 1 # 1-1"
    },
    "integral_salary": false,
    "contract_type": "2",
    "salary": "1423500",
    "code": "TRAB-01"
  },
  "payment": {
    "form": "1",
    "method": "42",
    "bank": "Banco de Pruebas",
    "account_type": "Ahorros",
    "account_number": "0001234501"
  },
  "payment_dates": [
    "2026-09-30"
  ],
  "earnings": {
    "basic": {
      "days": 30,
      "amount": "1423500"
    },
    "transport": [
      {
        "allowance": "200000"
      }
    ]
  },
  "deductions": {
    "health": {
      "percent": "4",
      "amount": "56940"
    },
    "pension": {
      "percent": "4",
      "amount": "56940"
    }
  }
}'
```

#### Respuesta 201

```json
{
  "id": "pr_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b",
  "object": "payroll",
  "environment": "live",
  "status": "accepted",
  "number": "NE15",
  "prefix": "NE",
  "external_id": "NOM-2026-09-001",
  "origin": "api",
  "cune": "abababababababababababababababababababababababababababababababababababababababababababababababab",
  "qr": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=abababababababababababababababababababababababababababababababababababababababababababababababab",
  "issued_at": "2026-10-23T09:15:02-05:00",
  "submission": "sync",
  "period": {
    "hire_date": "2024-03-01",
    "start": "2026-09-01",
    "end": "2026-09-30"
  },
  "pay_period": "5",
  "currency": "COP",
  "notes": [
    "Nómina de septiembre de 2026"
  ],
  "employee": {
    "type": "01",
    "subtype": "00",
    "high_risk_pension": false,
    "document_type": "13",
    "document_number": "1000000101",
    "first_surname": "PRUEBA",
    "second_surname": "NOMINA01",
    "first_name": "TRABAJADOR",
    "other_names": "DE PRUEBA",
    "workplace": {
      "country": "CO",
      "municipality_code": "76001",
      "address": "Calle 1 # 1-1"
    },
    "integral_salary": false,
    "contract_type": "2",
    "salary": "1423500",
    "code": "TRAB-01"
  },
  "payment": {
    "form": "1",
    "method": "42",
    "bank": "Banco de Pruebas",
    "account_type": "Ahorros",
    "account_number": "0001234501"
  },
  "payment_dates": [
    "2026-09-30"
  ],
  "earnings": {
    "basic": {
      "days": 30,
      "amount": "1423500"
    },
    "transport": [
      {
        "allowance": "200000"
      }
    ]
  },
  "deductions": {
    "health": {
      "percent": "4",
      "amount": "56940"
    },
    "pension": {
      "percent": "4",
      "amount": "56940"
    }
  },
  "totals": {
    "earnings": "1623500.00",
    "deductions": "113880.00",
    "net": "1509620.00"
  },
  "dian": {
    "status_code": "00",
    "message": "Procesado Correctamente.",
    "rules": []
  },
  "files": {
    "xml": true,
    "zip": true,
    "dian_response": true
  },
  "created_at": "2026-10-23T09:15:02-05:00",
  "updated_at": "2026-10-23T09:15:03-05:00"
}
```

[Probar en el Playground](https://platform.trevol.si/playground?op=createPayroll&ejemplo=mensual)

## Calcular una nómina electrónica sin emitirla

`POST /v1/payrolls/preview` · `previewPayroll`

Valida y calcula los totales de la nómina **sin** reservar un número ni enviar nada. No pide `Idempotency-Key` y no se cobra. El trabajador que mandaste vuelve en la respuesta; Trevol no lo guarda.

**Cuerpo** ([PayrollInput](/docs/api/objetos#PayrollInput), obligatorio)

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `external_id` | texto |  | Tu identificador del documento: único entre los documentos API de la empresa y el ambiente. En las nóminas es único entre las nóminas y sus ajustes (aparte de las facturas y los eventos). |
| `period` | [PayrollPeriod](/docs/api/objetos#PayrollPeriod) | sí | El periodo que se liquida y el tiempo laborado (`time_worked` se calcula si no se manda: años de 360 días y meses de 30). |
| `pay_period` | texto | sí | Periodo de nómina (tabla 5.5.1): "1" semanal, "2" decenal, "3" catorcenal, "4" quincenal, "5" mensual, "6" otro. |
| `currency` | texto |  | Moneda (ISO 4217). Por defecto COP; con otra va `exchange_rate`. |
| `exchange_rate` | decimal |  | Tasa de cambio a pesos. Obligatoria con una moneda distinta de COP y prohibida con COP. |
| `novelty` | [PayrollNovelty](/docs/api/objetos#PayrollNovelty) |  | El CUNE del documento con la novedad contractual, si la hay. Solo en la nómina. |
| `notes` | lista de texto |  | Máximo 20. |
| `employee` | [PayrollEmployee](/docs/api/objetos#PayrollEmployee) | sí | El trabajador. Sus datos solo salen en las respuestas a esta llave (la del empleador): nunca en webhooks, en el registro de peticiones ni en lo que se guarda de la idempotencia. |
| `payment` | [PayrollPayment](/docs/api/objetos#PayrollPayment) | sí |  |
| `payment_dates` | lista de fecha (AAAA-MM-DD) | sí | Las fechas de pago (1 a 31). Máximo 31. |
| `earnings` | [PayrollEarnings](/docs/api/objetos#PayrollEarnings) | sí |  |
| `deductions` | [PayrollDeductions](/docs/api/objetos#PayrollDeductions) | sí |  |
| `rounding` | decimal |  | Redondeo hasta 2.00; no suma a los totales. |
| `generation_place` | [PayrollPlace](/docs/api/objetos#PayrollPlace) |  | Dónde se generó el documento. Por defecto, el municipio de la empresa. |
| `employer` | [PayrollEmployer](/docs/api/objetos#PayrollEmployer) |  | Solo si la empresa es persona natural: sus apellidos y nombres (si la razón social no se separa bien en «apellido1 apellido2 nombre1»). |

**Respuestas**

| Estado | Qué pasó |
| --- | --- |
| 200 | Totales ([Preview](/docs/api/objetos#Preview)) |
| Error | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |

`POST /v1/payrolls/preview` (`previewPayroll`)

#### cURL

```bash
curl -X POST "https://api.trevol.si/v1/payrolls/preview" \
  -H "Authorization: Bearer $TREVOL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "external_id": "NOM-2026-09-001",
  "period": {
    "hire_date": "2024-03-01",
    "start": "2026-09-01",
    "end": "2026-09-30"
  },
  "pay_period": "5",
  "notes": [
    "Nómina de septiembre de 2026"
  ],
  "employee": {
    "type": "01",
    "subtype": "00",
    "high_risk_pension": false,
    "document_type": "13",
    "document_number": "1000000101",
    "first_surname": "PRUEBA",
    "second_surname": "NOMINA01",
    "first_name": "TRABAJADOR",
    "other_names": "DE PRUEBA",
    "workplace": {
      "country": "CO",
      "municipality_code": "76001",
      "address": "Calle 1 # 1-1"
    },
    "integral_salary": false,
    "contract_type": "2",
    "salary": "1423500",
    "code": "TRAB-01"
  },
  "payment": {
    "form": "1",
    "method": "42",
    "bank": "Banco de Pruebas",
    "account_type": "Ahorros",
    "account_number": "0001234501"
  },
  "payment_dates": [
    "2026-09-30"
  ],
  "earnings": {
    "basic": {
      "days": 30,
      "amount": "1423500"
    },
    "transport": [
      {
        "allowance": "200000"
      }
    ]
  },
  "deductions": {
    "health": {
      "percent": "4",
      "amount": "56940"
    },
    "pension": {
      "percent": "4",
      "amount": "56940"
    }
  }
}'
```

[Probar en el Playground](https://platform.trevol.si/playground?op=previewPayroll&ejemplo=mensual)

## Reenviar una pendiente o en error

`POST /v1/payrolls/{id}/send` · `sendPayroll`

Vuelve a enviar una nómina `pending` o `error`. Si el set de pruebas la valida (`validating`), solo consulta.

Sin cuerpo. Con un documento `accepted` responde `200` con el documento tal cual; con uno que la DIAN todavía verifica no reenvía nada (`202`); con uno `rejected` es `409 invalid_state` (se corrige con `PUT`). No pide `Idempotency-Key` (reintentarlo es seguro).

**Respuestas**

| Estado | Qué pasó |
| --- | --- |
| 200 | El documento ([Payroll](/docs/api/objetos#Payroll)) |
| 202 | Versión 2026-10-22: la DIAN no contestó (`status: processing`; Trevol termina el documento y avisa por webhook; no crees otro documento para la misma venta, y si repites con la misma Idempotency-Key respondemos sin enviar) o el documento se está enviando (`status: sending`); también la contingencia (`status: contingency`). Lleva `Location` y, salvo la contingencia, `Retry-After: 30`. En 2026-10-21 la DIAN sin contestar es un 503 `dian_unavailable`. También `status: validating` (en las dos versiones): el set de pruebas de habilitación de nómina recibió el documento y todavía lo valida; reintentar con la misma Idempotency-Key, `POST …/send` o corregir responde lo mismo SIN reenviar (`PUT` en ese estado es 409 `invalid_state`). ([Payroll](/docs/api/objetos#Payroll)) |
| 409 | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |
| Error | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |

`POST /v1/payrolls/{id}/send` (`sendPayroll`)

#### cURL

```bash
curl -X POST "https://api.trevol.si/v1/payrolls/pr_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b/send" \
  -H "Authorization: Bearer $TREVOL_API_KEY"
```

#### Respuesta 200

```json
{
  "id": "pr_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b",
  "object": "payroll",
  "environment": "live",
  "status": "accepted",
  "number": "NE15",
  "prefix": "NE",
  "external_id": "NOM-2026-09-001",
  "origin": "api",
  "cune": "abababababababababababababababababababababababababababababababababababababababababababababababab",
  "qr": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=abababababababababababababababababababababababababababababababababababababababababababababababab",
  "issued_at": "2026-10-23T09:15:02-05:00",
  "submission": "sync",
  "period": {
    "hire_date": "2024-03-01",
    "start": "2026-09-01",
    "end": "2026-09-30"
  },
  "pay_period": "5",
  "currency": "COP",
  "notes": [
    "Nómina de septiembre de 2026"
  ],
  "employee": {
    "type": "01",
    "subtype": "00",
    "high_risk_pension": false,
    "document_type": "13",
    "document_number": "1000000101",
    "first_surname": "PRUEBA",
    "second_surname": "NOMINA01",
    "first_name": "TRABAJADOR",
    "other_names": "DE PRUEBA",
    "workplace": {
      "country": "CO",
      "municipality_code": "76001",
      "address": "Calle 1 # 1-1"
    },
    "integral_salary": false,
    "contract_type": "2",
    "salary": "1423500",
    "code": "TRAB-01"
  },
  "payment": {
    "form": "1",
    "method": "42",
    "bank": "Banco de Pruebas",
    "account_type": "Ahorros",
    "account_number": "0001234501"
  },
  "payment_dates": [
    "2026-09-30"
  ],
  "earnings": {
    "basic": {
      "days": 30,
      "amount": "1423500"
    },
    "transport": [
      {
        "allowance": "200000"
      }
    ]
  },
  "deductions": {
    "health": {
      "percent": "4",
      "amount": "56940"
    },
    "pension": {
      "percent": "4",
      "amount": "56940"
    }
  },
  "totals": {
    "earnings": "1623500.00",
    "deductions": "113880.00",
    "net": "1509620.00"
  },
  "dian": {
    "status_code": "00",
    "message": "Procesado Correctamente.",
    "rules": []
  },
  "files": {
    "xml": true,
    "zip": true,
    "dian_response": true
  },
  "created_at": "2026-10-23T09:15:02-05:00",
  "updated_at": "2026-10-23T09:15:03-05:00"
}
```

[Probar en el Playground](https://platform.trevol.si/playground?op=sendPayroll)

## Listar (nómina electrónica)

`GET /v1/payrolls` · `listPayrolls`

Paginación por cursor y filtros `status`, `external_id`, `created_from`, `created_to`, `employee_code` (el código interno del empleado) y `period_end_from` / `period_end_to`. **No se filtra por el documento del trabajador**: la cédula en la URL quedaría en los registros del servidor.

**Parámetros**

| Nombre | En | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| `limit` | consulta | entero |  |  |
| `starting_after` | consulta | texto |  |  |
| `status` | consulta | texto |  |  |
| `external_id` | consulta | texto |  |  |
| `created_from` | consulta | texto |  |  |
| `created_to` | consulta | texto |  |  |
| `employee_code` | consulta | texto |  |  |
| `period_end_from` | consulta | fecha (AAAA-MM-DD) |  |  |
| `period_end_to` | consulta | fecha (AAAA-MM-DD) |  |  |

**Respuestas**

| Estado | Qué pasó |
| --- | --- |
| 200 | {object: list, data, has_more, next_cursor} (objeto) |
| Error | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |

`GET /v1/payrolls` (`listPayrolls`)

#### cURL

```bash
curl "https://api.trevol.si/v1/payrolls?limit=100" \
  -H "Authorization: Bearer $TREVOL_API_KEY"
```

[Probar en el Playground](https://platform.trevol.si/playground?op=listPayrolls)

## Una nómina electrónica

`GET /v1/payrolls/{id}` · `retrievePayroll`

La nómina tal como se emitió, con el trabajador, los devengados, las deducciones y los totales (`earnings`, `deductions`, `net`).

**Respuestas**

| Estado | Qué pasó |
| --- | --- |
| 200 | El documento ([Payroll](/docs/api/objetos#Payroll)) |
| Error | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |

`GET /v1/payrolls/{id}` (`retrievePayroll`)

#### cURL

```bash
curl "https://api.trevol.si/v1/payrolls/pr_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b" \
  -H "Authorization: Bearer $TREVOL_API_KEY"
```

#### Respuesta 200

```json
{
  "id": "pr_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b",
  "object": "payroll",
  "environment": "live",
  "status": "accepted",
  "number": "NE15",
  "prefix": "NE",
  "external_id": "NOM-2026-09-001",
  "origin": "api",
  "cune": "abababababababababababababababababababababababababababababababababababababababababababababababab",
  "qr": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=abababababababababababababababababababababababababababababababababababababababababababababababab",
  "issued_at": "2026-10-23T09:15:02-05:00",
  "submission": "sync",
  "period": {
    "hire_date": "2024-03-01",
    "start": "2026-09-01",
    "end": "2026-09-30"
  },
  "pay_period": "5",
  "currency": "COP",
  "notes": [
    "Nómina de septiembre de 2026"
  ],
  "employee": {
    "type": "01",
    "subtype": "00",
    "high_risk_pension": false,
    "document_type": "13",
    "document_number": "1000000101",
    "first_surname": "PRUEBA",
    "second_surname": "NOMINA01",
    "first_name": "TRABAJADOR",
    "other_names": "DE PRUEBA",
    "workplace": {
      "country": "CO",
      "municipality_code": "76001",
      "address": "Calle 1 # 1-1"
    },
    "integral_salary": false,
    "contract_type": "2",
    "salary": "1423500",
    "code": "TRAB-01"
  },
  "payment": {
    "form": "1",
    "method": "42",
    "bank": "Banco de Pruebas",
    "account_type": "Ahorros",
    "account_number": "0001234501"
  },
  "payment_dates": [
    "2026-09-30"
  ],
  "earnings": {
    "basic": {
      "days": 30,
      "amount": "1423500"
    },
    "transport": [
      {
        "allowance": "200000"
      }
    ]
  },
  "deductions": {
    "health": {
      "percent": "4",
      "amount": "56940"
    },
    "pension": {
      "percent": "4",
      "amount": "56940"
    }
  },
  "totals": {
    "earnings": "1623500.00",
    "deductions": "113880.00",
    "net": "1509620.00"
  },
  "dian": {
    "status_code": "00",
    "message": "Procesado Correctamente.",
    "rules": []
  },
  "files": {
    "xml": true,
    "zip": true,
    "dian_response": true
  },
  "created_at": "2026-10-23T09:15:02-05:00",
  "updated_at": "2026-10-23T09:15:03-05:00"
}
```

[Probar en el Playground](https://platform.trevol.si/playground?op=retrievePayroll)

## Archivo xml

`GET /v1/payrolls/{id}/xml` · `downloadPayrollXml`

El XML firmado que se mandó a la DIAN (`application/xml`).

**Respuestas**

| Estado | Qué pasó |
| --- | --- |
| 200 | xml (archivo) |
| Error | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |

`GET /v1/payrolls/{id}/xml` (`downloadPayrollXml`)

#### cURL

```bash
curl "https://api.trevol.si/v1/payrolls/pr_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b/xml" \
  -H "Authorization: Bearer $TREVOL_API_KEY" \
  -o payroll_xml.xml
```

[Probar en el Playground](https://platform.trevol.si/playground?op=downloadPayrollXml)

## Archivo zip

`GET /v1/payrolls/{id}/zip` · `downloadPayrollZip`

El ZIP del documento (`application/zip`).

**Respuestas**

| Estado | Qué pasó |
| --- | --- |
| 200 | zip (archivo) |
| Error | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |

`GET /v1/payrolls/{id}/zip` (`downloadPayrollZip`)

#### cURL

```bash
curl "https://api.trevol.si/v1/payrolls/pr_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b/zip" \
  -H "Authorization: Bearer $TREVOL_API_KEY" \
  -o payroll_zip.zip
```

[Probar en el Playground](https://platform.trevol.si/playground?op=downloadPayrollZip)

## Archivo dian_response

`GET /v1/payrolls/{id}/dian_response` · `downloadPayrollDianResponse`

El `ApplicationResponse` con que la DIAN contestó (`application/xml`), si la DIAN lo devolvió.

**Respuestas**

| Estado | Qué pasó |
| --- | --- |
| 200 | dian_response (archivo) |
| Error | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |

`GET /v1/payrolls/{id}/dian_response` (`downloadPayrollDianResponse`)

#### cURL

```bash
curl "https://api.trevol.si/v1/payrolls/pr_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b/dian_response" \
  -H "Authorization: Bearer $TREVOL_API_KEY" \
  -o payroll_dian_response.xml
```

[Probar en el Playground](https://platform.trevol.si/playground?op=downloadPayrollDianResponse)

## Corregir una nómina electrónica rechazada (mismo número) y reenviarla

`PUT /v1/payrolls/{id}` · `correctPayroll`

Corrige una nómina rechazada con el **mismo número** y la vuelve a enviar. `409 invalid_state` si el set de pruebas la está validando.

Solo si el documento está `rejected`, `error` o `pending`. Uno `accepted` no se corrige (se ajusta con una nota) y uno que la DIAN todavía verifica es `409 invalid_state`: espera el resultado. El `external_id` y la numeración no se cambian. Pide `Idempotency-Key`.

**Parámetros**

| Nombre | En | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | cabecera | texto | sí | Obligatoria: 1 a 255 caracteres ASCII visibles, única por pedido (7 días). |

**Cuerpo** ([PayrollInput](/docs/api/objetos#PayrollInput), obligatorio)

| Campo | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `external_id` | texto |  | Tu identificador del documento: único entre los documentos API de la empresa y el ambiente. En las nóminas es único entre las nóminas y sus ajustes (aparte de las facturas y los eventos). |
| `period` | [PayrollPeriod](/docs/api/objetos#PayrollPeriod) | sí | El periodo que se liquida y el tiempo laborado (`time_worked` se calcula si no se manda: años de 360 días y meses de 30). |
| `pay_period` | texto | sí | Periodo de nómina (tabla 5.5.1): "1" semanal, "2" decenal, "3" catorcenal, "4" quincenal, "5" mensual, "6" otro. |
| `currency` | texto |  | Moneda (ISO 4217). Por defecto COP; con otra va `exchange_rate`. |
| `exchange_rate` | decimal |  | Tasa de cambio a pesos. Obligatoria con una moneda distinta de COP y prohibida con COP. |
| `novelty` | [PayrollNovelty](/docs/api/objetos#PayrollNovelty) |  | El CUNE del documento con la novedad contractual, si la hay. Solo en la nómina. |
| `notes` | lista de texto |  | Máximo 20. |
| `employee` | [PayrollEmployee](/docs/api/objetos#PayrollEmployee) | sí | El trabajador. Sus datos solo salen en las respuestas a esta llave (la del empleador): nunca en webhooks, en el registro de peticiones ni en lo que se guarda de la idempotencia. |
| `payment` | [PayrollPayment](/docs/api/objetos#PayrollPayment) | sí |  |
| `payment_dates` | lista de fecha (AAAA-MM-DD) | sí | Las fechas de pago (1 a 31). Máximo 31. |
| `earnings` | [PayrollEarnings](/docs/api/objetos#PayrollEarnings) | sí |  |
| `deductions` | [PayrollDeductions](/docs/api/objetos#PayrollDeductions) | sí |  |
| `rounding` | decimal |  | Redondeo hasta 2.00; no suma a los totales. |
| `generation_place` | [PayrollPlace](/docs/api/objetos#PayrollPlace) |  | Dónde se generó el documento. Por defecto, el municipio de la empresa. |
| `employer` | [PayrollEmployer](/docs/api/objetos#PayrollEmployer) |  | Solo si la empresa es persona natural: sus apellidos y nombres (si la razón social no se separa bien en «apellido1 apellido2 nombre1»). |

**Respuestas**

| Estado | Qué pasó |
| --- | --- |
| 200 | El documento ([Payroll](/docs/api/objetos#Payroll)) |
| 202 | Versión 2026-10-22: la DIAN no contestó (`status: processing`; Trevol termina el documento y avisa por webhook; no crees otro documento para la misma venta, y si repites con la misma Idempotency-Key respondemos sin enviar) o el documento se está enviando (`status: sending`); también la contingencia (`status: contingency`). Lleva `Location` y, salvo la contingencia, `Retry-After: 30`. En 2026-10-21 la DIAN sin contestar es un 503 `dian_unavailable`. También `status: validating` (en las dos versiones): el set de pruebas de habilitación de nómina recibió el documento y todavía lo valida; reintentar con la misma Idempotency-Key, `POST …/send` o corregir responde lo mismo SIN reenviar (`PUT` en ese estado es 409 `invalid_state`). ([Payroll](/docs/api/objetos#Payroll)) |
| 409 | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |
| Error | Error (application/problem+json) ([Problem](/docs/api/objetos#Problem)) |

`PUT /v1/payrolls/{id}` (`correctPayroll`)

#### cURL

```bash
curl -X PUT "https://api.trevol.si/v1/payrolls/pr_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b" \
  -H "Authorization: Bearer $TREVOL_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "external_id": "NOM-2026-09-001",
  "period": {
    "hire_date": "2024-03-01",
    "start": "2026-09-01",
    "end": "2026-09-30"
  },
  "pay_period": "5",
  "notes": [
    "Nómina de septiembre de 2026"
  ],
  "employee": {
    "type": "01",
    "subtype": "00",
    "high_risk_pension": false,
    "document_type": "13",
    "document_number": "1000000101",
    "first_surname": "PRUEBA",
    "second_surname": "NOMINA01",
    "first_name": "TRABAJADOR",
    "other_names": "DE PRUEBA",
    "workplace": {
      "country": "CO",
      "municipality_code": "76001",
      "address": "Calle 1 # 1-1"
    },
    "integral_salary": false,
    "contract_type": "2",
    "salary": "1423500",
    "code": "TRAB-01"
  },
  "payment": {
    "form": "1",
    "method": "42",
    "bank": "Banco de Pruebas",
    "account_type": "Ahorros",
    "account_number": "0001234501"
  },
  "payment_dates": [
    "2026-09-30"
  ],
  "earnings": {
    "basic": {
      "days": 30,
      "amount": "1423500"
    },
    "transport": [
      {
        "allowance": "200000"
      }
    ]
  },
  "deductions": {
    "health": {
      "percent": "4",
      "amount": "56940"
    },
    "pension": {
      "percent": "4",
      "amount": "56940"
    }
  }
}'
```

#### Respuesta 200

```json
{
  "id": "pr_3f0c1a2b3f0c1a2b3f0c1a2b3f0c1a2b",
  "object": "payroll",
  "environment": "live",
  "status": "accepted",
  "number": "NE15",
  "prefix": "NE",
  "external_id": "NOM-2026-09-001",
  "origin": "api",
  "cune": "abababababababababababababababababababababababababababababababababababababababababababababababab",
  "qr": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=abababababababababababababababababababababababababababababababababababababababababababababababab",
  "issued_at": "2026-10-23T09:15:02-05:00",
  "submission": "sync",
  "period": {
    "hire_date": "2024-03-01",
    "start": "2026-09-01",
    "end": "2026-09-30"
  },
  "pay_period": "5",
  "currency": "COP",
  "notes": [
    "Nómina de septiembre de 2026"
  ],
  "employee": {
    "type": "01",
    "subtype": "00",
    "high_risk_pension": false,
    "document_type": "13",
    "document_number": "1000000101",
    "first_surname": "PRUEBA",
    "second_surname": "NOMINA01",
    "first_name": "TRABAJADOR",
    "other_names": "DE PRUEBA",
    "workplace": {
      "country": "CO",
      "municipality_code": "76001",
      "address": "Calle 1 # 1-1"
    },
    "integral_salary": false,
    "contract_type": "2",
    "salary": "1423500",
    "code": "TRAB-01"
  },
  "payment": {
    "form": "1",
    "method": "42",
    "bank": "Banco de Pruebas",
    "account_type": "Ahorros",
    "account_number": "0001234501"
  },
  "payment_dates": [
    "2026-09-30"
  ],
  "earnings": {
    "basic": {
      "days": 30,
      "amount": "1423500"
    },
    "transport": [
      {
        "allowance": "200000"
      }
    ]
  },
  "deductions": {
    "health": {
      "percent": "4",
      "amount": "56940"
    },
    "pension": {
      "percent": "4",
      "amount": "56940"
    }
  },
  "totals": {
    "earnings": "1623500.00",
    "deductions": "113880.00",
    "net": "1509620.00"
  },
  "dian": {
    "status_code": "00",
    "message": "Procesado Correctamente.",
    "rules": []
  },
  "files": {
    "xml": true,
    "zip": true,
    "dian_response": true
  },
  "created_at": "2026-10-23T09:15:02-05:00",
  "updated_at": "2026-10-23T09:15:03-05:00"
}
```

[Probar en el Playground](https://platform.trevol.si/playground?op=correctPayroll&ejemplo=mensual)
