2026-07-06 15:43:23 -05:00
# BREEDR API Documentation (v0.8.1)
2026-03-11 09:51:35 -05:00
Base URL: `/api`
All endpoints return JSON responses. Errors follow the format `{ "error": "message" }` .
2026-07-06 15:43:23 -05:00
Validation failures return `400` , missing resources return `404` .
2026-03-11 09:51:35 -05:00
---
## 1. Dogs (`/api/dogs`)
Manage individual dogs in the kennel.
### `GET /`
2026-07-06 15:43:23 -05:00
Get active kennel dogs (paginated).
2026-03-11 09:51:35 -05:00
- **Query Params**:
- `include_external=1` : Include external dogs (studs/others)
- `external_only=1` : Only show external dogs
2026-07-06 15:43:23 -05:00
- `page` (default 1), `limit` (default 50, max 200)
- `search` : Filter by name or registration number
- `sex` : `male` | `female`
- **Response**: `{ "data": [Dog...], "total", "page", "limit", "stats": { "total", "males", "females" } }` — each Dog has `sire` and `dam` attached.
### `GET /all`
Get all active dogs (kennel + external, unpaginated). Used for dropdowns/pairing/pedigree.
2026-03-11 09:51:35 -05:00
### `GET /:id`
Get single dog details.
2026-07-06 15:43:23 -05:00
- **Response**: [Dog ](#dog-object ) object including `sire` , `dam` , and `offspring` array. `404` if not found.
2026-03-11 09:51:35 -05:00
### `POST /`
Create a new dog.
- **Body**: See [Dog ](#dog-object ) fields. `name` , `breed` , `sex` are required.
2026-07-06 15:43:23 -05:00
- **Validation**: If `sire_id` /`dam_id` are provided they must reference an existing dog of the correct sex (sire → male, dam → female), else `400` . The dog + parent links are written in a single transaction.
- **Response**: The created Dog object (`201` ).
2026-03-11 09:51:35 -05:00
### `PUT /:id`
Update an existing dog.
- **Body**: Dog fields to update.
2026-07-06 15:43:23 -05:00
- **Validation**: `404` if the dog doesn't exist. Same sire/dam checks as `POST /` , plus a dog cannot be its own parent.
2026-03-11 09:51:35 -05:00
- **Response**: The updated Dog object.
### `DELETE /:id`
2026-07-06 15:43:23 -05:00
Permanently delete a dog and its related records (health, heat cycles, parent links) in a single transaction.
- **Response**: `{ "success": true, "message": "..." }` — `404` if not found.
2026-03-11 09:51:35 -05:00
### `POST /:id/photos`
2026-07-06 15:43:23 -05:00
Upload a photo for a dog (JPEG/PNG/GIF/WebP, ≤ 10 MB).
2026-03-11 09:51:35 -05:00
- **Form-Data**: `photo` (file)
- **Response**: `{ "url": "...", "photos": [...] }`
### `DELETE /:id/photos/:photoIndex`
Delete a specific photo from a dog's photo array.
2026-07-06 15:43:23 -05:00
- **Validation**: `400` if `photoIndex` is not an integer within the photo array's bounds.
2026-03-11 09:51:35 -05:00
- **Response**: `{ "photos": [...] }`
---
## 2. Litters (`/api/litters`)
Manage breeding litters and puppy logs.
### `GET /`
2026-07-06 15:43:23 -05:00
Get all litters (paginated).
- **Query Params**: `page` (default 1), `limit` (default 50)
- **Response**: `{ "data": [Litter...], "total", "page", "limit" }` with sire/dam names and puppies attached.
2026-03-11 09:51:35 -05:00
### `GET /:id`
Get single litter details.
- **Response**: [Litter ](#litter-object ) object.
### `POST /`
Create a new litter.
- **Body**: `sire_id` , `dam_id` , `breeding_date` (required), `whelping_date` , `puppy_count` , `notes` .
2026-07-06 15:43:23 -05:00
- **Validation**: Sire must be male, dam must be female.
2026-03-11 09:51:35 -05:00
- **Response**: The created Litter object.
### `PUT /:id`
2026-07-06 15:43:23 -05:00
Update litter details (`breeding_date` , `whelping_date` , `puppy_count` , `notes` — parents cannot change).
### `DELETE /:id`
Delete a litter. Puppies are unlinked (their dog records are kept).
2026-03-11 09:51:35 -05:00
### `POST /:id/puppies/:puppyId`
Link a dog to a litter as a puppy.
- **Side Effect**: Automatically sets the litter's sire and dam as the puppy's parents.
### `DELETE /:id/puppies/:puppyId`
Remove a puppy from a litter (sets `litter_id` to NULL).
### `GET /:litterId/puppies/:puppyId/logs`
Get weight and health logs for a puppy.
### `POST /:litterId/puppies/:puppyId/logs`
2026-07-06 15:43:23 -05:00
Add a weight/health log entry (stored in `health_records` ; weights serialized into `description` ).
- **Body**: `record_date` (required), `weight_oz` , `weight_lbs` , `notes` , `record_type` (default `weight_log` ).
### `DELETE /:litterId/puppies/:puppyId/logs/:logId`
Delete a weight/health log entry.
2026-03-11 09:51:35 -05:00
---
## 3. Health (`/api/health`)
Manage OFA clearances and veterinary records.
2026-07-06 15:07:04 -05:00
**Record types** (`record_type` ): `ofa_clearance` , `vaccination` , `exam` , `surgery` , `medication` , `other` .
**Valid `test_type` values** (OFA clearances only): `hip_ofa` , `hip_pennhip` , `elbow_ofa` , `patella_ofa` , `heart_ofa` , `heart_echo` , `eye_caer` , `thyroid_ofa` .
> DNA is **not** a health test type — DNA panels are managed exclusively by the Genetics module (`/api/genetics`).
2026-03-11 09:51:35 -05:00
### `GET /dog/:dogId`
Get all health records for a dog.
### `GET /dog/:dogId/clearance-summary`
Get GRCA core clearance status (Hip, Elbow, Heart, Eyes).
- **Response**: `{ summary, grca_eligible, age_eligible, chic_number }`
2026-07-06 15:07:04 -05:00
- Only recurring tests (CAER eyes, advanced/echo cardiac) carry an `expires_at` ; permanent certifications (hip, elbow, etc.) never report `expired` /`expiring_soon` .
2026-03-11 09:51:35 -05:00
### `GET /dog/:dogId/chic-eligible`
Check if a dog has all required CHIC tests.
2026-07-06 15:07:04 -05:00
### `GET /:id`
Get a single health record.
2026-03-11 09:51:35 -05:00
### `POST /`
Create health record.
2026-07-06 15:07:04 -05:00
- **Body**: `dog_id` , `record_type` , `test_date` (all required), plus optional `test_type` , `test_name` , `ofa_result` , `ofa_number` , `performed_by` , `expires_at` , `result` , `next_due` , `document_url` , `notes` .
- **Validation**: `test_type` , if present, must be one of the valid values above (else `400` ).
- **Note**: `performed_by` is the single clinician field (the legacy `vet_name` column is deprecated).
### `PUT /:id`
Update an existing health record. Same body as `POST /` (minus `dog_id` ).
### `DELETE /:id`
Delete a health record.
- **Response**: `{ "message": "Health record deleted successfully" }`
### `POST /upload`
Upload a supporting document (PDF or image, ≤ 15 MB) and get back a URL to store in a record's `document_url` . Record-agnostic — works before the record itself is saved.
- **Form-Data**: `document` (file)
- **Response**: `{ "url": "/uploads/..." }`
### `GET /dog/:dogId/cancer-history`
Get cancer-history records for a dog.
### `POST /cancer-history`
Add a cancer-history record.
- **Body**: `dog_id` , `cancer_type` (required), `age_at_diagnosis` , `age_at_death` , `cause_of_death` , `notes` .
2026-03-11 09:51:35 -05:00
---
## 4. Genetics (`/api/genetics`)
Manage DNA panel results and breeding risks.
### `GET /dog/:dogId`
Get the full genetic panel for a dog. Returns `tests` (actual records) and `panel` (full list including `not_tested` placeholders).
### `GET /pairing-risk?sireId=X&damId=Y`
Check genetic compatibility between two dogs.
- **Response**: `{ risks: [...], safe_to_pair: boolean }`
2026-07-06 15:43:23 -05:00
### `GET /:id`
Get a single genetic test record.
2026-03-11 09:51:35 -05:00
### `POST /`
Add a genetic test result.
2026-07-06 15:43:23 -05:00
- **Body**: `dog_id` , `marker` , `result` (clear|carrier|affected|not_tested), plus optional `test_provider` , `test_date` , `document_url` , `notes` .
### `PUT /:id`
Update a genetic test result.
### `DELETE /:id`
Delete a genetic test result.
2026-03-11 09:51:35 -05:00
---
## 5. Breeding (`/api/breeding`)
Track heat cycles and whelping projections.
2026-07-06 15:43:23 -05:00
### `GET /heat-cycles`
Get all heat cycles (with dog info). Optional `?year=YYYY&month=M` filter.
2026-03-11 09:51:35 -05:00
### `GET /heat-cycles/active`
Get currently active heat cycles.
2026-07-06 15:43:23 -05:00
### `GET /heat-cycles/dog/:dogId`
Get all heat cycles for a specific dog.
2026-03-11 09:51:35 -05:00
### `GET /heat-cycles/:id/suggestions`
Get optimal breeding window (days 9-15) and whelping projections.
### `POST /heat-cycles`
Log a new heat cycle. Dog must be female.
2026-07-06 15:43:23 -05:00
- **Body**: `dog_id` , `start_date` (required), `end_date` , `breeding_date` , `breeding_successful` , `notes` .
### `PUT /heat-cycles/:id`
Update a heat cycle (same body as `POST` , minus `dog_id` ).
### `DELETE /heat-cycles/:id`
Delete a heat cycle.
2026-03-11 09:51:35 -05:00
### `GET /whelping-calculator?breeding_date=YYYY-MM-DD`
Standalone tool to calculate expected whelping window.
---
## 6. Pedigree (`/api/pedigree`)
Advanced ancestry and COI calculations.
### `GET /:id?generations=N`
Get an interactive pedigree tree (ancestors). Default 5 generations.
### `GET /:id/descendants?generations=N`
Get a descendant tree. Default 3 generations.
### `POST /trial-pairing`
2026-07-06 15:43:23 -05:00
Calculate Coefficient of Inbreeding (COI) for a hypothetical mating. (`POST /coi` is an alias.)
2026-03-11 09:51:35 -05:00
- **Body**: `sire_id` , `dam_id` .
- **Response**: `{ coi, commonAncestors, directRelation, recommendation }`
2026-07-06 15:43:23 -05:00
### `GET /:id/coi`
Get the COI for an existing dog (computed from its actual parents).
### `GET /relations/:sireId/:damId`
Check the direct relationship between two dogs (parent/offspring, siblings, etc.).
### `GET /:id/cancer-lineage`
Cancer history aggregated across a dog's lineage.
2026-03-11 09:51:35 -05:00
---
## 7. Settings (`/api/settings`)
### `GET /`
Get kennel metadata (name, address, etc.).
### `PUT /`
Update kennel settings.
---
## Data Objects
### Dog Object
```json
{
"id" : 1 ,
"name" : "BREEDR Champion" ,
"registration_number" : "AKC123456" ,
"breed" : "Golden Retriever" ,
"sex" : "male" ,
"birth_date" : "2020-01-01" ,
"color" : "Golden" ,
"microchip" : "900123456789" ,
"is_active" : 1 ,
"is_champion" : 1 ,
"is_external" : 0 ,
"photo_urls" : [ "/uploads/img.jpg" ],
"notes" : "Excellent temperament" ,
"sire" : { "id" : 10 , "name" : "Sire Name" },
"dam" : { "id" : 11 , "name" : "Dam Name" }
}
```
### Litter Object
```json
{
"id" : 5 ,
"sire_id" : 1 ,
"dam_id" : 2 ,
2026-07-06 15:43:23 -05:00
"sire_name" : "Sire Name" ,
"dam_name" : "Dam Name" ,
"breeding_date" : "2026-01-01" ,
"whelping_date" : "2026-03-05" ,
"puppy_count" : 8 ,
"notes" : null ,
"puppies" : [ ... ],
"actual_puppy_count" : 8
2026-03-11 09:51:35 -05:00
}
```