Ranch.Bot
Skip to reference

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

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.

ParameterInRequiredSchema
farm_idpathYes{"type":"string","format":"uuid"}
skipqueryNo{"type":"integer"}
takequeryNo{"type":"integer"}
inventory_statusqueryNo{"type":"string","enum":["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED","ALL"],"default":"CURRENT"}
queryqueryNo{"type":"string","maxLength":200} Saved identifier value or current profile name to find. Blank is rejected.
match_modequeryNo{"type":"string","enum":["exact","partial"]} exact (default) full-value equality, or partial literal case-insensitive substring discovery.
identifier_typequeryNo{"type":"string","enum":["BRAND","EID","MANAGEMENT_TAG","NAME","TATTOO"]} Restrict matching to one saved identifier type; binding on an exact query.

Request example

bash example
curl --fail-with-body -X GET \
  'https://api.ranch.bot/v1/farm/<farm_id>/animals' \
  -H "Authorization: Bearer $RANCHBOT_TOKEN"

Responses

StatusMeaningContent type
200Successapplication/json
400Request validation failed.application/json
401Missing/invalid authentication or insufficient farm role.application/json
403Missing required scope or credential type is disallowed.application/json
404Resource or active farm membership not found.application/json
429Rate limit exceeded. Retry after the indicated delay.application/json
500Unexpected server failure.application/json

200 response schema (application/json)

