Husbandry.Pro API

Changelog

Breaking changes to documented, non-experimental endpoints get at least 90 days' notice and a Sunset header. Additive changes may ship at any time.

Feeder Farm

Endpoints and webhooks for the Feeder Farm workspace. Additive.

New endpoints

  • GET /feeder-farm/cultures and GET /feeder-farm/cultures/{id}:

colonies and batches with their lifecycle state and estimate-aware counts

  • POST /feeder-farm/cultures/{id}/care: record a care event, exactly as

a Care Route tap does; request_id makes retries safe

  • GET /feeder-farm/stock: linked sizes with live stock on hand
  • GET /feeder-farm/plan: the 14-day plan for one workspace
  • GET /feeder-farm/sales: orders with lines and packed lots

New scopes

  • feeder_farm:read, feeder_farm:write
  • feeder_farm_sales:read: PII, because each order carries the buyer's

name, email and phone

New webhook events

feeder_farm.sale.created, .sale.shipped, .sale.delivered, .sale.cancelled, feeder_farm.lot.packed, feeder_farm.alert.raised and feeder_farm.processing.finished. Each carries workspace_id to filter on.

Isopod availability, sales and issues

Three read endpoints for the isopod workspace. Additive, with one tightening.

New endpoints

  • GET /isopod/availability: sellable stock per living culture, computed

as the workspace does (prepared lots plus approved surplus, never the population estimate), with sale_blocked while an open issue holds the culture out of sale

  • GET /isopod/sales and GET /isopod/sales/{id}: isopod orders with

amounts, shipping and DOA status

  • GET /isopod/issues: mortality, pest and husbandry issues with the

cultures they affect

New scope

  • isopod_sales:read: isopod orders. PII, because each order carries the

buyer's name, email and phone. Availability and issues use isopods:read.

Tightened validation

Id filters on the isopod list endpoints (workspace_id, culture_id, taxon_id, enclosure_id) must now be numeric ids; a malformed value is a 400 invalid_query instead of being ignored, which used to return every row. state on /isopod/cultures must be a lifecycle state or live. observed_at on a new observation cannot be in the future.

Register your own OAuth apps

Developers can now register OAuth apps themselves under Profile, API, Your apps, instead of emailing us. A new app is in development: only your own account can connect to it while you build. Submit it for review to open it to every member. See the OAuth guide.

OAuth 2.0 for third-party apps

Apps that serve many Husbandry.Pro accounts can now connect them through OAuth instead of asking each user for an API key. Additive only; keys work exactly as before.

  • Authorization code flow with PKCE (S256, required), at /oauth/authorize
  • Token endpoint POST /oauth/token and revocation POST /oauth/revoke
  • One-hour access tokens (hpo_live_…) used like keys; rotating refresh

tokens (hpr_live_…) with replay detection

  • Discovery metadata at /.well-known/oauth-authorization-server
  • GET /me reports key.type: "oauth" and the connection under key.oauth

Users see and disconnect connected apps under Profile, API, Connected apps. Apps are registered on request after review. See the OAuth guide.

Isopod cultures, observations and lots

Version 1.2.0 adds the isopod workspace to the API. Additive only.

New scopes

  • isopods:read — cultures, observations and sale lots
  • isopods:write — record observations (implies isopods:read)

New endpoints

  • GET /isopod/cultures and GET /isopod/cultures/{id}
  • GET and POST /isopod/cultures/{id}/observations
  • GET /isopod/lots

Counts are estimate-aware everywhere: a range is returned as min/max with its precision and confidence, and POST /isopod/cultures/{id}/observations accepts the same shape, so a scale, a camera rig or a rack script can log what it measured without pretending to a precision it does not have. API-recorded observations default to method sensor_ai.

New webhook events

  • isopod.culture.split
  • isopod.observation.created
  • isopod.sale.shipped

Every write scope now has endpoints behind it

Version 1.1.0 completes the write surface. Nothing that worked before changes shape; every addition is a new operation or a new field.

New endpoints

  • POST /contacts and GET, PATCH, DELETE /contacts/{id} (contacts:write)
  • POST /breeding/records and /breeding/records/{id}; POST /breeding/clutches

and /breeding/clutches/{id} (breeding:write)

  • POST /medical/conditions and /medical/conditions/{id} (medical:write)
  • POST /environment/environments and /environment/environments/{id}

(environment:write)

  • POST /documents (base64 upload) and /documents/{id} (documents:write)
  • POST /sales/invoices, /sales/invoices/{id}, and

POST /sales/invoices/{id}/payments (sales:write)

  • GET, PATCH, DELETE /activities/{id} (activities:write)

The five scopes that were marked *not yet in use* — breeding:write, medical:write, documents:write, contacts:write, sales:write — are now live. Keys that already held them work without being reissued. The 405 that POST /contacts and POST /environment/environments used to return is gone.

Writes enforce the plan. Contacts, invoices, clutches, and document uploads answer 403 feature_not_in_plan or advanced_feature_required when the account's plan does not include the feature, exactly as the app does.

Activities of a trashed animal are hidden with it. GET /activities no longer lists records for an animal in the trash, ?animal_id= of such an animal returns 404, and the records return when the animal is restored. Recording, editing, or deleting a feeding or weight over the API now re-derives the animal's last_fed_at and latest_weight, as it does in the app.

OpenAPI models are now reusable. Every request and response model is published once under components.schemas (Animal, AnimalList, ContactCreateRequest, …) and referenced with $ref, so generated SDKs get one type per model instead of one per operation. Inline shapes are unchanged.

New error codes: feature_not_in_plan, contact_email_in_use, invoice_number_in_use, invoice_paid, invoice_voided, payment_exceeds_balance, storage_unavailable. All are listed at /developers/errors.

API v1 documented surface

Version 1.0.0 of the Husbandry.Pro API is the documented v1 surface.

Base URL is https://next.husbandry.pro. Paths are under /api/v1. The classic husbandry.pro domain is a separate older system and does not serve this API.

Open to integrators on the Breeder plan and above, and to accounts on the live-test allowlist while GET /status reports limited. The docs stay public either way.

What v1 includes:

  • Account (GET /me)
  • Animals, read and write, plus this account's species list
  • Activities, read and write, plus activity types
  • Breeding records and clutches (read)
  • Medical conditions (read)
  • Contacts and invoices (read; these scopes carry customer personal data)
  • Documents (list metadata; upload and download are not in v1)
  • Environment list, metrics, and stored readings (read)
  • Sensor devices, JSON ingest, constrained-firmware ping (GET and POST), and

headless pairing

  • Webhook endpoints (create, pause, retarget, delete)
  • Species reference library
  • Status and the OpenAPI document at /api/v1/openapi.json

Writes that were not in 1.0.0, and returned 405 if called: breeding, medical, contacts, sales, document upload, and creating environments. Those scopes could still be granted so a key would keep working when the endpoints landed — which they did in 1.1.0, above.

Authentication is a bearer token (hpk_ personal access token or hpd_ device key). X-API-Key is accepted too. Device keys can only push readings and read their own device configuration.