> ## Documentation Index
> Fetch the complete documentation index at: https://docs.perceptron.inc/llms.txt
> Use this file to discover all available pages before exploring further.

# Multilook

> Ask independent questions over shared media in one request.

Use Multilook when several independent prompts share the same images, video, or audio. The endpoint reuses the shared context within the call and returns one result per prompt. For one question involving several media items, use ordinary chat completions with [multiple assets](/perceptron-mk1.5/guides/multiple-assets) instead.

## Send independent prompts

Install `perceptron>=0.4.0` and set `PERCEPTRON_API_KEY` as shown in the [quickstart](/perceptron-mk1.5/index).

<CodeGroup>
  ```python Python theme={null}
  from perceptron import Client, video

  client = Client(provider="perceptron")
  response = client.chat.completions.multilook(
      model="perceptron-mk1.5",
      context=[{
          "role": "user",
          "content": [video(
              "https://raw.githubusercontent.com/perceptron-ai-inc/perceptron/"
              "main/cookbook/_shared/assets/tutorials/isaac_frame_by_frame/surf.mp4"
          )],
      }],
      prompts=[
          "Describe the setting in one sentence.",
          "Describe the surfers' actions in chronological order.",
      ],
      n=1,
      reasoning_effort="high",
      max_completion_tokens=1024,
  )

  for result in response.results:
      if not result.ok:
          error = result.error.message if result.error else "No completions returned"
          print(f"Prompt {result.prompt_index} failed: {error}")
          continue
      for completion in result.completions:
          if not completion.complete:
              print(f"Prompt {result.prompt_index} incomplete: {completion.finish_reason}")
              continue
          print(result.prompt_index, completion.text)

  if response.usage is not None:
      print("Input tokens:", response.usage.prompt_tokens)
      print("Cached input tokens:", response.usage.cached_tokens)
      print("Audio input tokens:", response.usage.audio_tokens)
  ```

  ```bash curl theme={null}
  curl https://api.perceptron.inc/v1/chat/completions/multilook \
    -H "Authorization: Bearer $PERCEPTRON_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "perceptron-mk1.5",
      "context": [{
        "role": "user",
        "content": [{
          "type": "video_url",
          "video_url": {"url": "https://raw.githubusercontent.com/perceptron-ai-inc/perceptron/main/cookbook/_shared/assets/tutorials/isaac_frame_by_frame/surf.mp4"}
        }]
      }],
      "prompts": [
        "Describe the setting in one sentence.",
        "Describe the surfers actions in chronological order."
      ],
      "n": 1,
      "reasoning_effort": "high",
      "max_completion_tokens": 1024
    }'
  ```
</CodeGroup>

Each entry in `results` identifies its `prompt_index` and contains either `completions` or an `error`. Inspect each result separately; one prompt can fail while another succeeds. Check each completion's `finish_reason` before treating its content as complete.

The SDK exposes `completion.text`, `completion.reasoning`, and `completion.complete`. For Multilook, `complete` accepts `stop` and `interrupted`; a `length` finish is incomplete. Request-level failures raise an SDK exception; per-prompt failures remain in `response.results`.

## Set reasoning for the whole request

Set the top-level `reasoning_effort` to `none`, `minimal`, `low`, `medium`, or `high`. A tier other than `none` enables reasoning; `minimal` currently maps to `low`. The selected tier applies to **every prompt and all `n` completions** in the request. Per-prompt effort settings are not supported; group prompts into separate requests if they need different tiers.

The example uses `high` for both questions. Each completion keeps its final answer in `message.content` and any returned reasoning in `message.reasoning_content`. Reasoning consumes that completion's `max_completion_tokens` budget, so leave room for the answer and check its `finish_reason`.

The SDK rejects an unsupported effort value before sending the request. If sent directly to the API, it rejects the whole request with HTTP 400 and a message naming `reasoning_effort`, rather than returning a separate error for each prompt.

The deprecated `vision_config.enable_thinking` flag, when supplied, overrides whether reasoning is enabled for every prompt. `false` keeps reasoning off even with `high`; `true` enables reasoning even with `none`, which then leaves the tier unpinned. Omit the old flag when using `reasoning_effort`. See [Reasoning](/perceptron-mk1.5/capabilities/thinking) for output handling and effort selection.

## Audio and video soundtracks

Shared user context and structured prompts accept `input_audio`, `audio_url`, and `audio_file_id` parts. For example, put a recording in the shared context and ask separate prompts for a transcript and a summary. See [Audio](/perceptron-mk1.5/capabilities/audio) for the input shapes and supported formats.

For videos with soundtracks, set top-level `vision_config: {"enable_audio_in_video": true}`. This opt-in applies across the request's video parts; standalone audio does not need it. Audio token limits still apply, and individual prompts can fail with `audio_token_limit_exceeded`; inspect every result's `error` before using its completions.

## Context and asset indexing

Each prompt sees the shared `context` followed by its own content. Prompts do not see each other's inputs or answers. Compute `asset_idx` separately for each context-plus-prompt sequence: shared assets come first, followed by that prompt's media.

Put media reused across prompts in `context`. A prompt can also contain its own content parts, but that media is outside the reusable prefix. File references work in both places.

For SDK responses, call `completion.annotations()` to parse an answer and `completion.resolve_asset_idx(annotation)` to resolve one of its flattened annotations. The completion retains its own context-plus-prompt asset count, including the last-asset fallback when `asset_idx` is omitted.

## Limits and compatibility

* Send up to 16 prompts. `n` can be 1–8, with at most 64 completions per call. `n > 1` requires a positive `temperature`.
* Multilook does not stream and does not support `response_format` or `stop`.
* It does not support function declarations, `tool_choice`, `parallel_tool_calls`, assistant tool calls, or tool-result history. Use chat completions for a [tool loop](/perceptron-mk1.5/guides/tool-calling).
* Keep dependent questions in a multi-turn chat; independent Multilook prompts cannot consume another prompt's answer.

The response reports aggregate `usage`. `prompt_tokens_details.cached_tokens` is the subset of prompt tokens served from the shared prefill within that request. See the [Mk1.5 pricing table](/perceptron-mk1.5/models/perceptron-mk1.5#pricing) for the cache-read rate. Reuse within one call does not promise a cache hit on a later request.

Aggregate `usage.prompt_tokens_details.audio_tokens` reports audio input across the call and is already part of `prompt_tokens`. Multilook reports zero if the upstream audio breakdown is absent. Per-prompt usage contains completion-token counts, so use the call-level usage once for input accounting.
