Skip to content

Clients

A client represents a pet owner: the human responsible for one or more patients (pets) at a clinic. Clients carry the billing relationship, the contact details, and the household-level preferences. Every patient in the Shepherd API is linked to at least one client, and most clinical and financial workflows start from a client lookup.

Clients have several related sub-resources (phones, notes, info, discount) that are managed through their own endpoints rather than as deep writes on the client object itself.

Authoritative schemas live in the live Swagger UI. The fields below are a representative subset for orientation.

FieldTypeDescription
idstringUnique identifier for the client.
identifierstringShort human-facing identifier shown in the Shepherd UI.
firstName / middleName / lastNamestringName parts.
emailstringPrimary email address.
dateOfBirthstringClient’s date of birth.
clientPhonesarrayPhone numbers. Populated with embed=clientPhones.
clientInfoobjectThe contact block, including the postal address. Populated with embed=clientInfo; there are no address fields on the client itself.
clientCoOwnerobjectCo-owner, with their own phone list. Populated with embed=clientCoOwner.
clientStatusId / clientTypeId / genderIdstringLookup references.
clientDiscountIdstringDiscount program applied to this client.
authorizedAgentsarrayPeople authorised to act for the client.
isTaxExemptbooleanWhether the client is exempt from taxes.
clinicIdstringThe owning clinic.
legacyIdstringIdentifier carried over from a previous practice-management system.
dateCreatedstringISO 8601 UTC timestamp of creation.
dateUpdatedstringISO 8601 UTC timestamp of last update.
deletedbooleanSoft-delete flag; filter on this in queries.
POST /pav2/open-api-clients

Returns a paginated collection of clients for the clinic identified by X-Clinic-Id. Accepts the standard collection parameters: page, rpp, sort, searchQuery, embed, and the dateCreatedFrom / dateCreatedTo date-range pair. See Conventions for the full parameter rules.

Terminal window
curl -X POST https://open-api.shepherd.vet/pav2/open-api-clients \
-H "Content-Type: application/json" \
-H "X-Integration-Public-Key: $SHEPHERD_PUBLIC_KEY" \
-H "X-Integration-Private-Key: $SHEPHERD_PRIVATE_KEY" \
-H "X-Clinic-Id: $SHEPHERD_CLINIC_ID" \
-d '{
"page": 1,
"rpp": 25,
"sort": "lastName|asc",
"searchQuery": "smith",
"embed": "clientPhones"
}'
{
"item": [
{
"id": "e45a6e12-3a1c-4e7d-9fd2-3473a4d8a7a6",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane.smith@example.com",
"clientPhones": [
{
"id": "7d7ea1ee-3329-4b06-9966-b2f800c16f53",
"countryId": "158d44c8-d163-4c27-8e77-b2b300f2522f",
"phoneNumber": "5555550123",
"phoneTypeId": "534494bb-d287-eb09-e90b-8a2b4e5b9398",
"isPrimary": true
}
],
"dateCreated": "2026-03-14T18:22:11Z",
"dateUpdated": "2026-05-01T09:14:00Z",
"deleted": false
}
],
"totalRecords": 184,
"page": 1,
"recordsPerPage": 25,
"sort": "lastName|asc",
"searchQuery": "smith",
"embed": "clientPhones",
"links": []
}
POST /pav2/open-api-clients/write

Creates a new client record for the clinic.

Required: firstName, lastName, and clientPhones. The phone array is required by the model, so send it even if the client has no number on file; pass [] in that case.

Each entry in clientPhones requires countryId, phoneNumber, and phoneTypeId, all resolved from Lookups (open-api-countries and open-api-phone-types). isPrimary and phoneNumberName are optional.

A co-owner, the contact block, and authorized agents can be created in the same call via the clientCoOwner, clientInfo, and authorizedAgents objects. Notes and discounts are separate sub-resources.

Terminal window
curl -X POST https://open-api.shepherd.vet/pav2/open-api-clients/write \
-H "Content-Type: application/json" \
-H "X-Integration-Public-Key: $SHEPHERD_PUBLIC_KEY" \
-H "X-Integration-Private-Key: $SHEPHERD_PRIVATE_KEY" \
-H "X-Clinic-Id: $SHEPHERD_CLINIC_ID" \
-d '{
"firstName": "Jane",
"lastName": "Smith",
"email": "jane.smith@example.com",
"clientPhones": [
{
"countryId": "158d44c8-d163-4c27-8e77-b2b300f2522f",
"phoneNumber": "5555550123",
"phoneTypeId": "534494bb-d287-eb09-e90b-8a2b4e5b9398",
"isPrimary": true
}
]
}'
PUT /pav2/open-api-clients/{id}/update

