Ranch.Bot
Skip to reference

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.

ParameterInRequiredSchema
farm_idpathYes{"type":"string","format":"uuid"}
skipqueryNo{"type":"integer"}
takequeryNo{"type":"integer"}
typequeryNo{"type":"string","enum":["FEED","GENETIC","HEALTH","MOVEMENT","OTHER"]} Filter by record type.
animal_idqueryNo{"type":"string","format":"uuid"} Direct saved records for one animal UUID, regardless of inventory status.
group_idqueryNo{"type":"string","format":"uuid"} Direct saved records for one same-farm group UUID (archived groups allowed).
include_group_contextqueryNo{"type":"boolean"} With animal_id, also include records attached to the animal's current active same-farm groups. Requires animal_id.
applied_fromqueryNo{"type":"string","format":"date-time"} Inclusive RFC3339 timestamp with an explicit timezone offset.
applied_beforequeryNo{"type":"string","format":"date-time"} Exclusive RFC3339 timestamp with an explicit timezone offset.

Request example

bash example
curl --fail-with-body -X GET \
  'https://api.ranch.bot/v1/farm/<farm_id>/records' \
  -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[].typestringRequiredenum: ["OTHER","FEED","GENETIC","HEALTH","MOVEMENT"]
records[].idstringRequired
records[].created_atstringRequiredformat: "date-time"
records[].updated_atstringRequiredformat: "date-time"
records[].namestringRequired
records[].is_activebooleanRequired
records[].description (variant 1)nullRequired
records[].description (variant 2)stringRequired
records[].applied_atstringRequiredformat: "date-time"
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
records[].filesarrayRequired
records[].files[]objectRequired
records[].files[].id (variant 1)stringRequired
records[].files[].id (variant 2)nullRequired
records[].files[].is_active (variant 1)booleanRequired
records[].files[].is_active (variant 2)nullRequired
records[].files[].mime_type (variant 1)stringRequired
records[].files[].mime_type (variant 2)nullRequired
records[].files[].name (variant 1)stringRequired
records[].files[].name (variant 2)nullRequired
records[].files[].size (variant 1)integerRequired
records[].files[].size (variant 2)nullRequired
records[].files[].url (variant 1)stringRequired
records[].files[].url (variant 2)nullRequired
records[].files[].created_at (variant 1)stringRequiredformat: "date-time"
records[].files[].created_at (variant 2)nullRequired
records[].files[].updated_at (variant 1)stringRequiredformat: "date-time"
records[].files[].updated_at (variant 2)nullRequired
records[].animalsarrayOptional
records[].animals[]objectRequired
records[].animals[].idstringOptional
records[].groupsarrayOptional
records[].groups[]objectRequired
records[].groups[].idstringOptional
records[].match_contextobjectOptional
records[].match_context.direct_animalbooleanOptional
records[].match_context.direct_groupbooleanOptional
records[].match_context.current_groupsarrayOptional
records[].match_context.current_groups[]objectRequired
records[].match_context.current_groups[].idstringOptional
records[].match_context.current_groups[].namestringOptional
records[].match_context.current_groups[].membership_at_eventJSONOptionalconst: "unknown"
scopeobjectOptional
scope.farm_idstringOptional
scope.animal_id (variant 1)stringOptional
scope.animal_id (variant 2)nullOptional
scope.group_id (variant 1)stringOptional
scope.group_id (variant 2)nullOptional
scope.include_group_contextbooleanOptional
scope.type (variant 1)stringOptional
scope.type (variant 2)nullOptional
scope.applied_from (variant 1)stringOptional
scope.applied_from (variant 2)nullOptional
scope.applied_before (variant 1)stringOptional
scope.applied_before (variant 2)nullOptional
scope.authorized_groupsarrayOptional
scope.authorized_groups[]objectRequired
scope.authorized_groups[].idstringOptional
scope.authorized_groups[].namestringOptional
scope.datasetstringOptional
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}/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.

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

Request body (application/json)

