API - Response reference.
A successful call to POST /api/public/detect returns HTTP 200 with a JSON body describing everything found in your image or video. This page documents every field.
The response shape is the same for both the EU and global models — only the species vocabulary differs (deepfaune_label_en for eu, SpeciesNet common names for global).
Example response (image)
json
{
"species": {
"red deer": 2
},
"metadata": {
"photo_id": "ca947365-cbd7-4651-bfc3-b7a505f99b33",
"camera_id": "b5fd3fef-7d54-4c14-86d2-699187eb0728"
},
"has_human": false,
"n_animals": 2,
"n_persons": 0,
"detections": [
{
"box": [0.7787, 0.4361, 0.9992, 0.7783],
"label": "animal",
"antlers": "no",
"species": "red deer",
"confidence": 0.909
},
{
"box": [0.0594, 0.2822, 0.1589, 0.4604],
"label": "animal",
"antlers": "yes",
"species": "red deer",
"sex_hint": "likely_male",
"antler_box": [0.0898, 0.1735, 0.1156, 0.2697],
"confidence": 0.522
}
],
"media_type": "image",
"n_vehicles": 0,
"needs_review": false
}
Top-level fields
Field | Type | Description |
|---|---|---|
| string |
|
| object | A summary map of species name → count, aggregated across the capture. In the example, two red deer were found, so |
| integer | Total number of animals detected. |
| integer | Number of people detected. |
| integer | Number of vehicles detected. |
| boolean |
|
| boolean |
|
| array | One entry per detected object (animal, person or vehicle). See below. |
| object | Echoed back from your request unchanged. Whatever you send in |
The detections array
Each element describes one detected object.
Field | Type | Present when | Description |
|---|---|---|---|
| number[4] | always | Bounding box |
| string | always | The detection category: |
| number | always | Model confidence for this detection, 0–1. In the example the standing deer scored 0.909; the second, partly obscured, 0.522. |
| string | animals only | The recognised species, in the model's vocabulary (e.g. |
| string | checked deer only |
|
| string |
| Always |
| number[4] |
| Bounding box of the antlers, same format as |
Person and vehicle detections carry a
boxandlabelbut nospeciesor antler fields.
Bounding boxes
All boxes — box and antler_box — use the same format: four numbers [x1, y1, x2, y2], each between 0 and 1, measured from the top-left of the full image. This makes them resolution-independent, so the same response works whether you render a thumbnail or the full-size image.
To convert a box to pixels for drawing an overlay:
js
const [x1, y1, x2, y2] = det.box;
const left = x1 * imageWidth;
const top = y1 * imageHeight;
const width = (x2 - x1) * imageWidth;
const height = (y2 - y1) * imageHeight;
// draw a rectangle at (left, top) of size width × heightantler_box is drawn exactly the same way and, when present, marks where the antlers are.
Antler and sex fields
Antler detection is deliberately conservative, and the response reflects that:
antlers: "yes"is the only value that addssex_hint: "likely_male"and anantler_box. Treat it as likely, not certain.antlers: "uncertain"contributes toneeds_reviewso you can take a closer look.antlers: "no"(or the absence of antler fields) never implies a female animal — a doe, cast antlers, or a turned or cropped head simply can't be judged.
Only the deer species you enable for antler checking will carry these fields; all other animals omit them.
needs_review
This flag is true when the result contains something worth a human glance, typically:
an
"uncertain"antler call, ora recognised species that falls outside the allow-list you sent in
species(or your profile defaults).
A flagged result is still returned in full — needs_review simply tells your application to route it for confirmation rather than treat it as final.
Video responses
A video request returns the same top-level fields with media_type: "video", where the counts (species, n_animals, …) are aggregated across the sampled frames, plus additional frame-level detail (a representative key frame and a per-frame breakdown). The exact frame fields are documented separately — see the video example in the docs.
HTTP status
A 200 response always carries the JSON above. Any non-200 status indicates a problem (authentication, credits, validation, etc.) — see the Errors reference for the full list and how to handle each.
Is this article helpful?