Updates an existing client. This is a PUT, so it is a full replacement: send the complete client representation, not just the fields you changed. Any editable field omitted from the body is cleared. See Updating records for the general rule.

Required on every update: firstName, lastName, and clientPhones. Omitting any of them is rejected.

What happens to each field you leave out of the body:

Kept when omittedCleared or reset when omitted
clientStatusId, the clientInfo contact block, authorizedAgents (an edit list, below)middleName, email, dateOfBirth, clientTypeId, genderId, clientDiscountId, alerts, additionalText, referralSourceIds, clientCoOwner (and its phones), isTaxExempt (resets to false, so the client is charged tax), and every notification preference

The home clinic, system identifiers, and deleted status cannot be changed here. authorizedAgents is an edit list rather than a replacement: each entry adds an agent (omit id), edits one in place (include id), or removes one (set authorizedAgentIdForRemove with a removalNote); agents you do not reference are left alone.

Returns 200 OK with the updated client. A 404 means the {id} does not resolve within the clinic named by X-Clinic-Id.

Preserving co-owners and their phone numbers

Section titled “Preserving co-owners and their phone numbers”

The most common data-loss report against this endpoint involves co-owners. clientCoOwner is a nested object that carries its own clientCoOwnerPhones array, so a body that includes the co-owner but not their phones removes those phone numbers.

Fetch the full co-owner record before you merge. There are two ways to get it:

Embed it in the client read. Ask for the co-owner and their phones by name, using the dot notation described in Embedding related entities:

{ "ids": "e45a6e12-3a1c-4e7d-9fd2-3473a4d8a7a6", "embed": "clientCoOwner,clientCoOwner.clientCoOwnerPhones" }

Or query the co-owner endpoint directly. POST /pav2/open-api-client-co-owners returns co-owner records with their phone information attached. Co-owners are keyed by the owning client’s ID, so passing that ID in ids returns the co-owner for that client:

{ "ids": "e45a6e12-3a1c-4e7d-9fd2-3473a4d8a7a6", "embed": "client" }

Either way you end up with the complete co-owner object to resubmit.

The example changes one field, the email address, and carries every other editable field through from the current record. clientInfo and clientStatusId are left out because they are kept when omitted.

Terminal window
# 1. Read the current client, embedding the nested collections you will resend.
curl -X POST https://open-api.shepherd.vet/pav2/open-api-clients \
-H "Content-Type: application/json" \
-H "X-Integration-Public-Key: $SHEPHERD_PUBLIC_KEY" \
-H "X-Integration-Private-Key: $SHEPHERD_PRIVATE_KEY" \
-H "X-Clinic-Id: $SHEPHERD_CLINIC_ID" \
-d '{
"ids": "e45a6e12-3a1c-4e7d-9fd2-3473a4d8a7a6",
"rpp": 1,
"embed": "clientPhones,clientCoOwner,clientCoOwner.clientCoOwnerPhones"
}' > current-client.json
# 2. Build merged-client.json from item[0]: every update field copied from the
# record (renaming the two mass-communication flags), with your change applied.
# 3. PUT the complete object back.
curl -X PUT https://open-api.shepherd.vet/pav2/open-api-clients/e45a6e12-3a1c-4e7d-9fd2-3473a4d8a7a6/update \
-H "Content-Type: application/json" \
-H "X-Integration-Public-Key: $SHEPHERD_PUBLIC_KEY" \
-H "X-Integration-Private-Key: $SHEPHERD_PRIVATE_KEY" \
-H "X-Clinic-Id: $SHEPHERD_CLINIC_ID" \
-d @merged-client.json

Client-adjacent data lives on its own endpoints. Each follows the same list / write conventions as the parent resource.

EndpointPurpose
/pav2/open-api-client-phonesPhone numbers attached to a client (mobile, home, work).
/pav2/open-api-client-infosExtended profile fields and household metadata.
/pav2/open-api-client-notesFree-form notes recorded by clinic staff against the client.
/pav2/open-api-client-discountsDiscount programs and percentage adjustments applied to the client’s invoices.
/pav2/open-api-client-co-ownersCo-owners attached to a client, with their phone numbers. Keyed by the owning client’s ID.
  • Conventions: pagination, embed, sort, and date-range rules.
  • Authentication: the three required headers.
  • Errors: HTTP status codes and the error body shapes.
  • Patients: the pets attached to each client.