People And Scheduling Migration
This page covers v1-to-v2 migration notes for users, absences, shifts, and shift day notes.
Where to find exact schemas
For the v2-native endpoint behavior, start with People And Scheduling. Use the Users API reference, Absences API reference, and Shifts API reference for exact schemas, examples, status codes, and field-level validation.
Endpoint Mapping
| v1 usage pattern | v2 direction |
|---|---|
GET .../users/all | Use GET /api/v2/users; parse the shared pagination response shape. |
GET .../users/email/{email} | No public v2 endpoint is exposed. List users via GET /api/v2/users (paginated), match on email client-side, and persist the v2 user ID. |
GET .../absence/{id} | Use GET /api/v2/absences/{id}. |
GET .../absence/external/{externalAbsenceId} | Use GET /api/v2/absences/external-id/{externalId}. |
POST/PUT/PATCH/DELETE .../absence... | Use the plural /api/v2/absences paths and v2 request models. |
GET/PUT/PATCH .../shift/{id} | Use GET/PUT/PATCH /api/v2/shifts/{id} and map label to name. |
.../shift/external/{externalShiftId}/... | Use /api/v2/shifts/external-id/{externalId}/... for shift reads and shift-day-note operations. |
.../shift/{shiftId}/note/{date} | Use /api/v2/shifts/{shiftId}/notes/{date}. |
Users
Users are read-only through the public API.
Client-impacting changes:
- stop parsing
GET .../users/allas a bare array. - use
includeExternal=falsewhen only internal users should be returned; the default includes external users. - use
includeGroups=truewhen the response must include group references. - replace v1
departmentIdsparsing with v2groupswhen groups are requested. - replace v1
extUserIdorexternalUserIdfields with v2externalId. - do not migrate email lookup calls to
/api/v2/users/email/{email}; that path is not part of the public v2 contract.
Absences
Absence request and response models are more structured in v2.
| v1 field | v2 field |
|---|---|
externalAbsenceId | externalId |
userEmail | user.email |
supplierId | user.supplierId |
externalUserId | user.externalId |
period.fromDate, period.fromTime, period.toDate, period.toTime | same names under period |
numeric type | type.code in requests, type.code plus type.name in responses |
note | note |
Important migration points:
POST /api/v2/absencesreturns201 Created.PUTis full replacement and requiresperiodandtype.PATCHis presence-aware; omitted fields remain unchanged.externalId: nullandnote: nullclear those fields where documented.- delete operations return
204 No Content. - absence lists are paginated and support filters such as
fromDate,toDate,userId,userEmail, andtype.
Shifts
Shifts are configuration data for work schedules. v2 keeps public shift updates 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 onlynameandexternalId.
Field mapping:
| v1 field | v2 field |
|---|---|
label | name |
externalId | externalId |
| response only had basic shift fields | response can also include schedule, startTime, endTime, timeZone, and availability |
External-ID clearing convention changed
External-ID clearing is documented as JSON null in v2. An exactly empty string is also normalized
to null and clears the field; whitespace-only external IDs are invalid.
Shift Day Notes
Shift day notes moved from singular /note paths to 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} |
Client-impacting changes:
- handle
201 Createdfrom shift-day-note create. - handle
409 Conflictwhen a note already exists for the addressed shift/date. - handle
400 Bad Requestwhen the create date is not part of the shift schedule. - body
datemust match the path date on replace. - prefer persisted shift IDs when possible. External shift IDs are integration identifiers; use the v2 shift ID to target a specific shift.