Videos API

Create, manage, and generate videos programmatically.

Create Video

POST /videos

Create a video from a text prompt. The API will generate a script and scenes.

bash
curl -X POST https://api.sketchpen.app/api/v1/videos \
  -H "X-Api-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A tutorial on machine learning basics",
    "fps": 24,
    "aspect_ratio": "16:9"
  }'

Request Body

FieldTypeRequiredDescription
`prompt`stringYesNatural language description of the video (max 2000 chars)
`fps`integerNoFrames per second (default: 24)
`aspect_ratio`stringNoAspect ratio: 16:9, 9:16, 1:1 (default: 16:9)
`theme`stringNoVideo theme ID (default: presentation)
`voice_id`stringNoVoice ID for narration
`audio_mode`stringNoAudio mode: none, single, multi_voice (default: single)
`bg_mode`stringNoBackground mode: white, dynamic (default: white)
`asset_ids`arrayNoAsset IDs to include
`speaker_ids`arrayNoSpeaker IDs to include (subset of asset_ids)

ℹ️ Video Limits

Maximum 40 scenes per video. Videos exceeding this limit during generation will be capped.

⚠️ Concurrent Videos

You can have up to 3 videos processing at once. Attempting to create more returns HTTP 429 with error code MAX_CONCURRENT_VIDEOS. Videos with status pending, scripting, refining, visualising, narrating, curating, or rendering count as "in progress".

Response

json
{
  "id": "uuid",
  "status": "scripting",
  "prompt": "A tutorial on machine learning basics",
  "theme": "presentation",
  "scenes": [
    {
      "id": "uuid",
      "speech": "Machine learning is a way...",
      "visual_description": "An illustration of connected nodes...",
      "image_url": null,
      "assets": [],
      "captions": [
        {"word": "Machine", "start": 0.0, "end": 0.3},
        {"word": "learning", "start": 0.3, "end": 0.6}
      ]
    }
  ],
  "video_url": null,
  "audio_url": null,
  "thumbnail_url": null,
  "processing_time_sec": null,
  "config": {
    "fps": 24,
    "width": 1920,
    "height": 1080,
    "aspect_ratio": "16:9",
    "bg_color": "#FFFFFF",
    "bg_mode": "white",
    "audio_mode": "single",
    "voice_id": "21m00Tcm4TlvDq8ikWAM"
  },
  "assets": [],
  "created_at": "2024-01-01T00:00:00Z",
  "updated_at": "2024-01-01T00:00:00Z"
}

Create Video from Script

POST /videos/from-script

Create a video with pre-defined scenes for more control.

bash
curl -X POST https://api.sketchpen.app/api/v1/videos/from-script \
  -H "X-Api-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My Tutorial",
    "scenes": [
      {
        "speech": "Welcome to our tutorial",
        "visual_description": "Introduction slide",
        "start_time": 0.0,
        "image_file_id": "uuid-of-uploaded-image",
        "character_ids": ["uuid-of-character-asset"],
        "object_ids": ["uuid-of-object-asset"]
      }
    ],
    "aspect_ratio": "16:9",
    "speaker_ids": ["uuid-of-character-asset"]
  }'

Request Body

FieldTypeRequiredDescription
`title`stringNoVideo title (max 200 chars)
`scenes`arrayYesArray of scene objects (max 40)
`fps`integerNoFrames per second (default: 24)
`aspect_ratio`stringNoAspect ratio: 16:9, 9:16, 1:1 (default: 16:9)
`theme`stringNoVideo theme (default: presentation)
`voice_id`stringNoVoice ID for narration
`audio_mode`stringNoAudio mode: none, single, multi_voice (default: single)
`bg_mode`stringNoBackground mode: white, dynamic (default: white)
`asset_ids`arrayNoAsset IDs to include
`speaker_ids`arrayNoSpeaker IDs to include

Scene Object

