Skip to main content

21 posts tagged with "Changed"

Changes to existing request or response behaviour.

View All Tags

8 October 2026

Client profiles: Alberta and British Columbia time zones​

A client profile saved with timeZone America/Edmonton, America/Yellowknife, America/Inuvik or Canada/Mountain now reads back as America/Edmonton instead of America/Denver, and one saved with America/Vancouver or Canada/Pacific reads back as America/Vancouver instead of America/Los_Angeles. Time zone answers from GET /api/v1/forms/{id} gain "Calgary, Edmonton" and "Vancouver, Victoria", and the US options now read "Denver, Salt Lake City" and "Los Angeles, Seattle".

28 September 2026

Appointment write endpoints are published​

Creating and updating appointments, group appointments and group participants is now available to every practice, and the group appointment operations appear in the API reference for the first time.

17 September 2026

Beta endpoints are labelled​

Endpoints that are still in beta now show a [BETA] prefix or a BETA chip in the documentation pages.

Practitioner rosters​

Added GET /api/v1/practitioner-roster and GET /api/v1/practitioner-roster/{id}, which return a practitioner's recurring working pattern: the date range, the location, how often the pattern repeats, and the time slots for all seven weekdays, including any services a slot excludes from online booking. Filter by practitioner, location, active status, availability, online bookings, or the date a roster is in effect.

15 September 2026

Invoices can be created and updated by every practice​

POST /api/v1/invoices and PATCH /api/v1/invoices/{id} are out of limited release and enabled for all practices. Request and response shapes are unchanged, so an integration built against them during the limited release needs no update.

26 August 2026

Resource items: locationId is replaced by a locations collection​

On GET /api/v1/resource-items and GET /api/v1/resource-items/{id}, the single locationId field is gone. A resource item now returns locations, a list of the locations it is available at, each with an id, a name and a link. This is a breaking change to the resource item response.

A resource can be shared across locations, which the single field could not express. Read resourceItem.locations and match on the entry you need instead of comparing locationId. The locationId filter on the list endpoint is unchanged and now matches an item at any of its locations.

Before:

"locationId": 3

After:

"locations": [
{
"id": 3,
"name": "Coburg",
"links": [{ "href": "/api/v1/locations/3", "rel": "self", "method": "GET" }]
},
{
"id": 7,
"name": "Fitzroy",
"links": [{ "href": "/api/v1/locations/7", "rel": "self", "method": "GET" }]
}
]

25 August 2026

Appointments: when scheduleReminder may be set​

On PATCH /api/v1/appointments/{id} and PATCH /api/v1/group-appointments/{appointmentId}/participants/{clientId}, scheduleReminder is rejected once the appointment's start time has passed, and while the attendance state is anything other than Pending or Confirmed unless a reminder has already been sent. Setting it to true also requires a client who can receive reminders. Omit the property in those cases. The rules now match the ones the Zanda app applies.

Invoices can be created against a deactivated practitioner​

POST /api/v1/invoices no longer rejects an invoice whose practitioner has since been deactivated, which matches what the practice can do in the app.

20 August 2026

Client profiles can be created and updated by every practice​

POST /api/v1/client-profiles/clients and PATCH /api/v1/client-profiles/clients/{id} are out of limited release and enabled for all practices. Request and response shapes are unchanged, so an integration built against them during the limited release needs no update.

Creating or updating a profile with a lookup id that is no longer active, such as an archived classification, category or status, is rejected with 400. Read the current options from the matching reference-data endpoint.

19 August 2026

Referrals: referrerType is now an object​

On GET /api/v1/referrals and GET /api/v1/referrals/{id}, the referrerType field has changed from a plain text name to an object with an id, a name, and a link to the matching referrer type. This is a breaking change to the referral response.

If you currently read the referrer type's name, change referral.referrerType to referral.referrerType.name. You can now also use referral.referrerType.id to fetch it from GET /api/v1/referrer-types/{id}, or match it against the GET /api/v1/referrer-types list. As before, referrerType is null when a referrer has no type set.

Before:

"referrerType": "General Practitioner"

After:

"referrerType": {
"id": 42,
"name": "General Practitioner",
"links": [{ "href": "/api/v1/referrer-types/42", "rel": "self", "method": "GET" }]
}

Note and form templates​

  • GET /api/v1/note-templates lists the practice's note templates.
  • GET /api/v1/form-templates and GET /api/v1/form-templates/{id} list and fetch form templates.

10 August 2026

Notes​

GET /api/v1/notes and GET /api/v1/notes/{id} return client notes. The list returns note metadata; fetch a single note to read its answers.

Payments can be created, updated and deleted by every practice​

POST /api/v1/payments, PATCH /api/v1/payments/{id} and DELETE /api/v1/payments/{id} are out of limited release and enabled for all practices. Nothing about them changed on the way out, so an integration built against them during the limited release needs no update.

4 August 2026

Appointments: a resource is validated against the location​

On POST /api/v1/appointments, a resource that does not belong to the appointment's location is now rejected with 400, instead of being accepted and producing an appointment that cannot be opened.

31 July 2026

Invoices: PATCH takes insurer ids, not client-insurer ids​

On PATCH /api/v1/invoices/{id}, the request field clientInsurerIds is renamed to insurerIds, and the values it accepts have changed: pass insurer ids, not the ids of the client-insurer link records. This is a breaking change to the invoice update request.

