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

# Submit a WebM Video File for Per-Frame Attention Analysis

> Upload a .webm video to EyeQuant using a presigned storage URL and poll for per-frame visual attention analysis results across every frame.

EyeQuant's video analysis lets you run machine perception predictions across every frame of a recorded screen capture or design walkthrough. You upload your `.webm` file to a secure presigned storage URL associated with your account, then create an analysis that references that upload. Once processing completes, you receive per-frame attention predictions you can use to evaluate your video content.

<Note>
  Video files must meet the following requirements before upload:

  * **Format:** `.webm` only
  * **Size:** 100 MB or less
  * **Duration:** 60 seconds or less
</Note>

<Steps>
  <Step title="Set up authentication">
    Install the `requests` library if you haven't already, then define a `BearerTokenAuth` helper class that attaches your API token to every request. Create a persistent session so your credentials carry across all subsequent calls.

    ```python theme={null}
    import requests
    import json
    import time
    import os
    import sys

    access_token = "YOUR-API-ACCESS-TOKEN"
    base_url = "https://api.eyequant.com/v2"

    class BearerTokenAuth(requests.auth.AuthBase):
        def __init__(self, access_token):
            self.access_token = access_token

        def __call__(self, request):
            request.headers["Authorization"] = "Bearer {}".format(self.access_token)
            return request

    api = requests.Session()
    api.auth = BearerTokenAuth(access_token)
    ```
  </Step>

  <Step title="Request a presigned upload URL">
    Before you can upload your video, you need a presigned URL pointing to the secure storage bucket associated with your EyeQuant account. Fetch one by sending a `GET` request to `/v2/upload-urls`.

    ```python theme={null}
    upload_url_response = api.get(
        base_url + "/upload-urls",
        data=json.dumps({}),
        headers={"Content-Type": "application/json"},
    )
    upload_url = upload_url_response.json()["url"]
    ```

    The `url` value in the response is the destination for your video file in the next step.
  </Step>

  <Step title="Upload the video file">
    Send a `PUT` request directly to the presigned URL with your video's raw binary content as the request body. Note that this request goes to the presigned storage URL — not to the EyeQuant API — so you do not need to include your API token here.

    ```python theme={null}
    with open("VIDEO.webm", "rb") as video_file:
        response = requests.put(upload_url, data=video_file.read())
        response.raise_for_status()
    ```
  </Step>

  <Step title="Create the analysis">
    With the video now uploaded, create a video analysis by sending a `POST` request to `/v2/analyses/video`. Pass the same presigned `upload_url` as the `content` field so EyeQuant knows where to find your file.

    ```python theme={null}
    analysis_configuration = {
        "input": {
            "content": upload_url,
            "title": "Video Analysis",
        }
    }
    create_response = api.post(
        base_url + "/analyses/video",
        data=json.dumps(analysis_configuration),
        headers={"Content-Type": "application/json"},
    )
    create_response.raise_for_status()
    analysis_url = create_response.json()["location"]
    ```

    Save the `location` value from the response — you'll poll that URL to track progress.
  </Step>

  <Step title="Poll for results">
    Video processing takes longer than image or URL analysis depending on the length and size of your file. Poll the `analysis_url` every 30 seconds until the `status` field is no longer `pending`.

    ```python theme={null}
    analysis = {"status": "pending"}
    while analysis["status"] == "pending":
        time.sleep(30)
        analysis_response = api.get(analysis_url)
        analysis_response.raise_for_status()
        analysis = analysis_response.json()

    if analysis["status"] == "success":
        print("Video analysis complete!")
    ```

    When `status` is `success`, the response body contains your per-frame prediction outputs.
  </Step>
</Steps>

<Note>
  Video analysis may take several minutes to complete, depending on the duration and file size of your upload. Poll the status endpoint every 30 seconds rather than more frequently to avoid unnecessary requests.
</Note>
