<track>. Each observation combines a timestamp with spatial geometry. Use this for object trajectories, motion review, or video overlays.
Tracking uses the chat completions endpoint. Request the object and track format in your prompt, and use vision_config.annotation_format: "box" for bounding boxes. The response contains markup in message.content.
Track an object
Installperceptron>=0.4.0 and set PERCEPTRON_API_KEY. This example uses the public basketball video from the Perceptron cookbook.
asset_idx="0" selects the first media asset. It is optional: the model can omit it from the track even though this prompt requests it. Without an explicit or inherited selector, the track refers to the last asset available when it was produced, which is video 0 in this request. For several videos, request explicit selectors and apply the same last-asset default when a selector is missing.
Each t is a time within the selected video; each box gives top-left and bottom-right coordinates. For several objects, ask for separate tracks and describe how to distinguish them.
See the annotation reference for the full grammar. Avoid passing the answer through an ordinary HTML parser: HTML treats track as a void element and can discard its grouping.
Stream a tracking answer
SSE chunks are transport boundaries. A chunk may end inside a tag, attribute, timestamp, or coordinate. The simplest reliable consumer accumulates text and validates the finish reason before parsing it. Run this after definingclient and request above:
final, including usage from a trailing chunk with an empty choices array. Network and API errors can interrupt the loop; allow them to fail the operation rather than treating the accumulated prefix as a complete answer. A "length" finish reason means the output budget was exhausted, even if some waypoints are usable.
For live overlays, an incremental annotation parser can emit fully closed child observations while retaining the surrounding track context. Keep these provisional results separate from the final answer. Never append closing tags to make truncated output look complete; retain the completed observations and mark the track incomplete.
Parse the tracks
The SDK parses annotation markup without HTML’s special treatment of<track>. Run this after the non-streaming request above, or use final in place of response after streaming:
strict=True raises reported parse errors, but it is not a complete schema validator. Retain the raw text and validate annotation syntax and selectors before using parsed results; see rendering annotations. resolve_asset_idx() preserves an explicit 0, applies inherited selectors, and uses the last asset in this response’s request when no selector is present. Keep the response associated with that request’s media; later turns do not change its asset indices. Validate normalized coordinate ranges, box ordering, and timestamps against the source video before drawing. Parsing does not establish whether an observation is correct or within the video’s duration.
Turn waypoints into an overlay
The model supplies observations, which may be sparse. To render them:- Resolve an explicit or inherited selector, or default to the last asset available when the track was produced. Confirm the selected asset is a video and use its displayed dimensions.
- Validate the timestamps and normalized geometry, then sort observations by time.
- Draw at observed timestamps. If needed, interpolate between nearby observations of the same object.
- Stop or mark the overlay uncertain across long gaps, occlusion, or a scene cut.
Improve tracking prompts
- Identify the target with visible properties and an initial location, such as “the red car in the left lane at the start.”
- State whether you want the whole object, a component, or its center. Choose
boxorpointto match that task. - Ask for positions only while the object is visible. A missing observation is preferable to an invented trajectory.
- Narrow the video interval or number of requested objects if the answer repeatedly reaches the output limit.
- Keep timestamps in seconds when authoring annotations. Input
video_frames.timestamp_msuses milliseconds; convert explicitly when connecting the two.