> ## Documentation Index
> Fetch the complete documentation index at: https://code.dcycle.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Workforce Absences (v2)

> Create up to 1,000 absences and accidents at work of your employees in one request

[← Own Workforce API](/api-reference/own-workforce/overview)

Record your employees' absences and accidents at work. A record is a row of the accidents and absenteeism import
template: an absence, an accident, or an accident and the absence it caused. It belongs to an employee, by the `id`
that [Create Workforce Employees (v2)](/api-reference/own-workforce/employees-create-v2) answers. The request answers
`201 Created` with what each record created; nothing is calculated, so there is no job to follow.

<Warning>
  **Beta.** Part of the bulk ingest API, currently in beta. The contract may still change before general availability.
</Warning>

<RequestExample>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST "https://api.dcycle.io/v2/own-workforce/absences" \
    -H "x-api-key: ${DCYCLE_API_KEY}" \
    -H "x-organization-id: ${DCYCLE_ORG_ID}" \
    -H "Idempotency-Key: 4a3b2c1d-0e9f-4a8b-97c6-d5e4f3a2b190" \
    -H "Content-Type: application/json" \
    -d '{
      "records": [
        {
          "own_workforce_id": "6f5e4d3c-2b1a-4f09-8e7d-6c5b4a392817",
          "type": "sick_leave",
          "absence_start_date": "2026-02-05",
          "absence_end_date": "2026-02-07",
          "absence_hours": 24,
          "client_row_id": "HR-ABS-118"
        },
        {
          "own_workforce_id": "6f5e4d3c-2b1a-4f09-8e7d-6c5b4a392817",
          "type": "work_accident",
          "accident_date": "2026-05-10",
          "accident_context": "in_labore",
          "absence_start_date": "2026-05-10",
          "absence_end_date": "2026-05-13"
        }
      ]
    }'
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import os
  import uuid

  import requests

  response = requests.post(
      "https://api.dcycle.io/v2/own-workforce/absences",
      headers={
          "x-api-key": os.environ["DCYCLE_API_KEY"],
          "x-organization-id": os.environ["DCYCLE_ORG_ID"],
          "Idempotency-Key": str(uuid.uuid4()),  # keep it to retry this same batch
      },
      json={
          "records": [
              {
                  "own_workforce_id": "6f5e4d3c-2b1a-4f09-8e7d-6c5b4a392817",
                  "type": "sick_leave",
                  "absence_start_date": "2026-02-05",
                  "absence_end_date": "2026-02-07",
                  "absence_hours": 24,
              }
          ]
      },
      timeout=60,
  )
  response.raise_for_status()
  print([item["absence"]["id"] for item in response.json()["items"]])
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "items": [
      {
        "source_row_index": 0,
        "client_row_id": "HR-ABS-118",
        "absence": {
          "id": "8e7d6c5b-4a39-4281-a7f6-e5d4c3b2a190",
          "own_workforce_id": "6f5e4d3c-2b1a-4f09-8e7d-6c5b4a392817",
          "type": "sick_leave",
          "absence_start_date": "2026-02-05",
          "absence_end_date": "2026-02-07",
          "absence_hours": 24.0,
          "accident_date": null,
          "accident_context": null,
          "created_at": "2026-10-20T09:12:44.031Z"
        }
      },
      {
        "source_row_index": 1,
        "client_row_id": null,
        "absence": {
          "id": "2c1b0a99-8877-4665-9443-322110ffeedd",
          "own_workforce_id": "6f5e4d3c-2b1a-4f09-8e7d-6c5b4a392817",
          "type": "work_accident",
          "absence_start_date": "2026-05-10",
          "absence_end_date": "2026-05-13",
          "absence_hours": 32.0,
          "accident_date": "2026-05-10",
          "accident_context": "in_labore",
          "created_at": "2026-10-20T09:12:44.031Z"
        }
      }
    ]
  }
  ```

  ```json 422 theme={"theme":{"light":"github-light","dark":"github-dark"}}
  {
    "type": "https://code.dcycle.io/api-reference/errors#BULK_RECORDS_REJECTED",
    "title": "Unprocessable Entity",
    "status": 422,
    "code": "BULK_RECORDS_REJECTED",
    "detail": "1 of the submitted records are invalid; nothing was written.",
    "errors": [
      {
        "source_row_index": 0,
        "client_row_id": "HR-ABS-118",
        "error_code": "ABSENCE_OVERLAP",
        "error_params": { "field": "absence_start_date" }
      }
    ],
    "rejected": 1,
    "request_id": "b2248a31-0f1b-4a7d-83ce-b29bd5977b4c"
  }
  ```

  ```json 200 (dry_run=true) theme={"theme":{"light":"github-light","dark":"github-dark"}}
  { "dry_run": true, "submitted": 2, "valid": 2 }
  ```
</ResponseExample>

## How it works

Every record is checked as the file import checks a row:

* **An absence** must not overlap another absence of the employee, counting both start and end days. An absence
  without an end date is ongoing and overlaps every later one. The check covers the absences already stored and the
  other records of the request.
* **An accident** cannot be the employee's second on the same day, against the stored accidents and the request's.
* **Hours left out** of an absence with an end date are derived as the import derives them: 8 per day of the absence,
  both ends included, times the working hours ratio of the employee's contract on its first day (1 when no contract
  covers it).

If any record is invalid the **whole** request is rejected with `422` and nothing is written; the answer lists every
invalid record. Otherwise everything is created at once.

## Request

### Headers

<ParamField header="x-api-key" type="string" required>
  Your API key (see [Authentication](/api-reference/introduction#authentication)).
</ParamField>

<ParamField header="x-organization-id" type="string" required>
  Your organization. Its employees, and those of the organizations under it that you can write to, can take absences
  and accidents; each belongs to its employee's organization.
</ParamField>

<ParamField header="Idempotency-Key" type="string" required>
  1 to 255 characters, unique per batch. A retry within 24 hours with the same key and body answers the same records (with
  `Idempotent-Replayed: true`) instead of creating them again; the same key with another body or on another route is
  `422 IDEMPOTENCY_KEY_REUSED`, and while the first request is still being processed `409 IDEMPOTENCY_KEY_IN_PROGRESS`.
</ParamField>

### Query Parameters

<ParamField query="dry_run" type="boolean" default="false">
  Check only: the same `422` for invalid records, nothing written; `200` with
  `{"dry_run": true, "submitted": n, "valid": n}` when every record is valid.
</ParamField>

### Body Parameters

<ParamField body="records" type="array[object]" required>
  The absences and accidents to create, 1 to 1,000. Each record needs an absence (`absence_start_date`), an accident
  (`accident_date`) or both. A field not listed here is rejected (`SCHEMA_INVALID`).

  <Expandable title="record">
    <ParamField body="own_workforce_id" type="uuid" required>
      The employee: an `id` of [Create Workforce Employees (v2)](/api-reference/own-workforce/employees-create-v2) or
      [List Workforce Employees](/api-reference/own-workforce/list).
    </ParamField>

    <ParamField body="type" type="string" required>
      Your category for the record, as free text, up to 255 characters (`sick_leave`, `work_accident`...).
    </ParamField>

    <ParamField body="absence_start_date" type="date">
      First day of the absence, `YYYY-MM-DD`, from 1970 to next year. When the record also has an accident, the
      absence cannot start before it.
    </ParamField>

    <ParamField body="absence_end_date" type="date">
      Last day of the absence, on or after its start. Omitted: the absence is ongoing.
    </ParamField>

    <ParamField body="absence_hours" type="number">
      Hours absent: over 0, with up to 1 decimal. Omitted with an end date: derived as explained above.
    </ParamField>

    <ParamField body="accident_date" type="date">
      Day of the accident at work, not in the future. Send it with `accident_context`.
    </ParamField>

    <ParamField body="accident_context" type="string">
      `in_labore` (during work) or `in_itinere` (commuting to or from it).
    </ParamField>

    <ParamField body="client_row_id" type="string">
      Your own reference for the record, up to 255 characters, echoed in errors and in the answer.
    </ParamField>
  </Expandable>
</ParamField>

## Response

`201 Created` with `items`: one per record, in the order sent, with its `source_row_index`, `client_row_id` and the
created `absence` (absence and accident fields; those the record did not have are `null`). Its `id` is the one
[Delete Workforce Absences (v2)](/api-reference/own-workforce/absences-delete-v2) takes.

## Errors

[Problem details](/api-reference/errors). Per-record codes in `errors[].error_code` of a `422 BULK_RECORDS_REJECTED`:

| `error_code` | Cause |
| - | - |
| `SCHEMA_INVALID` | The record does not match the schema: a missing or unknown field (e.g. `organization_id`), neither an absence nor an accident, an end date or hours without a start date, `accident_date` without `accident_context` or in the future, an absence starting before its accident, `absence_hours` not over 0 or with more than 1 decimal... `error_params.errors` says where. |
| `REFERENCE_NOT_FOUND` | `own_workforce_id` does not exist or is outside your organization's perimeter (both answer the same). |
| `ABSENCE_OVERLAP` | The absence overlaps another absence of the employee, stored or in the request. |
| `ACCIDENT_DUPLICATE` | The employee already has an accident on that day, stored or in the request. |

Request-level errors: `401` for a missing or invalid API key, `403 LOGGED_USER_NOT_MEMBER` when the key's user is not a
member of the organization, `422 REQUEST_VALIDATION_FAILED` for a malformed body (no `records`, more than 1,000, no
`Idempotency-Key`), `422 IDEMPOTENCY_KEY_REUSED`, `409 IDEMPOTENCY_KEY_IN_PROGRESS`, and `429` beyond the
[rate limits](/api-reference/rate-limits).

## Limits

| Limit | Value |
| - | - |
| Records per request | 1 to 1,000 |

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Delete Workforce Absences (v2)" icon="trash" href="/api-reference/own-workforce/absences-delete-v2">
    Delete absences and accidents by id
  </Card>

  <Card title="Create Workforce Employees (v2)" icon="users" href="/api-reference/own-workforce/employees-create-v2">
    The employees, and their ids
  </Card>

  <Card title="List Workforce Absences" icon="table" href="/api-reference/own-workforce/list-absences">
    The absences stored
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.