FieldTypePresenceConstraints
totalnumberRequired
recordsarrayRequired
records[]objectRequired
records[].idstringRequired
records[].created_atstringRequiredformat: "date-time"
records[].updated_atstringRequiredformat: "date-time"
records[].is_activebooleanRequired
records[].farm_idstringRequired
records[].metadataJSONRequired
records[].groupsarrayRequired
records[].groups[]objectRequired
records[].groups[].id (variant 1)stringRequired
records[].groups[].id (variant 2)nullRequired
records[].groups[].farm_id (variant 1)stringRequired
records[].groups[].farm_id (variant 2)nullRequired
records[].groups[].description (variant 1)stringRequired
records[].groups[].description (variant 2)nullRequired
records[].groups[].is_active (variant 1)booleanRequired
records[].groups[].is_active (variant 2)nullRequired
records[].groups[].name (variant 1)stringRequired
records[].groups[].name (variant 2)nullRequired
records[].groups[].created_at (variant 1)stringRequiredformat: "date-time"
records[].groups[].created_at (variant 2)nullRequired
records[].groups[].updated_at (variant 1)stringRequiredformat: "date-time"
records[].groups[].updated_at (variant 2)nullRequired
records[].animal_identifiersarrayRequired
records[].animal_identifiers[]objectRequired
records[].animal_identifiers[].id (variant 1)stringRequired
records[].animal_identifiers[].id (variant 2)nullRequired
records[].animal_identifiers[].animal_id (variant 1)stringRequired
records[].animal_identifiers[].animal_id (variant 2)nullRequired
records[].animal_identifiers[].is_active (variant 1)booleanRequired
records[].animal_identifiers[].is_active (variant 2)nullRequired
records[].animal_identifiers[].is_primary (variant 1)booleanRequired
records[].animal_identifiers[].is_primary (variant 2)nullRequired
records[].animal_identifiers[].type (variant 1)stringRequired
records[].animal_identifiers[].type (variant 2)nullRequired
records[].animal_identifiers[].value (variant 1)stringRequired
records[].animal_identifiers[].value (variant 2)nullRequired
records[].animal_identifiers[].created_at (variant 1)stringRequiredformat: "date-time"
records[].animal_identifiers[].created_at (variant 2)nullRequired
records[].animal_identifiers[].updated_at (variant 1)stringRequiredformat: "date-time"
records[].animal_identifiers[].updated_at (variant 2)nullRequired
records[].inventory_statusstringRequiredenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
records[].birth_factsobjectOptional
records[].birth_facts.record (variant 1)objectRequired
records[].birth_facts.record (variant 1).record_idstringRequired
records[].birth_facts.record (variant 1).birth_event_idstringRequired
records[].birth_facts.record (variant 1).revisionnumberRequired
records[].birth_facts.record (variant 1).birth_datestringRequired
records[].birth_facts.record (variant 1).time_precision (variant 1)stringRequired
records[].birth_facts.record (variant 1).time_precision (variant 2)nullRequired
records[].birth_facts.record (variant 1).dam_idstringRequired
records[].birth_facts.record (variant 1).sire (variant 1)objectRequired
records[].birth_facts.record (variant 1).sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
records[].birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1)stringRequired
records[].birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2)nullRequired
records[].birth_facts.record (variant 1).sire (variant 1).provenance (variant 1)stringRequired
records[].birth_facts.record (variant 1).sire (variant 1).provenance (variant 2)nullRequired
records[].birth_facts.record (variant 1).sire (variant 1).confidence (variant 1)numberRequired
records[].birth_facts.record (variant 1).sire (variant 1).confidence (variant 2)nullRequired
records[].birth_facts.record (variant 1).sire (variant 2)nullRequired
records[].birth_facts.record (variant 2)nullRequired
records[].birth_facts.derivedobjectRequired
records[].birth_facts.derived.birth_date (variant 1)stringRequired
records[].birth_facts.derived.birth_date (variant 2)nullRequired
records[].birth_facts.derived.time_precision (variant 1)stringRequired
records[].birth_facts.derived.time_precision (variant 2)nullRequired
records[].birth_facts.derived.dam_id (variant 1)stringRequired
records[].birth_facts.derived.dam_id (variant 2)nullRequired
records[].birth_facts.derived.sire (variant 1)objectRequired
records[].birth_facts.derived.sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
records[].birth_facts.derived.sire (variant 1).animal_id (variant 1)stringRequired
records[].birth_facts.derived.sire (variant 1).animal_id (variant 2)nullRequired
records[].birth_facts.derived.sire (variant 1).provenance (variant 1)stringRequired
records[].birth_facts.derived.sire (variant 1).provenance (variant 2)nullRequired
records[].birth_facts.derived.sire (variant 1).confidence (variant 1)numberRequired
records[].birth_facts.derived.sire (variant 1).confidence (variant 2)nullRequired
records[].birth_facts.derived.sire (variant 2)nullRequired
records[].birth_facts.profile_birth_date (variant 1)stringRequired
records[].birth_facts.profile_birth_date (variant 2)nullRequired
records[].birth_facts.effective_birth_date (variant 1)stringRequired
records[].birth_facts.effective_birth_date (variant 2)nullRequired
records[].birth_facts.conflictsarrayRequired
records[].birth_facts.conflicts[]objectRequired
records[].birth_facts.conflicts[].independent_birth_datestringRequired
records[].birth_facts.conflicts[].recorded_birth_datestringRequired
records[].birth_facts.conflicts[].record_idstringRequired
records[].search_matchesarrayOptional
records[].search_matches[] (variant 1)objectRequired
records[].search_matches[] (variant 1).sourceJSONRequiredconst: "identifier"
records[].search_matches[] (variant 1).identifier_idstringRequired
records[].search_matches[] (variant 1).identifier_typestringRequired
records[].search_matches[] (variant 1).valuestringRequired
records[].search_matches[] (variant 2)objectRequired
records[].search_matches[] (variant 2).sourceJSONRequiredconst: "profile_name"
records[].search_matches[] (variant 2).valuestringRequired
outcomestringOptionalenum: ["not_found","unique","ambiguous","candidates"]
scopeobjectOptional
scope.farm_idstringOptional
scope.querystringOptional
scope.match_modestringOptionalenum: ["exact","partial"]
scope.identifier_type (variant 1)stringOptional
scope.identifier_type (variant 2)nullOptional
scope.inventory_statusstringOptional
scope.searches_profile_namesbooleanOptional
scope.searched_identifier_typesarrayOptional
scope.searched_identifier_types[]stringRequired
paginationobjectOptional
pagination.skipintegerRequired
pagination.take (variant 1)integerRequired
pagination.take (variant 2)nullRequired
pagination.returnedintegerRequired
pagination.has_morebooleanRequired
pagination.next_skip (variant 1)integerRequired
pagination.next_skip (variant 2)nullRequired
json example
{
  "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.

ParameterInRequiredSchema
farm_idpathYes{"type":"string","format":"uuid"}

Request body (application/json)

FieldTypePresenceConstraints
metadataJSONOptional
inventory_statusstringOptionalenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
json example
{}

Request example

bash 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

StatusMeaningContent type
201Successapplication/json
400Request validation failed.application/json
401Missing/invalid authentication or insufficient farm role.application/json
403Missing required scope or credential type is disallowed.application/json
404Resource or active farm membership not found.application/json
429Rate limit exceeded. Retry after the indicated delay.application/json
500Unexpected server failure.application/json

201 response schema (application/json)

FieldTypePresenceConstraints
idstringRequired
created_atstringRequiredformat: "date-time"
updated_atstringRequiredformat: "date-time"
is_activebooleanRequired
farm_idstringRequired
metadataJSONRequired
inventory_statusstringRequiredenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
json example
{
  "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).

ParameterInRequiredSchema
farm_idpathYes{"type":"string","format":"uuid"}
animal_idpathYes{"type":"string","format":"uuid"}

Request example

bash example
curl --fail-with-body -X DELETE \
  'https://api.ranch.bot/v1/farm/<farm_id>/animals/<animal_id>' \
  -H "Authorization: Bearer $RANCHBOT_TOKEN"

Responses

StatusMeaningContent type
204Completed; no response body.No body
400Request validation failed.application/json
401Missing/invalid authentication or insufficient farm role.application/json
403Missing required scope or credential type is disallowed.application/json
404Resource or active farm membership not found.application/json
429Rate limit exceeded. Retry after the indicated delay.application/json
500Unexpected 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.

ParameterInRequiredSchema
farm_idpathYes{"type":"string","format":"uuid"}
animal_idpathYes{"type":"string","format":"uuid"}
include_saved_birthsqueryNo{"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_skipqueryNo{"type":"integer","minimum":0} Offset into saved_births; default 0.
birth_takequeryNo{"type":"integer","minimum":1,"maximum":200} Page size for saved_births; default 50, maximum 200.

Request example

bash example
curl --fail-with-body -X GET \
  'https://api.ranch.bot/v1/farm/<farm_id>/animals/<animal_id>' \
  -H "Authorization: Bearer $RANCHBOT_TOKEN"

Responses

StatusMeaningContent type
200Successapplication/json
400Request validation failed.application/json
401Missing/invalid authentication or insufficient farm role.application/json
403Missing required scope or credential type is disallowed.application/json
404Resource or active farm membership not found.application/json
429Rate limit exceeded. Retry after the indicated delay.application/json
500Unexpected server failure.application/json

200 response schema (application/json)

FieldTypePresenceConstraints
idstringRequired
created_atstringRequiredformat: "date-time"
updated_atstringRequiredformat: "date-time"
is_activebooleanRequired
farm_idstringRequired
metadataJSONRequired
groupsarrayRequired
groups[]objectRequired
groups[].id (variant 1)stringRequired
groups[].id (variant 2)nullRequired
groups[].farm_id (variant 1)stringRequired
groups[].farm_id (variant 2)nullRequired
groups[].description (variant 1)stringRequired
groups[].description (variant 2)nullRequired
groups[].is_active (variant 1)booleanRequired
groups[].is_active (variant 2)nullRequired
groups[].name (variant 1)stringRequired
groups[].name (variant 2)nullRequired
groups[].created_at (variant 1)stringRequiredformat: "date-time"
groups[].created_at (variant 2)nullRequired
groups[].updated_at (variant 1)stringRequiredformat: "date-time"
groups[].updated_at (variant 2)nullRequired
animal_identifiersarrayRequired
animal_identifiers[]objectRequired
animal_identifiers[].id (variant 1)stringRequired
animal_identifiers[].id (variant 2)nullRequired
animal_identifiers[].animal_id (variant 1)stringRequired
animal_identifiers[].animal_id (variant 2)nullRequired
animal_identifiers[].is_active (variant 1)booleanRequired
animal_identifiers[].is_active (variant 2)nullRequired
animal_identifiers[].is_primary (variant 1)booleanRequired
animal_identifiers[].is_primary (variant 2)nullRequired
animal_identifiers[].type (variant 1)stringRequired
animal_identifiers[].type (variant 2)nullRequired
animal_identifiers[].value (variant 1)stringRequired
animal_identifiers[].value (variant 2)nullRequired
animal_identifiers[].created_at (variant 1)stringRequiredformat: "date-time"
animal_identifiers[].created_at (variant 2)nullRequired
animal_identifiers[].updated_at (variant 1)stringRequiredformat: "date-time"
animal_identifiers[].updated_at (variant 2)nullRequired
recordsarrayRequired
records[]objectRequired
records[].id (variant 1)stringRequired
records[].id (variant 2)nullRequired
records[].applied_at (variant 1)stringRequiredformat: "date-time"
records[].applied_at (variant 2)nullRequired
records[].description (variant 1)stringRequired
records[].description (variant 2)nullRequired
records[].is_active (variant 1)booleanRequired
records[].is_active (variant 2)nullRequired
records[].name (variant 1)stringRequired
records[].name (variant 2)nullRequired
records[].type (variant 1)stringRequired
records[].type (variant 2)nullRequired
records[].created_at (variant 1)stringRequiredformat: "date-time"
records[].created_at (variant 2)nullRequired
records[].updated_at (variant 1)stringRequiredformat: "date-time"
records[].updated_at (variant 2)nullRequired
records[].record_itemsarrayRequired
records[].record_items[]objectRequired
records[].record_items[].id (variant 1)stringRequired
records[].record_items[].id (variant 2)nullRequired
records[].record_items[].description (variant 1)stringRequired
records[].record_items[].description (variant 2)nullRequired
records[].record_items[].is_active (variant 1)booleanRequired
records[].record_items[].is_active (variant 2)nullRequired
records[].record_items[].metadata (variant 1)JSONRequired
records[].record_items[].metadata (variant 2)nullRequired
records[].record_items[].name (variant 1)stringRequired
records[].record_items[].name (variant 2)nullRequired
records[].record_items[].created_at (variant 1)stringRequiredformat: "date-time"
records[].record_items[].created_at (variant 2)nullRequired
records[].record_items[].updated_at (variant 1)stringRequiredformat: "date-time"
records[].record_items[].updated_at (variant 2)nullRequired
filesarrayRequired
files[]objectRequired
files[].id (variant 1)stringRequired
files[].id (variant 2)nullRequired
files[].is_active (variant 1)booleanRequired
files[].is_active (variant 2)nullRequired
files[].mime_type (variant 1)stringRequired
files[].mime_type (variant 2)nullRequired
files[].name (variant 1)stringRequired
files[].name (variant 2)nullRequired
files[].size (variant 1)integerRequired
files[].size (variant 2)nullRequired
files[].url (variant 1)stringRequired
files[].url (variant 2)nullRequired
files[].created_at (variant 1)stringRequiredformat: "date-time"
files[].created_at (variant 2)nullRequired
files[].updated_at (variant 1)stringRequiredformat: "date-time"
files[].updated_at (variant 2)nullRequired
saved_birthsobjectOptional
saved_births.totalintegerOptional
saved_births.recordsarrayOptional
saved_births.records[]objectRequired
saved_births.records[].idstringRequiredformat: "uuid"
saved_births.records[].farm_idstringRequiredformat: "uuid"
saved_births.records[].request_idstringRequiredformat: "uuid"
saved_births.records[].confirmation_hashstringRequired
saved_births.records[].created_by_user_idstringRequiredformat: "uuid"
saved_births.records[].dam_idstringRequiredformat: "uuid"
saved_births.records[].birth_datestringRequiredformat: "date-time"
saved_births.records[].time_precisionstring or nullRequired
saved_births.records[].bundleobjectRequired
saved_births.records[].bundle.inputobjectRequired
saved_births.records[].bundle.input.dam_idstringRequiredformat: "uuid"
saved_births.records[].bundle.input.birth_datestringRequired
saved_births.records[].bundle.input.time_precisionstringOptionalenum: ["date_only","morning","afternoon","evening","night"]; default: "date_only"
saved_births.records[].bundle.input.total_bornintegerOptionalmaximum: 1000
saved_births.records[].bundle.input.dam_updateobjectOptional
saved_births.records[].bundle.input.dam_update.kindstringOptionalminLength: 1; maxLength: 80
saved_births.records[].bundle.input.dam_update.notesstringOptionalminLength: 1; maxLength: 1000
saved_births.records[].bundle.input.maternal_observationsarrayOptionalmaxItems: 20; default: []
saved_births.records[].bundle.input.maternal_observations[]objectRequired
saved_births.records[].bundle.input.maternal_observations[].datestringRequired
saved_births.records[].bundle.input.maternal_observations[].textstringRequiredminLength: 1; maxLength: 1000
saved_births.records[].bundle.input.lactation_observationsarrayOptionalmaxItems: 20; default: []
saved_births.records[].bundle.input.lactation_observations[]objectRequired
saved_births.records[].bundle.input.lactation_observations[].datestringRequired
saved_births.records[].bundle.input.lactation_observations[].textstringRequiredminLength: 1; maxLength: 1000
saved_births.records[].bundle.input.offspringarrayOptionalmaxItems: 20; default: []
saved_births.records[].bundle.input.offspring[]objectRequired
saved_births.records[].bundle.input.offspring[].review_labelstringRequiredminLength: 1; maxLength: 80
saved_births.records[].bundle.input.offspring[].animal_idstringOptionalformat: "uuid"
saved_births.records[].bundle.input.offspring[].sexstringOptionalenum: ["male","female","unknown"]
saved_births.records[].bundle.input.offspring[].inventory_statusstringOptionalenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
saved_births.records[].bundle.input.offspring[].birth_weightobjectOptional
saved_births.records[].bundle.input.offspring[].birth_weight.valuenumberRequiredmaximum: 1000
saved_births.records[].bundle.input.offspring[].birth_weight.unitstringRequiredenum: ["kg","lb"]
saved_births.records[].bundle.input.offspring[].birth_weight.basisstringOptionalenum: ["measured","estimated","unknown"]
saved_births.records[].bundle.input.offspring[].vigorarrayOptionalmaxItems: 20; default: []
saved_births.records[].bundle.input.offspring[].vigor[]objectRequired
saved_births.records[].bundle.input.offspring[].vigor[].datestringRequired
saved_births.records[].bundle.input.offspring[].vigor[].textstringRequiredminLength: 1; maxLength: 1000
saved_births.records[].bundle.input.offspring[].supplementationarrayOptionalmaxItems: 20; default: []
saved_births.records[].bundle.input.offspring[].supplementation[]objectRequired
saved_births.records[].bundle.input.offspring[].supplementation[].datestringRequired
saved_births.records[].bundle.input.offspring[].supplementation[].substancestringRequiredminLength: 1; maxLength: 80
saved_births.records[].bundle.input.offspring[].supplementation[].amountnumberRequiredmaximum: 100000
saved_births.records[].bundle.input.offspring[].supplementation[].unitstringRequiredminLength: 1; maxLength: 80
saved_births.records[].bundle.input.offspring[].supplementation[].sourcestringRequiredminLength: 1; maxLength: 1000
saved_births.records[].bundle.input.sireobjectOptionaldefault: {"status":"unknown"}
saved_births.records[].bundle.input.sire.statusstringRequiredenum: ["unknown","presumed","confirmed"]
saved_births.records[].bundle.input.sire.animal_idstringOptionalformat: "uuid"
saved_births.records[].bundle.input.sire.provenancestringOptionalminLength: 1; maxLength: 1000
saved_births.records[].bundle.input.sire.confidencenumberOptionalminimum: 0; maximum: 1
saved_births.records[].bundle.input.protocolobjectOptional
saved_births.records[].bundle.input.protocol.claimed_namestringRequiredminLength: 1; maxLength: 80
saved_births.records[].bundle.input.protocol.completed_datestringRequired
saved_births.records[].bundle.input.protocol.version_idstringOptionalformat: "uuid"
saved_births.records[].bundle.input.protocol.offspring_labelsarrayRequiredminItems: 1; maxItems: 20
saved_births.records[].bundle.input.protocol.offspring_labels[]stringRequiredminLength: 1; maxLength: 80
saved_births.records[].bundle.input.follow_uparrayOptionalmaxItems: 20; default: []
saved_births.records[].bundle.input.follow_up[]objectRequired
saved_births.records[].bundle.input.follow_up[].namestringRequiredminLength: 1; maxLength: 1000
saved_births.records[].bundle.input.follow_up[].due_datestringOptional
saved_births.records[].bundle.input.follow_up[].offspring_labelsarrayRequiredminItems: 1; maxItems: 20
saved_births.records[].bundle.input.follow_up[].offspring_labels[]stringRequiredminLength: 1; maxLength: 80
saved_births.records[].bundle.input.group_idsarrayOptionalmaxItems: 20; default: []
saved_births.records[].bundle.input.group_ids[]stringRequiredformat: "uuid"
saved_births.records[].bundle.input.current_locationstringOptionalminLength: 1; maxLength: 80
saved_births.records[].bundle.input.source_sms_idstringOptionalformat: "uuid"
saved_births.records[].bundle.input.source_message_idstringOptionalformat: "uuid"
saved_births.records[].bundle.input.evidencearrayOptionalmaxItems: 20; default: []
saved_births.records[].bundle.input.evidence[]objectRequired
saved_births.records[].bundle.input.evidence[].file_idstringRequiredformat: "uuid"
saved_births.records[].bundle.input.evidence[].media_idstringOptionalformat: "uuid"
saved_births.records[].bundle.input.evidence[].link_to_dambooleanOptionaldefault: false
saved_births.records[].bundle.input.evidence[].offspring_labelstringOptionalminLength: 1; maxLength: 80
saved_births.records[].bundle.input.unresolvedarrayOptionalmaxItems: 30; default: []
saved_births.records[].bundle.input.unresolved[]stringRequiredminLength: 1; maxLength: 1000
saved_births.records[].bundle.input.additional_source_sms_idsarrayOptionalmaxItems: 20; default: []
saved_births.records[].bundle.input.additional_source_sms_ids[]stringRequiredformat: "uuid"
saved_births.records[].bundle.reviewobjectRequired
saved_births.records[].record_idstringRequiredformat: "uuid"
saved_births.records[].source_sms_idstring or nullRequiredformat: "uuid"
saved_births.records[].source_message_idstring or nullRequiredformat: "uuid"
saved_births.records[].agent_action_idstring or nullRequiredformat: "uuid"
saved_births.records[].created_atstringRequiredformat: "date-time"
saved_births.records[].offspringarrayRequired
saved_births.records[].offspring[]objectRequired
saved_births.records[].offspring[].idstringRequiredformat: "uuid"
saved_births.records[].offspring[].birth_event_idstringRequiredformat: "uuid"
saved_births.records[].offspring[].animal_idstringRequiredformat: "uuid"
saved_births.records[].offspring[].review_labelstringRequired
saved_births.records[].offspring[].positionintegerRequired
saved_births.records[].offspring[].detailsobjectRequired
saved_births.records[].tasksarrayRequired
saved_births.records[].tasks[]objectRequired
saved_births.records[].tasks[].idstringRequiredformat: "uuid"
saved_births.records[].tasks[].farm_idstringRequiredformat: "uuid"
saved_births.records[].tasks[].birth_event_idstringRequiredformat: "uuid"
saved_births.records[].tasks[].namestringRequired
saved_births.records[].tasks[].statusstringRequiredenum: ["TODO","DONE","CANCELLED"]
saved_births.records[].tasks[].due_datestring or nullRequiredformat: "date-time"
saved_births.records[].tasks[].created_atstringRequiredformat: "date-time"
saved_births.records[].tasks[].updated_atstringRequiredformat: "date-time"
saved_births.records[].tasks[].animalsarrayOptional
saved_births.records[].tasks[].animals[]objectRequired
saved_births.records[].tasks[].animals[].idstringRequiredformat: "uuid"
saved_births.records[].recordobjectRequired
saved_births.records[].record.idstringRequiredformat: "uuid"
saved_births.records[].record.subtypestring or nullOptionalenum: ["BIRTH",null]
saved_births.records[].record.revisionintegerOptional
saved_births.records[].record.is_activebooleanOptional
saved_births.records[].record.typestringOptional
saved_births.records[].record.applied_atstringOptionalformat: "date-time"
saved_births.records[].record.filesarrayRequired
saved_births.records[].record.files[]objectRequired
saved_births.records[].record.files[].idstringRequiredformat: "uuid"
saved_births.records[].record.files[].namestringRequired
saved_births.records[].record.files[].mime_typestringRequired
saved_births.records[].birth_detailsobjectOptional
saved_births.records[].birth_details.birth_datestringRequiredformat: "date"
saved_births.records[].birth_details.time_precisionstring or nullRequired
saved_births.records[].birth_details.dam_idstringRequiredformat: "uuid"
saved_births.records[].birth_details.total_borninteger or nullRequired
saved_births.records[].birth_details.subtypestring or nullRequiredenum: ["BIRTH",null]
saved_births.records[].birth_details.revisionintegerRequired
saved_births.records[].birth_details.lifecycle_statusstringRequiredenum: ["active","entered_in_error"]
saved_births.records[].birth_details.date_sourcestringRequired
saved_births.records[].care_recordsarrayRequired
saved_births.records[].care_records[]objectRequired
saved_births.records[].care_records[].idstringRequiredformat: "uuid"
saved_births.records[].care_records[].namestringRequired
saved_births.records[].care_records[].applied_atstring or nullRequiredformat: "date-time"
saved_births.records[].care_records[].record_itemsarrayRequired
saved_births.records[].care_records[].record_items[]objectRequired
saved_births.records[].sire_animalsarrayOptional
saved_births.records[].sire_animals[]objectRequired
saved_births.records[].sire_animals[].idstringRequiredformat: "uuid"
saved_births.records[].sire_animals[].is_activebooleanRequired
saved_births.records[].sire_animals[].metadataobjectRequired
saved_births.records[].sire_animals[].animal_identifiersarrayRequired
saved_births.records[].sire_animals[].animal_identifiers[]objectRequired
saved_births.records[].sire_animals[].animal_identifiers[].idstringOptionalformat: "uuid"
saved_births.records[].sire_animals[].animal_identifiers[].typestringOptional
saved_births.records[].sire_animals[].animal_identifiers[].valuestringOptional
saved_births.records[].sire_animals[].animal_identifiers[].is_activebooleanOptional
saved_births.records[].offspring_inventoryarrayOptional
saved_births.records[].offspring_inventory[]objectRequired
saved_births.records[].offspring_inventory[].animal_idstringRequiredformat: "uuid"
saved_births.records[].offspring_inventory[].review_labelstringRequired
saved_births.records[].offspring_inventory[].positionintegerRequired
saved_births.records[].offspring_inventory[].inventory_statusstring or nullRequiredenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED",null]
saved_births.records[].offspring_inventory[].is_activeboolean or nullRequired
saved_births.records[].linked_recordsarrayOptional
saved_births.records[].linked_records[]objectRequired
saved_births.records[].linked_records[].idstringRequiredformat: "uuid"
saved_births.records[].linked_records[].kindstringRequiredenum: ["primary","care"]
saved_births.records[].linked_records[].namestring or nullOptional
saved_births.records[].linked_records[].applied_atstring or nullOptionalformat: "date-time"
saved_births.records[].linked_records[].file_idsarrayOptional
saved_births.records[].linked_records[].file_ids[]stringRequiredformat: "uuid"
saved_births.records[].media_file_idsarrayOptional
saved_births.records[].media_file_ids[]stringRequiredformat: "uuid"
saved_births.paginationobjectOptional
saved_births.pagination.skipintegerOptional
saved_births.pagination.takeintegerOptional
saved_births.pagination.returnedintegerOptional
saved_births.pagination.has_morebooleanOptional
saved_births.pagination.next_skipinteger or nullOptional
inventory_statusstringRequiredenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
birth_factsobjectOptional
birth_facts.record (variant 1)objectRequired
birth_facts.record (variant 1).record_idstringRequired
birth_facts.record (variant 1).birth_event_idstringRequired
birth_facts.record (variant 1).revisionnumberRequired
birth_facts.record (variant 1).birth_datestringRequired
birth_facts.record (variant 1).time_precision (variant 1)stringRequired
birth_facts.record (variant 1).time_precision (variant 2)nullRequired
birth_facts.record (variant 1).dam_idstringRequired
birth_facts.record (variant 1).sire (variant 1)objectRequired
birth_facts.record (variant 1).sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1)stringRequired
birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2)nullRequired
birth_facts.record (variant 1).sire (variant 1).provenance (variant 1)stringRequired
birth_facts.record (variant 1).sire (variant 1).provenance (variant 2)nullRequired
birth_facts.record (variant 1).sire (variant 1).confidence (variant 1)numberRequired
birth_facts.record (variant 1).sire (variant 1).confidence (variant 2)nullRequired
birth_facts.record (variant 1).sire (variant 2)nullRequired
birth_facts.record (variant 2)nullRequired
birth_facts.derivedobjectRequired
birth_facts.derived.birth_date (variant 1)stringRequired
birth_facts.derived.birth_date (variant 2)nullRequired
birth_facts.derived.time_precision (variant 1)stringRequired
birth_facts.derived.time_precision (variant 2)nullRequired
birth_facts.derived.dam_id (variant 1)stringRequired
birth_facts.derived.dam_id (variant 2)nullRequired
birth_facts.derived.sire (variant 1)objectRequired
birth_facts.derived.sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
birth_facts.derived.sire (variant 1).animal_id (variant 1)stringRequired
birth_facts.derived.sire (variant 1).animal_id (variant 2)nullRequired
birth_facts.derived.sire (variant 1).provenance (variant 1)stringRequired
birth_facts.derived.sire (variant 1).provenance (variant 2)nullRequired
birth_facts.derived.sire (variant 1).confidence (variant 1)numberRequired
birth_facts.derived.sire (variant 1).confidence (variant 2)nullRequired
birth_facts.derived.sire (variant 2)nullRequired
birth_facts.profile_birth_date (variant 1)stringRequired
birth_facts.profile_birth_date (variant 2)nullRequired
birth_facts.effective_birth_date (variant 1)stringRequired
birth_facts.effective_birth_date (variant 2)nullRequired
birth_facts.conflictsarrayRequired
birth_facts.conflicts[]objectRequired
birth_facts.conflicts[].independent_birth_datestringRequired
birth_facts.conflicts[].recorded_birth_datestringRequired
birth_facts.conflicts[].record_idstringRequired
json example
{
  "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.

ParameterInRequiredSchema
farm_idpathYes{"type":"string","format":"uuid"}
animal_idpathYes{"type":"string","format":"uuid"}

Request body (application/json)

FieldTypePresenceConstraints
metadataJSONOptional
inventory_statusstringOptionalenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
json example
{}

Request example

bash 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

StatusMeaningContent type
200Successapplication/json
400Request validation failed.application/json
401Missing/invalid authentication or insufficient farm role.application/json
403Missing required scope or credential type is disallowed.application/json
404Resource or active farm membership not found.application/json
429Rate limit exceeded. Retry after the indicated delay.application/json
500Unexpected server failure.application/json

200 response schema (application/json)

FieldTypePresenceConstraints
idstringRequired
created_atstringRequiredformat: "date-time"
updated_atstringRequiredformat: "date-time"
is_activebooleanRequired
farm_idstringRequired
metadataJSONRequired
inventory_statusstringRequiredenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
json example
{
  "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.

ParameterInRequiredSchema
farm_idpathYes{"type":"string","format":"uuid"}

Request body (application/json)

FieldTypePresenceConstraints
eidstringRequired
json example
{
  "eid": "example"
}

Request example

bash 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

StatusMeaningContent type
200Existing match returned.application/json
201New animal created.application/json
400Request validation failed.application/json
401Missing/invalid authentication or insufficient farm role.application/json
403Missing required scope or credential type is disallowed.application/json
404Resource or active farm membership not found.application/json
429Rate limit exceeded. Retry after the indicated delay.application/json
500Unexpected server failure.application/json

200 response schema (application/json)

FieldTypePresenceConstraints
animalobjectRequired
animal.idstringRequired
animal.created_atstringRequiredformat: "date-time"
animal.updated_atstringRequiredformat: "date-time"
animal.is_activebooleanRequired
animal.farm_idstringRequired
animal.metadataJSONRequired
animal.groupsarrayRequired
animal.groups[]objectRequired
animal.groups[].id (variant 1)stringRequired
animal.groups[].id (variant 2)nullRequired
animal.groups[].farm_id (variant 1)stringRequired
animal.groups[].farm_id (variant 2)nullRequired
animal.groups[].description (variant 1)stringRequired
animal.groups[].description (variant 2)nullRequired
animal.groups[].is_active (variant 1)booleanRequired
animal.groups[].is_active (variant 2)nullRequired
animal.groups[].name (variant 1)stringRequired
animal.groups[].name (variant 2)nullRequired
animal.groups[].created_at (variant 1)stringRequiredformat: "date-time"
animal.groups[].created_at (variant 2)nullRequired
animal.groups[].updated_at (variant 1)stringRequiredformat: "date-time"
animal.groups[].updated_at (variant 2)nullRequired
animal.animal_identifiersarrayRequired
animal.animal_identifiers[]objectRequired
animal.animal_identifiers[].id (variant 1)stringRequired
animal.animal_identifiers[].id (variant 2)nullRequired
animal.animal_identifiers[].animal_id (variant 1)stringRequired
animal.animal_identifiers[].animal_id (variant 2)nullRequired
animal.animal_identifiers[].is_active (variant 1)booleanRequired
animal.animal_identifiers[].is_active (variant 2)nullRequired
animal.animal_identifiers[].is_primary (variant 1)booleanRequired
animal.animal_identifiers[].is_primary (variant 2)nullRequired
animal.animal_identifiers[].type (variant 1)stringRequired
animal.animal_identifiers[].type (variant 2)nullRequired
animal.animal_identifiers[].value (variant 1)stringRequired
animal.animal_identifiers[].value (variant 2)nullRequired
animal.animal_identifiers[].created_at (variant 1)stringRequiredformat: "date-time"
animal.animal_identifiers[].created_at (variant 2)nullRequired
animal.animal_identifiers[].updated_at (variant 1)stringRequiredformat: "date-time"
animal.animal_identifiers[].updated_at (variant 2)nullRequired
animal.inventory_statusstringRequiredenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
animal.birth_factsobjectOptional
animal.birth_facts.record (variant 1)objectRequired
animal.birth_facts.record (variant 1).record_idstringRequired
animal.birth_facts.record (variant 1).birth_event_idstringRequired
animal.birth_facts.record (variant 1).revisionnumberRequired
animal.birth_facts.record (variant 1).birth_datestringRequired
animal.birth_facts.record (variant 1).time_precision (variant 1)stringRequired
animal.birth_facts.record (variant 1).time_precision (variant 2)nullRequired
animal.birth_facts.record (variant 1).dam_idstringRequired
animal.birth_facts.record (variant 1).sire (variant 1)objectRequired
animal.birth_facts.record (variant 1).sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
animal.birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1)stringRequired
animal.birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2)nullRequired
animal.birth_facts.record (variant 1).sire (variant 1).provenance (variant 1)stringRequired
animal.birth_facts.record (variant 1).sire (variant 1).provenance (variant 2)nullRequired
animal.birth_facts.record (variant 1).sire (variant 1).confidence (variant 1)numberRequired
animal.birth_facts.record (variant 1).sire (variant 1).confidence (variant 2)nullRequired
animal.birth_facts.record (variant 1).sire (variant 2)nullRequired
animal.birth_facts.record (variant 2)nullRequired
animal.birth_facts.derivedobjectRequired
animal.birth_facts.derived.birth_date (variant 1)stringRequired
animal.birth_facts.derived.birth_date (variant 2)nullRequired
animal.birth_facts.derived.time_precision (variant 1)stringRequired
animal.birth_facts.derived.time_precision (variant 2)nullRequired
animal.birth_facts.derived.dam_id (variant 1)stringRequired
animal.birth_facts.derived.dam_id (variant 2)nullRequired
animal.birth_facts.derived.sire (variant 1)objectRequired
animal.birth_facts.derived.sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
animal.birth_facts.derived.sire (variant 1).animal_id (variant 1)stringRequired
animal.birth_facts.derived.sire (variant 1).animal_id (variant 2)nullRequired
animal.birth_facts.derived.sire (variant 1).provenance (variant 1)stringRequired
animal.birth_facts.derived.sire (variant 1).provenance (variant 2)nullRequired
animal.birth_facts.derived.sire (variant 1).confidence (variant 1)numberRequired
animal.birth_facts.derived.sire (variant 1).confidence (variant 2)nullRequired
animal.birth_facts.derived.sire (variant 2)nullRequired
animal.birth_facts.profile_birth_date (variant 1)stringRequired
animal.birth_facts.profile_birth_date (variant 2)nullRequired
animal.birth_facts.effective_birth_date (variant 1)stringRequired
animal.birth_facts.effective_birth_date (variant 2)nullRequired
animal.birth_facts.conflictsarrayRequired
animal.birth_facts.conflicts[]objectRequired
animal.birth_facts.conflicts[].independent_birth_datestringRequired
animal.birth_facts.conflicts[].recorded_birth_datestringRequired
animal.birth_facts.conflicts[].record_idstringRequired
createdbooleanRequired
json example
{
  "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)

FieldTypePresenceConstraints
animalobjectRequired
animal.idstringRequired
animal.created_atstringRequiredformat: "date-time"
animal.updated_atstringRequiredformat: "date-time"
animal.is_activebooleanRequired
animal.farm_idstringRequired
animal.metadataJSONRequired
animal.groupsarrayRequired
animal.groups[]objectRequired
animal.groups[].id (variant 1)stringRequired
animal.groups[].id (variant 2)nullRequired
animal.groups[].farm_id (variant 1)stringRequired
animal.groups[].farm_id (variant 2)nullRequired
animal.groups[].description (variant 1)stringRequired
animal.groups[].description (variant 2)nullRequired
animal.groups[].is_active (variant 1)booleanRequired
animal.groups[].is_active (variant 2)nullRequired
animal.groups[].name (variant 1)stringRequired
animal.groups[].name (variant 2)nullRequired
animal.groups[].created_at (variant 1)stringRequiredformat: "date-time"
animal.groups[].created_at (variant 2)nullRequired
animal.groups[].updated_at (variant 1)stringRequiredformat: "date-time"
animal.groups[].updated_at (variant 2)nullRequired
animal.animal_identifiersarrayRequired
animal.animal_identifiers[]objectRequired
animal.animal_identifiers[].id (variant 1)stringRequired
animal.animal_identifiers[].id (variant 2)nullRequired
animal.animal_identifiers[].animal_id (variant 1)stringRequired
animal.animal_identifiers[].animal_id (variant 2)nullRequired
animal.animal_identifiers[].is_active (variant 1)booleanRequired
animal.animal_identifiers[].is_active (variant 2)nullRequired
animal.animal_identifiers[].is_primary (variant 1)booleanRequired
animal.animal_identifiers[].is_primary (variant 2)nullRequired
animal.animal_identifiers[].type (variant 1)stringRequired
animal.animal_identifiers[].type (variant 2)nullRequired
animal.animal_identifiers[].value (variant 1)stringRequired
animal.animal_identifiers[].value (variant 2)nullRequired
animal.animal_identifiers[].created_at (variant 1)stringRequiredformat: "date-time"
animal.animal_identifiers[].created_at (variant 2)nullRequired
animal.animal_identifiers[].updated_at (variant 1)stringRequiredformat: "date-time"
animal.animal_identifiers[].updated_at (variant 2)nullRequired
animal.inventory_statusstringRequiredenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
animal.birth_factsobjectOptional
animal.birth_facts.record (variant 1)objectRequired
animal.birth_facts.record (variant 1).record_idstringRequired
animal.birth_facts.record (variant 1).birth_event_idstringRequired
animal.birth_facts.record (variant 1).revisionnumberRequired
animal.birth_facts.record (variant 1).birth_datestringRequired
animal.birth_facts.record (variant 1).time_precision (variant 1)stringRequired
animal.birth_facts.record (variant 1).time_precision (variant 2)nullRequired
animal.birth_facts.record (variant 1).dam_idstringRequired
animal.birth_facts.record (variant 1).sire (variant 1)objectRequired
animal.birth_facts.record (variant 1).sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
animal.birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1)stringRequired
animal.birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2)nullRequired
animal.birth_facts.record (variant 1).sire (variant 1).provenance (variant 1)stringRequired
animal.birth_facts.record (variant 1).sire (variant 1).provenance (variant 2)nullRequired
animal.birth_facts.record (variant 1).sire (variant 1).confidence (variant 1)numberRequired
animal.birth_facts.record (variant 1).sire (variant 1).confidence (variant 2)nullRequired
animal.birth_facts.record (variant 1).sire (variant 2)nullRequired
animal.birth_facts.record (variant 2)nullRequired
animal.birth_facts.derivedobjectRequired
animal.birth_facts.derived.birth_date (variant 1)stringRequired
animal.birth_facts.derived.birth_date (variant 2)nullRequired
animal.birth_facts.derived.time_precision (variant 1)stringRequired
animal.birth_facts.derived.time_precision (variant 2)nullRequired
animal.birth_facts.derived.dam_id (variant 1)stringRequired
animal.birth_facts.derived.dam_id (variant 2)nullRequired
animal.birth_facts.derived.sire (variant 1)objectRequired
animal.birth_facts.derived.sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
animal.birth_facts.derived.sire (variant 1).animal_id (variant 1)stringRequired
animal.birth_facts.derived.sire (variant 1).animal_id (variant 2)nullRequired
animal.birth_facts.derived.sire (variant 1).provenance (variant 1)stringRequired
animal.birth_facts.derived.sire (variant 1).provenance (variant 2)nullRequired
animal.birth_facts.derived.sire (variant 1).confidence (variant 1)numberRequired
animal.birth_facts.derived.sire (variant 1).confidence (variant 2)nullRequired
animal.birth_facts.derived.sire (variant 2)nullRequired
animal.birth_facts.profile_birth_date (variant 1)stringRequired
animal.birth_facts.profile_birth_date (variant 2)nullRequired
animal.birth_facts.effective_birth_date (variant 1)stringRequired
animal.birth_facts.effective_birth_date (variant 2)nullRequired
animal.birth_facts.conflictsarrayRequired
animal.birth_facts.conflicts[]objectRequired
animal.birth_facts.conflicts[].independent_birth_datestringRequired
animal.birth_facts.conflicts[].recorded_birth_datestringRequired
animal.birth_facts.conflicts[].record_idstringRequired
createdbooleanRequired
json example
{
  "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.

ParameterInRequiredSchema
farm_idpathYes{"type":"string","format":"uuid"}
inventory_statusqueryNo{"type":"string","enum":["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED","ALL"],"default":"CURRENT"}

Request example

bash example
curl --fail-with-body -X GET \
  'https://api.ranch.bot/v1/farm/<farm_id>/animals/index' \
  -H "Authorization: Bearer $RANCHBOT_TOKEN"

Responses

StatusMeaningContent type
200Successapplication/json
400Request validation failed.application/json
401Missing/invalid authentication or insufficient farm role.application/json
403Missing required scope or credential type is disallowed.application/json
404Resource or active farm membership not found.application/json
429Rate limit exceeded. Retry after the indicated delay.application/json
500Unexpected server failure.application/json

200 response schema (application/json)

FieldTypePresenceConstraints
synced_atstringRequired
totalnumberRequired
animalsarrayRequired
animals[]objectRequired
animals[].idstringRequired
animals[].metadataJSONRequired
animals[].identifiersarrayRequired
animals[].identifiers[]objectRequired
animals[].identifiers[].typestringRequiredenum: ["BRAND","EID","MANAGEMENT_TAG","NAME","TATTOO"]
animals[].identifiers[].valuestringRequired
animals[].identifiers[].is_primarybooleanRequired
animals[].last_weightsarrayRequired
animals[].last_weights[]objectRequired
animals[].last_weights[].valuenumberRequired
animals[].last_weights[].unit (variant 1)nullRequired
animals[].last_weights[].unit (variant 2)stringRequired
animals[].last_weights[].applied_atstringRequiredformat: "date-time"
animals[].inventory_statusstringRequiredenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
animals[].birth_factsobjectOptional
animals[].birth_facts.record (variant 1)objectRequired
animals[].birth_facts.record (variant 1).record_idstringRequired
animals[].birth_facts.record (variant 1).birth_event_idstringRequired
animals[].birth_facts.record (variant 1).revisionnumberRequired
animals[].birth_facts.record (variant 1).birth_datestringRequired
animals[].birth_facts.record (variant 1).time_precision (variant 1)stringRequired
animals[].birth_facts.record (variant 1).time_precision (variant 2)nullRequired
animals[].birth_facts.record (variant 1).dam_idstringRequired
animals[].birth_facts.record (variant 1).sire (variant 1)objectRequired
animals[].birth_facts.record (variant 1).sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
animals[].birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1)stringRequired
animals[].birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2)nullRequired
animals[].birth_facts.record (variant 1).sire (variant 1).provenance (variant 1)stringRequired
animals[].birth_facts.record (variant 1).sire (variant 1).provenance (variant 2)nullRequired
animals[].birth_facts.record (variant 1).sire (variant 1).confidence (variant 1)numberRequired
animals[].birth_facts.record (variant 1).sire (variant 1).confidence (variant 2)nullRequired
animals[].birth_facts.record (variant 1).sire (variant 2)nullRequired
animals[].birth_facts.record (variant 2)nullRequired
animals[].birth_facts.derivedobjectRequired
animals[].birth_facts.derived.birth_date (variant 1)stringRequired
animals[].birth_facts.derived.birth_date (variant 2)nullRequired
animals[].birth_facts.derived.time_precision (variant 1)stringRequired
animals[].birth_facts.derived.time_precision (variant 2)nullRequired
animals[].birth_facts.derived.dam_id (variant 1)stringRequired
animals[].birth_facts.derived.dam_id (variant 2)nullRequired
animals[].birth_facts.derived.sire (variant 1)objectRequired
animals[].birth_facts.derived.sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
animals[].birth_facts.derived.sire (variant 1).animal_id (variant 1)stringRequired
animals[].birth_facts.derived.sire (variant 1).animal_id (variant 2)nullRequired
animals[].birth_facts.derived.sire (variant 1).provenance (variant 1)stringRequired
animals[].birth_facts.derived.sire (variant 1).provenance (variant 2)nullRequired
animals[].birth_facts.derived.sire (variant 1).confidence (variant 1)numberRequired
animals[].birth_facts.derived.sire (variant 1).confidence (variant 2)nullRequired
animals[].birth_facts.derived.sire (variant 2)nullRequired
animals[].birth_facts.profile_birth_date (variant 1)stringRequired
animals[].birth_facts.profile_birth_date (variant 2)nullRequired
animals[].birth_facts.effective_birth_date (variant 1)stringRequired
animals[].birth_facts.effective_birth_date (variant 2)nullRequired
animals[].birth_facts.conflictsarrayRequired
animals[].birth_facts.conflicts[]objectRequired
animals[].birth_facts.conflicts[].independent_birth_datestringRequired
animals[].birth_facts.conflicts[].recorded_birth_datestringRequired
animals[].birth_facts.conflicts[].record_idstringRequired
json example
{
  "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.

ParameterInRequiredSchema
farm_idpathYes{"type":"string","format":"uuid"}
eidqueryYes{"type":"string","minLength":1} Exact EID, including leading zeros.

Request example

bash 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

StatusMeaningContent type
200Successapplication/json
400Request validation failed.application/json
401Missing/invalid authentication or insufficient farm role.application/json
403Missing required scope or credential type is disallowed.application/json
404Resource or active farm membership not found.application/json
409Multiple active animals match this EID; clarify the animal. No writes performed.application/json
429Rate limit exceeded. Retry after the indicated delay.application/json
500Unexpected server failure.application/json

200 response schema (application/json)

FieldTypePresenceConstraints
idstringRequired
created_atstringRequiredformat: "date-time"
updated_atstringRequiredformat: "date-time"
is_activebooleanRequired
farm_idstringRequired
metadataJSONRequired
groupsarrayRequired
groups[]objectRequired
groups[].id (variant 1)stringRequired
groups[].id (variant 2)nullRequired
groups[].farm_id (variant 1)stringRequired
groups[].farm_id (variant 2)nullRequired
groups[].description (variant 1)stringRequired
groups[].description (variant 2)nullRequired
groups[].is_active (variant 1)booleanRequired
groups[].is_active (variant 2)nullRequired
groups[].name (variant 1)stringRequired
groups[].name (variant 2)nullRequired
groups[].created_at (variant 1)stringRequiredformat: "date-time"
groups[].created_at (variant 2)nullRequired
groups[].updated_at (variant 1)stringRequiredformat: "date-time"
groups[].updated_at (variant 2)nullRequired
animal_identifiersarrayRequired
animal_identifiers[]objectRequired
animal_identifiers[].id (variant 1)stringRequired
animal_identifiers[].id (variant 2)nullRequired
animal_identifiers[].animal_id (variant 1)stringRequired
animal_identifiers[].animal_id (variant 2)nullRequired
animal_identifiers[].is_active (variant 1)booleanRequired
animal_identifiers[].is_active (variant 2)nullRequired
animal_identifiers[].is_primary (variant 1)booleanRequired
animal_identifiers[].is_primary (variant 2)nullRequired
animal_identifiers[].type (variant 1)stringRequired
animal_identifiers[].type (variant 2)nullRequired
animal_identifiers[].value (variant 1)stringRequired
animal_identifiers[].value (variant 2)nullRequired
animal_identifiers[].created_at (variant 1)stringRequiredformat: "date-time"
animal_identifiers[].created_at (variant 2)nullRequired
animal_identifiers[].updated_at (variant 1)stringRequiredformat: "date-time"
animal_identifiers[].updated_at (variant 2)nullRequired
inventory_statusstringRequiredenum: ["CURRENT","UNKNOWN","SOLD","DECEASED","NOT_MANAGED"]
birth_factsobjectOptional
birth_facts.record (variant 1)objectRequired
birth_facts.record (variant 1).record_idstringRequired
birth_facts.record (variant 1).birth_event_idstringRequired
birth_facts.record (variant 1).revisionnumberRequired
birth_facts.record (variant 1).birth_datestringRequired
birth_facts.record (variant 1).time_precision (variant 1)stringRequired
birth_facts.record (variant 1).time_precision (variant 2)nullRequired
birth_facts.record (variant 1).dam_idstringRequired
birth_facts.record (variant 1).sire (variant 1)objectRequired
birth_facts.record (variant 1).sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
birth_facts.record (variant 1).sire (variant 1).animal_id (variant 1)stringRequired
birth_facts.record (variant 1).sire (variant 1).animal_id (variant 2)nullRequired
birth_facts.record (variant 1).sire (variant 1).provenance (variant 1)stringRequired
birth_facts.record (variant 1).sire (variant 1).provenance (variant 2)nullRequired
birth_facts.record (variant 1).sire (variant 1).confidence (variant 1)numberRequired
birth_facts.record (variant 1).sire (variant 1).confidence (variant 2)nullRequired
birth_facts.record (variant 1).sire (variant 2)nullRequired
birth_facts.record (variant 2)nullRequired
birth_facts.derivedobjectRequired
birth_facts.derived.birth_date (variant 1)stringRequired
birth_facts.derived.birth_date (variant 2)nullRequired
birth_facts.derived.time_precision (variant 1)stringRequired
birth_facts.derived.time_precision (variant 2)nullRequired
birth_facts.derived.dam_id (variant 1)stringRequired
birth_facts.derived.dam_id (variant 2)nullRequired
birth_facts.derived.sire (variant 1)objectRequired
birth_facts.derived.sire (variant 1).statusstringRequiredenum: ["unknown","presumed","confirmed"]
birth_facts.derived.sire (variant 1).animal_id (variant 1)stringRequired
birth_facts.derived.sire (variant 1).animal_id (variant 2)nullRequired
birth_facts.derived.sire (variant 1).provenance (variant 1)stringRequired
birth_facts.derived.sire (variant 1).provenance (variant 2)nullRequired
birth_facts.derived.sire (variant 1).confidence (variant 1)numberRequired
birth_facts.derived.sire (variant 1).confidence (variant 2)nullRequired
birth_facts.derived.sire (variant 2)nullRequired
birth_facts.profile_birth_date (variant 1)stringRequired
birth_facts.profile_birth_date (variant 2)nullRequired
birth_facts.effective_birth_date (variant 1)stringRequired
birth_facts.effective_birth_date (variant 2)nullRequired
birth_facts.conflictsarrayRequired
birth_facts.conflicts[]objectRequired
birth_facts.conflicts[].independent_birth_datestringRequired
birth_facts.conflicts[].recorded_birth_datestringRequired
birth_facts.conflicts[].record_idstringRequired
json example
{
  "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.

json example
{
  "success": false,
  "errors": [
    {
      "code": 400,
      "name": "ValidationError",
      "message": "Example validation failure"
    }
  ]
}