POST /api/nomina/nomina/
POST /api/nomina/nomina/
Nómina electrónica y su nota de ajuste.
Comparte el ciclo de vida de los documentos electrónicos —borrador, firmado,
enviado, aceptado o rechazado— pero no su pipeline: la nómina no es UBL y va
por SendNominaSync.
Sin PUT ni PATCH, por lo mismo que en DocumentoViewSet: un
documento fiscal es un hecho con fecha, número y firma, y editarlo en sitio
abre la puerta a que lo que se emitió y lo que se guarda dejen de coincidir.
Mientras es borrador, corregirlo es borrarlo y volver a crearlo; una vez
emitido, lo que corrige una nómina es su nota de ajuste (tipo_xml
103), que la DIAN tiene prevista justamente para esto.
Lo que cambia el documento son las acciones, cada una con su regla. El estado no es un campo que se escriba.
operationId: nomina_nomina_create
Autenticación
Sección titulada «Autenticación»Cualquiera de estas credenciales:
- LlaveApi — Llave de API de una integración. El valor completo es
Api-Key <prefijo>.<secreto>, tal como lo imprimemanage.py crear_llave_api. La llave alcanza exactamente los mismos emisores que la persona a cuyo nombre se creó.
Cuerpo de la petición
Sección titulada «Cuerpo de la petición»Tipo de contenido: application/json · obligatorio.
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
emisor | integer | sí | |
empleado | EmpleadoAnidadoRequest | sí | El empleado tal como viaja dentro de la nómina. Igual que el de su endpoint pero sin emisor —lo pone la nómina, que ya lo trae— y sin el validador de unicidad, porque aquí el par emisor + identificación no identifica un error sino al empleado que hay que crear o actualizar: la nómina hace ese upsert al guardarse. Estricto: una clave que no sea un campo escribible responde 400. Aquí importa más que en el endpoint del empleado, porque un campo mal escrito haría heredar a la nómina el valor viejo del maestro sin que nadie se enterara. |
prefijo | string | no | Lo elige el emisor: la nómina no se numera con resolución de la DIAN (regla NIE010). |
consecutivo | integer (int64) | sí | |
tipo_xml | any | no | |
tipo_nota | any | no | Vacío en la nómina; obligatorio en la nota de ajuste. * 1 - Reemplazar * 2 - Eliminar |
nomina_predecesora | string (uuid) | no | Admite null. |
periodo_nomina | integer | sí | |
fecha_liquidacion_inicio | string (date) | sí | |
fecha_liquidacion_fin | string (date) | sí | |
tiempo_laborado | integer | sí | Días laborados en el periodo (numeral 8.3.1). |
fecha_generacion | string (date) | sí | |
hora_generacion | string (time) | sí | |
fecha_pago | string (date) | sí | |
moneda | integer | sí | |
trm | string (decimal) | no | Solo cuando la moneda no es COP. Admite null. |
notas | string | no | |
novedad | boolean | no | |
cune_novedad | string | no | |
total_devengados | string (decimal) | no | |
total_deducciones | string (decimal) | no | |
redondeo | string (decimal) | no | |
total_comprobante | string (decimal) | no | Devengados menos deducciones, más el redondeo. |
conceptos | array<NominaConceptoRequest> | no | |
codigo_trabajador | string | no | Va en NumeroSecuenciaXML, que identifica el documento. |
alto_riesgo_pension | boolean | no | |
salario_integral | boolean | no | |
sueldo | string (decimal) | no | |
tipo_trabajador | integer | no | |
subtipo_trabajador | integer | no | |
tipo_contrato | integer | no | |
lugar_trabajo_pais | integer | no | |
lugar_trabajo_departamento | integer | no | |
lugar_trabajo_municipio | integer | no | |
lugar_trabajo_direccion | string | no | |
forma_pago | integer | no | |
medio_pago | integer | no | |
banco | string | no | |
tipo_cuenta | any | no | |
numero_cuenta | string | no | |
fecha_retiro | string (date) | no | Admite null. |
Ejemplo
Sección titulada «Ejemplo»curl -X POST "https://api.rededoc.uk/api/nomina/nomina/" \ -H "Authorization: <llaveapi>" \ -H "Content-Type: application/json" \ -d '{ "emisor": 1, "empleado": { "tipo_identificacion": 1, "numero_documento": "texto", "primer_apellido": "texto", "segundo_apellido": "texto", "primer_nombre": "texto", "otros_nombres": "texto", "codigo_trabajador": "texto", "tipo_trabajador": 1, "subtipo_trabajador": 1, "tipo_contrato": 1, "alto_riesgo_pension": true, "salario_integral": true, "sueldo": "0.00", "fecha_ingreso": "2026-01-31", "pais": 1, "departamento": 1, "municipio": 1, "direccion": "texto", "forma_pago": 1, "medio_pago": 1, "banco": "texto", "tipo_cuenta": null, "numero_cuenta": "texto" }, "prefijo": "texto", "consecutivo": 0, "tipo_xml": null, "tipo_nota": null, "nomina_predecesora": "00000000-0000-0000-0000-000000000000", "periodo_nomina": 1, "fecha_liquidacion_inicio": "2026-01-31", "fecha_liquidacion_fin": "2026-01-31", "tiempo_laborado": 0, "fecha_generacion": "2026-01-31", "hora_generacion": "texto", "fecha_pago": "2026-01-31", "moneda": 1, "trm": "0.00", "notas": "texto", "novedad": true, "cune_novedad": "texto", "total_devengados": "0.00", "total_deducciones": "0.00", "redondeo": "0.00", "total_comprobante": "0.00", "conceptos": [ { "grupo": "devengado", "concepto": "basico", "cantidad": "0.00", "porcentaje": "0.00", "valor": "0.00", "valor_no_salarial": "0.00", "fecha_inicio": "2026-01-31", "fecha_fin": "2026-01-31", "hora_inicio": "2026-01-31T10:00:00-05:00", "hora_fin": "2026-01-31T10:00:00-05:00", "descripcion": "texto", "tipo_incapacidad": null } ], "codigo_trabajador": "texto", "alto_riesgo_pension": true, "salario_integral": true, "sueldo": "0.00", "tipo_trabajador": 1, "subtipo_trabajador": 1, "tipo_contrato": 1, "lugar_trabajo_pais": 1, "lugar_trabajo_departamento": 1, "lugar_trabajo_municipio": 1, "lugar_trabajo_direccion": "texto", "forma_pago": 1, "medio_pago": 1, "banco": "texto", "tipo_cuenta": null, "numero_cuenta": "texto", "fecha_retiro": "2026-01-31" }'Respuestas
Sección titulada «Respuestas»| Código | Descripción |
|---|---|
201 | |
400 | Error |
401 | Error |
429 | Error |
201 — cuerpo
Sección titulada «201 — cuerpo»| Campo | Tipo | Descripción |
|---|---|---|
id | string (uuid) | Solo lectura. |
emisor | integer | |
empleado | EmpleadoAnidado | El empleado tal como viaja dentro de la nómina. Igual que el de su endpoint pero sin emisor —lo pone la nómina, que ya lo trae— y sin el validador de unicidad, porque aquí el par emisor + identificación no identifica un error sino al empleado que hay que crear o actualizar: la nómina hace ese upsert al guardarse. Estricto: una clave que no sea un campo escribible responde 400. Aquí importa más que en el endpoint del empleado, porque un campo mal escrito haría heredar a la nómina el valor viejo del maestro sin que nadie se enterara. |
prefijo | string | Lo elige el emisor: la nómina no se numera con resolución de la DIAN (regla NIE010). |
consecutivo | integer (int64) | |
numero | string | Número del documento. Si se omite, se arma como prefijo + consecutivo. Solo lectura. |
tipo_xml | any | |
tipo_nota | any | Vacío en la nómina; obligatorio en la nota de ajuste. * 1 - Reemplazar * 2 - Eliminar |
nomina_predecesora | string (uuid) | Admite null. |
periodo_nomina | integer | |
fecha_liquidacion_inicio | string (date) | |
fecha_liquidacion_fin | string (date) | |
tiempo_laborado | integer | Días laborados en el periodo (numeral 8.3.1). |
fecha_generacion | string (date) | |
hora_generacion | string (time) | |
fecha_pago | string (date) | |
moneda | integer | |
trm | string (decimal) | Solo cuando la moneda no es COP. Admite null. |
notas | string | |
novedad | boolean | |
cune_novedad | string | |
total_devengados | string (decimal) | |
total_deducciones | string (decimal) | |
redondeo | string (decimal) | |
total_comprobante | string (decimal) | Devengados menos deducciones, más el redondeo. |
conceptos | array<NominaConcepto> | |
codigo_trabajador | string | Va en NumeroSecuenciaXML, que identifica el documento. |
alto_riesgo_pension | boolean | |
salario_integral | boolean | |
sueldo | string (decimal) | |
tipo_trabajador | integer | |
subtipo_trabajador | integer | |
tipo_contrato | integer | |
lugar_trabajo_pais | integer | |
lugar_trabajo_departamento | integer | |
lugar_trabajo_municipio | integer | |
lugar_trabajo_direccion | string | |
forma_pago | integer | |
medio_pago | integer | |
banco | string | |
tipo_cuenta | any | |
numero_cuenta | string | |
fecha_retiro | string (date) | Admite null. |
{ "id": "00000000-0000-0000-0000-000000000000", "emisor": 1, "empleado": { "id": 1, "tipo_identificacion": 1, "tipo_identificacion_codigo": "texto", "numero_documento": "texto", "primer_apellido": "texto", "segundo_apellido": "texto", "primer_nombre": "texto", "otros_nombres": "texto", "nombre_completo": "texto", "codigo_trabajador": "texto", "tipo_trabajador": 1, "subtipo_trabajador": 1, "tipo_contrato": 1, "alto_riesgo_pension": true, "salario_integral": true, "sueldo": "0.00", "fecha_ingreso": "2026-01-31", "pais": 1, "departamento": 1, "municipio": 1, "direccion": "texto", "forma_pago": 1, "medio_pago": 1, "banco": "texto", "tipo_cuenta": null, "numero_cuenta": "texto", "activo": true, "creado_en": "2026-01-31T10:00:00-05:00", "actualizado_en": "2026-01-31T10:00:00-05:00" }, "prefijo": "texto", "consecutivo": 0, "numero": "texto", "tipo_xml": null, "tipo_nota": null, "nomina_predecesora": "00000000-0000-0000-0000-000000000000", "periodo_nomina": 1, "fecha_liquidacion_inicio": "2026-01-31", "fecha_liquidacion_fin": "2026-01-31", "tiempo_laborado": 0, "fecha_generacion": "2026-01-31", "hora_generacion": "texto", "fecha_pago": "2026-01-31", "moneda": 1, "trm": "0.00", "notas": "texto", "novedad": true, "cune_novedad": "texto", "total_devengados": "0.00", "total_deducciones": "0.00", "redondeo": "0.00", "total_comprobante": "0.00", "conceptos": [ { "id": 1, "grupo": "devengado", "concepto": "basico", "concepto_nombre": "texto", "cantidad": "0.00", "porcentaje": "0.00", "valor": "0.00", "valor_no_salarial": "0.00", "fecha_inicio": "2026-01-31", "fecha_fin": "2026-01-31", "hora_inicio": "2026-01-31T10:00:00-05:00", "hora_fin": "2026-01-31T10:00:00-05:00", "descripcion": "texto", "tipo_incapacidad": null } ], "codigo_trabajador": "texto", "alto_riesgo_pension": true, "salario_integral": true, "sueldo": "0.00", "tipo_trabajador": 1, "subtipo_trabajador": 1, "tipo_contrato": 1, "lugar_trabajo_pais": 1, "lugar_trabajo_departamento": 1, "lugar_trabajo_municipio": 1, "lugar_trabajo_direccion": "texto", "forma_pago": 1, "medio_pago": 1, "banco": "texto", "tipo_cuenta": null, "numero_cuenta": "texto", "fecha_retiro": "2026-01-31"}400 — cuerpo
Sección titulada «400 — cuerpo»| Campo | Tipo | Descripción |
|---|---|---|
detail | string | Mensaje para mostrar a la persona. |
errores | array<object> | Nunca vacía. Cada error trae codigo, que es lo que el cliente mapea —los de DRF tal cual (required, invalid, does_not_exist, not_found…) y los propios en español (campo_desconocido, solicitud_invalida…)—, y mensaje, para la persona. Si el error es de un campo, su ruta va delante del mensaje: detalles[0].impuestos[0].tributo: Este campo es obligatorio. |
{ "detail": "texto", "errores": [ { "codigo": "texto", "mensaje": "texto" } ]}401 — cuerpo
Sección titulada «401 — cuerpo»| Campo | Tipo | Descripción |
|---|---|---|
detail | string | Mensaje para mostrar a la persona. |
errores | array<object> | Nunca vacía. Cada error trae codigo, que es lo que el cliente mapea —los de DRF tal cual (required, invalid, does_not_exist, not_found…) y los propios en español (campo_desconocido, solicitud_invalida…)—, y mensaje, para la persona. Si el error es de un campo, su ruta va delante del mensaje: detalles[0].impuestos[0].tributo: Este campo es obligatorio. |
{ "detail": "texto", "errores": [ { "codigo": "texto", "mensaje": "texto" } ]}429 — cuerpo
Sección titulada «429 — cuerpo»| Campo | Tipo | Descripción |
|---|---|---|
detail | string | Mensaje para mostrar a la persona. |
errores | array<object> | Nunca vacía. Cada error trae codigo, que es lo que el cliente mapea —los de DRF tal cual (required, invalid, does_not_exist, not_found…) y los propios en español (campo_desconocido, solicitud_invalida…)—, y mensaje, para la persona. Si el error es de un campo, su ruta va delante del mensaje: detalles[0].impuestos[0].tributo: Este campo es obligatorio. |
{ "detail": "texto", "errores": [ { "codigo": "texto", "mensaje": "texto" } ]}RedEDoc es un servicio de Semántica Digital S.A.S.