---
title: "Get creative analysis for several videos"
method: GET
path: "/videos/analysis"
tags: ["Video Intelligence"]
---

# Get creative analysis for several videos

`GET /videos/analysis`

The batch form of GET /videos/{video_id}/analysis — same payload per video, up to 100 ids per call. Pass `video_ids` once per id (`?video_ids=A&video_ids=B`).

Unlike the single-video route this never 404s: ids that do not belong to this shop are listed in `not_found`, while owned-but-unanalyzed videos appear in `data` with `analyzed: false`. Use it to check analysis coverage across a set of videos in one round trip.

Only videos belonging to the calling key's shop are readable; any other `video_id` returns 404. Single-shop only — set `x-shop-id` to one shop ID.

## Query parameters

- `video_ids` string[], required — Repeatable video id (max 100 per request).
- `include_experimental` boolean — Attach the analyzer's full scored-feature block as `features_experimental`.

## Response `200`

Successful Response

- VideoAnalysisBatchResponse
  - `data` VideoAnalysis[], required
    - `video_id` string, required
    - `analyzed` boolean, required — False when the shop owns this video but the pipeline has not analyzed it yet — every other field is then null.
    - `analysis_source` string, nullable — `video` for a full-motion analysis, `thumbnail` for a still-frame one. Thumbnail analyses carry no transcript and no motion features.
    - `analysis_version` integer, nullable — Analyzer version that produced this row.
    - `analyzed_at` string, date-time, nullable
    - `transcript` string, nullable — Spoken-audio transcript of the video.
    - `transcript_language` string, nullable
    - `transcript_duration_s` number, nullable
    - `transcript_source` string, nullable — `uvi` when the transcript came from the analyzer, `video_transcripts` when it came from the shop's transcript store.
    - `hook_summary` string, nullable — One-line description of how the video opens.
    - `structure_outline` string[], nullable — Ordered beats of the video (e.g. Hook, Demo, CTA).
    - `on_screen_text` string, nullable — On-screen text (OCR), all segments joined into one string. Null when the video has no on-screen text.
    - `vision_tags` unknown
    - `detected_products` unknown
    - `features` object, nullable — Stable scored creative features: `hook_present_first_3s`, `has_product_demo`, `solution_shown`, `has_voiceover`, `video_pace`, `content_summary`. Members the analyzer could not score are omitted rather than returned as null.
    - `features_experimental` object, nullable — Only present with `include_experimental=true`: the analyzer's full scored-feature block. Unstable — members are added, renamed and removed as the analyzer changes, so do not build on it without pinning the fields you read.
  - `not_found` string[], required — Requested `video_ids` that do not belong to this shop. Videos that are owned but unanalyzed appear in `data` with `analyzed: false`.

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/reacherapp/apis/reacher-data-api.md) · [All operations](https://skmtc.dev/reacherapp/apis/reacher-data-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/reacherapp/reacher-data-api/revisions/5eefff009b5b/schema)
