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

# Get Video Details

> Get detailed information about a specific video

## Overview

This endpoint retrieves comprehensive details about a specific video, including status, URL, duration, and metadata. Use this to monitor individual video progress or retrieve video information for display.

<Info>
  This endpoint requires authentication and only returns videos that belong to your team.
</Info>

## Path Parameters

<ParamField path="videoId" type="string" required>
  The unique identifier of the video to retrieve
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET "https://api.hooked.so/v1/video/vid_abc123" \
    -H "x-api-key: your_api_key_here"
  ```

  ```javascript Node.js theme={null}
  const videoId = 'vid_abc123';
  const response = await fetch(`https://api.hooked.so/v1/video/${videoId}`, {
    headers: { 'x-api-key': 'your_api_key_here' }
  });

  const data = await response.json();
  console.log(`Video status: ${data.data.status}`);
  console.log(`Duration: ${data.data.durationInSeconds}s`);
  ```

  ```python Python theme={null}
  import requests

  video_id = 'vid_abc123'
  response = requests.get(
      f'https://api.hooked.so/v1/video/{video_id}',
      headers={'x-api-key': 'your_api_key_here'}
  )

  data = response.json()['data']
  print(f"Video status: {data['status']}")
  print(f"Duration: {data['durationInSeconds']}s")
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "success": true,
    "message": "Video details fetched successfully",
    "data": {
      "id": "vid_abc123",
      "name": "Product Tutorial",
      "type": "class",
      "status": "COMPLETED",
      "url": "https://s3.amazonaws.com/hooked-videos/vid_abc123.mp4",
      "thumbnail": "https://cdn.hooked.so/thumbnails/abc123.jpg",
      "progress": 100,
      "message": "Video completed successfully",
      "durationInFrames": 7500,
      "durationInSeconds": 300,
      "avatarId": "avatar_sarah_01",
      "voiceId": "tzX5paJ07p5hyWFcU3uG",
      "musicId": "1",
      "videoSettings": {
        "aspectRatio": "ratio_9_16",
        "caption": {
          "disabled": false,
          "preset": "classic"
        }
      },
      "script": "Hello! Welcome to this tutorial...",
      "projectId": "proj_abc123",
      "createdAt": "2024-01-15T10:00:00Z",
      "updatedAt": "2024-01-15T10:05:00Z",
      "usedCredits": 5,
      "webhook": null
    }
  }
  ```
</ResponseExample>

## Response Fields

<ResponseField name="success" type="boolean">
  Indicates if the request was successful
</ResponseField>

<ResponseField name="message" type="string">
  Status message
</ResponseField>

<ResponseField name="data" type="object">
  <Expandable title="Video Object">
    <ResponseField name="id" type="string">
      Unique video identifier
    </ResponseField>

    <ResponseField name="name" type="string">
      Video name/title
    </ResponseField>

    <ResponseField name="type" type="string">
      Video type (class, ugc\_ads, ugc\_video, script\_to\_video, prompt\_to\_video, hook\_demo, product\_ads, scenes, add\_captions, extend\_video, remove\_background, tiktok\_slideshow)
    </ResponseField>

    <ResponseField name="status" type="string">
      Current video status: `STARTED`, `COMPLETED`, or `FAILED`
    </ResponseField>

    <ResponseField name="url" type="string">
      Signed S3 URL to download the video (only available when status is COMPLETED)
    </ResponseField>

    <ResponseField name="thumbnail" type="string">
      URL to the video thumbnail image
    </ResponseField>

    <ResponseField name="progress" type="number">
      Processing progress percentage (0-100)
    </ResponseField>

    <ResponseField name="message" type="string">
      Current status message
    </ResponseField>

    <ResponseField name="durationInFrames" type="number">
      Video duration in frames (at 25 FPS)
    </ResponseField>

    <ResponseField name="durationInSeconds" type="number">
      Video duration in seconds
    </ResponseField>

    <ResponseField name="avatarId" type="string">
      ID of the avatar used in the video
    </ResponseField>

    <ResponseField name="voiceId" type="string">
      ID of the voice used for narration
    </ResponseField>

    <ResponseField name="musicId" type="string">
      ID of the background music track
    </ResponseField>

    <ResponseField name="videoSettings" type="object">
      Video configuration including aspect ratio and caption settings
    </ResponseField>

    <ResponseField name="script" type="string">
      The narration script used in the video
    </ResponseField>

    <ResponseField name="projectId" type="string">
      Associated project ID (if created from a project)
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO 8601 timestamp of creation
    </ResponseField>

    <ResponseField name="updatedAt" type="string">
      ISO 8601 timestamp of last update
    </ResponseField>

    <ResponseField name="usedCredits" type="number">
      Number of credits consumed by this video
    </ResponseField>

    <ResponseField name="webhook" type="string">
      Webhook URL for status notifications (if configured)
    </ResponseField>
  </Expandable>
</ResponseField>

## Error Responses

<ResponseExample>
  ```json Video Not Found theme={null}
  {
    "success": false,
    "message": "Video not found"
  }
  ```

  ```json Unauthorized Access theme={null}
  {
    "success": false,
    "message": "Video does not belong to the user"
  }
  ```

  ```json Unauthorized theme={null}
  {
    "success": false,
    "message": "Not authenticated"
  }
  ```
</ResponseExample>

## Status Codes

| Status       | Code | Description                      |
| ------------ | ---- | -------------------------------- |
| Success      | 200  | Video found and details returned |
| Not Found    | 404  | Video doesn't exist              |
| Forbidden    | 403  | Video belongs to another team    |
| Unauthorized | 403  | Invalid or missing API key       |
| Server Error | 500  | Internal server error            |

## Video Status States

<AccordionGroup>
  <Accordion title="STARTED" icon="spinner">
    Video is currently being processed. The `progress` field shows the current percentage.
  </Accordion>

  <Accordion title="COMPLETED" icon="check">
    Video processing finished successfully. The `url` field contains a signed URL to download the video. URL is valid for 24 hours.
  </Accordion>

  <Accordion title="FAILED" icon="xmark">
    Video processing failed. Check the `message` field for details about what went wrong.
  </Accordion>
</AccordionGroup>

## Downloading Videos

Once a video has status `COMPLETED`, the `url` field provides a signed S3 URL:

```javascript Download Example theme={null}
async function downloadVideo(videoId) {
  const response = await fetch(`https://api.hooked.so/v1/video/${videoId}`, {
    headers: { 'x-api-key': API_KEY }
  });

  const video = await response.json();

  if (video.data.status === 'COMPLETED') {
    // URL is pre-signed and ready to download
    window.location.href = video.data.url;
  }
}
```

## Polling for Completion

To monitor video progress, you can poll this endpoint:

```javascript Polling Example theme={null}
async function waitForVideoCompletion(videoId, maxWait = 300000) {
  const startTime = Date.now();
  const pollInterval = 5000; // Check every 5 seconds

  while (Date.now() - startTime < maxWait) {
    const response = await fetch(`https://api.hooked.so/v1/video/${videoId}`, {
      headers: { 'x-api-key': API_KEY }
    });

    const data = await response.json();
    const { status, progress } = data.data;

    console.log(`Progress: ${progress}%`);

    if (status === 'COMPLETED') {
      return data.data;
    } else if (status === 'FAILED') {
      throw new Error(`Video failed: ${data.data.message}`);
    }

    await new Promise(resolve => setTimeout(resolve, pollInterval));
  }

  throw new Error('Video rendering timeout');
}
```

<Info>
  **Better approach**: Use webhooks instead of polling. See [Video Webhook](/api-reference/video/webhook) for details.
</Info>

## Use Cases

<CardGroup cols={2}>
  <Card title="Progress Tracking" icon="chart-line">
    Monitor video rendering progress
  </Card>

  <Card title="Download Management" icon="download">
    Get download URLs for completed videos
  </Card>

  <Card title="Status Display" icon="info">
    Show video status in your dashboard
  </Card>

  <Card title="Error Handling" icon="alert">
    Detect and handle rendering failures
  </Card>
</CardGroup>

## Related Endpoints

<CardGroup cols={2}>
  <Card title="List Videos" icon="list" href="/api-reference/video/list">
    View all videos
  </Card>

  <Card title="Create Video" icon="plus" href="/api-reference/video/create">
    Create a new video
  </Card>

  <Card title="Video Webhook" icon="webhook" href="/api-reference/video/webhook">
    Handle video completion notifications
  </Card>
</CardGroup>


## OpenAPI

````yaml GET /v1/video/{videoId}
openapi: 3.0.0
info:
  title: Hooked API
  version: 1.0.0
  description: AI Video Generation API
servers:
  - url: https://api.hooked.so
security:
  - ApiKeyAuth: []
paths:
  /v1/video/{videoId}:
    get:
      tags: []
      summary: Retrieve Video Details
      description: >-
        Get detailed information about a specific video including status,
        duration, and download URL
      operationId: getVideoDetails
      parameters:
        - name: videoId
          in: path
          description: Video ID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Video details retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: Unique video identifier
                  name:
                    type: string
                    description: Video name/title
                  status:
                    type: string
                    enum:
                      - STARTED
                      - COMPLETED
                      - FAILED
                    description: Current video processing status
                  url:
                    type: string
                    description: >-
                      Signed URL to download the video (only available when
                      status is COMPLETED)
                  durationInFrames:
                    type: integer
                    description: Duration of the video in frames (at 25fps)
                  durationInSeconds:
                    type: number
                    description: >-
                      Duration of the video in seconds (calculated from
                      durationInFrames)
                  projectId:
                    type: string
                    nullable: true
                    description: Associated project ID if video belongs to a project
                  teamId:
                    type: string
                    description: Team ID that owns this video
                  thumbnail:
                    type: string
                    nullable: true
                    description: URL to video thumbnail image
                  size:
                    type: integer
                    description: Video file size in bytes
                  progress:
                    type: integer
                    minimum: 0
                    maximum: 100
                    description: Processing progress percentage (0-100)
                  message:
                    type: string
                    nullable: true
                    description: Status message or error details
                  createdAt:
                    type: string
                    format: date-time
                    description: Video creation timestamp
                  updatedAt:
                    type: string
                    format: date-time
                    description: Last update timestamp
        '403':
          description: Video does not belong to the authenticated user
        '404':
          description: Video not found
      security:
        - ApiKeyAuth: []
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````