> ## 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.

# Schedule Video

> Schedule a video for automatic publishing to social platforms

<Note>
  **Try it out!** Use the API playground on the right to test the Schedule Video endpoint directly.
</Note>

## Overview

Schedule a completed video for automatic publishing to a connected social platform. The video will be published at the specified time without any manual intervention.

This is perfect for:

* Building a content calendar
* Automating your publishing workflow
* Scheduling content for optimal posting times
* Bulk scheduling videos across platforms

<Info>
  Videos must be in **completed** status before they can be scheduled. Connect your social platforms in the [Hooked Dashboard](https://hooked.so/settings/integrations) first.
</Info>

***

## Endpoint

```
POST /v1/schedule/create
```

***

## Required Fields

<ParamField body="videoId" type="string" required>
  ID of the completed video to schedule. Get this from the video creation response or the `/v1/video/list` endpoint.
</ParamField>

<ParamField body="integrationId" type="string" required>
  ID of the connected social platform. Get available integrations from `/v1/integration/list`.
</ParamField>

<ParamField body="scheduledDateTime" type="string" required>
  ISO 8601 datetime for when to publish the video. Must be in the future.

  Example: `2024-03-15T14:00:00.000Z`
</ParamField>

***

## Optional Fields

<ParamField body="platformData" type="object">
  Platform-specific metadata for the post

  <Expandable title="Platform Data Object">
    <ParamField body="title" type="string">
      Post title (max 100 characters). Used for YouTube video titles.
    </ParamField>

    <ParamField body="description" type="string">
      Post description (max 5000 characters). Used for video descriptions and captions.
    </ParamField>

    <ParamField body="tags" type="array">
      Array of tags/hashtags (max 30). Platform-specific handling:

      * **YouTube**: Video tags
      * **TikTok/Instagram**: Appended as hashtags to description
    </ParamField>

    <ParamField body="privacyStatus" type="string" default="public">
      Privacy setting (YouTube only):

      * `public` - Anyone can view
      * `unlisted` - Only people with the link can view
      * `private` - Only you can view
    </ParamField>

    <ParamField body="madeForKids" type="boolean" default="false">
      Whether content is made for kids (YouTube only). Required for COPPA compliance.
    </ParamField>
  </Expandable>
</ParamField>

***

## Request Examples

### Basic Schedule

```javascript theme={null}
const response = await fetch('https://api.hooked.so/v1/schedule/create', {
  method: 'POST',
  headers: {
    'x-api-key': process.env.HOOKED_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    videoId: 'vid_abc123xyz',
    integrationId: 'int_yt_def456',
    scheduledDateTime: '2024-03-15T14:00:00.000Z'
  })
});

const data = await response.json();
console.log('Scheduled:', data.data.scheduleId);
```

### With Platform Data (YouTube)

```javascript theme={null}
const response = await fetch('https://api.hooked.so/v1/schedule/create', {
  method: 'POST',
  headers: {
    'x-api-key': process.env.HOOKED_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    videoId: 'vid_abc123xyz',
    integrationId: 'int_yt_def456',
    scheduledDateTime: '2024-03-15T14:00:00.000Z',
    platformData: {
      title: '10 Tips for Better Productivity',
      description: 'In this video, I share my top 10 productivity tips that have helped me work smarter, not harder.\n\nTimestamps:\n0:00 Intro\n0:30 Tip 1...',
      tags: ['productivity', 'tips', 'workflow', 'efficiency'],
      privacyStatus: 'public',
      madeForKids: false
    }
  })
});
```

### With Platform Data (TikTok/Instagram)

```javascript theme={null}
const response = await fetch('https://api.hooked.so/v1/schedule/create', {
  method: 'POST',
  headers: {
    'x-api-key': process.env.HOOKED_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    videoId: 'vid_abc123xyz',
    integrationId: 'int_tt_ghi789',
    scheduledDateTime: '2024-03-15T18:00:00.000Z',
    platformData: {
      description: 'This productivity hack changed everything!',
      tags: ['productivity', 'lifehack', 'tips', 'viral']
    }
  })
});
```

### Complete Workflow Example

```javascript theme={null}
async function createAndScheduleVideo() {
  // Step 1: Create a video
  const videoResponse = await fetch('https://api.hooked.so/v1/project/create/script-to-video', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.HOOKED_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      script: 'Your video script here...',
      voiceId: 'voice_confident',
      mediaType: 'ai-images'
    })
  });

  const { data: videoData } = await videoResponse.json();
  const videoId = videoData.videoId;

  // Step 2: Wait for video to complete (use webhooks in production!)
  // ...

  // Step 3: Get available integrations
  const integrationsResponse = await fetch('https://api.hooked.so/v1/integration/list', {
    headers: { 'x-api-key': process.env.HOOKED_API_KEY }
  });

  const { data: intData } = await integrationsResponse.json();
  const youtubeIntegration = intData.integrations.find(i => i.type === 'youtube');

  // Step 4: Schedule for tomorrow at 2 PM UTC
  const tomorrow = new Date();
  tomorrow.setDate(tomorrow.getDate() + 1);
  tomorrow.setHours(14, 0, 0, 0);

  const scheduleResponse = await fetch('https://api.hooked.so/v1/schedule/create', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.HOOKED_API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      videoId: videoId,
      integrationId: youtubeIntegration.id,
      scheduledDateTime: tomorrow.toISOString(),
      platformData: {
        title: 'My Awesome Video',
        description: 'Check out this video!',
        privacyStatus: 'public'
      }
    })
  });

  return await scheduleResponse.json();
}
```

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.hooked.so/v1/schedule/create" \
    -H "x-api-key: your_api_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "videoId": "vid_abc123xyz",
      "integrationId": "int_yt_def456",
      "scheduledDateTime": "2024-03-15T14:00:00.000Z",
      "platformData": {
        "title": "10 Tips for Productivity",
        "description": "Learn how to boost your productivity...",
        "tags": ["productivity", "tips"],
        "privacyStatus": "public"
      }
    }'
  ```

  ```python Python theme={null}
  import requests
  from datetime import datetime, timedelta

  # Schedule for tomorrow at 2 PM UTC
  scheduled_time = (datetime.utcnow() + timedelta(days=1)).replace(hour=14, minute=0, second=0)

  response = requests.post(
      'https://api.hooked.so/v1/schedule/create',
      headers={
          'x-api-key': 'your_api_key_here',
          'Content-Type': 'application/json'
      },
      json={
          'videoId': 'vid_abc123xyz',
          'integrationId': 'int_yt_def456',
          'scheduledDateTime': scheduled_time.isoformat() + 'Z',
          'platformData': {
              'title': '10 Tips for Productivity',
              'description': 'Learn how to boost your productivity...',
              'tags': ['productivity', 'tips'],
              'privacyStatus': 'public'
          }
      }
  )

  data = response.json()
  print('Schedule ID:', data['data']['scheduleId'])
  ```
</RequestExample>

***

## Response

<ResponseExample>
  ```json Success Response theme={null}
  {
    "success": true,
    "message": "Video scheduled successfully",
    "data": {
      "scheduleId": "post_abc123xyz",
      "status": "pending",
      "scheduledDateTime": "2024-03-15T14:00:00.000Z",
      "platform": "youtube",
      "videoId": "vid_abc123xyz"
    }
  }
  ```

  ```json Error - Video Not Completed theme={null}
  {
    "code": "bad_request",
    "message": "Video must be completed before scheduling",
    "details": {
      "videoStatus": "processing"
    }
  }
  ```

  ```json Error - Time in Past theme={null}
  {
    "code": "bad_request",
    "message": "Scheduled time must be in the future",
    "details": {
      "scheduledDateTime": "2024-03-01T14:00:00.000Z",
      "currentTime": "2024-03-10T10:00:00.000Z"
    }
  }
  ```

  ```json Error - Video Not Found theme={null}
  {
    "code": "not_found",
    "message": "Video not found",
    "details": {
      "resource_id": "vid_invalid",
      "resource_type": "Video"
    }
  }
  ```

  ```json Error - Integration Not Found theme={null}
  {
    "code": "not_found",
    "message": "Integration not found",
    "details": {
      "resource_id": "int_invalid",
      "resource_type": "Integration"
    }
  }
  ```
</ResponseExample>

***

## Platform-Specific Notes

### YouTube

| Field           | Requirement | Notes                                                         |
| --------------- | ----------- | ------------------------------------------------------------- |
| `title`         | Recommended | Max 100 characters. Falls back to video name if not provided. |
| `description`   | Recommended | Max 5000 characters. Supports line breaks and links.          |
| `tags`          | Optional    | Max 30 tags. Used for search discovery.                       |
| `privacyStatus` | Optional    | Defaults to `public`.                                         |
| `madeForKids`   | Optional    | Required for COPPA compliance. Defaults to `false`.           |

### TikTok

| Field         | Requirement | Notes                                             |
| ------------- | ----------- | ------------------------------------------------- |
| `description` | Recommended | Max 2200 characters. Hashtags are auto-extracted. |
| `tags`        | Optional    | Appended as hashtags to description.              |

### Instagram

| Field         | Requirement | Notes                                      |
| ------------- | ----------- | ------------------------------------------ |
| `description` | Recommended | Caption for the post. Max 2200 characters. |
| `tags`        | Optional    | Appended as hashtags to caption.           |

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Schedule Ahead" icon="calendar">
    Schedule at least 15 minutes in the future to allow for processing.
  </Card>

  <Card title="Use Optimal Times" icon="clock">
    Research your audience's active hours for better engagement.
  </Card>

  <Card title="Set Up Webhooks" icon="webhook">
    Get notified when posts are published or if publishing fails.
  </Card>

  <Card title="Include Metadata" icon="tag">
    Add titles, descriptions, and tags for better discoverability.
  </Card>
</CardGroup>

***

## Error Handling

| Error                                  | Description             | Solution                                               |
| -------------------------------------- | ----------------------- | ------------------------------------------------------ |
| `Video not found`                      | Invalid video ID        | Use a valid video ID from `/v1/video/list`             |
| `Integration not found`                | Invalid integration ID  | Use a valid integration ID from `/v1/integration/list` |
| `Video must be completed`              | Video still processing  | Wait for video to complete before scheduling           |
| `Scheduled time must be in the future` | Time has already passed | Use a future datetime                                  |
| `Video does not belong to your team`   | Wrong team              | Ensure you're using the correct API key                |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="List Scheduled" icon="list" href="/api-reference/schedule/list">
    View all your scheduled posts
  </Card>

  <Card title="Update Schedule" icon="edit" href="/api-reference/schedule/update">
    Change time or metadata
  </Card>

  <Card title="Cancel Schedule" icon="trash" href="/api-reference/schedule/delete">
    Cancel a scheduled post
  </Card>

  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Get notified on publish
  </Card>
</CardGroup>


## OpenAPI

````yaml POST /v1/schedule/create
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/schedule/create:
    post:
      tags:
        - Scheduling
      summary: Schedule Video
      description: Schedule a video for automatic publishing to social platforms
      operationId: createSchedule
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - videoId
                - integrationId
                - scheduledDateTime
              properties:
                videoId:
                  type: string
                  description: ID of the completed video to schedule
                integrationId:
                  type: string
                  description: ID of the connected social platform
                scheduledDateTime:
                  type: string
                  format: date-time
                  description: ISO 8601 datetime for publishing
                platformData:
                  type: object
                  properties:
                    title:
                      type: string
                      maxLength: 100
                    description:
                      type: string
                      maxLength: 5000
                    tags:
                      type: array
                      items:
                        type: string
                      maxItems: 30
                    privacyStatus:
                      type: string
                      enum:
                        - public
                        - private
                        - unlisted
                    madeForKids:
                      type: boolean
      responses:
        '201':
          description: Schedule created successfully
      security:
        - ApiKeyAuth: []
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````