Animals API
HTTP reference for animals. Read authentication and access before using these operations. All examples use made-up data and placeholder credentials.
- GET /v1/farm/{farm_id}/animals
- POST /v1/farm/{farm_id}/animals
- DELETE /v1/farm/{farm_id}/animals/{animal_id}
- GET /v1/farm/{farm_id}/animals/{animal_id}
- PUT /v1/farm/{farm_id}/animals/{animal_id}
- POST /v1/farm/{farm_id}/animals/find-or-create-by-eid
- GET /v1/farm/{farm_id}/animals/index
- GET /v1/farm/{farm_id}/animals/lookup-by-eid
GET /v1/farm/{farm_id}/animals
Get Animals
Current animals HTTP operation. External credential scopes: read:animals. Minimum farm role: READER. Pagination accepts integer skip and take; set both explicitly. An omitted value passes through to the data query. Collection property names differ by resource; use the response schema. Production rate limit: 100 requests per 15-minute window per device account, 1000 per browser session, otherwise per client IP. RateLimit headers report the current window; respect Retry-After on 429. Defaults to CURRENT inventory. Use inventory_status=ALL to include all nondeleted historical profiles, or select UNKNOWN, SOLD, DECEASED, or NOT_MANAGED. With a nonblank query, searches active saved identifiers and the canonical current profile name (metadata.name). Exact is case-sensitive full-value equality; partial is a literal case-insensitive substring over profile names, NAME and MANAGEMENT_TAG identifiers. Defaults to inventory_status=ALL and skip 0 / take 50 (max 200) while searching.
| Parameter | In | Required | Schema |
|---|---|---|---|
| farm_id | path | Yes | {"type":"string","format":"uuid"} |
| skip | query | No | {"type":"integer"} |
| take | query | No | {"type":"integer"} |
| inventory_status | query | No | {"type":"string","enum":["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED","ALL"],"default":"CURRENT"} |
| query | query | No | {"type":"string","maxLength":200} Saved identifier value or current profile name to find. Blank is rejected. |
| match_mode | query | No | {"type":"string","enum":["exact","partial"]} exact (default) full-value equality, or partial literal case-insensitive substring discovery. |
| identifier_type | query | No | {"type":"string","enum":["BRAND","EID","MANAGEMENT_TAG","NAME","TATTOO"]} Restrict matching to one saved identifier type; binding on an exact query. |
Request example
curl --fail-with-body -X GET \
'https://api.ranch.bot/v1/farm/<farm_id>/animals' \
-H "Authorization: Bearer $RANCHBOT_TOKEN"Responses
| Status | Meaning | Content type |
|---|---|---|
| 200 | Success | application/json |
| 400 | Request validation failed. | application/json |
| 401 | Missing/invalid authentication or insufficient farm role. | application/json |
| 403 | Missing required scope or credential type is disallowed. | application/json |
| 404 | Resource or active farm membership not found. | application/json |
| 429 | Rate limit exceeded. Retry after the indicated delay. | application/json |
| 500 | Unexpected server failure. | application/json |
200 response schema (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| total | number | Required | |
| records | array | Required | |
| records[] | object | Required | |
| records[].id | string | Required | |
| records[].created_at | string | Required | format: "date-time" |
| records[].updated_at | string | Required | format: "date-time" |
| records[].is_active | boolean | Required | |
| records[].farm_id | string | Required | |
| records[].metadata | JSON | Required | |
| records[].groups | array | Required | |
| records[].groups[] | object | Required | |
| records[].groups[].id (variant 1) | string | Required | |
| records[].groups[].id (variant 2) | null | Required | |
| records[].groups[].farm_id (variant 1) | string | Required | |
| records[].groups[].farm_id (variant 2) | null | Required | |
| records[].groups[].description (variant 1) | string | Required | |
| records[].groups[].description (variant 2) | null | Required | |
| records[].groups[].is_active (variant 1) | boolean | Required | |
| records[].groups[].is_active (variant 2) | null | Required | |
| records[].groups[].name (variant 1) | string | Required | |
| records[].groups[].name (variant 2) | null | Required | |
| records[].groups[].created_at (variant 1) | string | Required | format: "date-time" |
| records[].groups[].created_at (variant 2) | null | Required | |
| records[].groups[].updated_at (variant 1) | string | Required | format: "date-time" |
| records[].groups[].updated_at (variant 2) | null | Required | |
| records[].animal_identifiers | array | Required | |
| records[].animal_identifiers[] | object | Required | |
| records[].animal_identifiers[].id (variant 1) | string | Required | |
| records[].animal_identifiers[].id (variant 2) | null | Required | |
| records[].animal_identifiers[].animal_id (variant 1) | string | Required | |
| records[].animal_identifiers[].animal_id (variant 2) | null | Required | |
| records[].animal_identifiers[].is_active (variant 1) | boolean | Required | |
| records[].animal_identifiers[].is_active (variant 2) | null | Required | |
| records[].animal_identifiers[].is_primary (variant 1) | boolean | Required | |
| records[].animal_identifiers[].is_primary (variant 2) | null | Required | |
| records[].animal_identifiers[].type (variant 1) | string | Required | |
| records[].animal_identifiers[].type (variant 2) | null | Required | |
| records[].animal_identifiers[].value (variant 1) | string | Required | |
| records[].animal_identifiers[].value (variant 2) | null | Required | |
| records[].animal_identifiers[].created_at (variant 1) | string | Required | format: "date-time" |
| records[].animal_identifiers[].created_at (variant 2) | null | Required | |
| records[].animal_identifiers[].updated_at (variant 1) | string | Required | format: "date-time" |
| records[].animal_identifiers[].updated_at (variant 2) | null | Required | |
| records[].inventory_status | string | Required | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
| records[].birth_facts | object | Optional | |
| records[].birth_facts.record (variant 1) | object | Required | |
| records[].birth_facts.record (variant 1).record_id | string | Required | |
| records[].birth_facts.record (variant 1).birth_event_id | string | Required | |
| records[].birth_facts.record (variant 1).revision | number | Required | |
| records[].birth_facts.record (variant 1).birth_date | string | Required | |
| records[].birth_facts.record (variant 1).time_precision (variant 1) | string | Required | |
| records[].birth_facts.record (variant 1).time_precision (variant 2) | null | Required | |
| records[].birth_facts.record (variant 1).dam_id | string | Required | |
| records[].birth_facts.record (variant 1).sire (variant 1) | object | Required | |
| records[].birth_facts.record (variant 1).sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| records[].birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1) | string | Required | |
| records[].birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2) | null | Required | |
| records[].birth_facts.record (variant 1).sire (variant 1).provenance (variant 1) | string | Required | |
| records[].birth_facts.record (variant 1).sire (variant 1).provenance (variant 2) | null | Required | |
| records[].birth_facts.record (variant 1).sire (variant 1).confidence (variant 1) | number | Required | |
| records[].birth_facts.record (variant 1).sire (variant 1).confidence (variant 2) | null | Required | |
| records[].birth_facts.record (variant 1).sire (variant 2) | null | Required | |
| records[].birth_facts.record (variant 2) | null | Required | |
| records[].birth_facts.derived | object | Required | |
| records[].birth_facts.derived.birth_date (variant 1) | string | Required | |
| records[].birth_facts.derived.birth_date (variant 2) | null | Required | |
| records[].birth_facts.derived.time_precision (variant 1) | string | Required | |
| records[].birth_facts.derived.time_precision (variant 2) | null | Required | |
| records[].birth_facts.derived.dam_id (variant 1) | string | Required | |
| records[].birth_facts.derived.dam_id (variant 2) | null | Required | |
| records[].birth_facts.derived.sire (variant 1) | object | Required | |
| records[].birth_facts.derived.sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| records[].birth_facts.derived.sire (variant 1).animal_id (variant 1) | string | Required | |
| records[].birth_facts.derived.sire (variant 1).animal_id (variant 2) | null | Required | |
| records[].birth_facts.derived.sire (variant 1).provenance (variant 1) | string | Required | |
| records[].birth_facts.derived.sire (variant 1).provenance (variant 2) | null | Required | |
| records[].birth_facts.derived.sire (variant 1).confidence (variant 1) | number | Required | |
| records[].birth_facts.derived.sire (variant 1).confidence (variant 2) | null | Required | |
| records[].birth_facts.derived.sire (variant 2) | null | Required | |
| records[].birth_facts.profile_birth_date (variant 1) | string | Required | |
| records[].birth_facts.profile_birth_date (variant 2) | null | Required | |
| records[].birth_facts.effective_birth_date (variant 1) | string | Required | |
| records[].birth_facts.effective_birth_date (variant 2) | null | Required | |
| records[].birth_facts.conflicts | array | Required | |
| records[].birth_facts.conflicts[] | object | Required | |
| records[].birth_facts.conflicts[].independent_birth_date | string | Required | |
| records[].birth_facts.conflicts[].recorded_birth_date | string | Required | |
| records[].birth_facts.conflicts[].record_id | string | Required | |
| records[].search_matches | array | Optional | |
| records[].search_matches[] (variant 1) | object | Required | |
| records[].search_matches[] (variant 1).source | JSON | Required | const: "identifier" |
| records[].search_matches[] (variant 1).identifier_id | string | Required | |
| records[].search_matches[] (variant 1).identifier_type | string | Required | |
| records[].search_matches[] (variant 1).value | string | Required | |
| records[].search_matches[] (variant 2) | object | Required | |
| records[].search_matches[] (variant 2).source | JSON | Required | const: "profile_name" |
| records[].search_matches[] (variant 2).value | string | Required | |
| outcome | string | Optional | enum: ["not_found","unique","ambiguous","candidates"] |
| scope | object | Optional | |
| scope.farm_id | string | Optional | |
| scope.query | string | Optional | |
| scope.match_mode | string | Optional | enum: ["exact","partial"] |
| scope.identifier_type (variant 1) | string | Optional | |
| scope.identifier_type (variant 2) | null | Optional | |
| scope.inventory_status | string | Optional | |
| scope.searches_profile_names | boolean | Optional | |
| scope.searched_identifier_types | array | Optional | |
| scope.searched_identifier_types[] | string | Required | |
| pagination | object | Optional | |
| pagination.skip | integer | Required | |
| pagination.take (variant 1) | integer | Required | |
| pagination.take (variant 2) | null | Required | |
| pagination.returned | integer | Required | |
| pagination.has_more | boolean | Required | |
| pagination.next_skip (variant 1) | integer | Required | |
| pagination.next_skip (variant 2) | null | Required |
{
"total": 0,
"records": []
}POST /v1/farm/{farm_id}/animals
Create Animal
Current animals HTTP operation. External credential scopes: write:animals. Minimum farm role: EDITOR. Direct requests execute without an app confirmation screen. Production rate limit: 100 requests per 15-minute window per device account, 1000 per browser session, otherwise per client IP. RateLimit headers report the current window; respect Retry-After on 429. inventory_status is separate from deletion: CURRENT, UNKNOWN, SOLD, DECEASED, or NOT_MANAGED. New animals default to CURRENT; use UNKNOWN when present inventory membership is unconfirmed. Status changes preserve profile history and identifiers.
| Parameter | In | Required | Schema |
|---|---|---|---|
| farm_id | path | Yes | {"type":"string","format":"uuid"} |
Request body (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| metadata | JSON | Optional | |
| inventory_status | string | Optional | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
{}Request example
curl --fail-with-body -X POST \
'https://api.ranch.bot/v1/farm/<farm_id>/animals' \
-H "Authorization: Bearer $RANCHBOT_TOKEN" \
-H "Content-Type: application/json" \
--data '{}'Responses
| Status | Meaning | Content type |
|---|---|---|
| 201 | Success | application/json |
| 400 | Request validation failed. | application/json |
| 401 | Missing/invalid authentication or insufficient farm role. | application/json |
| 403 | Missing required scope or credential type is disallowed. | application/json |
| 404 | Resource or active farm membership not found. | application/json |
| 429 | Rate limit exceeded. Retry after the indicated delay. | application/json |
| 500 | Unexpected server failure. | application/json |
201 response schema (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| id | string | Required | |
| created_at | string | Required | format: "date-time" |
| updated_at | string | Required | format: "date-time" |
| is_active | boolean | Required | |
| farm_id | string | Required | |
| metadata | JSON | Required | |
| inventory_status | string | Required | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
{
"id": "11111111-1111-4111-8111-111111111111",
"created_at": "2026-09-01T12:00:00.000Z",
"updated_at": "2026-09-01T12:00:00.000Z",
"is_active": true,
"farm_id": "11111111-1111-4111-8111-111111111111",
"metadata": null,
"inventory_status": "CURRENT"
}DELETE /v1/farm/{farm_id}/animals/{animal_id}
Delete Animal
Current animals HTTP operation. External credential scopes: write:animals. Minimum farm role: OWNER. Direct requests execute without an app confirmation screen. Production rate limit: 100 requests per 15-minute window per device account, 1000 per browser session, otherwise per client IP. RateLimit headers report the current window; respect Retry-After on 429. Deletion behavior is described below; a successful status does not imply erasure from all retained history. Marks the stored entity inactive (soft deletion).
| Parameter | In | Required | Schema |
|---|---|---|---|
| farm_id | path | Yes | {"type":"string","format":"uuid"} |
| animal_id | path | Yes | {"type":"string","format":"uuid"} |
Request example
curl --fail-with-body -X DELETE \
'https://api.ranch.bot/v1/farm/<farm_id>/animals/<animal_id>' \
-H "Authorization: Bearer $RANCHBOT_TOKEN"Responses
| Status | Meaning | Content type |
|---|---|---|
| 204 | Completed; no response body. | No body |
| 400 | Request validation failed. | application/json |
| 401 | Missing/invalid authentication or insufficient farm role. | application/json |
| 403 | Missing required scope or credential type is disallowed. | application/json |
| 404 | Resource or active farm membership not found. | application/json |
| 429 | Rate limit exceeded. Retry after the indicated delay. | application/json |
| 500 | Unexpected server failure. | application/json |
GET /v1/farm/{farm_id}/animals/{animal_id}
Get Animal
Current animals HTTP operation. External credential scopes: read:animals; include_saved_births additionally requires read:records. Minimum farm role: READER. Production rate limit: 100 requests per 15-minute window per device account, 1000 per browser session, otherwise per client IP. RateLimit headers report the current window; respect Retry-After on 429.
| Parameter | In | Required | Schema |
|---|---|---|---|
| farm_id | path | Yes | {"type":"string","format":"uuid"} |
| animal_id | path | Yes | {"type":"string","format":"uuid"} |
| include_saved_births | query | No | {"type":"boolean"} Also return saved_births for this animal as dam or offspring. Send the exact lowercase string true or false; omission defaults to false. Enabling expansion additionally requires the read:records scope (403 insufficient_scope otherwise) and is never truthy-coerced. |
| birth_skip | query | No | {"type":"integer","minimum":0} Offset into saved_births; default 0. |
| birth_take | query | No | {"type":"integer","minimum":1,"maximum":200} Page size for saved_births; default 50, maximum 200. |
Request example
curl --fail-with-body -X GET \
'https://api.ranch.bot/v1/farm/<farm_id>/animals/<animal_id>' \
-H "Authorization: Bearer $RANCHBOT_TOKEN"Responses
| Status | Meaning | Content type |
|---|---|---|
| 200 | Success | application/json |
| 400 | Request validation failed. | application/json |
| 401 | Missing/invalid authentication or insufficient farm role. | application/json |
| 403 | Missing required scope or credential type is disallowed. | application/json |
| 404 | Resource or active farm membership not found. | application/json |
| 429 | Rate limit exceeded. Retry after the indicated delay. | application/json |
| 500 | Unexpected server failure. | application/json |
200 response schema (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| id | string | Required | |
| created_at | string | Required | format: "date-time" |
| updated_at | string | Required | format: "date-time" |
| is_active | boolean | Required | |
| farm_id | string | Required | |
| metadata | JSON | Required | |
| groups | array | Required | |
| groups[] | object | Required | |
| groups[].id (variant 1) | string | Required | |
| groups[].id (variant 2) | null | Required | |
| groups[].farm_id (variant 1) | string | Required | |
| groups[].farm_id (variant 2) | null | Required | |
| groups[].description (variant 1) | string | Required | |
| groups[].description (variant 2) | null | Required | |
| groups[].is_active (variant 1) | boolean | Required | |
| groups[].is_active (variant 2) | null | Required | |
| groups[].name (variant 1) | string | Required | |
| groups[].name (variant 2) | null | Required | |
| groups[].created_at (variant 1) | string | Required | format: "date-time" |
| groups[].created_at (variant 2) | null | Required | |
| groups[].updated_at (variant 1) | string | Required | format: "date-time" |
| groups[].updated_at (variant 2) | null | Required | |
| animal_identifiers | array | Required | |
| animal_identifiers[] | object | Required | |
| animal_identifiers[].id (variant 1) | string | Required | |
| animal_identifiers[].id (variant 2) | null | Required | |
| animal_identifiers[].animal_id (variant 1) | string | Required | |
| animal_identifiers[].animal_id (variant 2) | null | Required | |
| animal_identifiers[].is_active (variant 1) | boolean | Required | |
| animal_identifiers[].is_active (variant 2) | null | Required | |
| animal_identifiers[].is_primary (variant 1) | boolean | Required | |
| animal_identifiers[].is_primary (variant 2) | null | Required | |
| animal_identifiers[].type (variant 1) | string | Required | |
| animal_identifiers[].type (variant 2) | null | Required | |
| animal_identifiers[].value (variant 1) | string | Required | |
| animal_identifiers[].value (variant 2) | null | Required | |
| animal_identifiers[].created_at (variant 1) | string | Required | format: "date-time" |
| animal_identifiers[].created_at (variant 2) | null | Required | |
| animal_identifiers[].updated_at (variant 1) | string | Required | format: "date-time" |
| animal_identifiers[].updated_at (variant 2) | null | Required | |
| records | array | Required | |
| records[] | object | Required | |
| records[].id (variant 1) | string | Required | |
| records[].id (variant 2) | null | Required | |
| records[].applied_at (variant 1) | string | Required | format: "date-time" |
| records[].applied_at (variant 2) | null | Required | |
| records[].description (variant 1) | string | Required | |
| records[].description (variant 2) | null | Required | |
| records[].is_active (variant 1) | boolean | Required | |
| records[].is_active (variant 2) | null | Required | |
| records[].name (variant 1) | string | Required | |
| records[].name (variant 2) | null | Required | |
| records[].type (variant 1) | string | Required | |
| records[].type (variant 2) | null | Required | |
| records[].created_at (variant 1) | string | Required | format: "date-time" |
| records[].created_at (variant 2) | null | Required | |
| records[].updated_at (variant 1) | string | Required | format: "date-time" |
| records[].updated_at (variant 2) | null | Required | |
| records[].record_items | array | Required | |
| records[].record_items[] | object | Required | |
| records[].record_items[].id (variant 1) | string | Required | |
| records[].record_items[].id (variant 2) | null | Required | |
| records[].record_items[].description (variant 1) | string | Required | |
| records[].record_items[].description (variant 2) | null | Required | |
| records[].record_items[].is_active (variant 1) | boolean | Required | |
| records[].record_items[].is_active (variant 2) | null | Required | |
| records[].record_items[].metadata (variant 1) | JSON | Required | |
| records[].record_items[].metadata (variant 2) | null | Required | |
| records[].record_items[].name (variant 1) | string | Required | |
| records[].record_items[].name (variant 2) | null | Required | |
| records[].record_items[].created_at (variant 1) | string | Required | format: "date-time" |
| records[].record_items[].created_at (variant 2) | null | Required | |
| records[].record_items[].updated_at (variant 1) | string | Required | format: "date-time" |
| records[].record_items[].updated_at (variant 2) | null | Required | |
| files | array | Required | |
| files[] | object | Required | |
| files[].id (variant 1) | string | Required | |
| files[].id (variant 2) | null | Required | |
| files[].is_active (variant 1) | boolean | Required | |
| files[].is_active (variant 2) | null | Required | |
| files[].mime_type (variant 1) | string | Required | |
| files[].mime_type (variant 2) | null | Required | |
| files[].name (variant 1) | string | Required | |
| files[].name (variant 2) | null | Required | |
| files[].size (variant 1) | integer | Required | |
| files[].size (variant 2) | null | Required | |
| files[].url (variant 1) | string | Required | |
| files[].url (variant 2) | null | Required | |
| files[].created_at (variant 1) | string | Required | format: "date-time" |
| files[].created_at (variant 2) | null | Required | |
| files[].updated_at (variant 1) | string | Required | format: "date-time" |
| files[].updated_at (variant 2) | null | Required | |
| saved_births | object | Optional | |
| saved_births.total | integer | Optional | |
| saved_births.records | array | Optional | |
| saved_births.records[] | object | Required | |
| saved_births.records[].id | string | Required | format: "uuid" |
| saved_births.records[].farm_id | string | Required | format: "uuid" |
| saved_births.records[].request_id | string | Required | format: "uuid" |
| saved_births.records[].confirmation_hash | string | Required | |
| saved_births.records[].created_by_user_id | string | Required | format: "uuid" |
| saved_births.records[].dam_id | string | Required | format: "uuid" |
| saved_births.records[].birth_date | string | Required | format: "date-time" |
| saved_births.records[].time_precision | string or null | Required | |
| saved_births.records[].bundle | object | Required | |
| saved_births.records[].bundle.input | object | Required | |
| saved_births.records[].bundle.input.dam_id | string | Required | format: "uuid" |
| saved_births.records[].bundle.input.birth_date | string | Required | |
| saved_births.records[].bundle.input.time_precision | string | Optional | enum: ["date_only","morning","afternoon","evening","night"]; default: "date_only" |
| saved_births.records[].bundle.input.total_born | integer | Optional | maximum: 1000 |
| saved_births.records[].bundle.input.dam_update | object | Optional | |
| saved_births.records[].bundle.input.dam_update.kind | string | Optional | minLength: 1; maxLength: 80 |
| saved_births.records[].bundle.input.dam_update.notes | string | Optional | minLength: 1; maxLength: 1000 |
| saved_births.records[].bundle.input.maternal_observations | array | Optional | maxItems: 20; default: [] |
| saved_births.records[].bundle.input.maternal_observations[] | object | Required | |
| saved_births.records[].bundle.input.maternal_observations[].date | string | Required | |
| saved_births.records[].bundle.input.maternal_observations[].text | string | Required | minLength: 1; maxLength: 1000 |
| saved_births.records[].bundle.input.lactation_observations | array | Optional | maxItems: 20; default: [] |
| saved_births.records[].bundle.input.lactation_observations[] | object | Required | |
| saved_births.records[].bundle.input.lactation_observations[].date | string | Required | |
| saved_births.records[].bundle.input.lactation_observations[].text | string | Required | minLength: 1; maxLength: 1000 |
| saved_births.records[].bundle.input.offspring | array | Optional | maxItems: 20; default: [] |
| saved_births.records[].bundle.input.offspring[] | object | Required | |
| saved_births.records[].bundle.input.offspring[].review_label | string | Required | minLength: 1; maxLength: 80 |
| saved_births.records[].bundle.input.offspring[].animal_id | string | Optional | format: "uuid" |
| saved_births.records[].bundle.input.offspring[].sex | string | Optional | enum: ["male","female","unknown"] |
| saved_births.records[].bundle.input.offspring[].inventory_status | string | Optional | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
| saved_births.records[].bundle.input.offspring[].birth_weight | object | Optional | |
| saved_births.records[].bundle.input.offspring[].birth_weight.value | number | Required | maximum: 1000 |
| saved_births.records[].bundle.input.offspring[].birth_weight.unit | string | Required | enum: ["kg","lb"] |
| saved_births.records[].bundle.input.offspring[].birth_weight.basis | string | Optional | enum: ["measured","estimated","unknown"] |
| saved_births.records[].bundle.input.offspring[].vigor | array | Optional | maxItems: 20; default: [] |
| saved_births.records[].bundle.input.offspring[].vigor[] | object | Required | |
| saved_births.records[].bundle.input.offspring[].vigor[].date | string | Required | |
| saved_births.records[].bundle.input.offspring[].vigor[].text | string | Required | minLength: 1; maxLength: 1000 |
| saved_births.records[].bundle.input.offspring[].supplementation | array | Optional | maxItems: 20; default: [] |
| saved_births.records[].bundle.input.offspring[].supplementation[] | object | Required | |
| saved_births.records[].bundle.input.offspring[].supplementation[].date | string | Required | |
| saved_births.records[].bundle.input.offspring[].supplementation[].substance | string | Required | minLength: 1; maxLength: 80 |
| saved_births.records[].bundle.input.offspring[].supplementation[].amount | number | Required | maximum: 100000 |
| saved_births.records[].bundle.input.offspring[].supplementation[].unit | string | Required | minLength: 1; maxLength: 80 |
| saved_births.records[].bundle.input.offspring[].supplementation[].source | string | Required | minLength: 1; maxLength: 1000 |
| saved_births.records[].bundle.input.sire | object | Optional | default: {"status":"unknown"} |
| saved_births.records[].bundle.input.sire.status | string | Required | enum: ["unknown","presumed","confirmed"] |
| saved_births.records[].bundle.input.sire.animal_id | string | Optional | format: "uuid" |
| saved_births.records[].bundle.input.sire.provenance | string | Optional | minLength: 1; maxLength: 1000 |
| saved_births.records[].bundle.input.sire.confidence | number | Optional | minimum: 0; maximum: 1 |
| saved_births.records[].bundle.input.protocol | object | Optional | |
| saved_births.records[].bundle.input.protocol.claimed_name | string | Required | minLength: 1; maxLength: 80 |
| saved_births.records[].bundle.input.protocol.completed_date | string | Required | |
| saved_births.records[].bundle.input.protocol.version_id | string | Optional | format: "uuid" |
| saved_births.records[].bundle.input.protocol.offspring_labels | array | Required | minItems: 1; maxItems: 20 |
| saved_births.records[].bundle.input.protocol.offspring_labels[] | string | Required | minLength: 1; maxLength: 80 |
| saved_births.records[].bundle.input.follow_up | array | Optional | maxItems: 20; default: [] |
| saved_births.records[].bundle.input.follow_up[] | object | Required | |
| saved_births.records[].bundle.input.follow_up[].name | string | Required | minLength: 1; maxLength: 1000 |
| saved_births.records[].bundle.input.follow_up[].due_date | string | Optional | |
| saved_births.records[].bundle.input.follow_up[].offspring_labels | array | Required | minItems: 1; maxItems: 20 |
| saved_births.records[].bundle.input.follow_up[].offspring_labels[] | string | Required | minLength: 1; maxLength: 80 |
| saved_births.records[].bundle.input.group_ids | array | Optional | maxItems: 20; default: [] |
| saved_births.records[].bundle.input.group_ids[] | string | Required | format: "uuid" |
| saved_births.records[].bundle.input.current_location | string | Optional | minLength: 1; maxLength: 80 |
| saved_births.records[].bundle.input.source_sms_id | string | Optional | format: "uuid" |
| saved_births.records[].bundle.input.source_message_id | string | Optional | format: "uuid" |
| saved_births.records[].bundle.input.evidence | array | Optional | maxItems: 20; default: [] |
| saved_births.records[].bundle.input.evidence[] | object | Required | |
| saved_births.records[].bundle.input.evidence[].file_id | string | Required | format: "uuid" |
| saved_births.records[].bundle.input.evidence[].media_id | string | Optional | format: "uuid" |
| saved_births.records[].bundle.input.evidence[].link_to_dam | boolean | Optional | default: false |
| saved_births.records[].bundle.input.evidence[].offspring_label | string | Optional | minLength: 1; maxLength: 80 |
| saved_births.records[].bundle.input.unresolved | array | Optional | maxItems: 30; default: [] |
| saved_births.records[].bundle.input.unresolved[] | string | Required | minLength: 1; maxLength: 1000 |
| saved_births.records[].bundle.input.additional_source_sms_ids | array | Optional | maxItems: 20; default: [] |
| saved_births.records[].bundle.input.additional_source_sms_ids[] | string | Required | format: "uuid" |
| saved_births.records[].bundle.review | object | Required | |
| saved_births.records[].record_id | string | Required | format: "uuid" |
| saved_births.records[].source_sms_id | string or null | Required | format: "uuid" |
| saved_births.records[].source_message_id | string or null | Required | format: "uuid" |
| saved_births.records[].agent_action_id | string or null | Required | format: "uuid" |
| saved_births.records[].created_at | string | Required | format: "date-time" |
| saved_births.records[].offspring | array | Required | |
| saved_births.records[].offspring[] | object | Required | |
| saved_births.records[].offspring[].id | string | Required | format: "uuid" |
| saved_births.records[].offspring[].birth_event_id | string | Required | format: "uuid" |
| saved_births.records[].offspring[].animal_id | string | Required | format: "uuid" |
| saved_births.records[].offspring[].review_label | string | Required | |
| saved_births.records[].offspring[].position | integer | Required | |
| saved_births.records[].offspring[].details | object | Required | |
| saved_births.records[].tasks | array | Required | |
| saved_births.records[].tasks[] | object | Required | |
| saved_births.records[].tasks[].id | string | Required | format: "uuid" |
| saved_births.records[].tasks[].farm_id | string | Required | format: "uuid" |
| saved_births.records[].tasks[].birth_event_id | string | Required | format: "uuid" |
| saved_births.records[].tasks[].name | string | Required | |
| saved_births.records[].tasks[].status | string | Required | enum: ["TODO","DONE","CANCELLED"] |
| saved_births.records[].tasks[].due_date | string or null | Required | format: "date-time" |
| saved_births.records[].tasks[].created_at | string | Required | format: "date-time" |
| saved_births.records[].tasks[].updated_at | string | Required | format: "date-time" |
| saved_births.records[].tasks[].animals | array | Optional | |
| saved_births.records[].tasks[].animals[] | object | Required | |
| saved_births.records[].tasks[].animals[].id | string | Required | format: "uuid" |
| saved_births.records[].record | object | Required | |
| saved_births.records[].record.id | string | Required | format: "uuid" |
| saved_births.records[].record.subtype | string or null | Optional | enum: ["BIRTH",null] |
| saved_births.records[].record.revision | integer | Optional | |
| saved_births.records[].record.is_active | boolean | Optional | |
| saved_births.records[].record.type | string | Optional | |
| saved_births.records[].record.applied_at | string | Optional | format: "date-time" |
| saved_births.records[].record.files | array | Required | |
| saved_births.records[].record.files[] | object | Required | |
| saved_births.records[].record.files[].id | string | Required | format: "uuid" |
| saved_births.records[].record.files[].name | string | Required | |
| saved_births.records[].record.files[].mime_type | string | Required | |
| saved_births.records[].birth_details | object | Optional | |
| saved_births.records[].birth_details.birth_date | string | Required | format: "date" |
| saved_births.records[].birth_details.time_precision | string or null | Required | |
| saved_births.records[].birth_details.dam_id | string | Required | format: "uuid" |
| saved_births.records[].birth_details.total_born | integer or null | Required | |
| saved_births.records[].birth_details.subtype | string or null | Required | enum: ["BIRTH",null] |
| saved_births.records[].birth_details.revision | integer | Required | |
| saved_births.records[].birth_details.lifecycle_status | string | Required | enum: ["active","entered_in_error"] |
| saved_births.records[].birth_details.date_source | string | Required | |
| saved_births.records[].care_records | array | Required | |
| saved_births.records[].care_records[] | object | Required | |
| saved_births.records[].care_records[].id | string | Required | format: "uuid" |
| saved_births.records[].care_records[].name | string | Required | |
| saved_births.records[].care_records[].applied_at | string or null | Required | format: "date-time" |
| saved_births.records[].care_records[].record_items | array | Required | |
| saved_births.records[].care_records[].record_items[] | object | Required | |
| saved_births.records[].sire_animals | array | Optional | |
| saved_births.records[].sire_animals[] | object | Required | |
| saved_births.records[].sire_animals[].id | string | Required | format: "uuid" |
| saved_births.records[].sire_animals[].is_active | boolean | Required | |
| saved_births.records[].sire_animals[].metadata | object | Required | |
| saved_births.records[].sire_animals[].animal_identifiers | array | Required | |
| saved_births.records[].sire_animals[].animal_identifiers[] | object | Required | |
| saved_births.records[].sire_animals[].animal_identifiers[].id | string | Optional | format: "uuid" |
| saved_births.records[].sire_animals[].animal_identifiers[].type | string | Optional | |
| saved_births.records[].sire_animals[].animal_identifiers[].value | string | Optional | |
| saved_births.records[].sire_animals[].animal_identifiers[].is_active | boolean | Optional | |
| saved_births.records[].offspring_inventory | array | Optional | |
| saved_births.records[].offspring_inventory[] | object | Required | |
| saved_births.records[].offspring_inventory[].animal_id | string | Required | format: "uuid" |
| saved_births.records[].offspring_inventory[].review_label | string | Required | |
| saved_births.records[].offspring_inventory[].position | integer | Required | |
| saved_births.records[].offspring_inventory[].inventory_status | string or null | Required | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED",null] |
| saved_births.records[].offspring_inventory[].is_active | boolean or null | Required | |
| saved_births.records[].linked_records | array | Optional | |
| saved_births.records[].linked_records[] | object | Required | |
| saved_births.records[].linked_records[].id | string | Required | format: "uuid" |
| saved_births.records[].linked_records[].kind | string | Required | enum: ["primary","care"] |
| saved_births.records[].linked_records[].name | string or null | Optional | |
| saved_births.records[].linked_records[].applied_at | string or null | Optional | format: "date-time" |
| saved_births.records[].linked_records[].file_ids | array | Optional | |
| saved_births.records[].linked_records[].file_ids[] | string | Required | format: "uuid" |
| saved_births.records[].media_file_ids | array | Optional | |
| saved_births.records[].media_file_ids[] | string | Required | format: "uuid" |
| saved_births.pagination | object | Optional | |
| saved_births.pagination.skip | integer | Optional | |
| saved_births.pagination.take | integer | Optional | |
| saved_births.pagination.returned | integer | Optional | |
| saved_births.pagination.has_more | boolean | Optional | |
| saved_births.pagination.next_skip | integer or null | Optional | |
| inventory_status | string | Required | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
| birth_facts | object | Optional | |
| birth_facts.record (variant 1) | object | Required | |
| birth_facts.record (variant 1).record_id | string | Required | |
| birth_facts.record (variant 1).birth_event_id | string | Required | |
| birth_facts.record (variant 1).revision | number | Required | |
| birth_facts.record (variant 1).birth_date | string | Required | |
| birth_facts.record (variant 1).time_precision (variant 1) | string | Required | |
| birth_facts.record (variant 1).time_precision (variant 2) | null | Required | |
| birth_facts.record (variant 1).dam_id | string | Required | |
| birth_facts.record (variant 1).sire (variant 1) | object | Required | |
| birth_facts.record (variant 1).sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1) | string | Required | |
| birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2) | null | Required | |
| birth_facts.record (variant 1).sire (variant 1).provenance (variant 1) | string | Required | |
| birth_facts.record (variant 1).sire (variant 1).provenance (variant 2) | null | Required | |
| birth_facts.record (variant 1).sire (variant 1).confidence (variant 1) | number | Required | |
| birth_facts.record (variant 1).sire (variant 1).confidence (variant 2) | null | Required | |
| birth_facts.record (variant 1).sire (variant 2) | null | Required | |
| birth_facts.record (variant 2) | null | Required | |
| birth_facts.derived | object | Required | |
| birth_facts.derived.birth_date (variant 1) | string | Required | |
| birth_facts.derived.birth_date (variant 2) | null | Required | |
| birth_facts.derived.time_precision (variant 1) | string | Required | |
| birth_facts.derived.time_precision (variant 2) | null | Required | |
| birth_facts.derived.dam_id (variant 1) | string | Required | |
| birth_facts.derived.dam_id (variant 2) | null | Required | |
| birth_facts.derived.sire (variant 1) | object | Required | |
| birth_facts.derived.sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| birth_facts.derived.sire (variant 1).animal_id (variant 1) | string | Required | |
| birth_facts.derived.sire (variant 1).animal_id (variant 2) | null | Required | |
| birth_facts.derived.sire (variant 1).provenance (variant 1) | string | Required | |
| birth_facts.derived.sire (variant 1).provenance (variant 2) | null | Required | |
| birth_facts.derived.sire (variant 1).confidence (variant 1) | number | Required | |
| birth_facts.derived.sire (variant 1).confidence (variant 2) | null | Required | |
| birth_facts.derived.sire (variant 2) | null | Required | |
| birth_facts.profile_birth_date (variant 1) | string | Required | |
| birth_facts.profile_birth_date (variant 2) | null | Required | |
| birth_facts.effective_birth_date (variant 1) | string | Required | |
| birth_facts.effective_birth_date (variant 2) | null | Required | |
| birth_facts.conflicts | array | Required | |
| birth_facts.conflicts[] | object | Required | |
| birth_facts.conflicts[].independent_birth_date | string | Required | |
| birth_facts.conflicts[].recorded_birth_date | string | Required | |
| birth_facts.conflicts[].record_id | string | Required |
{
"id": "11111111-1111-4111-8111-111111111111",
"created_at": "2026-09-01T12:00:00.000Z",
"updated_at": "2026-09-01T12:00:00.000Z",
"is_active": true,
"farm_id": "11111111-1111-4111-8111-111111111111",
"metadata": null,
"groups": [],
"animal_identifiers": [],
"records": [],
"files": [],
"inventory_status": "CURRENT"
}PUT /v1/farm/{farm_id}/animals/{animal_id}
Update Animal
Current animals HTTP operation. External credential scopes: write:animals. Minimum farm role: EDITOR. Direct requests execute without an app confirmation screen. Production rate limit: 100 requests per 15-minute window per device account, 1000 per browser session, otherwise per client IP. RateLimit headers report the current window; respect Retry-After on 429. inventory_status is separate from deletion: CURRENT, UNKNOWN, SOLD, DECEASED, or NOT_MANAGED. New animals default to CURRENT; use UNKNOWN when present inventory membership is unconfirmed. Status changes preserve profile history and identifiers.
| Parameter | In | Required | Schema |
|---|---|---|---|
| farm_id | path | Yes | {"type":"string","format":"uuid"} |
| animal_id | path | Yes | {"type":"string","format":"uuid"} |
Request body (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| metadata | JSON | Optional | |
| inventory_status | string | Optional | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
{}Request example
curl --fail-with-body -X PUT \
'https://api.ranch.bot/v1/farm/<farm_id>/animals/<animal_id>' \
-H "Authorization: Bearer $RANCHBOT_TOKEN" \
-H "Content-Type: application/json" \
--data '{}'Responses
| Status | Meaning | Content type |
|---|---|---|
| 200 | Success | application/json |
| 400 | Request validation failed. | application/json |
| 401 | Missing/invalid authentication or insufficient farm role. | application/json |
| 403 | Missing required scope or credential type is disallowed. | application/json |
| 404 | Resource or active farm membership not found. | application/json |
| 429 | Rate limit exceeded. Retry after the indicated delay. | application/json |
| 500 | Unexpected server failure. | application/json |
200 response schema (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| id | string | Required | |
| created_at | string | Required | format: "date-time" |
| updated_at | string | Required | format: "date-time" |
| is_active | boolean | Required | |
| farm_id | string | Required | |
| metadata | JSON | Required | |
| inventory_status | string | Required | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
{
"id": "11111111-1111-4111-8111-111111111111",
"created_at": "2026-09-01T12:00:00.000Z",
"updated_at": "2026-09-01T12:00:00.000Z",
"is_active": true,
"farm_id": "11111111-1111-4111-8111-111111111111",
"metadata": null,
"inventory_status": "CURRENT"
}POST /v1/farm/{farm_id}/animals/find-or-create-by-eid
Find Or Create Animal By Eid
Current animals HTTP operation. External credential scopes: write:animals. Minimum farm role: EDITOR. Direct requests execute without an app confirmation screen. Production rate limit: 100 requests per 15-minute window per device account, 1000 per browser session, otherwise per client IP. RateLimit headers report the current window; respect Retry-After on 429.
| Parameter | In | Required | Schema |
|---|---|---|---|
| farm_id | path | Yes | {"type":"string","format":"uuid"} |
Request body (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| eid | string | Required |
{
"eid": "example"
}Request example
curl --fail-with-body -X POST \
'https://api.ranch.bot/v1/farm/<farm_id>/animals/find-or-create-by-eid' \
-H "Authorization: Bearer $RANCHBOT_TOKEN" \
-H "Content-Type: application/json" \
--data '{"eid":"example"}'Responses
| Status | Meaning | Content type |
|---|---|---|
| 200 | Existing match returned. | application/json |
| 201 | New animal created. | application/json |
| 400 | Request validation failed. | application/json |
| 401 | Missing/invalid authentication or insufficient farm role. | application/json |
| 403 | Missing required scope or credential type is disallowed. | application/json |
| 404 | Resource or active farm membership not found. | application/json |
| 429 | Rate limit exceeded. Retry after the indicated delay. | application/json |
| 500 | Unexpected server failure. | application/json |
200 response schema (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| animal | object | Required | |
| animal.id | string | Required | |
| animal.created_at | string | Required | format: "date-time" |
| animal.updated_at | string | Required | format: "date-time" |
| animal.is_active | boolean | Required | |
| animal.farm_id | string | Required | |
| animal.metadata | JSON | Required | |
| animal.groups | array | Required | |
| animal.groups[] | object | Required | |
| animal.groups[].id (variant 1) | string | Required | |
| animal.groups[].id (variant 2) | null | Required | |
| animal.groups[].farm_id (variant 1) | string | Required | |
| animal.groups[].farm_id (variant 2) | null | Required | |
| animal.groups[].description (variant 1) | string | Required | |
| animal.groups[].description (variant 2) | null | Required | |
| animal.groups[].is_active (variant 1) | boolean | Required | |
| animal.groups[].is_active (variant 2) | null | Required | |
| animal.groups[].name (variant 1) | string | Required | |
| animal.groups[].name (variant 2) | null | Required | |
| animal.groups[].created_at (variant 1) | string | Required | format: "date-time" |
| animal.groups[].created_at (variant 2) | null | Required | |
| animal.groups[].updated_at (variant 1) | string | Required | format: "date-time" |
| animal.groups[].updated_at (variant 2) | null | Required | |
| animal.animal_identifiers | array | Required | |
| animal.animal_identifiers[] | object | Required | |
| animal.animal_identifiers[].id (variant 1) | string | Required | |
| animal.animal_identifiers[].id (variant 2) | null | Required | |
| animal.animal_identifiers[].animal_id (variant 1) | string | Required | |
| animal.animal_identifiers[].animal_id (variant 2) | null | Required | |
| animal.animal_identifiers[].is_active (variant 1) | boolean | Required | |
| animal.animal_identifiers[].is_active (variant 2) | null | Required | |
| animal.animal_identifiers[].is_primary (variant 1) | boolean | Required | |
| animal.animal_identifiers[].is_primary (variant 2) | null | Required | |
| animal.animal_identifiers[].type (variant 1) | string | Required | |
| animal.animal_identifiers[].type (variant 2) | null | Required | |
| animal.animal_identifiers[].value (variant 1) | string | Required | |
| animal.animal_identifiers[].value (variant 2) | null | Required | |
| animal.animal_identifiers[].created_at (variant 1) | string | Required | format: "date-time" |
| animal.animal_identifiers[].created_at (variant 2) | null | Required | |
| animal.animal_identifiers[].updated_at (variant 1) | string | Required | format: "date-time" |
| animal.animal_identifiers[].updated_at (variant 2) | null | Required | |
| animal.inventory_status | string | Required | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
| animal.birth_facts | object | Optional | |
| animal.birth_facts.record (variant 1) | object | Required | |
| animal.birth_facts.record (variant 1).record_id | string | Required | |
| animal.birth_facts.record (variant 1).birth_event_id | string | Required | |
| animal.birth_facts.record (variant 1).revision | number | Required | |
| animal.birth_facts.record (variant 1).birth_date | string | Required | |
| animal.birth_facts.record (variant 1).time_precision (variant 1) | string | Required | |
| animal.birth_facts.record (variant 1).time_precision (variant 2) | null | Required | |
| animal.birth_facts.record (variant 1).dam_id | string | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1) | object | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| animal.birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1) | string | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2) | null | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).provenance (variant 1) | string | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).provenance (variant 2) | null | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).confidence (variant 1) | number | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).confidence (variant 2) | null | Required | |
| animal.birth_facts.record (variant 1).sire (variant 2) | null | Required | |
| animal.birth_facts.record (variant 2) | null | Required | |
| animal.birth_facts.derived | object | Required | |
| animal.birth_facts.derived.birth_date (variant 1) | string | Required | |
| animal.birth_facts.derived.birth_date (variant 2) | null | Required | |
| animal.birth_facts.derived.time_precision (variant 1) | string | Required | |
| animal.birth_facts.derived.time_precision (variant 2) | null | Required | |
| animal.birth_facts.derived.dam_id (variant 1) | string | Required | |
| animal.birth_facts.derived.dam_id (variant 2) | null | Required | |
| animal.birth_facts.derived.sire (variant 1) | object | Required | |
| animal.birth_facts.derived.sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| animal.birth_facts.derived.sire (variant 1).animal_id (variant 1) | string | Required | |
| animal.birth_facts.derived.sire (variant 1).animal_id (variant 2) | null | Required | |
| animal.birth_facts.derived.sire (variant 1).provenance (variant 1) | string | Required | |
| animal.birth_facts.derived.sire (variant 1).provenance (variant 2) | null | Required | |
| animal.birth_facts.derived.sire (variant 1).confidence (variant 1) | number | Required | |
| animal.birth_facts.derived.sire (variant 1).confidence (variant 2) | null | Required | |
| animal.birth_facts.derived.sire (variant 2) | null | Required | |
| animal.birth_facts.profile_birth_date (variant 1) | string | Required | |
| animal.birth_facts.profile_birth_date (variant 2) | null | Required | |
| animal.birth_facts.effective_birth_date (variant 1) | string | Required | |
| animal.birth_facts.effective_birth_date (variant 2) | null | Required | |
| animal.birth_facts.conflicts | array | Required | |
| animal.birth_facts.conflicts[] | object | Required | |
| animal.birth_facts.conflicts[].independent_birth_date | string | Required | |
| animal.birth_facts.conflicts[].recorded_birth_date | string | Required | |
| animal.birth_facts.conflicts[].record_id | string | Required | |
| created | boolean | Required |
{
"animal": {
"id": "11111111-1111-4111-8111-111111111111",
"created_at": "2026-09-01T12:00:00.000Z",
"updated_at": "2026-09-01T12:00:00.000Z",
"is_active": true,
"farm_id": "11111111-1111-4111-8111-111111111111",
"metadata": null,
"groups": [],
"animal_identifiers": [],
"inventory_status": "CURRENT"
},
"created": true
}201 response schema (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| animal | object | Required | |
| animal.id | string | Required | |
| animal.created_at | string | Required | format: "date-time" |
| animal.updated_at | string | Required | format: "date-time" |
| animal.is_active | boolean | Required | |
| animal.farm_id | string | Required | |
| animal.metadata | JSON | Required | |
| animal.groups | array | Required | |
| animal.groups[] | object | Required | |
| animal.groups[].id (variant 1) | string | Required | |
| animal.groups[].id (variant 2) | null | Required | |
| animal.groups[].farm_id (variant 1) | string | Required | |
| animal.groups[].farm_id (variant 2) | null | Required | |
| animal.groups[].description (variant 1) | string | Required | |
| animal.groups[].description (variant 2) | null | Required | |
| animal.groups[].is_active (variant 1) | boolean | Required | |
| animal.groups[].is_active (variant 2) | null | Required | |
| animal.groups[].name (variant 1) | string | Required | |
| animal.groups[].name (variant 2) | null | Required | |
| animal.groups[].created_at (variant 1) | string | Required | format: "date-time" |
| animal.groups[].created_at (variant 2) | null | Required | |
| animal.groups[].updated_at (variant 1) | string | Required | format: "date-time" |
| animal.groups[].updated_at (variant 2) | null | Required | |
| animal.animal_identifiers | array | Required | |
| animal.animal_identifiers[] | object | Required | |
| animal.animal_identifiers[].id (variant 1) | string | Required | |
| animal.animal_identifiers[].id (variant 2) | null | Required | |
| animal.animal_identifiers[].animal_id (variant 1) | string | Required | |
| animal.animal_identifiers[].animal_id (variant 2) | null | Required | |
| animal.animal_identifiers[].is_active (variant 1) | boolean | Required | |
| animal.animal_identifiers[].is_active (variant 2) | null | Required | |
| animal.animal_identifiers[].is_primary (variant 1) | boolean | Required | |
| animal.animal_identifiers[].is_primary (variant 2) | null | Required | |
| animal.animal_identifiers[].type (variant 1) | string | Required | |
| animal.animal_identifiers[].type (variant 2) | null | Required | |
| animal.animal_identifiers[].value (variant 1) | string | Required | |
| animal.animal_identifiers[].value (variant 2) | null | Required | |
| animal.animal_identifiers[].created_at (variant 1) | string | Required | format: "date-time" |
| animal.animal_identifiers[].created_at (variant 2) | null | Required | |
| animal.animal_identifiers[].updated_at (variant 1) | string | Required | format: "date-time" |
| animal.animal_identifiers[].updated_at (variant 2) | null | Required | |
| animal.inventory_status | string | Required | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
| animal.birth_facts | object | Optional | |
| animal.birth_facts.record (variant 1) | object | Required | |
| animal.birth_facts.record (variant 1).record_id | string | Required | |
| animal.birth_facts.record (variant 1).birth_event_id | string | Required | |
| animal.birth_facts.record (variant 1).revision | number | Required | |
| animal.birth_facts.record (variant 1).birth_date | string | Required | |
| animal.birth_facts.record (variant 1).time_precision (variant 1) | string | Required | |
| animal.birth_facts.record (variant 1).time_precision (variant 2) | null | Required | |
| animal.birth_facts.record (variant 1).dam_id | string | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1) | object | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| animal.birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1) | string | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2) | null | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).provenance (variant 1) | string | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).provenance (variant 2) | null | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).confidence (variant 1) | number | Required | |
| animal.birth_facts.record (variant 1).sire (variant 1).confidence (variant 2) | null | Required | |
| animal.birth_facts.record (variant 1).sire (variant 2) | null | Required | |
| animal.birth_facts.record (variant 2) | null | Required | |
| animal.birth_facts.derived | object | Required | |
| animal.birth_facts.derived.birth_date (variant 1) | string | Required | |
| animal.birth_facts.derived.birth_date (variant 2) | null | Required | |
| animal.birth_facts.derived.time_precision (variant 1) | string | Required | |
| animal.birth_facts.derived.time_precision (variant 2) | null | Required | |
| animal.birth_facts.derived.dam_id (variant 1) | string | Required | |
| animal.birth_facts.derived.dam_id (variant 2) | null | Required | |
| animal.birth_facts.derived.sire (variant 1) | object | Required | |
| animal.birth_facts.derived.sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| animal.birth_facts.derived.sire (variant 1).animal_id (variant 1) | string | Required | |
| animal.birth_facts.derived.sire (variant 1).animal_id (variant 2) | null | Required | |
| animal.birth_facts.derived.sire (variant 1).provenance (variant 1) | string | Required | |
| animal.birth_facts.derived.sire (variant 1).provenance (variant 2) | null | Required | |
| animal.birth_facts.derived.sire (variant 1).confidence (variant 1) | number | Required | |
| animal.birth_facts.derived.sire (variant 1).confidence (variant 2) | null | Required | |
| animal.birth_facts.derived.sire (variant 2) | null | Required | |
| animal.birth_facts.profile_birth_date (variant 1) | string | Required | |
| animal.birth_facts.profile_birth_date (variant 2) | null | Required | |
| animal.birth_facts.effective_birth_date (variant 1) | string | Required | |
| animal.birth_facts.effective_birth_date (variant 2) | null | Required | |
| animal.birth_facts.conflicts | array | Required | |
| animal.birth_facts.conflicts[] | object | Required | |
| animal.birth_facts.conflicts[].independent_birth_date | string | Required | |
| animal.birth_facts.conflicts[].recorded_birth_date | string | Required | |
| animal.birth_facts.conflicts[].record_id | string | Required | |
| created | boolean | Required |
{
"animal": {
"id": "11111111-1111-4111-8111-111111111111",
"created_at": "2026-09-01T12:00:00.000Z",
"updated_at": "2026-09-01T12:00:00.000Z",
"is_active": true,
"farm_id": "11111111-1111-4111-8111-111111111111",
"metadata": null,
"groups": [],
"animal_identifiers": [],
"inventory_status": "CURRENT"
},
"created": true
}GET /v1/farm/{farm_id}/animals/index
Get Animals Index
Current animals HTTP operation. External credential scopes: read:animals. Minimum farm role: READER. Production rate limit: 100 requests per 15-minute window per device account, 1000 per browser session, otherwise per client IP. RateLimit headers report the current window; respect Retry-After on 429. Defaults to CURRENT inventory. Use inventory_status=ALL to include all nondeleted historical profiles, or select UNKNOWN, SOLD, DECEASED, or NOT_MANAGED.
| Parameter | In | Required | Schema |
|---|---|---|---|
| farm_id | path | Yes | {"type":"string","format":"uuid"} |
| inventory_status | query | No | {"type":"string","enum":["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED","ALL"],"default":"CURRENT"} |
Request example
curl --fail-with-body -X GET \
'https://api.ranch.bot/v1/farm/<farm_id>/animals/index' \
-H "Authorization: Bearer $RANCHBOT_TOKEN"Responses
| Status | Meaning | Content type |
|---|---|---|
| 200 | Success | application/json |
| 400 | Request validation failed. | application/json |
| 401 | Missing/invalid authentication or insufficient farm role. | application/json |
| 403 | Missing required scope or credential type is disallowed. | application/json |
| 404 | Resource or active farm membership not found. | application/json |
| 429 | Rate limit exceeded. Retry after the indicated delay. | application/json |
| 500 | Unexpected server failure. | application/json |
200 response schema (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| synced_at | string | Required | |
| total | number | Required | |
| animals | array | Required | |
| animals[] | object | Required | |
| animals[].id | string | Required | |
| animals[].metadata | JSON | Required | |
| animals[].identifiers | array | Required | |
| animals[].identifiers[] | object | Required | |
| animals[].identifiers[].type | string | Required | enum: ["BRAND","EID","MANAGEMENT_TAG","NAME","TATTOO"] |
| animals[].identifiers[].value | string | Required | |
| animals[].identifiers[].is_primary | boolean | Required | |
| animals[].last_weights | array | Required | |
| animals[].last_weights[] | object | Required | |
| animals[].last_weights[].value | number | Required | |
| animals[].last_weights[].unit (variant 1) | null | Required | |
| animals[].last_weights[].unit (variant 2) | string | Required | |
| animals[].last_weights[].applied_at | string | Required | format: "date-time" |
| animals[].inventory_status | string | Required | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
| animals[].birth_facts | object | Optional | |
| animals[].birth_facts.record (variant 1) | object | Required | |
| animals[].birth_facts.record (variant 1).record_id | string | Required | |
| animals[].birth_facts.record (variant 1).birth_event_id | string | Required | |
| animals[].birth_facts.record (variant 1).revision | number | Required | |
| animals[].birth_facts.record (variant 1).birth_date | string | Required | |
| animals[].birth_facts.record (variant 1).time_precision (variant 1) | string | Required | |
| animals[].birth_facts.record (variant 1).time_precision (variant 2) | null | Required | |
| animals[].birth_facts.record (variant 1).dam_id | string | Required | |
| animals[].birth_facts.record (variant 1).sire (variant 1) | object | Required | |
| animals[].birth_facts.record (variant 1).sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| animals[].birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1) | string | Required | |
| animals[].birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2) | null | Required | |
| animals[].birth_facts.record (variant 1).sire (variant 1).provenance (variant 1) | string | Required | |
| animals[].birth_facts.record (variant 1).sire (variant 1).provenance (variant 2) | null | Required | |
| animals[].birth_facts.record (variant 1).sire (variant 1).confidence (variant 1) | number | Required | |
| animals[].birth_facts.record (variant 1).sire (variant 1).confidence (variant 2) | null | Required | |
| animals[].birth_facts.record (variant 1).sire (variant 2) | null | Required | |
| animals[].birth_facts.record (variant 2) | null | Required | |
| animals[].birth_facts.derived | object | Required | |
| animals[].birth_facts.derived.birth_date (variant 1) | string | Required | |
| animals[].birth_facts.derived.birth_date (variant 2) | null | Required | |
| animals[].birth_facts.derived.time_precision (variant 1) | string | Required | |
| animals[].birth_facts.derived.time_precision (variant 2) | null | Required | |
| animals[].birth_facts.derived.dam_id (variant 1) | string | Required | |
| animals[].birth_facts.derived.dam_id (variant 2) | null | Required | |
| animals[].birth_facts.derived.sire (variant 1) | object | Required | |
| animals[].birth_facts.derived.sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| animals[].birth_facts.derived.sire (variant 1).animal_id (variant 1) | string | Required | |
| animals[].birth_facts.derived.sire (variant 1).animal_id (variant 2) | null | Required | |
| animals[].birth_facts.derived.sire (variant 1).provenance (variant 1) | string | Required | |
| animals[].birth_facts.derived.sire (variant 1).provenance (variant 2) | null | Required | |
| animals[].birth_facts.derived.sire (variant 1).confidence (variant 1) | number | Required | |
| animals[].birth_facts.derived.sire (variant 1).confidence (variant 2) | null | Required | |
| animals[].birth_facts.derived.sire (variant 2) | null | Required | |
| animals[].birth_facts.profile_birth_date (variant 1) | string | Required | |
| animals[].birth_facts.profile_birth_date (variant 2) | null | Required | |
| animals[].birth_facts.effective_birth_date (variant 1) | string | Required | |
| animals[].birth_facts.effective_birth_date (variant 2) | null | Required | |
| animals[].birth_facts.conflicts | array | Required | |
| animals[].birth_facts.conflicts[] | object | Required | |
| animals[].birth_facts.conflicts[].independent_birth_date | string | Required | |
| animals[].birth_facts.conflicts[].recorded_birth_date | string | Required | |
| animals[].birth_facts.conflicts[].record_id | string | Required |
{
"synced_at": "2026-09-01T12:00:00.000Z",
"total": 1,
"animals": []
}GET /v1/farm/{farm_id}/animals/lookup-by-eid
Look up an animal by exact EID without writing
Read-only exact EID lookup across inventory statuses. Never creates or updates inventory. Missing matches return 404; multiple matching animals return 409. Current animals HTTP operation. External credential scopes: read:animals. Minimum farm role: READER. Production rate limit: 100 requests per 15-minute window per device account, 1000 per browser session, otherwise per client IP. RateLimit headers report the current window; respect Retry-After on 429.
| Parameter | In | Required | Schema |
|---|---|---|---|
| farm_id | path | Yes | {"type":"string","format":"uuid"} |
| eid | query | Yes | {"type":"string","minLength":1} Exact EID, including leading zeros. |
Request example
curl --fail-with-body -X GET \
'https://api.ranch.bot/v1/farm/<farm_id>/animals/lookup-by-eid?eid=PLACEHOLDER_EID' \
-H "Authorization: Bearer $RANCHBOT_TOKEN"Responses
| Status | Meaning | Content type |
|---|---|---|
| 200 | Success | application/json |
| 400 | Request validation failed. | application/json |
| 401 | Missing/invalid authentication or insufficient farm role. | application/json |
| 403 | Missing required scope or credential type is disallowed. | application/json |
| 404 | Resource or active farm membership not found. | application/json |
| 409 | Multiple active animals match this EID; clarify the animal. No writes performed. | application/json |
| 429 | Rate limit exceeded. Retry after the indicated delay. | application/json |
| 500 | Unexpected server failure. | application/json |
200 response schema (application/json)
| Field | Type | Presence | Constraints |
|---|---|---|---|
| id | string | Required | |
| created_at | string | Required | format: "date-time" |
| updated_at | string | Required | format: "date-time" |
| is_active | boolean | Required | |
| farm_id | string | Required | |
| metadata | JSON | Required | |
| groups | array | Required | |
| groups[] | object | Required | |
| groups[].id (variant 1) | string | Required | |
| groups[].id (variant 2) | null | Required | |
| groups[].farm_id (variant 1) | string | Required | |
| groups[].farm_id (variant 2) | null | Required | |
| groups[].description (variant 1) | string | Required | |
| groups[].description (variant 2) | null | Required | |
| groups[].is_active (variant 1) | boolean | Required | |
| groups[].is_active (variant 2) | null | Required | |
| groups[].name (variant 1) | string | Required | |
| groups[].name (variant 2) | null | Required | |
| groups[].created_at (variant 1) | string | Required | format: "date-time" |
| groups[].created_at (variant 2) | null | Required | |
| groups[].updated_at (variant 1) | string | Required | format: "date-time" |
| groups[].updated_at (variant 2) | null | Required | |
| animal_identifiers | array | Required | |
| animal_identifiers[] | object | Required | |
| animal_identifiers[].id (variant 1) | string | Required | |
| animal_identifiers[].id (variant 2) | null | Required | |
| animal_identifiers[].animal_id (variant 1) | string | Required | |
| animal_identifiers[].animal_id (variant 2) | null | Required | |
| animal_identifiers[].is_active (variant 1) | boolean | Required | |
| animal_identifiers[].is_active (variant 2) | null | Required | |
| animal_identifiers[].is_primary (variant 1) | boolean | Required | |
| animal_identifiers[].is_primary (variant 2) | null | Required | |
| animal_identifiers[].type (variant 1) | string | Required | |
| animal_identifiers[].type (variant 2) | null | Required | |
| animal_identifiers[].value (variant 1) | string | Required | |
| animal_identifiers[].value (variant 2) | null | Required | |
| animal_identifiers[].created_at (variant 1) | string | Required | format: "date-time" |
| animal_identifiers[].created_at (variant 2) | null | Required | |
| animal_identifiers[].updated_at (variant 1) | string | Required | format: "date-time" |
| animal_identifiers[].updated_at (variant 2) | null | Required | |
| inventory_status | string | Required | enum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"] |
| birth_facts | object | Optional | |
| birth_facts.record (variant 1) | object | Required | |
| birth_facts.record (variant 1).record_id | string | Required | |
| birth_facts.record (variant 1).birth_event_id | string | Required | |
| birth_facts.record (variant 1).revision | number | Required | |
| birth_facts.record (variant 1).birth_date | string | Required | |
| birth_facts.record (variant 1).time_precision (variant 1) | string | Required | |
| birth_facts.record (variant 1).time_precision (variant 2) | null | Required | |
| birth_facts.record (variant 1).dam_id | string | Required | |
| birth_facts.record (variant 1).sire (variant 1) | object | Required | |
| birth_facts.record (variant 1).sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1) | string | Required | |
| birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2) | null | Required | |
| birth_facts.record (variant 1).sire (variant 1).provenance (variant 1) | string | Required | |
| birth_facts.record (variant 1).sire (variant 1).provenance (variant 2) | null | Required | |
| birth_facts.record (variant 1).sire (variant 1).confidence (variant 1) | number | Required | |
| birth_facts.record (variant 1).sire (variant 1).confidence (variant 2) | null | Required | |
| birth_facts.record (variant 1).sire (variant 2) | null | Required | |
| birth_facts.record (variant 2) | null | Required | |
| birth_facts.derived | object | Required | |
| birth_facts.derived.birth_date (variant 1) | string | Required | |
| birth_facts.derived.birth_date (variant 2) | null | Required | |
| birth_facts.derived.time_precision (variant 1) | string | Required | |
| birth_facts.derived.time_precision (variant 2) | null | Required | |
| birth_facts.derived.dam_id (variant 1) | string | Required | |
| birth_facts.derived.dam_id (variant 2) | null | Required | |
| birth_facts.derived.sire (variant 1) | object | Required | |
| birth_facts.derived.sire (variant 1).status | string | Required | enum: ["unknown","presumed","confirmed"] |
| birth_facts.derived.sire (variant 1).animal_id (variant 1) | string | Required | |
| birth_facts.derived.sire (variant 1).animal_id (variant 2) | null | Required | |
| birth_facts.derived.sire (variant 1).provenance (variant 1) | string | Required | |
| birth_facts.derived.sire (variant 1).provenance (variant 2) | null | Required | |
| birth_facts.derived.sire (variant 1).confidence (variant 1) | number | Required | |
| birth_facts.derived.sire (variant 1).confidence (variant 2) | null | Required | |
| birth_facts.derived.sire (variant 2) | null | Required | |
| birth_facts.profile_birth_date (variant 1) | string | Required | |
| birth_facts.profile_birth_date (variant 2) | null | Required | |
| birth_facts.effective_birth_date (variant 1) | string | Required | |
| birth_facts.effective_birth_date (variant 2) | null | Required | |
| birth_facts.conflicts | array | Required | |
| birth_facts.conflicts[] | object | Required | |
| birth_facts.conflicts[].independent_birth_date | string | Required | |
| birth_facts.conflicts[].recorded_birth_date | string | Required | |
| birth_facts.conflicts[].record_id | string | Required |
{
"id": "11111111-1111-4111-8111-111111111111",
"created_at": "2026-09-01T12:00:00.000Z",
"updated_at": "2026-09-01T12:00:00.000Z",
"is_active": true,
"farm_id": "11111111-1111-4111-8111-111111111111",
"metadata": null,
"groups": [],
"animal_identifiers": [],
"inventory_status": "CURRENT"
}Error body
Validation and authentication errors generally use this envelope. Rate-limit errors omit data; OAuth polling also has protocol-specific errors shown in its reference.
{
"success": false,
"errors": [
{
"code": 400,
"name": "ValidationError",
"message": "Example validation failure"
}
]
}