Records API
HTTP reference for records. Read authentication and access before using these operations. All examples use made-up data and placeholder credentials.
GET /v1/farm/{farm_id}/records
Get Records
Current records HTTP operation. External credential scopes: read:records. 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. An animal_id or group_id target and/or applied_from/applied_before time bound returns filtered history with skip 0 and take 50 by default, up to 200 records per page. The response always lists same-farm animal and group attachment ids in records[].animals and records[].groups; only the current group names in match_context.current_groups and scope.authorized_groups require include_group_context. Scoped credentials: animal_id also needs read:animals, group_id also needs read:groups, and include_group_context needs both.
Parameter In Required Schema farm_id path Yes {"type":"string","format":"uuid"} skip query No {"type":"integer"} take query No {"type":"integer"} type query No {"type":"string","enum":["FEED","GENETIC","HEALTH","MOVEMENT","OTHER"]} Filter by record type. animal_id query No {"type":"string","format":"uuid"} Direct saved records for one animal UUID, regardless of inventory status. group_id query No {"type":"string","format":"uuid"} Direct saved records for one same-farm group UUID (archived groups allowed). include_group_context query No {"type":"boolean"} With animal_id, also include records attached to the animal's current active same-farm groups. Requires animal_id. applied_from query No {"type":"string","format":"date-time"} Inclusive RFC3339 timestamp with an explicit timezone offset. applied_before query No {"type":"string","format":"date-time"} Exclusive RFC3339 timestamp with an explicit timezone offset.
Request example
bash example Copy example
curl --fail-with-body -X GET \
'https://api.ranch.bot/v1/farm/<farm_id>/records' \
-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[].type string Required enum: ["OTHER","FEED","GENETIC","HEALTH","MOVEMENT"] records[].id string Required records[].created_at string Required format: "date-time" records[].updated_at string Required format: "date-time" records[].name string Required records[].is_active boolean Required records[].description (variant 1) null Required records[].description (variant 2) string Required records[].applied_at string Required format: "date-time" 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 records[].files array Required records[].files[] object Required records[].files[].id (variant 1) string Required records[].files[].id (variant 2) null Required records[].files[].is_active (variant 1) boolean Required records[].files[].is_active (variant 2) null Required records[].files[].mime_type (variant 1) string Required records[].files[].mime_type (variant 2) null Required records[].files[].name (variant 1) string Required records[].files[].name (variant 2) null Required records[].files[].size (variant 1) integer Required records[].files[].size (variant 2) null Required records[].files[].url (variant 1) string Required records[].files[].url (variant 2) null Required records[].files[].created_at (variant 1) string Required format: "date-time" records[].files[].created_at (variant 2) null Required records[].files[].updated_at (variant 1) string Required format: "date-time" records[].files[].updated_at (variant 2) null Required records[].animals array Optional records[].animals[] object Required records[].animals[].id string Optional records[].groups array Optional records[].groups[] object Required records[].groups[].id string Optional records[].match_context object Optional records[].match_context.direct_animal boolean Optional records[].match_context.direct_group boolean Optional records[].match_context.current_groups array Optional records[].match_context.current_groups[] object Required records[].match_context.current_groups[].id string Optional records[].match_context.current_groups[].name string Optional records[].match_context.current_groups[].membership_at_event JSON Optional const: "unknown" scope object Optional scope.farm_id string Optional scope.animal_id (variant 1) string Optional scope.animal_id (variant 2) null Optional scope.group_id (variant 1) string Optional scope.group_id (variant 2) null Optional scope.include_group_context boolean Optional scope.type (variant 1) string Optional scope.type (variant 2) null Optional scope.applied_from (variant 1) string Optional scope.applied_from (variant 2) null Optional scope.applied_before (variant 1) string Optional scope.applied_before (variant 2) null Optional scope.authorized_groups array Optional scope.authorized_groups[] object Required scope.authorized_groups[].id string Optional scope.authorized_groups[].name string Optional scope.dataset string Optional 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
json example Copy example
{
"total": 0,
"records": []
}
POST /v1/farm/{farm_id}/records
Create Record
Current records HTTP operation. External credential scopes: write:records; a typed traceability payload that carries identification.profile_update additionally requires 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. Legacy creation requires at least one animal_ids or group_ids entry attached to an active entity in this farm. Typed creation supplies traceability and requires an opaque request_key (1-200 characters); it does not require those associations. The 201 response is the created record for legacy creation or a { "event": ... } envelope for typed creation. Associations must name active entities in this farm; the service filters out ids outside that set. Supply ids obtained from the same farm.
Parameter In Required Schema farm_id path Yes {"type":"string","format":"uuid"}
Request body (application/json)
Field Type Presence Constraints (variant 1) JSON Required (variant 2) (variant 1) JSON Required (variant 2) (variant 1).animal_ids JSON Required minItems: 1 (variant 2) (variant 2) JSON Required (variant 2) (variant 2).group_ids JSON Required minItems: 1
json example Copy example
{
"animal_ids": [
"11111111-1111-4111-8111-111111111111"
],
"group_ids": [],
"name": "Example observation",
"type": "OTHER",
"applied_at": "2026-09-01T12:00:00.000Z"
}
Request example
bash example Copy example
curl --fail-with-body -X POST \
'https://api.ranch.bot/v1/farm/<farm_id>/records' \
-H "Authorization: Bearer $RANCHBOT_TOKEN" \
-H "Content-Type: application/json" \
--data '{"animal_ids":["11111111-1111-4111-8111-111111111111"],"group_ids":[],"name":"Example observation","type":"OTHER","applied_at":"2026-09-01T12:00:00.000Z"}'
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 (variant 1) object Required (variant 1).type string Required enum: ["OTHER","FEED","GENETIC","HEALTH","MOVEMENT"] (variant 1).id string Required (variant 1).created_at string Required format: "date-time" (variant 1).updated_at string Required format: "date-time" (variant 1).name string Required (variant 1).is_active boolean Required (variant 1).description (variant 1) null Required (variant 1).description (variant 2) string Required (variant 1).applied_at string Required format: "date-time" (variant 2) object Required (variant 2).event object Required
json example Copy example
{
"type": "OTHER",
"id": "11111111-1111-4111-8111-111111111111",
"created_at": "2026-09-01T12:00:00.000Z",
"updated_at": "2026-09-01T12:00:00.000Z",
"name": "Example",
"is_active": true,
"description": null,
"applied_at": "2026-09-01T12:00:00.000Z"
}
Legacy record response
json example Copy example
{
"type": "OTHER",
"id": "11111111-1111-4111-8111-111111111111",
"created_at": "2026-09-01T12:00:00.000Z",
"updated_at": "2026-09-01T12:00:00.000Z",
"name": "Example",
"is_active": true,
"description": null,
"applied_at": "2026-09-01T12:00:00.000Z"
}
Typed traceability event response
json example Copy example
{
"event": {
"id": "44444444-4444-4444-8444-444444444444",
"kind": "SALE",
"status": "ACTIVE",
"current_revision": 1
}
}
DELETE /v1/farm/{farm_id}/records/{record_id}
Delete Record
Current records HTTP operation. External credential scopes: write:records. 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"} record_id path Yes {"type":"string","format":"uuid"}
Request example
bash example Copy example
curl --fail-with-body -X DELETE \
'https://api.ranch.bot/v1/farm/<farm_id>/records/<record_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}/records/{record_id}
Get Record
Current records HTTP operation. External credential scopes: 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"} record_id path Yes {"type":"string","format":"uuid"}
Request example
bash example Copy example
curl --fail-with-body -X GET \
'https://api.ranch.bot/v1/farm/<farm_id>/records/<record_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 type string Required enum: ["OTHER","FEED","GENETIC","HEALTH","MOVEMENT"] id string Required created_at string Required format: "date-time" updated_at string Required format: "date-time" name string Required is_active boolean Required description (variant 1) null Required description (variant 2) string Required applied_at string Required format: "date-time" farm_id (variant 1) null Optional farm_id (variant 2) string Optional format: "uuid" subtype (variant 1) null Optional subtype (variant 2) string Optional enum: ["BIRTH"] revision integer Optional record_revisions array Optional record_revisions[] object Required record_revisions[].id string Optional format: "uuid" record_revisions[].revision integer Optional record_revisions[].operation string Optional record_revisions[].reason (variant 1) null Optional record_revisions[].reason (variant 2) string Optional record_revisions[].actor_user_id (variant 1) null Optional record_revisions[].actor_user_id (variant 2) string Optional format: "uuid" record_revisions[].created_at string Optional format: "date-time" birth_event (variant 1) null Optional birth_event (variant 2) object Optional birth_event (variant 2).id string Optional format: "uuid" birth_event (variant 2).dam_id string Optional format: "uuid" birth_event (variant 2).birth_date string Optional format: "date-time" birth_event (variant 2).time_precision (variant 1) null Optional birth_event (variant 2).time_precision (variant 2) string Optional birth_event (variant 2).total_born (variant 1) null Optional birth_event (variant 2).total_born (variant 2) integer Optional birth_event (variant 2).offspring array Optional birth_event (variant 2).offspring[] object Required record_items array Required record_items[] object Required record_items[].id (variant 1) string Required record_items[].id (variant 2) null Required record_items[].description (variant 1) string Required record_items[].description (variant 2) null Required record_items[].is_active (variant 1) boolean Required record_items[].is_active (variant 2) null Required record_items[].metadata (variant 1) JSON Required record_items[].metadata (variant 2) null Required record_items[].name (variant 1) string Required record_items[].name (variant 2) null Required record_items[].created_at (variant 1) string Required format: "date-time" record_items[].created_at (variant 2) null Required record_items[].updated_at (variant 1) string Required format: "date-time" 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 animals array Required animals[] object Required animals[].id string Required groups array Required groups[] object Required groups[].id string Required
json example Copy example
{
"type": "OTHER",
"id": "11111111-1111-4111-8111-111111111111",
"created_at": "2026-09-01T12:00:00.000Z",
"updated_at": "2026-09-01T12:00:00.000Z",
"name": "Example",
"is_active": true,
"description": null,
"applied_at": "2026-09-01T12:00:00.000Z",
"record_items": [],
"files": [],
"animals": [],
"groups": []
}
PUT /v1/farm/{farm_id}/records/{record_id}
Update Record
Current records HTTP operation. External credential scopes: write:records. 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. Provided association ids are connected to the record; they do not replace the entire association set.
Parameter In Required Schema farm_id path Yes {"type":"string","format":"uuid"} record_id path Yes {"type":"string","format":"uuid"}
Request body (application/json)
Field Type Presence Constraints animal_ids array Optional default: [] animal_ids[] string Required format: "uuid" group_ids array Optional default: [] group_ids[] string Required format: "uuid" description string Optional name string Optional type string Optional enum: ["FEED","GENETIC","HEALTH","MOVEMENT","OTHER"] applied_at string Optional format: "date-time"
json example Copy example
{}
Request example
bash example Copy example
curl --fail-with-body -X PUT \
'https://api.ranch.bot/v1/farm/<farm_id>/records/<record_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 type string Required enum: ["OTHER","FEED","GENETIC","HEALTH","MOVEMENT"] id string Required created_at string Required format: "date-time" updated_at string Required format: "date-time" name string Required is_active boolean Required description (variant 1) null Required description (variant 2) string Required applied_at string Required format: "date-time"
json example Copy example
{
"type": "OTHER",
"id": "11111111-1111-4111-8111-111111111111",
"created_at": "2026-09-01T12:00:00.000Z",
"updated_at": "2026-09-01T12:00:00.000Z",
"name": "Example",
"is_active": true,
"description": null,
"applied_at": "2026-09-01T12:00:00.000Z"
}
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 Copy example
{
"success": false,
"errors": [
{
"code": 400,
"name": "ValidationError",
"message": "Example validation failure"
}
]
}