# Capturar (/docs/developers/api-reference/attendance/capture)

## Descripcion general [#descripcion-general]

Este endpoint captura **un tipo de incidencia** (falta, vacaciones, horas extra, retardo, etc.) para un conjunto de empleados a lo largo de un **rango de fechas**. Las incidencias se registran en el **registro global de asistencia**, del que cada corrida de nómina lee. Los periodos abiertos ya calculados **se recalculan solos** con cada captura, así que sus recibos reflejan el registro de inmediato. Si ese recálculo automático no se completa, la respuesta llega con `recalc_pending: true` y el periodo queda **desactualizado** hasta que lo recalcules.

Referencias por número/código: los empleados por `employee_numbers` y el tipo por `incidence_code`. El catálogo de tipos es **global y fijo de la plataforma** — el mismo conjunto de códigos para todas las razones sociales (consulta [Listar tipos de incidencia](/docs/developers/api-reference/incidence-types/list)).

Una fecha que caiga dentro de un **periodo cerrado** no se aplica en silencio: se convierte en un **ajuste retroactivo** que corrige la nómina en el siguiente periodo, y debes confirmarlo con `confirm_retro: true` (ver más abajo).

Las **horas extra** (`OVERTIME_DOUBLE_HOURS` y `OVERTIME_TRIPLE_HOURS`) capturadas por la API se crean **pendientes de autorizar**: no se pagan hasta que las autorizan todos los niveles configurados en la organización (jefe directo, Recursos Humanos o los dos). Su estatus se consulta en el campo `approval_status` de [Listar asistencia](/docs/developers/api-reference/attendance/list#estatus-de-autorizacion).

Requiere que la API key tenga el permiso **Capturar asistencia**.

## Endpoint [#endpoint]

`POST https://app.integranom.com/api/v1/attendance`

## Captura una incidencia en un rango [#captura-una-incidencia-en-un-rango]

***

Un tipo de incidencia, un conjunto de empleados, un rango de fechas. Para un tipo de **día** (falta, vacaciones, incapacidad) se crea una entrada por día con cantidad `1`, o `0.5` en vacaciones de medio día. **Vacaciones pagadas** (`VACATION_PAID`) y los permisos con y sin goce (`LEAVE_PAID`, `LEAVE_UNPAID`) solo crean entradas en los días hábiles del horario de cada empleado: sus días de descanso y los días festivos de ley se omiten (sin horario ni rotación asignados, cuenta el predeterminado de la organización; sin ninguno, solo los festivos), y una fecha de medio día que cae en uno de ellos se ignora. El ejemplo captura una falta el 3 y el 4 de junio para dos empleados → `created: 4`.

`created` es el número de entradas registradas; `retros_touched`, cuántos ajustes retroactivos se crearon o refrescaron (0 cuando ninguna fecha cae en un periodo cerrado). El rango no puede exceder **366 días**.

## Campos del cuerpo [#campos-del-cuerpo]

| Campo                     | Tipo                  | Requerido   | Notas                                                                                                                                                                                                                                              |
| ------------------------- | --------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `incidence_code`          | string                | Sí          | Código del tipo de incidencia en el catálogo global (p. ej. `LATENESS`).                                                                                                                                                                           |
| `employee_numbers`        | integer\[]            | Sí          | 1–500 empleados. Cada uno debe tener un empleo activo o pendiente.                                                                                                                                                                                 |
| `start_date` / `end_date` | string (`YYYY-MM-DD`) | Sí          | Rango (inclusivo). `end_date` ≥ `start_date`. Máximo 366 días.                                                                                                                                                                                     |
| `quantity`                | number                | Condicional | Requerida para tipos `hours` y `count`. En `VACATION_PAID` y `VACATION_UNPAID`, `0.5` registra medio día por fecha y cualquier otro valor se registra como `1` (día completo, por omisión); en los demás tipos `days` se ignora y se registra `1`. |
| `notes`                   | string                | No          | Máximo 500 caracteres.                                                                                                                                                                                                                             |
| `disability_folio`        | string                | No          | Folio del certificado de incapacidad, máximo 30 caracteres. Solo para tipos de incapacidad y un solo empleado. Se guarda en mayúsculas. Un folio pertenece a un solo empleado y sus días deben ser consecutivos.                                   |
| `confirm_retro`           | boolean               | No          | Autoriza que las fechas dentro de un periodo cerrado se registren como ajuste retroactivo. Ver abajo.                                                                                                                                              |

**cURL**

```bash
curl -X POST "https://app.integranom.com/api/v1/attendance" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "incidence_code": "FALTA",
  "employee_numbers": [1, 2],
  "start_date": "2026-06-03",
  "end_date": "2026-06-04"
}'
```

**Respuesta**

```json
{
"created": 4,
"retros_touched": 0,
"recalc_pending": false
}
```

## Fechas dentro de un periodo cerrado (ajuste retroactivo) [#fechas-dentro-de-un-periodo-cerrado-ajuste-retroactivo]

***

Cerrar un periodo es definitivo. Una incidencia dentro de sus fechas no reescribe la nómina ya pagada: se registra como un **ajuste retroactivo** que corrige la diferencia en el **siguiente** periodo.

Por eso, si alguna fecha cae en un periodo cerrado, la captura se rechaza con `409 RETRO_CONFIRMATION_REQUIRED` (con `retro_periods`, los periodos afectados). Reenvíala con **`confirm_retro: true`** para aceptar y registrar el ajuste — la respuesta trae `retros_touched` mayor a 0.

**cURL**

```bash
curl -X POST "https://app.integranom.com/api/v1/attendance" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "incidence_code": "FALTA",
  "employee_numbers": [1],
  "start_date": "2026-01-05",
  "end_date": "2026-01-05",
  "confirm_retro": true
}'
```

**Respuesta**

```json
{
"created": 1,
"retros_touched": 1,
"recalc_pending": false
}
```

## Cantidad (según la unidad del tipo) [#cantidad-según-la-unidad-del-tipo]

| Unidad del tipo                                           | `quantity`    | Comportamiento                                                                       |
| --------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------ |
| `days` de vacaciones (`VACATION_PAID`, `VACATION_UNPAID`) | Opcional      | Una entrada por día: `0.5` es medio día y cualquier otro valor se registra como `1`. |
| Demás `days` (falta, incapacidad, permiso…)               | Se ignora     | Una entrada por día con cantidad `1`.                                                |
| `hours` (horas extra)                                     | **Requerida** | Las horas capturadas por día del rango.                                              |
| `count` (retardos)                                        | **Requerida** | El número de ocurrencias por día del rango.                                          |

## Forma de la respuesta [#forma-de-la-respuesta]

`200` — `{ "created": number, "retros_touched": number, "recalc_pending": boolean }`.

| Campo            | Significado                                                                                                                                                                              |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `created`        | Entradas registradas en el registro global (reenvíos idénticos no se duplican; sobre horas extra rechazadas sin checadas vinculadas, la respuesta es `409 OVERTIME_REJECTED`).           |
| `retros_touched` | Ajustes retroactivos creados o refrescados por fechas dentro de un periodo cerrado.                                                                                                      |
| `recalc_pending` | `true` si el recálculo en tiempo real de algún periodo abierto no se completó: la incidencia quedó registrada, pero los recibos de ese periodo van desfasados hasta volver a calcularlo. |

## Errores [#errores]

| Status | Código                                | Causa                                                                                                                                                                                                                                                                                                    |
| ------ | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | —                                     | Cuerpo mal formado o inválido.                                                                                                                                                                                                                                                                           |
| `400`  | `EMPLOYEE_NOT_FOUND`                  | Algún `employee_number` no existe en la organización.                                                                                                                                                                                                                                                    |
| `400`  | `NO_ACTIVE_EMPLOYMENT`                | Algún empleado no tiene empleo activo o pendiente.                                                                                                                                                                                                                                                       |
| `400`  | `INCIDENCE_NOT_FOUND`                 | Sin tipo activo con ese `incidence_code` en el catálogo global.                                                                                                                                                                                                                                          |
| `400`  | `RANGE_TOO_LARGE`                     | El rango excede 366 días.                                                                                                                                                                                                                                                                                |
| `400`  | `NO_CHARGEABLE_DAYS`                  | En vacaciones pagadas o permisos, todas las fechas del rango son días de descanso o festivos para los empleados. No se captura nada.                                                                                                                                                                     |
| `400`  | `DISABILITY_FOLIO_NOT_ALLOWED`        | Se envió `disability_folio` con un tipo que no es incapacidad.                                                                                                                                                                                                                                           |
| `400`  | `DISABILITY_FOLIO_MULTIPLE_EMPLOYEES` | Se envió `disability_folio` para más de un empleado.                                                                                                                                                                                                                                                     |
| `401`  | —                                     | API key ausente o inválida.                                                                                                                                                                                                                                                                              |
| `403`  | —                                     | La API key no tiene el permiso **Capturar asistencia**.                                                                                                                                                                                                                                                  |
| `409`  | `DAY_CONFLICT`                        | Algún empleado ya tiene otro estatus de día en una de las fechas (los tipos de día son mutuamente excluyentes). Con `disability_folio`, también cuenta una incapacidad del mismo tipo ya capturada. No se captura nada.                                                                                  |
| `409`  | `OVERTIME_REJECTED`                   | Algún empleado ya tiene horas extra rechazadas de ese tipo, sin checadas vinculadas, en una de las fechas. No se captura nada; el registro rechazado se corrige en la plataforma, en **Incidencias de tiempo**: cambia sus horas para enviarlo de nuevo a autorización, o elimínalo y vuelve a capturar. |
| `409`  | `RETRO_CONFIRMATION_REQUIRED`         | Alguna fecha cae en un periodo cerrado. Reenvía con `confirm_retro: true`.                                                                                                                                                                                                                               |
| `409`  | `DISABILITY_FOLIO_TAKEN`              | El folio ya está registrado para otro empleado. No se captura nada.                                                                                                                                                                                                                                      |
| `409`  | `DISABILITY_FOLIO_NOT_CONSECUTIVE`    | El empleado ya tiene ese folio en fechas que no son consecutivas con las enviadas. No se captura nada.                                                                                                                                                                                                   |