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"
}
}'
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'])
{
"success": true,
"message": "Video scheduled successfully",
"data": {
"scheduleId": "post_abc123xyz",
"status": "pending",
"scheduledDateTime": "2024-03-15T14:00:00.000Z",
"platform": "youtube",
"videoId": "vid_abc123xyz"
}
}
{
"code": "bad_request",
"message": "Video must be completed before scheduling",
"details": {
"videoStatus": "processing"
}
}
{
"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"
}
}
{
"code": "not_found",
"message": "Video not found",
"details": {
"resource_id": "vid_invalid",
"resource_type": "Video"
}
}
{
"code": "not_found",
"message": "Integration not found",
"details": {
"resource_id": "int_invalid",
"resource_type": "Integration"
}
}
Scheduling
Schedule Video
Schedule a video for automatic publishing to social platforms
POST
/
v1
/
schedule
/
create
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"
}
}'
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'])
{
"success": true,
"message": "Video scheduled successfully",
"data": {
"scheduleId": "post_abc123xyz",
"status": "pending",
"scheduledDateTime": "2024-03-15T14:00:00.000Z",
"platform": "youtube",
"videoId": "vid_abc123xyz"
}
}
{
"code": "bad_request",
"message": "Video must be completed before scheduling",
"details": {
"videoStatus": "processing"
}
}
{
"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"
}
}
{
"code": "not_found",
"message": "Video not found",
"details": {
"resource_id": "vid_invalid",
"resource_type": "Video"
}
}
{
"code": "not_found",
"message": "Integration not found",
"details": {
"resource_id": "int_invalid",
"resource_type": "Integration"
}
}
Try it out! Use the API playground on the right to test the Schedule Video endpoint directly.
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
Videos must be in completed status before they can be scheduled. Connect your social platforms in the Hooked Dashboard first.
Endpoint
POST /v1/schedule/create
Required Fields
string
required
ID of the completed video to schedule. Get this from the video creation response or the
/v1/video/list endpoint.string
required
ID of the connected social platform. Get available integrations from
/v1/integration/list.string
required
ISO 8601 datetime for when to publish the video. Must be in the future.Example:
2024-03-15T14:00:00.000ZOptional Fields
object
Platform-specific metadata for the post
Show Platform Data Object
Show Platform Data Object
string
Post title (max 100 characters). Used for YouTube video titles.
string
Post description (max 5000 characters). Used for video descriptions and captions.
array
Array of tags/hashtags (max 30). Platform-specific handling:
- YouTube: Video tags
- TikTok/Instagram: Appended as hashtags to description
string
default:"public"
Privacy setting (YouTube only):
public- Anyone can viewunlisted- Only people with the link can viewprivate- Only you can view
boolean
default:"false"
Whether content is made for kids (YouTube only). Required for COPPA compliance.
Request Examples
Basic Schedule
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)
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)
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
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();
}
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"
}
}'
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'])
Response
{
"success": true,
"message": "Video scheduled successfully",
"data": {
"scheduleId": "post_abc123xyz",
"status": "pending",
"scheduledDateTime": "2024-03-15T14:00:00.000Z",
"platform": "youtube",
"videoId": "vid_abc123xyz"
}
}
{
"code": "bad_request",
"message": "Video must be completed before scheduling",
"details": {
"videoStatus": "processing"
}
}
{
"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"
}
}
{
"code": "not_found",
"message": "Video not found",
"details": {
"resource_id": "vid_invalid",
"resource_type": "Video"
}
}
{
"code": "not_found",
"message": "Integration not found",
"details": {
"resource_id": "int_invalid",
"resource_type": "Integration"
}
}
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. |
| Field | Requirement | Notes |
|---|---|---|
description | Recommended | Caption for the post. Max 2200 characters. |
tags | Optional | Appended as hashtags to caption. |
Best Practices
Schedule Ahead
Schedule at least 15 minutes in the future to allow for processing.
Use Optimal Times
Research your audience’s active hours for better engagement.
Set Up Webhooks
Get notified when posts are published or if publishing fails.
Include Metadata
Add titles, descriptions, and tags for better discoverability.
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
List Scheduled
View all your scheduled posts
Update Schedule
Change time or metadata
Cancel Schedule
Cancel a scheduled post
Webhooks
Get notified on publish
Authorizations
Body
application/json
Response
201
Schedule created successfully