{
    "openapi": "3.0.3",
    "info": {
        "title": "ACARiS Cow API",
        "version": "cow-v1",
        "description": "Read-only access to one farm's ACARiS results (animals, pens, lameness and body condition scores, current alerts) in the ICAR Animal Data Exchange (ADE) format. One API key belongs to exactly one farm. Keys are created in the ACARiS dashboard under Einstellungen → Betrieb → API-Zugang. Use is subject to the API terms. Quick guide: https://acaris.net/en_us/api-docs/ (DE: https://acaris.net/de_de/api-docs/).",
        "termsOfService": "https://acaris.net/de_de/api-terms/",
        "contact": {
            "email": "support@acaris.net"
        }
    },
    "externalDocs": {
        "description": "ICAR ADE resource definitions",
        "url": "https://github.com/adewg/ICAR/tree/ADE-1"
    },
    "servers": [
        {
            "url": "https://acaris.net/api/cow/v1/index.php"
        }
    ],
    "security": [
        {
            "bearer": []
        },
        {
            "apiKey": []
        }
    ],
    "components": {
        "securitySchemes": {
            "bearer": {
                "type": "http",
                "scheme": "bearer",
                "description": "Authorization: Bearer acr_…"
            },
            "apiKey": {
                "type": "apiKey",
                "in": "header",
                "name": "X-Api-Key",
                "description": "Alternative to the Authorization header."
            }
        },
        "parameters": {
            "scheme": {
                "name": "location-scheme",
                "in": "path",
                "required": true,
                "schema": {
                    "type": "string",
                    "enum": [
                        "net.acaris.farm"
                    ]
                }
            },
            "id": {
                "name": "location-id",
                "in": "path",
                "required": true,
                "description": "Your farm ID, as returned by /locations.",
                "schema": {
                    "type": "string"
                }
            },
            "limit": {
                "name": "limit",
                "in": "query",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 500,
                    "default": 100
                }
            },
            "offset": {
                "name": "offset",
                "in": "query",
                "schema": {
                    "type": "integer",
                    "minimum": 0,
                    "default": 0
                }
            },
            "from": {
                "name": "from",
                "in": "query",
                "description": "RFC 3339, UTC. Default: to minus 7 days.",
                "schema": {
                    "type": "string",
                    "format": "date-time"
                }
            },
            "to": {
                "name": "to",
                "in": "query",
                "description": "RFC 3339, UTC, exclusive. Default: now. At most 31 days after from.",
                "schema": {
                    "type": "string",
                    "format": "date-time"
                }
            }
        },
        "schemas": {
            "View": {
                "type": "object",
                "properties": {
                    "totalItems": {
                        "type": "integer"
                    },
                    "totalPages": {
                        "type": "integer"
                    },
                    "pageSize": {
                        "type": "integer"
                    },
                    "currentPage": {
                        "type": "integer"
                    },
                    "first": {
                        "type": "string"
                    },
                    "next": {
                        "type": "string"
                    },
                    "prev": {
                        "type": "string"
                    },
                    "last": {
                        "type": "string"
                    }
                }
            },
            "Collection": {
                "type": "object",
                "description": "ICAR resource collection. member items follow the ICAR resource named in each path; ACARiS-specific fields are in acarisExtension.",
                "properties": {
                    "view": {
                        "$ref": "#/components/schemas/View"
                    },
                    "member": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    }
                }
            },
            "Errors": {
                "type": "object",
                "description": "ICAR error collection (RFC 7807).",
                "properties": {
                    "errors": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "type": {
                                    "type": "string"
                                },
                                "severity": {
                                    "type": "string"
                                },
                                "status": {
                                    "type": "integer"
                                },
                                "title": {
                                    "type": "string"
                                },
                                "detail": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        },
        "responses": {
            "Collection": {
                "description": "ICAR collection",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Collection"
                        }
                    }
                }
            },
            "Error": {
                "description": "Error (400 invalid parameter, 401 invalid key, 403 scope_missing / bcs_not_booked / terms_not_accepted, 404 not found, 429 rate limited: 60 requests per minute per key)",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Errors"
                        }
                    }
                }
            }
        }
    },
    "paths": {
        "/locations": {
            "get": {
                "summary": "The farm this key belongs to (icarLocationResource)",
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Collection"
                    },
                    "401": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/locations/{location-scheme}/{location-id}/animals": {
            "get": {
                "summary": "Active animals (icarAnimalCoreResource). Data area: animals.",
                "description": "identifier: official ear tag as eu.bovine; alternativeIdentifiers: eu.animalId (numeric) and net.acaris.barnnumber. acarisExtension: lactation number, calving / dry-off / insemination / pregnancy-check / last hoof trim dates, current pen.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/scheme"
                    },
                    {
                        "$ref": "#/components/parameters/id"
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/offset"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Collection"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/locations/{location-scheme}/{location-id}/animal-sets": {
            "get": {
                "summary": "Pens with their animals (icarAnimalSetResource, purpose Enclosure). Data area: animals.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/scheme"
                    },
                    {
                        "$ref": "#/components/parameters/id"
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/offset"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Collection"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/locations/{location-scheme}/{location-id}/conformation-scores": {
            "get": {
                "summary": "Lameness (traitScored Locomotion) and body condition (traitScored BodyConditionScore) scores (icarConformationScoreEventResource).",
                "description": "Data areas: lameness, bcs. BCS only if booked for the farm; header X-Acaris-Bcs: not_booked when it is left out. Scores are on ACARiS scales (lameness 1-5 in 0.5 steps, BCS 1-5 in 0.25 steps), stated in acarisExtension.scale. Ordered by eventDateTime.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/scheme"
                    },
                    {
                        "$ref": "#/components/parameters/id"
                    },
                    {
                        "$ref": "#/components/parameters/from"
                    },
                    {
                        "$ref": "#/components/parameters/to"
                    },
                    {
                        "name": "trait",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "Locomotion",
                                "BodyConditionScore"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/offset"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Collection"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/locations/{location-scheme}/{location-id}/attention-events": {
            "get": {
                "summary": "Current open alerts (icarAttentionEventResource, category Health, causes Lameness or BodyCondition). Data area: alerts.",
                "description": "The alerts the ACARiS dashboard shows the farm right now. Lameness alerts carry the farm's follow-up status in acarisExtension.status (new, seen, trimmer_scheduled, vet_scheduled, recovering, aftercare_required, resolved, snoozed); ignored and recovered alerts are not listed. BCS alerts (score outside the farm's healthy range) only if BCS is booked and the key includes bcs. acarisExtension.lamenessListUpdated says when the lameness list was last recalculated.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/scheme"
                    },
                    {
                        "$ref": "#/components/parameters/id"
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/offset"
                    }
                ],
                "responses": {
                    "200": {
                        "$ref": "#/components/responses/Collection"
                    },
                    "default": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/service/status": {
            "get": {
                "summary": "Service health (no key needed)",
                "security": [],
                "responses": {
                    "200": {
                        "description": "ok"
                    }
                }
            }
        }
    }
}