Skip to content

Your first integration

By the end of this tutorial you’ll have made an authenticated request to the Shepherd API and listed today’s appointments for a single clinic. Plan on about ten minutes.

  • A runtime for one of curl, Python 3, .NET 8, PHP 8, or Node.js 20+.
  • Sandbox or production credentials from your Shepherd account manager. If you don’t have them, see Authentication.
  • A clinic UUID your integration has been granted access to.

The examples below read three environment variables:

Terminal window
export SHEPHERD_PUBLIC_KEY="pk_..."
export SHEPHERD_PRIVATE_KEY="sk_..."
export SHEPHERD_CLINIC_ID="00000000-0000-0000-0000-000000000000"

Use sandbox keys with https://demo-open-api.shepherd.vet/pav2/, or production keys with https://open-api.shepherd.vet/pav2/. The examples below point at production; change the base URL if you are on sandbox.

You’ll call POST /pav2/open-api-appointments and filter on a one-day window using dateCreatedFrom and dateCreatedTo. Every endpoint in the Shepherd API is a POST, even reads; the filter goes in the JSON body.

For “today” in UTC, the window runs from 00:00:00Z to 23:59:59Z. If your clinic operates in a different timezone, adjust the bounds; the API stores timestamps in UTC. The 1-month range cap is documented in Conventions, well above what we need here.

Terminal window
TODAY=$(date -u +%Y-%m-%d)
curl -X POST https://open-api.shepherd.vet/pav2/open-api-appointments \
-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\": 100,
\"dateCreatedFrom\": \"${TODAY}T00:00:00Z\",
\"dateCreatedTo\": \"${TODAY}T23:59:59Z\",
\"sort\": \"dateCreated|asc\"
}"

The response is a collection envelope (see Conventions):

{
"item": [ /* appointment records */ ],
"totalRecords": 17,
"page": 1,
"recordsPerPage": 100,
"sort": "dateCreated|asc",
"searchQuery": null,
"embed": null,
"links": []
}

Iterate item[] to process each appointment. If totalRecords is larger than recordsPerPage, increment page and call again. The 10,000-item paging ceiling applies; for a single day’s appointments at any normal clinic you’ll never get close.

  • Inline related records (clients, patients, providers) with embed. See Conventions.
  • Read the Appointments resource reference for the full request and response shape.
  • When something goes wrong, the body is JSON, but not always the same shape. See Errors.