FieldTypeRequiredDescription
`speech`string/dict/listYesNarration text (string for single voice, dict/list for multi-voice)
`visual_description`stringYesDescription of visuals to generate
`start_time`floatNoStart time in seconds (default: 0.0)
`image_file_id`UUIDNoFile ID of a pre-uploaded custom image. If set, AI image generation is skipped for this scene.
`character_ids`UUID[]NoAsset IDs of characters that appear in this scene
`object_ids`UUID[]NoAsset IDs of objects that appear in this scene

Multi-Voice Speech Format

When using audio_mode: "multi_voice", the speech field is a list of character lines. Each char_id is the name of the character asset (not UUID):

json
{
  "scenes": [
    {
      "speech": [
        {"char_id": "priya", "speech": "Hello, welcome to our tutorial!"},
        {"char_id": "marcus", "speech": "Thanks, glad to be here."}
      ],
      "visual_description": "Priya and Marcus talking",
      "character_ids": ["uuid-of-priya-asset", "uuid-of-marcus-asset"]
    }
  ],
  "audio_mode": "multi_voice",
  "speaker_ids": ["uuid-of-priya-asset", "uuid-of-marcus-asset"]
}
  • char_id = the name you gave the character asset (via POST /assets, e.g., "priya")
  • character_ids = the UUIDs of the same character assets
  • speaker_ids = which assets should speak (subset of asset_ids)

List Videos

GET /videos

bash
curl https://api.sketchpen.app/api/v1/videos \
  -H "X-Api-Key: sk_live_..."

Response:

json
[
  {
    "id": "uuid",
    "status": "completed",
    "prompt": "A tutorial on machine learning",
    "theme": "presentation",
    "video_url": null,
    "audio_url": null,
    "thumbnail_url": "https://...",
    "assets": [],
    "created_at": "2024-01-01T00:00:00Z",
    "updated_at": "2024-01-01T00:00:05Z"
  }
]

Get Video

GET /videos/{id}

bash
curl https://api.sketchpen.app/api/v1/videos/uuid \
  -H "X-Api-Key: sk_live_..."

Response (completed video):

json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "prompt": "A tutorial on machine learning basics",
  "theme": "presentation",
  "scenes": [
    {
      "id": "scene_uuid",
      "speech": "Machine learning is a way...",
      "visual_description": "An illustration of connected nodes...",
      "image_url": null,
      "assets": [],
      "captions": [
        {"word": "Machine", "start": 0.0, "end": 0.3},
        {"word": "learning", "start": 0.3, "end": 0.6}
      ]
    }
  ],
  "config": {
    "fps": 24,
    "width": 1920,
    "height": 1080,
    "aspect_ratio": "16:9",
    "bg_mode": "white",
    "audio_mode": "single"
  },
  "video_url": "https://bucket.s3.region.amazonaws.com/key?X-Amz-Algorithm=...",
  "thumbnail_url": "https://bucket.s3.region.amazonaws.com/key?X-Amz-Algorithm=...",
  "audio_url": null,
  "created_at": "2024-01-01T00:00:00Z",
  "updated_at": "2024-01-01T00:05:00Z"
}

ℹ️ Status

Videos go through: scriptingrefiningvisualisingnarratingcuratingrenderingcompleted. See Getting Started for the full lifecycle.

Video Status Lifecycle

Videos progress through these statuses in order:

StatusDescription
`pending`Video created, processing not started
`scripting`AI is generating the script from your prompt
`refining`Script is being refined
`visualising`Generating visual scenes
`narrating`Generating audio voiceovers
`curating`Synchronizing assets and engines
`rendering`Rendering final video
`completed`Video ready - video_url available
`failed`Generation failed - check error details

Approve Video

POST /videos/{id}/approve

Approve the script and start video generation. This deducts credits from your account.

bash
curl -X POST https://api.sketchpen.app/api/v1/videos/uuid/approve \
  -H "X-Api-Key: sk_live_..."

Response:

