Agenda’s catalog is how the clinic is set up: the services it offers, the offerings that make each one bookable, the resources that provide them, the sites where they are, and the hours each resource works. Availability is computed from it, so a change here changes the times patients can book.
Who can read and change it
Reading the catalog is open to people and machines holding the :read scope of what they list, such as agenda:services:read; a list accepts no other scope. Changing it accepts only people: a signed-in member whose roles grant the :write scope, such as agenda:services:write, typically through a staff tool. API keys and machine tokens can’t change the catalog.
| Operation | Request | Callers | Effect |
|---|---|---|---|
agenda.services.list |
GET /v1/agenda/services |
People and machines | Reads |
agenda.services.create |
POST /v1/agenda/services |
People only | Writes; not idempotent |
agenda.services.update |
PATCH /v1/agenda/services/{serviceId} |
People only | Writes; idempotent |
agenda.offerings.list |
GET /v1/agenda/offerings |
People and machines | Reads |
agenda.offerings.create |
POST /v1/agenda/offerings |
People only | Writes; not idempotent |
agenda.offerings.update |
PATCH /v1/agenda/offerings/{offeringId} |
People only | Writes; idempotent |
agenda.resources.list |
GET /v1/agenda/resources |
People and machines | Reads |
agenda.resources.create |
POST /v1/agenda/resources |
People only | Writes; not idempotent |
agenda.resources.update |
PATCH /v1/agenda/resources/{resourceId} |
People only | Writes; idempotent |
agenda.scheduleRules.list |
GET /v1/agenda/schedule-rules |
People and machines | Reads |
agenda.scheduleRules.create |
POST /v1/agenda/schedule-rules |
People only | Writes; not idempotent |
agenda.scheduleRules.update |
PATCH /v1/agenda/schedule-rules/{scheduleRuleId} |
People only | Writes; not idempotent |
agenda.resourceSchedules.update |
PATCH /v1/agenda/resource-schedules/{resourceId} |
People only | Writes; idempotent |
agenda.locations.list |
GET /v1/agenda/locations |
People and machines | Reads |
The lists of services, offerings, resources and locations answer a page at a time, 25 items by default and up to 100: see Pagination. Creating isn’t idempotent, so after a create whose outcome is unknown, list before you create again. There’s no delete operation: set a record’s status to inactive to stop using it. The booking operations offer only active offerings.
Services
A service is what a patient asks for, under the clinic’s name for it, such as a neurology consultation. agenda.services.list filters by status.
| Field | Meaning |
|---|---|
name |
Required. |
defaultDurationMinutes |
Required, 1 to 1440. The default length of its appointments; each offering can set its own. |
status |
active (the default) or inactive. |
Offerings
An offering attaches a service to an agenda, with what it takes to book it. agenda.offerings.list filters by serviceId and status.
| Field | Default | Meaning |
|---|---|---|
serviceId, name |
Required | The service it offers, and the offering’s name. |
durationMinutes |
Required | The visible appointment’s length, 1 to 1440 minutes. |
slotIntervalMinutes |
15 |
Minutes between possible start times, 5 to 240. |
bufferBeforeMinutes, bufferAfterMinutes |
0 |
Minutes the resources stay occupied before and after the visible appointment. |
minNoticeMinutes |
0 |
The least advance notice a booking needs. |
bookingHorizonDays |
90 |
How many days ahead it can be booked, up to 730. |
resourceRequirements |
[] |
Up to 30 requirements: the resources each booking needs. |
status |
active |
active or inactive. |
Each requirement names a kind of resource and a quantity, 1 by default. alternatives lists the resources that can fill it; when it’s empty, any resource of that kind can. required, true by default, says whether the requirement must be met for the booking to go ahead. In an update, resourceRequirements replaces the whole list for future bookings; existing appointments keep their resources.
An example body for agenda.offerings.create, a 30-minute consultation with one named professional and any room:
{
"serviceId": "svc_00000000-0000-4000-8000-000000000001",
"name": "Neurology consultation, Dr. Example",
"durationMinutes": 30,
"slotIntervalMinutes": 30,
"minNoticeMinutes": 120,
"resourceRequirements": [
{ "kind": "practitioner", "alternatives": ["srs_00000000-0000-4000-8000-000000000003"] },
{ "kind": "room" }
]
}Resources
A resource is anything with its own calendar that a booking uses. agenda.resources.list filters by kind and status.
| Field | Meaning |
|---|---|
kind |
Required: practitioner, assistant, room, chair, equipment, location, team or generic. Offerings’ requirements match it. |
name |
Required. |
timezone |
Required. The IANA time zone of its working hours, appointment dates and age rules. |
locationId |
The site it belongs to. null, the default, ties it to no site, so it covers every site. |
capacity |
How many units it can take at once, 1 by default; each booking uses its share. |
status |
active (the default) or inactive. |
Locations
Locations are the clinic’s sites, each with its name, address, city, timezone and status. The API reads them, with agenda.locations.list (agenda:locations:read), or with agenda.bookingLocations.list when you book (agenda:bookings:read). It has no operation that creates or changes a location.
Schedule rules
Schedule rules say when a resource works. Each rule is a band of local time, from from to to in HH:MM, read in the resource’s time zone:
| Field | Meaning |
|---|---|
kind |
weekly, date_override, time_off or block. |
weekdays |
For a weekly band, the days it applies, from Sunday 0 to Saturday 6. |
effectiveFrom, effectiveTo |
For a weekly band, the first and last dates it applies; null for no bound. |
date |
For a dated band or closure, its local date; null for a weekly band. |
agenda.scheduleRules.listfilters byresourceIdand answers the complete list, without pages. Each rule has itsid, itsresourceIdand itsversion.agenda.scheduleRules.createadds one rule withresourceId,kind,timezone,fromandto.agenda.scheduleRules.updatechanges a rule identified byscheduleRuleId; send itsexpectedVersion. An update without it is refused withSCHEDULE_RULE_EXPECTED_VERSION_REQUIRED.agenda.resourceSchedules.updatereplaces the resource’s whole schedule at once:rulesis the new set, up to 400 rules, andexpectedRulesholds theidandversionof every rule you loaded. If the schedule changed since, the replacement is refused and nothing changes.
An example body for agenda.resourceSchedules.update: Monday to Friday, 07:00 to 12:00 and 14:00 to 17:00, replacing one rule loaded at version 3:
{
"expectedRules": [{ "id": "sch_00000000-0000-4000-8000-000000000006", "version": 3 }],
"rules": [
{ "kind": "weekly", "weekdays": [1, 2, 3, 4, 5], "from": "07:00", "to": "12:00" },
{ "kind": "weekly", "weekdays": [1, 2, 3, 4, 5], "from": "14:00", "to": "17:00" }
]
}Versions
Every catalog record has a version. An update requires the version you read as expectedVersion, and is refused with 409 when someone changed the record since:
| Record | error.code |
|---|---|
| Service | SERVICE_VERSION_MISMATCH |
| Offering | OFFERING_VERSION_MISMATCH |
| Resource | RESOURCE_VERSION_MISMATCH |
| Schedule rule | SCHEDULE_RULE_VERSION_MISMATCH |
| A resource’s schedule, on replace | SCHEDULE_RULES_CHANGED |
Read the record again, apply your change to what you read, and send it with the new version. See Handle errors and retries.