Reserve space for output
Setmax_completion_tokens to the output budget for each request. It is an upper bound, not a requested answer length. Reasoning, the final answer, annotation markup, and generated function arguments consume this budget.
Plan for both constraints:
reasoning_effort does not increase max_completion_tokens.
Chat completions rejects a request if its input plus requested output budget exceeds the context window, or if max_completion_tokens exceeds the model’s output limit. Leave room for the desired output; increasing the output limit alone cannot make an oversized conversation fit.
Image token counting
Images are decoded and processed into visual patches. The processed spatial grid determines their visual token count. Resizing, aspect ratio, minimum and maximum image budgets, and patch grouping affect that grid.- Compressed file size is not a token count. Saving the same dimensions as a smaller JPEG does not proportionally reduce visual tokens.
- Large images may be resized, and small images may be upscaled. Source dimensions alone do not establish the exact processed token count.
- Each supplied image contributes to the input, including reference images and images returned by tools. Uploading a file once avoids repeated upload work; it does not make later model input free.
- Cropping to a relevant region can improve detail per request, but the crop is another input if you also send the original image.
usage.prompt_tokens on representative Mk1.5 requests using the same prompts, tools, image dimensions, and aspect ratios as your application. That number includes the complete input, not only the image. Resolution-to-token tables for another model do not account for Mk1.5’s preprocessing.
Video token counting
Video token use depends on the frames processed and their spatial resolution. Frames are grouped temporally and spatially, so multiplying a standalone image estimate by the source video’s frame rate is not an accurate video-token calculation. For avideo_url or video_file_id, the model processes sampled frames across the selected video. A frame cap reduces sampling density over longer footage; it does not mean that only the beginning of the video is analyzed. The visual budget can also limit per-frame resolution.
With video_frames, you choose the input images and timestamps, but those frames still undergo video preprocessing. Supplying fewer frames can omit a brief event; more frames can increase input cost and compete for visual detail. Neither duration nor frame count alone determines the final token total.
Use the video input guide for frame examples and timestamp conventions. For cost estimates, compare representative short and long clips, aspect ratios, and frame selections using reported usage. Measure the frame-selection strategy you intend to use rather than assuming a fixed number of tokens per second of source video.
Audio and soundtrack token counting
Standalone audio uses approximately 750 audio tokens per minute. A two-minute recording therefore contributes about 1,500 audio tokens, plus message formatting and text. File size, compression, and a text transcript’s length do not determine the audio-token count. Settingvision_config.enable_audio_in_video: true adds the video’s soundtrack to its visual input. Budget approximately 750 audio tokens per minute of processed soundtrack, plus timestamp text, on top of the frame tokens. The option must be explicitly set to true; omitting it or setting it to false leaves soundtrack processing disabled. When enabled, an encoded audio track consumes audio tokens even if it contains only silence. A video with no audio stream or no soundtrack overlapping the processed interval falls back to visual input; video_frames has no soundtrack. See video soundtracks.
The current Mk1.5 limit is 16,384 audio tokens per item, roughly 21.8 minutes at that rate. This per-item cap is separate from the model’s 36,864-token context window: several individually valid recordings, or a video with both frames and audio, can exceed the shared context. Over-limit audio returns audio_token_limit_exceeded instead of being truncated. Split or shorten the recording; lowering the output budget does not change the per-item audio cap.
Use the rate to estimate capacity, then use reported usage for accounting. usage.prompt_tokens_details.audio_tokens includes standalone audio and opted-in soundtracks and is already included in prompt_tokens. It does not include all surrounding text overhead and is not an extra charge to add again. See Audio for input examples.
Tokens, media units, and asset indices
These are separate counts:
For example, one reference image followed by a
video_frames group containing 20 frames uses 21 media units and two asset positions: image 0, video 1. It does not use 21 tokens. The current request cap is 256 media units; staying below it does not guarantee that the tokenized input fits the context window.
See multiple assets for indexing across user messages and image tool results.
Read usage from a response
Installperceptron>=0.4.0 and set PERCEPTRON_API_KEY. This example prints the usage returned with an image answer and handles missing usage, cache, or audio breakdowns. The same handling applies to audio and video requests.
prompt_tokens measures input; completion_tokens measures generated output, including reasoning when used. total_tokens combines the two. Count the reported output, not only the length of message.content: reasoning and function arguments can be returned in separate fields.
When prompt_tokens_details.cached_tokens is present, it is a subset of prompt_tokens. Do not add it again to the total. Cached input still occupies context; its pricing is different. An absent breakdown does not establish a cache hit, and repeating a URL or request does not promise one.
The chat-completions audio breakdown is optional too. A missing or null audio_tokens value means the breakdown was not reported; it is not a measured zero. An explicit zero reports no audio tokens. Multilook instead defaults a missing upstream audio breakdown to zero, so zero alone cannot prove audio was skipped there. For multiple inputs, the aggregate cannot identify which particular video’s soundtrack was analyzed.
Multilook reports aggregate usage for independent prompts over shared context. Use its aggregate once when accounting for the request; do not add the same aggregate to every prompt result.
For streaming requests, send stream_options={"include_usage": True}. Usage may arrive after the last content delta in a chunk with choices: []. The SDK includes it in the completion returned by stream.get_final_completion() after consuming the stream. Read it independently of choice deltas if you handle chunks yourself, and avoid summing cumulative usage snapshots within one response. The tracking stream example shows this pattern.
Budget a tool conversation
Each model request in a tool loop has its own input and output usage. Previous assistant calls and tool results become input on later requests; tool-returned images contribute visual tokens too. Add usage across model requests to measure the whole workflow. Bound the number of rounds and the size of tool results, and reserve capacity for the final answer. Compact long retrieved text to the relevant evidence while keeping call/result pairs intact. If you remove or reorder media in history, update any affectedasset_idx references.
Handle an output limit
finish_reason: "length" means the generated response is incomplete. Do not treat a partial JSON object, track, or function argument string as a completed result.
Increase max_completion_tokens when both model limits and remaining context allow it. Otherwise reduce the input, shorten the requested answer, or split the task into smaller requests. For tracking, request fewer objects or a narrower interval rather than completing missing markup yourself.
Keep usage from incomplete responses when available: they still generated tokens. Review quality alongside usage when changing image resolution, frame sampling, reasoning effort, or output budgets.