Structured JSON Output & HTTP Response Headers

Reference specification for the JSON payload and binary image headers returned by POST /api/analyze.

Interactive OpenAPI Specifications: Explore and test all endpoints directly from your browser.

1. Top-Level JSON Structure (output_format="json")

When calling POST /api/analyze with output_format="json" (default), the response has the following structure:

Field Type Description
success boolean true when analysis completed normally.
sport string Resolved canonical sport key: "basket", "foot", "handball", or "usfootball".
image_info object Input image dimensions: width (px), height (px), and original filename.
performance object Execution latency breakdown in seconds (see Section 2 below).
homography object 2D court calibration metadata: computed (bool), source ("onnx_keypoints_ransac", "vlm_landmarks_ransac", or "perspective_fallback"), visible_court_side ("left", "right", "full"), inliers_count, and the 3×3 matrix.
detections object Categorized object detections: players, goalkeepers, referees, ball, goal_or_basket, and field_marks (see Section 3).
landmarks array Detected court keypoints in pixel coordinates (x, y) with label, confidence, and source ("onnx_model", "vlm_prior", or "goal_bbox_anchor").
token_usage object VLM token consumption and cost: prompt_tokens, candidates_tokens, thoughts_tokens, total_tokens, cost_usd, and model.

2. Performance & Latency Block (performance)

Every JSON response includes exact server-side timing (in seconds) for each stage of the pipeline:

Field Type Description
vlm_inference_seconds float Time spent waiting for the VLM API (OpenRouter / Google Gemini).
court_homography_seconds float Time spent running ONNX keypoint detection, RANSAC homography estimation, and 2D player projection.
team_classification_seconds float Time spent classifying player/goalkeeper teams (T0/T1, T0-GK/T1-GK) and active/bench filtering.
warm_pipeline_seconds float Total end-to-end processing time for the request (in seconds).

3. Player & Goalkeeper Detection Objects (detections.players / detections.goalkeepers)

Field Type Units / Values Description
bbox [x1, y1, x2, y2] Pixels (px) 2D bounding box in image pixel coordinates.
ground_point_px [x, y] Pixels (px) Estimated floor contact point (Z = 0) in the image.
team 0 | 1 Team ID Assigned team index (0 = Team 0 / Cyan, 1 = Team 1 / Pink).
label string "T0", "T1", "T0-GK", "T1-GK" Display label distinguishing outfield players and goalkeepers.
role string "player" | "goalkeeper" Tactical role on the court/pitch.
court_position_cm [X_cm, Y_cm] Centimeters (cm) Projected 2D top-down radar coordinates from top-left corner (0, 0) of the canonical court:
• Basketball (NBA): 2865 × 1524 cm
• Football (Soccer): 12000 × 7000 cm
• Handball (IHF): 4000 × 2000 cm
• US Football (NFL): 10973 × 4877 cm
is_on_court boolean true | false true if the player is active on the court (drawn on the 2D radar); false if on the bench / out-of-bounds.
jersey_number string | null e.g. "24" Recognized jersey number when legible.

4. HTTP Headers When Returning an Image Directly (output_format="image" | "annotated")

When calling POST /api/analyze with output_format="image" (or "side_by_side", "annotated", or return_image=true), the HTTP response body is the raw binary image/jpeg file, and key telemetry metrics are returned in custom HTTP response headers:

HTTP Response Header Example Value Description
Content-Type image/jpeg MIME type of the returned visualization image.
X-Detected-Sport basket Resolved sport key used for analysis and radar drawing.
X-Homography-Source onnx_keypoints_ransac Method used to compute the 2D radar homography.
X-Players-Count 10 Total number of detected players.
X-Goalkeepers-Count 0 Total number of detected goalkeepers (T0-GK / T1-GK).
X-Processing-Time-Seconds 34.6587 Total warm pipeline execution time in seconds (performance.warm_pipeline_seconds).
X-VLM-Inference-Seconds 33.914 VLM inference time in seconds (performance.vlm_inference_seconds).
X-Estimated-Cost-USD 0.0283635 VLM API call cost in USD (token_usage.cost_usd).

Example curl Inspecting Image Headers

curl -D - -X POST http://localhost:8001/api/analyze \
  -F "image=@tests/basket/basket-01.png" \
  -F "sport=basket" \
  -F "output_format=image" \
  -o basket_side_by_side.jpg