json
{
  "id": "uuid",
  "status": "visualising",
  "prompt": "A tutorial on machine learning basics",
  "scenes": [...],
  "video_url": null,
  "created_at": "2024-01-01T00:00:00Z",
  "updated_at": "2024-01-01T00:00:05Z"
}

Status immediately changes to visualising — image and audio generation begins.

⚠️ Credits

Approving deducts credits based on scene count and audio length. Each scene costs 1 credit, each 1,000 characters of audio costs 1 credit. Insufficient credits returns INSUFFICIENT_CREDITS (HTTP 402).

Regenerate Script

POST /videos/{id}/regenerate

Regenerate the script based on feedback.

bash
curl -X POST https://api.sketchpen.app/api/v1/videos/uuid/regenerate \
  -H "X-Api-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "feedback": "Make it more beginner friendly"
  }'
ParameterTypeDescription
`feedback`stringInstructions for the AI on how to improve the scenes.

This resets the video status to scripting and generates a new script.

Update Scene

PATCH /videos/scenes/{scene_id}

Edit a scene's speech or visual description before approving.

bash
curl -X PATCH https://api.sketchpen.app/api/v1/videos/scenes/uuid \
  -H "X-Api-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "speech": "Updated speech text",
    "visual_description": "Updated visual description"
  }'
FieldTypeDescription
`speech`stringUpdated narration text
`visual_description`stringUpdated visual description
`prompt`stringUpdated generation prompt

Replace Scene Image

POST /videos/{video_id}/scenes/{scene_id}/image

Upload a custom image to override the AI-generated visual for a specific scene:

bash
curl -X POST https://api.sketchpen.app/api/v1/videos/{video_id}/scenes/{scene_id}/image \
  -H "X-Api-Key: sk_..." \
  -F "file=@/path/to/custom_image.jpg"

ℹ️ File Size Limit

Maximum upload size is 20 MB per image. Files larger than 20 MB will be rejected with HTTP 413.

Delete Video

DELETE /videos/{id}

bash
curl -X DELETE https://api.sketchpen.app/api/v1/videos/uuid \
  -H "X-Api-Key: sk_live_..."

Returns 204 No Content on success.

Embedding Videos

When a video is completed, the video_url in the response is a presigned S3 URL (valid for 7 days) or a CDN URL if a CDN is configured. Use it directly:

html
<video src="<video_url_from_response>" controls>

ℹ️ Presigned URLs

The video_url, thumbnail_url, audio_url, and image_url fields in API responses are presigned S3 URLs that expire after 7 days (or CDN URLs if configured). Download or re-host any files you need long-term.

⚠️ Post-Render File Cleanup

After a video completes successfully, intermediate files are automatically deleted to save storage:

  • Scene images (image_url on scenes becomes null)
  • Audio voiceover (audio_url becomes null)
  • Debug images

Only the final video file and thumbnail are preserved. This is by design.

Rate Limits

Endpoint Limit
POST /videos 20 per day
POST /videos/from-script 20 per day
POST /videos/{id}/regenerate 5 per hour, 3 per 10 minutes
PATCH /videos/scenes/{id} No limit
POST /videos/{id}/scenes/{id}/image 30 per hour

Rate-limited requests return HTTP 429 with a Retry-After header indicating when to retry.

Storage Usage

GET /videos/storage/usage

Get your current storage usage and limits.

bash
curl https://api.sketchpen.app/api/v1/videos/storage/usage \
  -H "X-Api-Key: sk_live_..."

Response:

json
{
  "used_bytes": 123456789,
  "cap_bytes": 524288000,
  "plan_key": "starter_monthly",
  "usage_percent": 23.5
}

Plan Limits

PlanStorageRetentionMax Upload
Starter500 MB7 days20 MB
Growth2 GB15 days20 MB
Scale5 GB30 days20 MB

Videos are automatically deleted after the retention period expires.

Full spec at /llms.txt