List Users
Returns a paginated list of all users.
Request
GET /api/oauth/v2/resource/users
Header
| Header | Value |
|---|---|
Authorization | Bearer {access_token} |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
offset | integer | No | Start position (default: 0) |
limit | integer | No | Number of results (default: 50, max: 200) |
view | string | No | Response format: default (default) or slim (slim response) |
createdSince | string (ISO 8601) | No | Only users created at or after this timestamp (createdAt >=) |
createdUntil | string (ISO 8601) | No | Only users created at or before this timestamp (createdAt <=) |
updatedSince | string (ISO 8601) | No | Only users modified at or after this timestamp (updatedAt >=). Newly created users are included, because the modification timestamp is set on creation. |
updatedUntil | string (ISO 8601) | No | Only users modified at or before this timestamp (updatedAt <=) |
Required scope: users
Note: For a sync,
updatedSincealone is enough — it covers new and modified users.
Note: Formats, time zone behavior, sorting, cursor strategy, and the
meta.totaltrap work the same across all timestamp filters. See Incremental Sync.
Note on deleted users: Users do not carry a deletion timestamp. There is no
deletedSincehere — deleted users cannot be determined via the API. The endpoint still returns them without marking them.In the
updatedSincefeed a deletion looks like an ordinary change. So do not count on deletion detection when syncing users.
Note on users without a modification timestamp: For some users,
updatedAtis empty. This affects legacy data from before automatic timestamping, as well as bulk imports.updatedSincedoes not return those users, not even with a very early date.So for the initial sync, fetch the full set once without a timestamp filter. After that, continue incrementally with
updatedSince.
Response
Success (200 OK)
{
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Dr.",
"firstName": "Maria",
"lastName": "Muster",
"abbreviation": "MM",
"sex": 1,
"email": "maria.muster@example.com",
"color": "#74AFAD",
"isDoctor": true,
"showBookingWeeks": 6,
"sort": 0,
"isBookable": true,
"tenancies": [
{
"id": "f0e1d2c3-b4a5-6789-fedc-ba9876543210",
"name": "Ordination Muster",
"abbreviation": "OM",
"color": "#00adba"
}
],
"createdAt": "2026-01-15T08:00:00+01:00",
"updatedAt": "2026-06-10T16:20:00+02:00"
}
],
"meta": {
"total": 5,
"offset": 0,
"limit": 50
}
}Response fields
| Field | Type | Description |
|---|---|---|
data | Array | List of users |
data[].id | string (UUID) | Unique user ID |
data[].title | string | null | Academic title (e.g. Dr.) |
data[].firstName | string | First name |
data[].lastName | string | Last name |
data[].abbreviation | string | null | Abbreviation |
data[].sex | integer | null | Sex (0 = male, 1 = female) |
data[].email | string | null | Email address |
data[].color | string | Color as hex code (e.g. #74AFAD) |
data[].isDoctor | boolean | Whether the user is a doctor |
data[].showBookingWeeks | integer | How many weeks ahead are bookable |
data[].sort | integer | Sort order |
data[].isBookable | boolean | Whether the user is bookable |
data[].tenancies | Array | Assigned tenants |
data[].tenancies[].id | string (UUID) | Tenant ID |
data[].tenancies[].name | string | Name of the tenant |
data[].tenancies[].abbreviation | string | Abbreviation |
data[].tenancies[].color | string | Color as hex code |
data[].createdAt | string (ISO 8601) | null | Creation timestamp |
data[].updatedAt | string (ISO 8601) | null | Last modification timestamp |
meta.total | integer | Total number of users |
meta.offset | integer | Current start position |
meta.limit | integer | Number of returned entries |
Note: The
idis returned as a UUID and is required for querying available slots and booking appointments.
Slim response (?view=slim)
With view=slim, the endpoint returns a slim response with less data per user. Without the parameter, the response stays unchanged.
If view is given more than once, the last value wins — ?view=default&view=slim returns the slim response.
The slim response contains:
id, title, firstName, lastName, abbreviation, isDoctor, createdAt, updatedAt
sex, email, color, sort, isBookable, showBookingWeeks, and tenancies are omitted.
Note: Currently the slim response additionally returns
createdAtandupdatedAt— the default response doesn't include these fields yet.
Example: view=slim
{
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Dr.",
"firstName": "Maria",
"lastName": "Muster",
"abbreviation": "MM",
"isDoctor": true,
"createdAt": "2026-01-10T08:30:00+01:00",
"updatedAt": "2026-05-02T11:45:00+02:00"
}
],
"meta": {
"total": 5,
"offset": 0,
"limit": 50
}
}curl -X GET "https://my.offisy.at/api/oauth/v2/resource/users?offset=0&limit=50&view=default&createdSince=beispiel&createdUntil=beispiel&updatedSince=2026-04-15T10%3A00%3A00&updatedUntil=2026-04-15T10%3A00%3A00" \
-H "Authorization: Bearer {access_token}"Possible errors
| Status | Code | Description |
|---|---|---|
| 400 | validation_error | Invalid value for view (valid values: default, slim) |
| 400 | validation_error | A timestamp filter contains an invalid value |
| 401 | invalid_client | Invalid or missing access token |
| 403 | insufficient_scope | Scope users not present |