Farm reports API
HTTP reference for farm reports. Read authentication and access before using these operations. All examples use made-up data and placeholder credentials.
GET /v1/farm/{farm_id}/reports/agristability
Get Agri Stability Schedule
Current farm reports HTTP operation. External credential scopes: read:records. Minimum farm role: READER. Production rate limit: 100 requests per 15-minute window, per legacy key, 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"} |
| year | query | No | {"type":"integer","minimum":1900,"maximum":9999} |
Request example
curl --fail-with-body -X GET \
'https://api.ranch.bot/v1/farm/<farm_id>/reports/agristability' \
-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 |
|---|---|---|---|
| farm | object | Required | |
| farm.id | string | Required | |
| farm.name | string | Required | |
| farm.species | string | Required | |
| year | number | Required | |
| generatedAt | string | Required | |
| schedule | object | Required | |
| schedule.year | number | Required | |
| schedule.period | object | Required | |
| schedule.period.start | string | Required | |
| schedule.period.end | string | Required | |
| schedule.opening | number | Required | |
| schedule.births | number | Required | |
| schedule.purchases | number | Required | |
| schedule.deaths | number | Required | |
| schedule.sales | number | Required | |
| schedule.closing | number | Required | |
| schedule.headDays | number | Required | |
| schedule.averageHead | number | Required | |
| schedule.birthEvents | number | Required | |
| schedule.saleEvents | number | Required | |
| priorYearClosing | number | Required | |
| continuity | object | Required | |
| continuity.openingMatchesPriorClosing | boolean | Required | |
| continuity.breakHead | number | Required | |
| continuity.notes | array | Required | |
| continuity.notes[] | string | Required | |
| gaps | array | Required | |
| gaps[] | string | Required | |
| byGroup | array | Required | |
| byGroup[] | object | Required | |
| byGroup[].group | object | Required | |
| byGroup[].group.id (variant 1) | null | Required | |
| byGroup[].group.id (variant 2) | string | Required | |
| byGroup[].group.name | string | Required | |
| byGroup[].closing | number | Required |
{
"farm": {
"id": "11111111-1111-4111-8111-111111111111",
"name": "Example",
"species": "example"
},
"year": 1,
"generatedAt": "example",
"schedule": {
"year": 1,
"period": {
"start": "example",
"end": "example"
},
"opening": 1,
"births": 1,
"purchases": 1,
"deaths": 1,
"sales": 1,
"closing": 1,
"headDays": 1,
"averageHead": 1,
"birthEvents": 1,
"saleEvents": 1
},
"priorYearClosing": 1,
"continuity": {
"openingMatchesPriorClosing": true,
"breakHead": 1,
"notes": []
},
"gaps": [],
"byGroup": []
}GET /v1/farm/{farm_id}/reports/inventory
Get Inventory Report
Current farm reports HTTP operation. External credential scopes: read:records. Minimum farm role: READER. Production rate limit: 100 requests per 15-minute window, per legacy key, 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"} |
| preset | query | No | {"type":"string","enum":["month","quarter","year","custom"],"default":"month"} |
| from | query | No | {"type":"string"} |
| to | query | No | {"type":"string"} |
Request example
curl --fail-with-body -X GET \
'https://api.ranch.bot/v1/farm/<farm_id>/reports/inventory' \
-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 |
|---|---|---|---|
| farm | object | Required | |
| farm.id | string | Required | |
| farm.name | string | Required | |
| farm.species | string | Required | |
| period | object | Required | |
| period.start | string | Required | |
| period.end | string | Required | |
| generatedAt | string | Required | |
| totals | object | Required | |
| totals.opening | number | Required | |
| totals.births | number | Required | |
| totals.purchases | number | Required | |
| totals.deaths | number | Required | |
| totals.sales | number | Required | |
| totals.transfers | number | Required | |
| totals.closing | number | Required | |
| byGroup | array | Required | |
| byGroup[] | object | Required | |
| byGroup[].group | object | Required | |
| byGroup[].group.id (variant 1) | null | Required | |
| byGroup[].group.id (variant 2) | string | Required | |
| byGroup[].group.name | string | Required | |
| byGroup[].opening | number | Required | |
| byGroup[].births | number | Required | |
| byGroup[].purchases | number | Required | |
| byGroup[].deaths | number | Required | |
| byGroup[].sales | number | Required | |
| byGroup[].transfers | number | Required | |
| byGroup[].closing | number | Required | |
| byCategory | object | Required | |
| reconciliation | object | Required | |
| reconciliation.closingCount | number | Required | |
| reconciliation.ledgerAdditions | number | Required | |
| reconciliation.ledgerRemovals | number | Required | |
| reconciliation.animalAdditions | number | Required | |
| reconciliation.additionsDrift | number | Required | |
| reconciliation.drift | boolean | Required | |
| reconciliation.notes | array | Required | |
| reconciliation.notes[] | string | Required | |
| unclassifiedRecords | array | Required | |
| unclassifiedRecords[] | object | Required | |
| unclassifiedRecords[].id | string | Required | |
| unclassifiedRecords[].name | string | Required | |
| unclassifiedRecords[].type | string | Required | |
| unclassifiedRecords[].applied_at | string | Required | |
| unclassifiedRecords[].headCount | number | Required | |
| records | array | Required | |
| records[] | object | Required | |
| records[].id | string | Required | |
| records[].name | string | Required | |
| records[].description (variant 1) | null | Required | |
| records[].description (variant 2) | string | Required | |
| records[].type | string | Required | |
| records[].applied_at | string | Required | |
| records[].category | string | Required | enum: ["BIRTH","PURCHASE","DEATH","SALE","TRANSFER","OTHER"] |
| records[].groupIds | array | Required | |
| records[].groupIds[] | string | Required | |
| records[].headCount | number | Required | |
| records[].headCountKnown | boolean | Required | |
| preset | string | Required | enum: ["custom","month","quarter","year"] |
{
"farm": {
"id": "11111111-1111-4111-8111-111111111111",
"name": "Example",
"species": "example"
},
"period": {
"start": "example",
"end": "example"
},
"generatedAt": "example",
"totals": {
"opening": 1,
"births": 1,
"purchases": 1,
"deaths": 1,
"sales": 1,
"transfers": 1,
"closing": 1
},
"byGroup": [],
"byCategory": {},
"reconciliation": {
"closingCount": 1,
"ledgerAdditions": 1,
"ledgerRemovals": 1,
"animalAdditions": 1,
"additionsDrift": 1,
"drift": true,
"notes": []
},
"unclassifiedRecords": [],
"records": [],
"preset": "custom"
}Error body
Validation and authentication errors generally use this envelope. Rate-limit errors omit data; OAuth polling also has protocol-specific errors shown in its reference.
{
"success": false,
"errors": [
{
"code": 400,
"name": "ValidationError",
"message": "Example validation failure"
}
]
}