FieldTypePresenceConstraints
(variant 1)JSONRequired
(variant 2) (variant 1)JSONRequired
(variant 2) (variant 1).animal_idsJSONRequiredminItems: 1
(variant 2) (variant 2)JSONRequired
(variant 2) (variant 2).group_idsJSONRequiredminItems: 1
json 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
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

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
(variant 1)objectRequired
(variant 1).typestringRequiredenum: ["OTHER","FEED","GENETIC","HEALTH","MOVEMENT"]
(variant 1).idstringRequired
(variant 1).created_atstringRequiredformat: "date-time"
(variant 1).updated_atstringRequiredformat: "date-time"
(variant 1).namestringRequired
(variant 1).is_activebooleanRequired
(variant 1).description (variant 1)nullRequired
(variant 1).description (variant 2)stringRequired
(variant 1).applied_atstringRequiredformat: "date-time"
(variant 2)objectRequired
(variant 2).eventobjectRequired
json 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
{
  "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
{
  "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).

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

Request example

bash example
curl --fail-with-body -X DELETE \
  'https://api.ranch.bot/v1/farm/<farm_id>/records/<record_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}/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.

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

Request example

bash example
curl --fail-with-body -X GET \
  'https://api.ranch.bot/v1/farm/<farm_id>/records/<record_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
typestringRequiredenum: ["OTHER","FEED","GENETIC","HEALTH","MOVEMENT"]
idstringRequired
created_atstringRequiredformat: "date-time"
updated_atstringRequiredformat: "date-time"
namestringRequired
is_activebooleanRequired
description (variant 1)nullRequired
description (variant 2)stringRequired
applied_atstringRequiredformat: "date-time"
farm_id (variant 1)nullOptional
farm_id (variant 2)stringOptionalformat: "uuid"
subtype (variant 1)nullOptional
subtype (variant 2)stringOptionalenum: ["BIRTH"]
revisionintegerOptional
record_revisionsarrayOptional
record_revisions[]objectRequired
record_revisions[].idstringOptionalformat: "uuid"
record_revisions[].revisionintegerOptional
record_revisions[].operationstringOptional
record_revisions[].reason (variant 1)nullOptional
record_revisions[].reason (variant 2)stringOptional
record_revisions[].actor_user_id (variant 1)nullOptional
record_revisions[].actor_user_id (variant 2)stringOptionalformat: "uuid"
record_revisions[].created_atstringOptionalformat: "date-time"
birth_event (variant 1)nullOptional
birth_event (variant 2)objectOptional
birth_event (variant 2).idstringOptionalformat: "uuid"
birth_event (variant 2).dam_idstringOptionalformat: "uuid"
birth_event (variant 2).birth_datestringOptionalformat: "date-time"
birth_event (variant 2).time_precision (variant 1)nullOptional
birth_event (variant 2).time_precision (variant 2)stringOptional
birth_event (variant 2).total_born (variant 1)nullOptional
birth_event (variant 2).total_born (variant 2)integerOptional
birth_event (variant 2).offspringarrayOptional
birth_event (variant 2).offspring[]objectRequired
record_itemsarrayRequired
record_items[]objectRequired
record_items[].id (variant 1)stringRequired
record_items[].id (variant 2)nullRequired
record_items[].description (variant 1)stringRequired
record_items[].description (variant 2)nullRequired
record_items[].is_active (variant 1)booleanRequired
record_items[].is_active (variant 2)nullRequired
record_items[].metadata (variant 1)JSONRequired
record_items[].metadata (variant 2)nullRequired
record_items[].name (variant 1)stringRequired
record_items[].name (variant 2)nullRequired
record_items[].created_at (variant 1)stringRequiredformat: "date-time"
record_items[].created_at (variant 2)nullRequired
record_items[].updated_at (variant 1)stringRequiredformat: "date-time"
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
animalsarrayRequired
animals[]objectRequired
animals[].idstringRequired
groupsarrayRequired
groups[]objectRequired
groups[].idstringRequired
json 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.

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

Request body (application/json)

FieldTypePresenceConstraints
animal_idsarrayOptionaldefault: []
animal_ids[]stringRequiredformat: "uuid"
group_idsarrayOptionaldefault: []
group_ids[]stringRequiredformat: "uuid"
descriptionstringOptional
namestringOptional
typestringOptionalenum: ["FEED","GENETIC","HEALTH","MOVEMENT","OTHER"]
applied_atstringOptionalformat: "date-time"
json example
{}

Request example

bash 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

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
typestringRequiredenum: ["OTHER","FEED","GENETIC","HEALTH","MOVEMENT"]
idstringRequired
created_atstringRequiredformat: "date-time"
updated_atstringRequiredformat: "date-time"
namestringRequired
is_activebooleanRequired
description (variant 1)nullRequired
description (variant 2)stringRequired
applied_atstringRequiredformat: "date-time"
json 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
{
  "success": false,
  "errors": [
    {
      "code": 400,
      "name": "ValidationError",
      "message": "Example validation failure"
    }
  ]
}