---
title: "Full video bundle for the detail / qa pages."
method: GET
path: "/api/v1/videos/{video_id}"
tags: ["Videos"]
---

# Full video bundle for the detail / qa pages.

`GET /api/v1/videos/{video_id}`

## Request

- Base URL: `https://api.avatarfactory.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.avatarfactory.io/api/v1/videos/{video_id}`
- Auth: one of:
  - API key in cookie `session`
  - HTTP bearer

## Path parameters

- `video_id` integer, required

## Response `200`

OK

- VideoDetailResponse
  - `approval_status` string, nullable
  - `assets` VideoAssetItem[]
    - `duration_seconds` number, nullable
    - `file_size_bytes` integer, nullable
    - `id` integer, required
    - `kind` string, required
    - `label` string, nullable
    - `scene_index` integer, nullable
    - `source_image` string, nullable
    - `video_file` string, nullable
  - `audio_file` string, nullable
  - `avatar` GalleryAvatar
    - `face_focus` FaceFocusPoint: Where a square or circular crop of a face image has to look. Percentages of the FULL stored frame, so the SPA can hand them straight to a CSS ``object-position``. Written by ``app.modules.avatars.face_focus``; absent (``None``) when no face was detected, and the shared `AvatarFace` component then falls back to its upper-third default.
      - `x` number, required
      - `y` number, required
    - `face_image` string, nullable
    - `id` integer, required
    - `name` string, nullable
  - `avatar_id` integer, nullable
  - `background` GalleryBackground
    - `id` integer, required
    - `image_file` string, nullable
    - `name` string, nullable
  - `background_id` integer, nullable
  - `caption_cuts` CaptionCut[]
    - `position` string, nullable
    - `style` string, required
    - `video_file` string, required
  - `captions_ready` boolean
  - `clean_master_file` string, nullable
  - `completed_at` string, date-time, nullable
  - `composition_json` string, nullable
  - `created_at` string, date-time, nullable
  - `draft_id` integer, nullable
  - `duration_seconds` number, nullable
  - `error_message` string, nullable
  - `estimated_duration_seconds` number, nullable
  - `final_video_file` string, nullable
  - `has_post` boolean
  - `heygen_video_id` string, nullable
  - `id` integer, required
  - `ig_account` VideoIgAccount
    - `account_name` string, nullable
    - `id` integer, required
    - `platform` string, nullable
  - `ig_caption` string, nullable
  - `needs_rebuild` boolean
  - `original_video_file` string, nullable
  - `publishing` VideoPublishing: Bundle of per-platform publish state for the Publishing card.
    - `instagram` PlatformPublishState: Per-platform publish state for the Publishing card. `connected` is true only when the avatar has a matching row in `social_accounts` for the platform. `posted` is true only when a `Post` exists for this video AND its status is "published" AND the avatar is connected · all three must hold so the UI never renders a green "Published" badge when one of the underlying facts is missing (the bug Piece C fixes).
      - `account_name` string, nullable
      - `connected` boolean
      - `posted` boolean
    - `tiktok` PlatformPublishState: Per-platform publish state for the Publishing card. `connected` is true only when the avatar has a matching row in `social_accounts` for the platform. `posted` is true only when a `Post` exists for this video AND its status is "published" AND the avatar is connected · all three must hold so the UI never renders a green "Published" badge when one of the underlying facts is missing (the bug Piece C fixes).
      - `account_name` string, nullable
      - `connected` boolean
      - `posted` boolean
  - `raw_video_file` string, nullable
  - `render_error` string, nullable
  - `render_strategy` string, nullable
  - `script_text` string, nullable
  - `segments` VideoSegment[]
    - `text` string, nullable
  - `shots` VideoShotItem[]
    - `action_lead_seconds` number, nullable
    - `awaiting_review` boolean
    - `candidate_clip` string, nullable
    - `chain_guard_reason` string, nullable
    - `chain_start` string, nullable
    - `doing` string, nullable
    - `identity_score` number, nullable
    - `identity_verdict` string, nullable
    - `model` string, required
    - `reroll_cost` number, nullable
    - `scene_image` string, nullable
    - `scene_source` string, nullable
    - `scene_title` string, nullable
    - `seconds` number, nullable
    - `shot_index` integer, required
    - `status` string, nullable
    - `transcript` string, nullable
  - `shots_submitted` integer, nullable
  - `source_reel` SourceReelItem: The reel a cloned video was copied from (Clone-a-Reel), shown as the detail page's Source Reel rail card (Lior, 2026-08-15). None of this is fabricated: url + duration come from the cached ingest, thumb is the first analyzed source frame, shot_count is the analysis's shot list, and ingest_id powers the instant Copy Again handoff.
    - `cloned_at` string, date-time, nullable
    - `duration_seconds` number, nullable
    - `ingest_id` integer, required
    - `shot_count` integer, nullable
    - `thumb` string, nullable
    - `url` string, required
  - `status` string, nullable
  - `supports_caption_styles` boolean
  - `template_id` string, nullable
  - `text_style` string, nullable
  - `thumbnail_file` string, nullable
  - `title` string, nullable

## Other responses

- `404`: Not Found
- `422`: Unprocessable Entity

---

[API](https://skmtc.dev/avatarfactory/apis/avatarfactory-api.md) · [All operations](https://skmtc.dev/avatarfactory/apis/avatarfactory-api/llms.txt) · [OpenAPI document](https://skmtc.dev/avatarfactory/apis/avatarfactory-api/revisions/66fc7aa3f296?raw)
