Skill for AI coding agents
If you use an AI coding assistant such as Claude Code to build your application that’s integrated with Shepherd, install this skill first. It gives the agent the Shepherd API’s endpoints, schemas, and rules, plus a tool that checks every request before your code sends it, so the code it writes is correct the first time and easy on the servers every clinic shares.
Shepherd OpenAPI skill
- Version 1.1.0
- 267 KB zip, 42 files
- MIT license
SHA-256 18a6df23bf162bd798b68270f172b70bafb4830f23cf23ec9badda76d617046f
The skill is free and MIT licensed: use it, change it, and ship code written with it. It follows the open Agent Skills format, so it is plain Markdown, JSON, and one Python script that you can read before you install it.
Why use it
Section titled “Why use it”AI assistants write API clients quickly, and they fill gaps in what they know with confident guesses. Against the Shepherd API, the usual guesses go wrong in the same few ways:
- The wrong host or header. Calls go to a host that does not serve the API, or the clinic id goes in the JSON body instead of the
X-Clinic-Idheader. - Unbounded reads. A sync asks for a clinic’s entire history in one query, or a misspelled filter is silently ignored and the query runs unfiltered.
- Retry loops. A slow request times out and the code sends it again, and again, multiplying the work on the server; or a rejected request is retried until the rate limit locks the integration out.
- Destructive updates. An update sends only the changed field, and the API, which treats updates as full replacements, clears everything else on the record.
- Duplicate records. A create is retried after a timeout and the clinic gets two appointments.
Each of these fails, loses clinic data, or slows the API for other clinics. With the skill installed, the agent knows the rules behind them and checks its requests against them before anything is sent.
What the agent gets
Section titled “What the agent gets”- The endpoint reference, offline. Every public endpoint, with its request fields, required fields, and response shape, generated from the live API description. The agent looks endpoints up instead of guessing, and does not need to browse.
- The rules the schema cannot express. Which lists need a date window, page-size and embed limits, which filter fields an endpoint accepts but never applies, how rate limits are counted, which failures to retry and which never to retry, and exactly which fields each update keeps or clears. These rules are checked against the live API with a test harness, not only read from the schema; see How we verify.
- A request linter.
scripts/shepherd_api.py lintchecks a request against those rules and the schema before any code sends it: host, verb, route, field names, fields the endpoint does not apply, sort fields, id and date formats, date windows, page sizes, embeds, and update completeness. - A budgeted development runner.
scripts/shepherd_api.py callsends one request at a time for exploration, against the sandbox by default, under a local rate budget and circuit breaker. - Starter clients and tests in Python, TypeScript, C#, and PHP that already handle timeouts, rate limits, paging, error bodies, and safe updates.
Directoryshepherd-openapi/
- SKILL.md the rules and workflow the agent follows
- LICENSE.txt
Directoryreferences/
- api-essentials.md hosts, headers, paging, filters, embeds
- limits-and-sync.md rate limits, retries, incremental sync
- writes.md creates, updates, read-merge-write
- errors.md status codes, error bodies, fixes
- resources.md, client-patterns.md, testing.md, production-checklist.md
Directoryendpoints/ per-area endpoint reference
- …
Directoryassets/
- openapi.json machine-readable endpoint description, with request rules
Directorytemplates/ starter clients and tests for four languages
- …
Directoryscripts/
- shepherd_api.py endpoint lookup, linter, and development runner
Install
Section titled “Install”Claude Code loads skills from a folder on disk and uses them automatically when a task involves the Shepherd API.
-
Download the zip above.
-
Unzip it into one of the skills folders:
Terminal window # For you, in every projectunzip shepherd-openapi-skill.zip -d ~/.claude/skills/# Or for one repository, shared with everyone who clones itunzip shepherd-openapi-skill.zip -d .claude/skills/Either way you end up with
skills/shepherd-openapi/SKILL.md. Committing the project copy gives your whole team the same rules. -
Start a new Claude Code session. Ask it to work on your integration, or invoke the skill directly with
/shepherd-openapi.
In Claude on the web or desktop, custom skills are uploaded as a zip. They require code execution to be enabled, and each person uploads their own copy.
-
Download the zip above. Don’t unzip it.
-
In Claude, open Customize, then Skills, and choose Upload a skill.
-
Upload
shepherd-openapi-skill.zip.
Menu names change from time to time; Anthropic’s Using Skills in Claude article has the current steps. Network access for skills in the Claude apps depends on your plan and admin settings, so live calls through the runner may be blocked; the reference, rules, and linter work without it.
Upload the skill once through the Skills API and attach it to requests that use the code execution tool. Skills on the API run in a container with no network access, so the agent can use the reference, rules, linter, and templates to write and review code, but cannot make live calls to Shepherd.
The skill follows the open Agent Skills format, which a growing number of coding agents support. Unzip it into the skills folder your agent reads, keeping the shepherd-openapi/ folder name, and check your agent’s documentation for where that is. The helper script needs Python 3.11 or newer.
Set up credentials
Section titled “Set up credentials”The agent never needs your keys in the conversation. Set them in the environment the agent runs in, and use sandbox keys while you develop:
export SHEPHERD_ENV=sandbox # or productionexport SHEPHERD_PUBLIC_KEY=...export SHEPHERD_PRIVATE_KEY=...export SHEPHERD_CLINIC_ID=...export SHEPHERD_APP_NAME=acme-lab-sync # optional: identifies your integrationSandbox keys work against https://demo-open-api.shepherd.vet/pav2/. If you don’t have them yet, see Authentication.
Try it
Section titled “Try it”Ask your agent for real work. For example:
- “Write a job that syncs appointments changed since the last run into our database.”
- “Add a function that updates a patient’s alerts.”
- “Our appointment import keeps timing out in production. Fix it.”
- “Add tests for our Shepherd client that cover rate limits and timeouts.”
- “Show me the first page of sandbox clients created last month.”
The helper script
Section titled “The helper script”The agent runs scripts/shepherd_api.py from the skill folder, and you can too. It uses only the Python standard library.
python3 scripts/shepherd_api.py endpoints --search invoicepython3 scripts/shepherd_api.py schema "POST /pav2/open-api-invoices"python3 scripts/shepherd_api.py lint "POST /pav2/open-api-appointments" --body '{"rpp":100,"dateFrom":"2026-05-01T00:00:00Z","dateTo":"2026-06-01T00:00:00Z"}'python3 scripts/shepherd_api.py call "POST /pav2/open-api-clinics" --body '{"page":1,"rpp":1}'python3 scripts/shepherd_api.py statusHere is the linter reviewing a request an agent might write from memory:
$ python3 scripts/shepherd_api.py lint "POST /pav2/open-api-appointments" \ --body '{"page":1,"rpp":1000,"dateCreatedFrom":"2026-01-01T00:00:00Z","embed":"appointmentPatients.patient","clinicId":"9890662f-52db-4a41-a5c1-b2e300d400b4"}'ERROR [clinic-in-body] The clinic id is the X-Clinic-Id HEADER. A clinicId in the body is ignored.ERROR [date-pair] `dateCreatedFrom` without `dateCreatedTo` spans from then until now. Send both ends, one month at most.ERROR [unbounded] This list has no bound: add a date window (one month at most) or an id filter (`appointmentStatusIds`, `cancellationReasonIds`, `clientIds`, `patientIds`, `providerIds`, `ids`). Enumerating a whole collection is not a supported access pattern.WARN [embed-rpp] `rpp` 1000 with embeds multiplies the response size. Keep embedded pages at 250 or fewer.INFO [is-deleted] Deleted records are included unless you send `isDeleted: false`. Either filter them out or handle the soft-delete flag.ERROR [heavy-embed] Embedding `appointmentPatients.patient` is expensive on large pages. Use `rpp` of 50 or less with it, and an id filter.For updates, pass the current record with --current and the linter lists every field the update would clear.
The call runner is for exploration during development, not for production traffic. It is deliberately conservative:
- It targets the sandbox unless
SHEPHERD_ENV=productionis set, and refuses creates and updates against production without--allow-production-write. - It lints first and does not send a request with errors.
- It sends one request at a time, within a local budget of 30 requests a minute and 600 an hour per key.
- It never retries a timeout or a create. After a
429it refuses further requests until the next UTC minute; after repeated timeouts or server errors it stops sending for five minutes. --dry-runprints the equivalentcurlcommand, with keys left as environment variables, instead of sending.
Starter clients and tests
Section titled “Starter clients and tests”The templates in assets/templates/ are starting points to copy into your project and own, not published packages. Each client implements the same behaviors, and each test suite exercises them against a mocked transport, so the tests run offline and instantly.
| Language | Client | Tests | Runtime |
|---|---|---|---|
| Python | shepherd_client.py | test_shepherd_client.py (pytest) | Python 3.11+, httpx |
| TypeScript | shepherd-client.ts | shepherd-client.test.ts (node:test) | Node.js 24+, no dependencies |
| C# | ShepherdClient.cs | ShepherdClientTests.cs (xUnit v3) | .NET 10 |
| PHP | src/ShepherdClient.php | tests/ShepherdClientTest.php (PHPUnit 13) | PHP 8.4+, Guzzle 8 |
The tests cover the cases that matter in production: 429 handling, 502 and 503 backoff, timeouts, 500s, and creates that are never retried, malformed clinic ids refused before sending, the circuit breaker, JSON string, JSON object, and plain-text error bodies, refusing unbounded lists, and read-merge-write updates that keep untouched fields.
What the skill asks of the agent
Section titled “What the skill asks of the agent”The rules in SKILL.md match the API reference on this site. In short, the agent will:
- Use the right environment. The sandbox for development and tests,
httpsonly, the three headers withX-Clinic-Idas a header. See Authentication. - Bound every read. A date window of one calendar month or less, or an id filter; explicit page sizes; shallow embeds. See Conventions.
- Respect the limits. One shared budget per key, sequential requests by default, a wait for the next UTC minute after a
429, and no retries of timeouts,4xxresponses,500s, or creates. See Rate limits and Errors. - Write safely. Read, merge, and write every update; look for an existing record before creating one after an ambiguous failure; get a human’s approval before the first production write. See Updating records.
- Test. Unit tests for the failure cases above, and a few opt-in contract tests against the sandbox.
Privacy and security
Section titled “Privacy and security”- The skill runs entirely inside your agent. It has no telemetry and sends nothing to Shepherd or anyone else; the only network requests are the API calls you or your agent run with
call. - Keys are read from environment variables and are never written to disk or printed. The runner keeps its budget and breaker state in
~/.cache/shepherd-openapi-skill/, under a hash of the public key. - Requests sent by the runner carry a
User-Agentnaming the skill version and yourSHEPHERD_APP_NAME, so Shepherd can tell development traffic apart if you ask for help. - As with any skill, review what you install. Everything in the zip is readable text, and the SHA-256 above lets you confirm you have the file published here.
Versions and updates
Section titled “Versions and updates”This is version 1.1.0, built from the public API as of September 2026 (API version 2.246.0.33). When the API changes in a way that affects integrations, a new version is published here. Download it again and replace the shepherd-openapi folder (or upload it again in the Claude apps).
| Version | Date | Changes |
|---|---|---|
| 1.1.0 | September 2026 | Rules corrected and extended from live test-harness evidence: filter fields an endpoint accepts but does not apply are flagged, unknown sort fields are errors, rpp and page below 1 or null are rejected, smaller pages on large-record endpoints, a bound required on breeds, a date window required on every patient-notes read, 401 (not 403) for an unlinked clinic, and 500s are never retried. The starter clients refuse a malformed clinic id and no longer retry a 500. |
| 1.0.0 | September 2026 | First release. |
Troubleshooting
Section titled “Troubleshooting”The agent isn’t using the skill. Mention the Shepherd API in your request, or in Claude Code invoke it with /shepherd-openapi. Check that the folder is named shepherd-openapi and contains SKILL.md directly.
The helper script won’t run. It needs Python 3.11 or newer on the path as python3. Without it, the agent still has the reference and rules, but cannot lint or make live calls.
Live calls fail with a network error. Your agent’s environment may block outbound requests; the Claude API always does, and the Claude apps can, depending on settings. Run the calls from your own machine instead.
Something in the skill is wrong or missing. Tell us. Include the skill version, the endpoint, and what you expected.