# People And Scheduling

People and scheduling endpoints expose user references, absences, shifts, and shift day notes used
by editorial planning workflows.

Use this page for v2 behavior. Use the [Users API reference](/api/platform/users),
[Absences API reference](/api/platform/absences), and [Shifts API reference](/api/platform/shifts) for exact schemas,
examples, response codes, and endpoint-specific validation.

## Users

Users are read-only through the public API.

Public endpoints:

```text
GET /api/v2/users
GET /api/v2/users/{id}
```

User lists use the shared pagination shape. Query options include:

- `includeExternal=false` when only internal users should be returned.
- `includeGroups=true` when the response must include group references.

There is no public v2 endpoint for direct user lookup by email.

## Absences

Absences use plural `/api/v2/absences` paths:

```text
GET    /api/v2/absences
GET    /api/v2/absences/{id}
GET    /api/v2/absences/external-id/{externalId}
POST   /api/v2/absences
PUT    /api/v2/absences/{id}
PATCH  /api/v2/absences/{id}
DELETE /api/v2/absences/{id}
```

External-ID write paths are also available where documented in the API reference.

Absence create uses a structured request body:

```json title="Absence create request"
{
  "externalId": "absence-123",
  "user": {
    "email": "editor@example.com",
    "supplierId": "supplier-7",
    "externalId": "user-42"
  },
  "period": {
    "fromDate": "2026-01-15",
    "fromTime": "09:00",
    "toDate": "2026-01-16",
    "toTime": "17:00"
  },
  "type": {
    "code": 3
  },
  "note": "Planned vacation"
}
```

In the `user` object, `email` and `externalId` identify the user, and `supplierId` is the
organization-scoped supplier identifier used for external/freelancer users.

Important rules:

- `POST /api/v2/absences` returns `201 Created`.
- `PUT` is full replacement and requires `period` and `type`.
- `PATCH` is presence-aware.
- `externalId: null` and `note: null` clear those fields where the API reference documents that
  behavior.
- `period.fromDate` and `period.toDate` are required when the period object is created or replaced.
- `period.fromTime` and `period.toTime` are optional time boundaries.
- delete operations return `204 No Content`.

Absence lists support pagination plus filters such as `fromDate`, `toDate`, `userId`, `userEmail`,
and `type`.

## Shifts

Shifts are configuration data for work schedules.

:::caution{title="Public v2 shift writes are intentionally narrow"}

- shift create is not exposed through public v2 REST.
- shift delete is not exposed through public v2 REST.
- shift writes by external ID are not exposed for the shift resource itself.
- `PUT/PATCH /api/v2/shifts/{id}` update only `name` and `externalId`.

:::

External-ID clearing uses JSON `null`:

```json
{
  "externalId": null
}
```

For shift updates, an exactly empty external ID (`""`) is treated like `null` and clears the field.
Whitespace-only external IDs are invalid, and non-empty external IDs are trimmed. For full
replacement, `name` is required and cannot be `null`.

## Shift Day Notes

Shift day notes use plural `/notes` paths:

| Operation | v2 path |
|-----------|---------|
| Read by shift ID and date | `GET /api/v2/shifts/{shiftId}/notes/{date}` |
| Read by external shift ID and date | `GET /api/v2/shifts/external-id/{externalId}/notes/{date}` |
| Create by shift ID | `POST /api/v2/shifts/{shiftId}/notes` |
| Create by external shift ID | `POST /api/v2/shifts/external-id/{externalId}/notes` |
| Replace by shift ID and date | `PUT /api/v2/shifts/{shiftId}/notes/{date}` |
| Replace by external shift ID and date | `PUT /api/v2/shifts/external-id/{externalId}/notes/{date}` |

Create requests require `date` and `note`:

```json
{
  "date": "2026-01-15",
  "note": "Planning meeting before the morning shift"
}
```

Replace requests require `date` and `note`; the body `date` must match the path date.

Important rules:

- create returns `201 Created`.
- duplicate notes return `409 Conflict`.
- create can return `400 Bad Request` when the date is not part of the shift schedule.
- note text must stay within the documented length limit.
- prefer persisted shift IDs when possible. External shift IDs are integration identifiers; use the
  v2 shift ID to target a specific shift.

## Related Migration Notes

For v1 field mappings and path changes, see
[People And Scheduling Migration](/docs/migration-from-v1/people-and-scheduling).
