List Appointments
Returns a paginated list of all appointments of the company.
Request
GET /api/oauth/v2/resource/appointments
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) |
from | string (ISO 8601) | Yes | Range start — as date (2026-03-01) or ISO 8601 (2026-03-01T00:00:00+01:00) |
until | string (ISO 8601) | Yes | Range end — as date (2026-03-31) or ISO 8601 (2026-03-31T23:59:59+01:00) |
type | string | No | Comma-separated list of appointment types (default: admin,customer,course). Allowed values: admin, customer, course, pause, private, vacation, illness, official_holiday, external. Special value all returns all types. |
customerId | string (UUID) | No | Filter appointments by a specific customer. Returns only appointments where the customer is directly assigned or appears in the attendee list of a course appointment. |
Note: The parameters
fromanduntilare required. The API only returns appointments within the specified range.
Tip: When provided without a time (e.g.
2026-03-01),fromis set to00:00:00anduntilto23:59:59— ideal for day-exact queries.
Note: This endpoint always requires both scopes
appointmentsandusers. For course appointments (typecourseorall), the scopecustomersis additionally required.
Note: If
customerIdis provided, the scopecustomersis additionally required — regardless of the chosen appointment type.
Note on course appointments: Course appointments (
type=course) contain personal customer data (attendees.customer) and user data (instructors). The scopecustomersis required for this. If you explicitly request?type=course(or?type=all) without this scope, the API responds with403 insufficient_scope.
Response
Success (200 OK)
Example: Single appointment (type: "customer")
{
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"title": "Erstgespräch",
"start": "2026-03-15T10:00:00+01:00",
"end": "2026-03-15T11:00:00+01:00",
"allDay": false,
"status": "active",
"type": "customer",
"course": null,
"note": "Bitte nüchtern erscheinen",
"customer": {
"id": "f0e1d2c3-b4a5-6789-fedc-ba9876543210",
"firstName": "Anna",
"lastName": "Muster"
},
"service": {
"id": "c3d4e5f6-a7b8-9012-cdef-012345678901",
"name": "Erstgespräch"
},
"source": "oauth",
"deleted": false,
"deletedAt": null,
"stornoReason": null,
"createdAt": "2026-03-01T09:00:00+01:00",
"updatedAt": "2026-03-01T09:00:00+01:00"
}
],
"meta": {
"total": 500,
"offset": 0,
"limit": 50
}
}Example: Course appointment (type: "course")
{
"data": [
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"title": "Yoga Anfänger",
"start": "2026-03-20T09:00:00+01:00",
"end": "2026-03-20T10:00:00+01:00",
"allDay": false,
"status": "active",
"type": "course",
"course": {
"id": "c3d4e5f6-a7b8-9012-cdef-012345678901",
"name": "Yoga Anfänger",
"maxAttendees": 20,
"currentAttendees": 12,
"color": "#ff0000",
"instructors": [
{ "id": "d4e5f6a7-b8c9-0123-defa-123456789012", "firstName": "Max", "lastName": "Muster" }
],
"location": { "id": "e5f6a7b8-c9d0-1234-efab-234567890123", "name": "Studio 1" },
"attendees": [
{
"customer": { "id": "f0e1d2c3-b4a5-6789-fedc-ba9876543210", "firstName": "Anna", "lastName": "Muster" },
"bookingDate": "2026-03-01T10:00:00+01:00"
}
]
},
"note": null,
"customer": null,
"service": null,
"source": "oauth",
"createdAt": "2026-03-01T09:00:00+01:00",
"updatedAt": "2026-03-01T09:00:00+01:00"
}
],
"meta": {
"total": 500,
"offset": 0,
"limit": 50
}
}Response fields
| Field | Type | Description |
|---|---|---|
data | Array | List of appointments |
data[].id | string (UUID) | Unique appointment ID |
data[].title | string | Title of the appointment |
data[].start | string (ISO 8601) | null | Start time |
data[].end | string (ISO 8601) | null | End time |
data[].allDay | boolean | All-day appointment |
data[].status | string | Status of the appointment (active or request) |
data[].type | string | Appointment type (admin, customer, course, pause, private, vacation, illness, official_holiday, external) |
data[].course | object | null | Course data — only populated when type: "course", otherwise null |
data[].course.id | string (UUID) | Course ID |
data[].course.name | string | Course name |
data[].course.maxAttendees | integer | null | Maximum number of attendees |
data[].course.currentAttendees | integer | Current number of attendees |
data[].course.color | string | null | Color as hex code (e.g. #ff0000) |
data[].course.instructors | Array | List of instructors |
data[].course.instructors[].id | string (UUID) | Instructor ID |
data[].course.instructors[].firstName | string | First name of the instructor |
data[].course.instructors[].lastName | string | Last name of the instructor |
data[].course.location | object | null | Course location |
data[].course.location.id | string (UUID) | Location ID |
data[].course.location.name | string | Location name |
data[].course.attendees | Array | List of course attendees |
data[].course.attendees[].customer | object | Attendee summary |
data[].course.attendees[].customer.id | string (UUID) | Customer ID |
data[].course.attendees[].customer.firstName | string | First name |
data[].course.attendees[].customer.lastName | string | Last name |
data[].course.attendees[].bookingDate | string (ISO 8601) | null | Booking date |
data[].note | string | Internal note |
data[].customer | object | null | Linked customer |
data[].customer.id | string (UUID) | Customer ID |
data[].customer.firstName | string | First name |
data[].customer.lastName | string | Last name |
data[].service | object | null | Linked service |
data[].service.id | string (UUID) | Service ID |
data[].service.name | string | Name of the service |
data[].source | string | Source of the appointment |
data[].deleted | boolean | true if the appointment is cancelled, otherwise false |
data[].deletedAt | string (ISO 8601) | null | Time of cancellation, null if not cancelled |
data[].stornoReason | string | null | Cancellation reason, null if not cancelled or no reason given |
data[].createdAt | string (ISO 8601) | null | Creation time |
data[].updatedAt | string (ISO 8601) | null | Last modification time |
meta.total | integer | Total number of appointments |
meta.offset | integer | Current start position |
meta.limit | integer | Number of returned entries |
Note: The
customerandserviceobjects contain only a summary with the most important fields (see table above).
curl -X GET "https://my.offisy.at/api/oauth/v2/resource/appointments?offset=0&limit=50&from=beispiel&until=beispiel&type=admin%2Ccustomer%2Ccourse&customerId=b2c3d4e5-f6a7-8901-bcde-f01234567890" \
-H "Authorization: Bearer {access_token}"Possible errors
| Status | Code | Description |
|---|---|---|
| 400 | validation_error | from and/or until missing or invalid |
| 401 | invalid_client | Invalid or missing access token |
| 403 | insufficient_scope | Scope appointments or users missing (both always required) |
| 403 | insufficient_scope | ?type=course/?type=all requested but scope customers missing |