StoryShort API
Generate and publish AI UGC videos programmatically. The StoryShort API lets you create videos with AI characters, poll for completion, and publish directly to TikTok, YouTube, Instagram, and Zapier.
Authentication
All API requests require a Bearer token in the Authorization header. Generate an API key from your dashboard settings.
Authorization: Bearer ss_your_api_key_hereKeep your API key secret. Do not expose it in client-side code or public repositories. All requests should be made from your server.
Base URL
All endpoints are relative to this base URL:
Generate a Video
/ai-agent/api/generate
Starts video generation with the AI agent in auto mode. Returns immediately while the video is created in the background.
curl -X POST https://api.storyshort.ai/ai-agent/api/generate \
-H "Authorization: Bearer ss_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Make a UGC ad for Capacity.so, an AI app builder",
"videoType": "ugc_ads",
"duration": 60,
"characterId": "optional_character_id",
"webhookUrl": "https://your-server.com/webhook"
}'Request Body
promptreq | Describe what video to create. Include URLs, product names, etc. |
videoType | faceless ugc_ads hook_demoDefault: ugc_ads |
duration | 30, 60, or 120 seconds. Default: 60 |
characterId | Character ID for ugc_ads / hook_demo. Omit to let the AI choose. |
aspectRatio | 9:16 16:9 1:1Default: 9:16 |
language | Language for the script. Default: english |
webhookUrl | URL to receive a POST when generation completes or fails. |
Response
{
"conversationId": "abc123",
"status": "processing",
"message": "Video generation started. Use the status endpoint to check progress."
}Check Status
/ai-agent/api/status/:conversationId
Poll for the current state of a generation. Returns the video URL once rendering is complete.
curl https://api.storyshort.ai/ai-agent/api/status/abc123 \
-H "Authorization: Bearer ss_your_api_key"Response
{
"conversationId": "abc123",
"videoId": "xyz789",
"videoUrl": "https://s3.amazonaws.com/.../video.mp4",
"status": "processing | rendering | completed",
"messageCount": 12
}List Characters
/ai-agent/api/characters
Get available characters for ugc_ads and hook_demo videos. Use the returned id as the characterId parameter.
curl https://api.storyshort.ai/ai-agent/api/characters \
-H "Authorization: Bearer ss_your_api_key"Response
{
"characters": [
{
"id": "abc",
"name": "Sarah",
"description": "Professional female presenter",
"preview": "https://...",
"language": "en"
}
]
}Webhook Events
If you provide a webhookUrl when generating a video, we'll send a POST request to that URL when generation completes or fails.
Success
{
"event": "generation_complete",
"conversationId": "abc123",
"videoId": "xyz789"
}Failure
{
"event": "generation_failed",
"conversationId": "abc123",
"error": "Error description"
}List Connected Accounts
/api/v1/accounts
List all connected social media accounts (TikTok, YouTube, Instagram, Zapier). Connect accounts from the StoryShort dashboard first.
curl https://api.storyshort.ai/api/v1/accounts \
-H "Authorization: Bearer ss_your_api_key"Response
{
"success": true,
"accounts": {
"tiktok": [
{ "id": "abc123", "platform": "tiktok", "username": "myaccount", "displayName": "My Account", "avatar": "https://..." }
],
"youtube": [
{ "id": "def456", "platform": "youtube", "channelId": "UC...", "title": "My Channel", "subscribers": "1000" }
],
"instagram": [
{ "id": "ghi789", "platform": "instagram", "username": "myinsta", "profilePicture": "https://..." }
],
"zapier": [
{ "id": "jkl012", "platform": "zapier", "name": "My Webhook" }
]
}
}List Videos
/api/v1/videos
List your videos with pagination. Use the returned id as the videoId when publishing.
curl "https://api.storyshort.ai/api/v1/videos?page=1&limit=10" \
-H "Authorization: Bearer ss_your_api_key"Query Parameters
page | Page number. Default: 1 |
limit | Results per page (max 100). Default: 20 |
Response
{
"success": true,
"videos": [
{
"id": "xyz789",
"title": "My UGC Ad",
"type": "ugc_ads",
"status": "completed",
"url": "https://s3.amazonaws.com/.../video.mp4",
"aspectRatio": "9: 16",
"duration": 60,
"createdAt": "2025-01-15T10: 30: 00Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 42, "totalPages": 3 }
}Publish Video
/api/v1/publish
Publish a video to one or more connected social media accounts. The video will be rendered automatically if it hasn't been already.
curl -X POST https://api.storyshort.ai/api/v1/publish \
-H "Authorization: Bearer ss_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"videoId": "xyz789",
"accountIds": ["tiktok_account_id", "youtube_account_id"],
"title": "Check out this video!",
"description": "Made with StoryShort",
"youtubeVisibility": "public"
}'Request Body
videoIdreq | The ID of the video to publish. |
accountIdsreq | Array of account IDs to publish to. Get these from /api/v1/accounts. |
title | Custom title or caption for the post. |
description | Description text (used by YouTube and Zapier). |
privacyStatus | TikTok privacy level. PUBLIC_TO_EVERYONE MUTUAL_FOLLOW_FRIENDS SELF_ONLY |
allowComment | Allow comments on TikTok. Default: true |
allowDuet | Allow duets on TikTok. Default: true |
allowStitch | Allow stitches on TikTok. Default: true |
youtubeVisibility | public unlisted privateDefault: public |
Response
{
"success": true,
"results": [
{ "accountId": "abc123", "platform": "tiktok", "success": true, "publishId": "pub_xyz" },
{ "accountId": "def456", "platform": "youtube", "success": true, "videoId": "yt_abc" }
]
}Full Example
Generate a video, wait for completion, then publish to TikTok — all in one script.
"text-violet-400">import time
"text-violet-400">import requests
API_KEY = "ss_your_api_key"
BASE = "https://api.storyshort.ai"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
"text-zinc-500"># 1. Start generation
res = requests.post(f"{BASE}/ai-agent/api/generate", headers=HEADERS, json={
"prompt": "Make a UGC ad for Capacity.so — an AI app builder",
"videoType": "ugc_ads",
"duration": 60
})
conversation_id = res.json()["conversationId"]
print(f"Started: {conversation_id}")
"text-zinc-500"># 2. Poll for status
"text-violet-400">while "text-violet-400">True:
status = requests.get(
f"{BASE}/ai-agent/api/status/{conversation_id}",
headers=HEADERS
).json()
print(f"Status: {status['status']}")
"text-violet-400">if status["status"] == "completed":
print(f"Video URL: {status['videoUrl']}")
video_id = status["videoId"]
"text-violet-400">break
time.sleep(10)
"text-zinc-500"># 3. Get connected accounts
accounts = requests.get(f"{BASE}/api/v1/accounts", headers=HEADERS).json()
tiktok_ids = [a["id"] for a in accounts["accounts"]["tiktok"]]
print(f"TikTok accounts: {tiktok_ids}")
"text-zinc-500"># 4. Publish to TikTok
pub = requests.post(f"{BASE}/api/v1/publish", headers=HEADERS, json={
"videoId": video_id,
"accountIds": tiktok_ids,
"title": "Check out this AI app builder!"
})
print(f"Published: {pub.json()}")Ready to start automating?