v2 responses & errors

The API v2 reference lets you browse the endpoints interactively. This page covers the request rules, response fields and error codes in detail.

  • Base path: /v2
  • Content type: application/json for requests and responses
  • Authentication: api-key header (Authentication)
  • Machine-readable spec (public): GET /v2/openapi.json (OpenAPI 3.1). Interactive docs are at /v2/docs (Swagger UI) and /v2/redoc. The spec declares the api-key header as the ApiKeyAuth security scheme and uses stable operation IDs predict and predict_with_model, suitable for generating client SDKs.

Request notes

POST /v2/predict

Analyse one image with the latest model.

Headers

Header Required Description
api-key Yes Your API key
Content-Type Yes application/json
X-Request-ID No Your own request ID (Request IDs)

Request body

Field Type Required Description
image string Yes Base64-encoded image (Image best practices). Must not be empty.
threshold number or null No Discomfort threshold, 0.0 ≤ threshold ≤ 1.0 (integers 0 and 1 accepted). Must be a JSON number. Strings ("0.5"), booleans, NaN, and Infinity are rejected. If omitted or null, the model's default is used.

Unknown fields in the request body are ignored.

{
  "image": "/9j/4AAQSkZJRgABAQAAAQABAAD...",
  "threshold": 0.5
}

Response 200 OK: see Response schema.

Errors: 400, 401, 422, 500 (Errors).

POST /v2/models/{model_id}/predict

Identical to POST /v2/predict, but uses the model you name.

Path parameter Type Description
model_id string Model identifier, e.g. bc-v1 (Choosing a model in v2)

Headers, body, and response are the same as POST /v2/predict. An unknown model_id returns 404 model_not_found.

curl -X POST "$BASE_URL/v2/models/bc-v1/predict" \
  -H "api-key: $API_KEY" -H "Content-Type: application/json" \
  --data @body.json

Response schema

Every key below is always present. Keys that don't apply are null, never missing.

Field Type Description
request_id string Request ID (also in the X-Request-ID header)
model object Model that produced the result
model.id string Model identifier, e.g. "bc-v1"
model.version string Sylvester service release version, e.g. "0.0.34"
detection string "detected", "low_confidence", or "not_detected" (Detection)
prediction object | null Present only when detection is "detected"
prediction.label string "comfort" or "discomfort"
prediction.score number Probability of discomfort, 0.0–1.0
prediction.threshold number Threshold applied. label is "discomfort" when score > threshold.
cat object | null The detected cat (detected) or best candidate (low_confidence); null when not_detected
cat.bounding_box object x_min, y_min, x_max, y_max (integers, pixels; Bounding box coordinates)
cat.detection_confidence number Detector confidence for this cat, 0.0–1.0
image object The decoded input image
image.width integer Width in pixels
image.height integer Height in pixels

More attributes may be added inside cat in future (for example coat colour or estimated age), each shaped as { "value": ..., "confidence": ... }. Ignore keys you don't use.

Response examples

Cat detected

{
  "request_id": "req_743a78dbedca420f9ab7dac5dd0df7d7",
  "model": { "id": "bc-v1", "version": "0.0.34" },
  "detection": "detected",
  "prediction": {
    "label": "discomfort",
    "score": 0.32395651936531067,
    "threshold": 0.3
  },
  "cat": {
    "bounding_box": { "x_min": 56, "y_min": 74, "x_max": 1005, "y_max": 1013 },
    "detection_confidence": 0.9662923216819763
  },
  "image": { "width": 1028, "height": 1028 }
}

Low confidence: a cat-like object was found, but not clearly enough to classify

{
  "request_id": "smoke-1",
  "model": { "id": "bc-v1", "version": "0.0.34" },
  "detection": "low_confidence",
  "prediction": null,
  "cat": {
    "bounding_box": { "x_min": 4, "y_min": 74, "x_max": 1013, "y_max": 775 },
    "detection_confidence": 0.6602507829666138
  },
  "image": { "width": 1028, "height": 1028 }
}

No cat detected

{
  "request_id": "req_0b7c2d0e8e1d4a5f9c3b6a1e2d4f8a90",
  "model": { "id": "bc-v1", "version": "0.0.34" },
  "detection": "not_detected",
  "prediction": null,
  "cat": null,
  "image": { "width": 1920, "height": 1080 }
}

Errors

All v2 errors (4xx/5xx generated by the API) share one shape:

{
  "request_id": "req_60b465463f52493c8c085a5e74445c67",
  "error": {
    "code": "invalid_image",
    "message": "Image is not valid base64.",
    "details": {}
  }
}
Field Type Description
request_id string Same as the X-Request-ID response header
error.code string Stable, machine-readable code. Branch on this.
error.message string Human-readable explanation. The wording may change, so don't parse it.
error.details object Extra structured information; {} when there is none

Error codes

HTTP code When message examples details
400 invalid_image Not valid base64, empty, not a decodable image, or unsupported bit depth Image is not valid base64. · Image is empty. · Image could not be decoded. · Unsupported pixel format; send an 8-bit image. {}
401 unauthorized Missing or invalid api-key Invalid or missing API key. {}
404 model_not_found Unknown model_id Model 'bc-v9' does not exist. {"model_id": "bc-v9"}
404 not_found Unknown path under /v2 Not Found {}
405 method_not_allowed Wrong HTTP method (the Allow response header lists valid methods) Method Not Allowed {}
422 invalid_request Body missing, malformed JSON, missing image, invalid threshold Request validation failed. {"errors": [{"field": "...", "message": "..."}]}
500 internal_error Unexpected server failure An internal error occurred. {}
other 4xx http_error Other protocol-level errors varies {}

New codes may be added. Treat unknown codes by their HTTP status.

422 examples

Missing image:

{
  "request_id": "doc-example-1",
  "error": {
    "code": "invalid_request",
    "message": "Request validation failed.",
    "details": {
      "errors": [ { "field": "image", "message": "Field required" } ]
    }
  }
}

threshold out of range (1.5):

{
  "request_id": "doc-example-1",
  "error": {
    "code": "invalid_request",
    "message": "Request validation failed.",
    "details": {
      "errors": [ { "field": "threshold", "message": "Input should be less than or equal to 1" } ]
    }
  }
}

threshold sent as a string ("0.5"):

{ "field": "threshold", "message": "Input should be a valid number" }

Malformed JSON body:

{ "field": "body", "message": "JSON decode error" }

details.errors[].field names the request field (image, threshold), or body when the body as a whole is the problem. The submitted values are never echoed back in error responses.