Take the ids from the insurer resource rather than from the client's insurer list. A request still sending clientInsurerIds is rejected.

16 July 2026

All write endpoints: malformed request bodies are rejected​

Request bodies used to be accepted silently when they carried fields the API did not recognise, or the same field twice. Both now fail with 400 Bad Request and a code of InvalidRequestBody. This is a breaking change to every POST, PUT and PATCH endpoint.

An unknown field, clientIdd for clientId, used to be ignored, so the value you thought you were setting was quietly dropped. A body containing the same property twice used to keep the last one, with no way to tell which had been applied. Both are now errors.

Field names are compared case-insensitively for the duplicate check, so clientId and ClientID in one body is also rejected. Review any payload built by string concatenation, or merged from more than one source.

14 July 2026

Invoices: an insurer cannot be added twice​

Adding the same insurer to an invoice more than once is now rejected with 400 instead of creating a second identical entry.

Invoices can be created​

POST /api/v1/invoices creates an invoice.

Saleable categories, relationship types and referrer types​

Three more reference lists, each with a list and a by-id endpoint: GET /api/v1/saleable-categories, GET /api/v1/relationship-types and GET /api/v1/referrer-types.

13 July 2026

Appointments: cancellationReason is now an object​

On GET /api/v1/appointments and GET /api/v1/appointments/{id}, cancellationReason has changed from a plain text name to an object with an id, a name and a link to the matching reason. This is a breaking change to the appointment response.

If you read the reason's text, change appointment.cancellationReason to appointment.cancellationReason.name. You can now also match it against GET /api/v1/cancellation-reasons. As before, it is null when the appointment was not cancelled.

Before:

"cancellationReason": "Client unwell"

After:

"cancellationReason": {
"id": 7,
"name": "Client unwell",
"links": [{ "href": "/api/v1/cancellation-reasons/7", "rel": "self", "method": "GET" }]
}

Cancellation reasons and appointment flags​

GET /api/v1/cancellation-reasons and GET /api/v1/appointment-flags list the practice's cancellation reasons and appointment flags, each with a by-id endpoint.

22 June 2026

Client profiles: country and timeZone are validated​

On client profile create and update, values outside the supported country list, and time zones that are not valid IANA identifiers, are now rejected with 400 instead of being stored. Existing profiles are unaffected.

15 June 2026

Referrals: startDate and endDate are dates, not date-times​

On GET /api/v1/referrals and GET /api/v1/referrals/{id}, the two referral dates are returned as plain dates rather than as timestamps at midnight. The matching filters, startDateFrom, startDateTo, endDateFrom and endDateTo, accept a plain date too. This is a breaking change if you parse either field as a date-time.

A referral begins and ends on a day, not at an instant, so the time component was always zero and the timezone it implied was misleading. Parse both fields as dates, and send dates when you filter. Both remain null when the referral has no such date set.

Before:

"startDate": "2026-06-15T00:00:00Z"

After:

"startDate": "2026-06-15"

Invoices: deep pages timed out​

Requesting a high page number from GET /api/v1/invoices could take long enough to fail with a server error rather than return.

11 June 2026

Client profiles carry their custom profile fields​

A client profile response now lists the values recorded against the practice's custom profile fields, each linked to its definition in GET /api/v1/custom-profile-fields.

Client profiles: the marketing source is an embedded object​

marketingSource now carries the source's id and name and a link to GET /api/v1/marketing-sources/{id}, instead of a name on its own.

1 June 2026

Page size now ranges from 1 to 100​

pageSize accepts anything from 1 to 100, where it previously accepted 5 to 25. The default is unchanged at 10 records.

Referrals: client and referrer details were swapped​

GET /api/v1/referrals returned the client's details in the referrer fields and the referrer's in the client fields.

11 May 2026

Paged responses: totalItemCount and pageCount are gone, and pageNumber is now page​

The envelope every list endpoint returns has changed. pageNumber is renamed to page, and the two totals, totalItemCount and pageCount, have been removed. This is a breaking change to every list endpoint.

Counting the whole result set on every request is what made large lists slow, and no total can be returned without doing it. To walk a list, read hasNextPage and request the next page while it is true, rather than dividing a total by your page size. If you display a count, you will need to stop showing one, or count what you have fetched. items, links and pageSize are unchanged.

Before:

{
"pageNumber": 1,
"pageSize": 10,
"totalItemCount": 438,
"pageCount": 44,
"hasNextPage": true
}

After:

{
"page": 1,
"pageSize": 10,
"hasNextPage": true
}

31 March 2026

Client profiles: the custom category is an embedded object​

customCategory now carries the category's id and name and a link to it, the same shape customStatus was given earlier this month.

Sorting on appointments​

You can now sort GET /api/v1/appointments by dateCreated, dateFrom, dateTo, id or flag, with the sort parameter. Add :desc to reverse a field, and separate several with commas, as in sort=dateFrom:desc,id.

Sorting on invoices​

You can now sort GET /api/v1/invoices by invoiceDate, invoiceDueDate, totalCharges or id.

Payments carry their location​

A payment response now names the location it was taken at.

19 March 2026

Payments: the payment method is an embedded object​

method on a payment now carries the method's id and name and a link to GET /api/v1/payment-methods/{id}, instead of a name on its own.

Client profiles: the custom status is an embedded object​

customStatus on a client profile now carries the status's id and name and a link to it. It is null when the profile has no status set.