Videos
1. Overview
The Firework Video API allows you to upload videos to the Firework platform programmatically. This API supports video file uploads with rich metadata including product associations.
Base URL: https://api.firework.com
2. Authentication
The Firework Video API uses OAuth 2.0 for authentication. Before using this API, you must obtain an access token.
Authentication Methods Supported:
Client Credentials: OAuth 2.0 Client Credentials flow for server-to-server authentication (machine-to-machine)
📖 Documentation:
Client Credentials OAuth - Server-to-server authentication for OAuth apps
3. Endpoint Summary
POST /api/v1/upload_signatures
videos:write
Get pre-signed credentials for S3 upload
POST /api/v1/upload_multipart/signatures
videos:write
Initiate multipart upload and get signed parts
POST /api/v1/upload_multipart/complete
videos:write
Complete a multipart upload with ETags
POST /api/v1/videos
videos:write
Video creation with file upload
POST /api/v1/videos
videos:write
Video creation from URL (sync, default)
POST /api/v1/videos
videos:write
Video creation from URL (async: "async":true)
POST /api/v1/videos
videos:write
Video creation from S3 key (application/json)
POST /api/v1/videos
videos:write
Video creation from inline base64 (≤5MB clips)
GET /api/v1/videos
videos:read
List videos in a channel (cursor-paginated)
GET /api/v1/videos/{id}
videos:read
Get video by ID
PATCH /api/v1/videos/{id}
videos:write
Video updates
DELETE /api/v1/videos/{id}
videos:write
Delete a video (204 No Content)
POST /api/v1/videos/{id}/archive
videos:write
Archive a video
POST /api/v1/videos/{id}/unarchive
videos:write
Unarchive a video
POST /api/v1/videos/{id}/publish
videos:write
Publish now or schedule (published_at)
POST /api/v1/videos/{id}/unpublish
videos:write
Unpublish (revert to draft)
POST /api/v1/videos/{id}/subtitles
videos:write
Add a subtitle (file / content / url)
DELETE /api/v1/videos/{id}/subtitles/{subtitle_id}
videos:write
Remove a subtitle (204 No Content)
POST /api/v1/videos/{id}/posters
videos:write
Add a poster from a URL
PATCH /api/v1/videos/{id}/posters
videos:write
Atomically update multiple poster weights
PATCH /api/v1/videos/{id}/posters/{poster_id}
videos:write
Update one poster's weight
DELETE /api/v1/videos/{id}/posters/{poster_id}
videos:write
Remove a poster (204 No Content)
GET /api/v1/videos/{id}/download
videos:read
Get the transcoded-file download URL
POST /api/v1/videos/download_urls
videos:read
Get download URLs for up to 50 videos
GET /api/v1/videos/{id}/product_matches
videos:read
List AI product-match recommendations
POST /api/v1/videos/{id}/product_matches
videos:write
Start asynchronous AI product matching
POST /api/v1/videos/{id}/product_matches/accept
videos:write
Accept a complete desired subset of matches
GET /api/v1/videos/imports/{id}
videos:read
Get video import job status
4. Upload Signature (Single File)
Get pre-signed credentials to upload a video directly to AWS S3 using a single POST request. This enables a two-step upload process suitable for files under ~100MB.
For files over 100MB, use the Multipart Upload API (Section 5. Multipart Upload) instead, which supports parallel and resumable uploads.
Upload Flow:
Endpoint: POST /api/v1/upload_signatures Authentication: Bearer token required Scope: videos:write
4.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
Content-Type
Must be application/json
✅
4.2. Request Body
filename
string
✅
Basename of the video file, with an allowed video extension such as .mp4 or .mov
mime_type
string
✅
The MIME type of the video: video/mp4 or video/quicktime
channel_id
string
✅
The encoded channel ID where the video will be uploaded
4.3. Video Limits
The upload signature enforces the following limits:
Minimum file size
25 KB
Maximum file size
5 GB
Minimum duration
3 seconds
Maximum duration
1 hour
4.4. Upload Signature Response
Success Response: 201 Created
key
string
The S3 object key where the file will be stored. Save this for video creation
post_url
string
The S3 URL to POST the file to
policy
string
Base64-encoded policy document
signature
string
The AWS Signature V4 value (X-Amz-Signature)
date
string
The signing date (X-Amz-Date), e.g., "20250129T120000Z"
credential
string
The AWS credential scope (X-Amz-Credential)
algorithm
string
Always "AWS4-HMAC-SHA256"
acl
string
Always "private"
4.5. Upload Signature Error Responses
400 Bad Request
Invalid mime_type - only video/mp4 and video/quicktime allowed
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions to upload to the specified channel
404 Not Found
Channel not found
422 Unprocessable Entity
Blocked or unsupported filename extension
4.6. Uploading to S3
After receiving the signature, upload the file directly to S3 using a multipart/form-data POST request.
⚠️ Important: The form fields must be sent in the correct order, with the
filefield last.
Required Form Fields (in order):
key
From signature response
acl
From signature response
X-Amz-Algorithm
From signature algorithm
X-Amz-Credential
From signature credential
X-Amz-Date
From signature date
Policy
From signature policy
X-Amz-Signature
From signature signature
Content-Type
Same as request mime_type
file
The video file (must be last)
S3 Response:
204
Success - file uploaded
400
Bad request - file size outside limits (< 25 KB or > 5 GB), or form error
403
Forbidden - signature invalid or expired (expires after 60 min)
4.7. Upload Signature Examples
4.7.1. Get Signature Request
4.7.2. Get Signature Response
4.7.3. Upload to S3
Use the post_url from the Get Signature response as the upload endpoint. Submit a POST request with the signature fields and your video file:
5. Multipart Upload
Upload large video files (100MB+) to AWS S3 using multipart upload. This splits the file into multiple parts that can be uploaded in parallel and resumed if a part fails, avoiding gateway timeouts.
⚠️ AWS S3 Part Size Requirements:
Each part (except the last) must be ≥ 5 MB (5,242,880 bytes)
Last part can be any size
Maximum 100 parts per upload
If parts are too small, the complete step will fail with "Multipart upload failed"
Multipart Upload Flow:
5.1. Initiate Multipart Upload
Start a multipart upload session. Returns an upload_id and presigned URLs for each part.
Endpoint: POST /api/v1/upload_multipart/signatures Authentication: Bearer token required Scope: videos:write
5.1.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
Content-Type
Must be application/json
✅
5.1.2. Request Body
filename
string
✅
Basename of the video file, with an allowed video extension such as .mp4 or .mov
mime_type
string
✅
The MIME type of the video: video/mp4 or video/quicktime
channel_id
string
✅
The encoded channel ID where the video will be uploaded
parts_count
integer
✅
Number of parts to split the file into (1-100)
Choosing
parts_count: Calculate based on your file size to ensure each part is ≥ 5 MB:
Formula:
parts_count = file_size_mb / 5(round down)Example 1: 100 MB file → max 20 parts (100 / 5 = 20)
Example 2: 500 MB file → max 100 parts (500 / 5 = 100)
Example 3: 15 MB file → max 3 parts (15 / 5 = 3)
Important: Each part (except last) must be ≥ 5 MB, or upload will fail
5.1.3. Initiate Response
Success Response: 201 Created
key
string
The S3 object key where the file will be stored. Save this for video creation
upload_id
string
The multipart upload session ID. Required for uploading parts and completion
parts
array
Array of part objects, one per requested part
Each element in parts:
part
integer
The part number (1-based)
signature
object
Signature object containing the presigned PUT URL
signature.put_url
string
Presigned URL to PUT-upload this part directly to S3
signature.key
string
The S3 object key
5.1.4. Initiate Error Responses
400 Bad Request
Invalid mime_type - only video/mp4 and video/quicktime allowed
400 Bad Request
Invalid parts_count - must be between 1 and 100
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions to upload to the specified channel
404 Not Found
Channel not found
422 Unprocessable Entity
Blocked or unsupported filename extension
5.2. Upload Parts to S3
After initiating the multipart upload, upload each part directly to S3 using the presigned PUT URLs from the response.
Parts can be uploaded in parallel for faster uploads. Each part returns an
ETagheader that you must save for the completion step.
For each part:
S3 Response:
200
Success - part uploaded. Save the ETag response header.
403
Forbidden - signature invalid or expired
Important: The
ETagheader value returned by S3 for each part is required for the completion step. It is typically a quoted MD5 hash, e.g.,"d41d8cd98f00b204e9800998ecf8427e".
5.3. Complete Multipart Upload
After all parts have been uploaded to S3, call this endpoint to assemble them into the final file.
Endpoint: POST /api/v1/upload_multipart/complete Authentication: Bearer token required Scope: videos:write
5.3.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
Content-Type
Must be application/json
✅
5.3.2. Request Body
key
string
✅
The S3 key returned from the initiate step
upload_id
string
✅
The upload session ID returned from the initiate step
parts
array
✅
Array of completed part objects (see below)
Each element in parts:
part
integer
✅
The part number (1-100, must match the initiate response, no duplicates)
etag
string
✅
The ETag returned by S3 when the part was uploaded (non-empty)
Validation Rules: The
partsarray must be non-empty, contain at most 100 elements, have no duplicate part numbers, and eachetagmust be a non-empty string.
5.3.3. File Size Validation
After assembly, the server validates the total file size against the same limits used for single-file uploads:
Minimum file size
25 KB
Maximum file size
5 GB
If the assembled file is outside these bounds, the server deletes the object from S3 and returns an error with a descriptive message: "File too small (min 25KB)" (400) or "File too large (max 5GB)" (413).
5.3.4. Complete Response
Success Response: 204 No Content
No response body. The file has been assembled on S3 and is ready to be used with the Create Video API (Section 6. Create Video) using the s3_key parameter.
5.3.5. Complete Error Responses
400 Bad Request
Invalid or missing parameters (key, upload_id, or parts), empty parts list, duplicate part numbers, invalid part numbers (must be 1-100), or empty etag values
400 Bad Request
"File too small (min 25KB)"
Assembled file is below minimum size (25 KB)
400 Bad Request
"Multipart upload failed"
AWS rejected the upload (e.g., parts < 5 MB)
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
413 Request Entity Too Large
"File too large (max 5GB)"
Assembled file exceeds the maximum size (5 GB)
500 Internal Server Error
Unexpected server error during upload completion - retry the request
⚠️ Common Failure: If you receive "Multipart upload failed" with a
400status, it's usually because one or more parts (except the last) were smaller than 5 MB. Recalculateparts_countto ensure each part is at least 5 MB. A500status indicates a transient server issue - retry the request.
5.4. Multipart Upload Examples
5.4.1. Step 1: Initiate Multipart Upload
Response:
5.4.2. Step 2: Upload Parts to S3 (can be parallel)
Split your file and upload each part using its presigned URL:
Tip: To get the ETag from curl, use
-ior-D -to include response headers in the output.
5.4.3. Step 3: Complete Multipart Upload
Response: 204 No Content
5.4.4. Step 4: Create Video with S3 Key
Use the key from the initiate step to create the video:
See Section 6. Create Video for full details on video creation.
6. Create Video
Upload a new video to the Firework platform. Supports direct file upload, video import from URL, creation from a pre-uploaded S3 key, and inline base64 upload for short clips.
Endpoint: POST /api/v1/videos Authentication: Bearer token required Scope: videos:write Rate Limit: 20 videos per 5 minutes per channel Content Type: multipart/form-data or application/json
channel_idis optional when the token resolves to a single channel (an app token whose business has exactly one channel); otherwise it is required. This applies to every creation option below.
6.1. Supported Video Files
MIME Types:
video/mp4,video/quicktimeFile Extensions:
.mp4,.movMaximum Size: 5GB
6.2. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
Content-Type
multipart/form-data (file upload) or application/json (URL import / S3 key upload)
✅
6.3. Request Body
Option 1: File Upload (multipart/form-data)
Upload the video file directly. Best for small files (under 100MB).
metadata
string
✅
JSON-encoded video metadata (see schema below)
file
file
✅
Video file to upload
Option 2: URL Import (application/json)
Import a video from a publicly accessible URL. Supports two modes:
Sync mode (default): The file is downloaded and uploaded to S3 within the request. Returns
201 Createdwith a video object. Best for small files, but may time out on large files or slow URLs.Async mode (
"async": true): Returns202 Acceptedimmediately with a video import tracking object. The file is downloaded and processed in the background. Recommended for large files or unreliable URLs.
How to choose:
Small files (< 100 MB), fast URLs
Sync (default)
Simpler flow, video available immediately
Large files (100 MB+)
Async
Avoids gateway timeouts
Unreliable/slow URLs
Async
Background retry on failure
Batch / fire-and-forget imports
Async
No need to wait for each video to finish
url
string
✅
None
Publicly accessible video URL (http or https)
async
boolean
❌
false
Set to true for async processing (returns 202 Accepted)
All other fields from metadata schema
-
-
-
See Metadata Schema (Section 6.4)
URL Validation Rules:
Must be
http://orhttps://schemeMust have a valid hostname (with at least one dot)
Must have a path component
The remote server must respond with a
Content-Typeheader ofvideo/mp4,video/quicktime, orapplication/octet-stream. Whenapplication/octet-streamis returned, the URL path must end with a video file extension (.mp4or.mov)The remote server must include a
Content-LengthheaderMaximum file size: 5 GB
Video duration: 3 seconds to 1 hour
Sync mode ("async" omitted or false): Returns 201 Created with a video object (same as file upload / S3 key). See Section 6.8.1.
Async mode ("async": true): Returns 202 Accepted with a video import object. See Section 6.8.2.
Async Processing Flow:
API validates the URL format, creates a video import job, and enqueues a background worker
Returns
202 Acceptedwith the import jobidandstatus: "running"Background worker downloads the file to S3, creates the video record, and triggers transcoding. The
video_idis populated at this point whilestatusremains"running"When transcoding completes:
statusbecomes"completed"andcompleted_atis setIf processing fails (e.g., download error, invalid format, duration out of range):
statusbecomes"errored"Tracking progress:
Webhooks (recommended): Configure
video_created,video_updated, andvideo_import_failedwebhooks to receive push notifications. The webhook payload includes theimport_idso you can correlate events back to this import job.Polling: Use
GET /api/v1/videos/imports/{id}to poll for status. We recommend polling at 5–10 second intervals.
Option 3: S3 Key Upload (application/json) - Recommended for Large Files
Create a video from a file already uploaded to S3 via the Upload Signature API (Section 4. Upload Signature) or the Multipart Upload API (Section 5. Multipart Upload). Recommended for files over 100MB to avoid gateway timeouts.
s3_key
string
✅
None
The S3 key returned from Upload Signature API
All other fields from metadata schema
-
-
-
See metadata schema section
Option 4: Inline Base64 Upload (application/json) - Short Clips Only
Create a video by embedding the file bytes directly in the JSON body as base64. The server decodes and stores the bytes, so the client never needs S3 egress — but the payload is buffered whole and rides the JSON body limit.
⚠️ Short clips only (≤ 5 MB decoded). The decoded size must not exceed 5 MB (roughly 6.7 MB of base64 text). Larger payloads are rejected with
400. For anything bigger, use URL import (Option 2) or the S3 key flow (Option 3).
file_base64
string
✅
None
Base64-encoded mp4/mov bytes, ≤ 5 MB decoded. A data: URI prefix is accepted and stripped
filename
string
❌
"upload.mp4"
Optional filename for the stored object
All other fields from metadata schema
-
-
-
See Metadata Schema (Section 6.4)
6.4. Metadata Schema
channel_id
string
✅
None
Encoded channel ID where video will be uploaded
caption
string
✅
None
Video title/caption
content_generation_type
string
❌
null
Whether the video contains AI-generated content
Only supported non-null value: "aigc"
description
string
❌
None
Video description
access
string
❌
"public"
Video visibility: "public" or "private"
archived_at
string
❌
None
ISO 8601 timestamp when the video should be archived
audio_disabled
boolean
❌
false
Whether audio is disabled for the video
hashtags
string[]
❌
[]
Array of hashtag strings
business_store_id
string
❌
use first one
Encoded business store ID
See products tagging rules
product_ids
string[]
❌
[]
Array of product identifiers
See products tagging rules
variant_ids
string[]
❌
[]
Array of product variant identifiers
See products tagging rules
custom_fields
object
❌
{}
Custom key-value metadata
See Metafields spec
display_social_attributions
boolean
❌
false
Display social media attribution on video
Requires external_media when true
external_media
object
❌
None
Social media source metadata
See External Media Schema below
poster_url
string
❌
None
URL to a custom poster image
Set to null or "" to remove. See Custom Poster section
video_hidden
boolean
❌
false
Hide video from PDP (Product Detail Page)
Applies to all product listings. See Product Tagging Rules
content_generation_type is accepted by every creation method, including asynchronous URL imports. It is create-only: PATCH /api/v1/videos/{id} does not support changing it after the video is created. An unsupported non-null value returns 422 Unprocessable Entity.
6.5. Custom Poster
The poster_url field allows you to specify a custom poster image for the video instead of using the auto-generated one.
Supported Formats:
jpg,png
Validation Rules:
Must be a valid, publicly accessible URL
URL must have a valid image file extension (
.jpg,.png)The image will be downloaded and stored on Firework's CDN
Behavior:
When provided during video creation, the custom poster replaces the auto-generated poster
When provided during video update, the custom poster replaces any existing poster
To remove a custom poster, set
poster_urltonullor an empty string""Omit the field entirely to preserve the existing poster
Examples:
Set a custom poster:
Remove the custom poster:
6.6 Product and Variant Identifiers:
The product_ids array accepts product identifiers that can be:
Encoded Firework product ID
External product ID
External product unit ID
Product unit GTIN
Product unit SKU
Product unit MPN
Product unit barcode
The variant_ids array accepts product unit identifiers that can be:
Encoded Firework product unit ID
External product unit ID
Product unit GTIN
Product unit SKU
Product unit MPN
Product Tagging Rules:
When
product_idsis provided:While you can use product unit identifiers, they will only tag the related products to the video, not the product units
It will replace existing product and variant tags with the specified ones. For example, if a video is currently tagged with product A (
external ID "123") and product B (external ID "234"), usingproduct_ids: ["123", "567"]will:Keep product A tagged to the video
Untag product B from the video
Tag product C (
external ID "567") to the video
An empty array
product_ids: []will untag all products and variants from the videoIf a specified product identifier cannot be found in the business store, it will be silently skipped. Only the valid, resolvable products will be tagged to the video. No error is returned for unrecognized product IDs.
Duplicate product identifiers (including the same product referenced by different identifier types) will be silently deduplicated
The order of products will follow the order of the array. The sort ID will be set to match the order of the
product_idsarray.
When
variant_idsis provided:It tags the specified product units (variants) to the video, not just the parent products
It has the same replace behavior as
product_ids: providingvariant_idsreplaces existing product and variant tags with the specified variants, unlessproduct_idsis also providedIf both
product_idsandvariant_idsare provided, the final product listing set is the resolvedproduct_idsfollowed by the resolvedvariant_idsAn empty array
variant_ids: []will untag all products and variants from the video whenproduct_idsis not also providedIf a specified variant identifier cannot be found in the business store, it will be silently skipped
Duplicate variant identifiers (including the same variant referenced by different identifier types) will be silently deduplicated
The order of variants will follow the order of the array after any
product_idsentries
Examples:
Example 1: Tag products using external IDs
This will tag 3 products to the video in the specified order.
Example 2: Tag products using Firework product IDs
This will tag 2 products using their encoded Firework IDs.
Example 3: Mix of identifier types
This uses external ID, GTIN, and Firework ID respectively.
Example 4: Replace existing product tags
Example 5: Untag all products
This removes all product tags from the video.
Example 6: Using product unit identifiers
Even though these are unit IDs, only the related products get tagged to the video, not the product units.
Example 7: Tag product variants explicitly
This tags the specific product units (variants) to the video. The response includes their encoded Firework IDs in variant_ids.
Example 8: Mix parent products and variants
This tags the parent product SHOE-001 and the specific variant UNIT-External-ID-1.
Example 9: Create video with hidden products and variants (hide from PDP)
This tags products and variants to the video but hides it from the Product Detail Page.
Example 10: Hide existing video from PDP (update without replacing products or variants)
When sent to PATCH /api/v1/videos/{id} without product_ids or variant_ids, this bulk-updates all existing product listings to be hidden.
Example 11: Un-hide video on PDP
Sets all existing product listings back to visible on PDP.
video_hiddenbehavior:When
video_hiddenis provided withproduct_idsorvariant_ids, all created/replaced product listings will be marked with the given valueWhen
video_hiddenis provided withoutproduct_idsorvariant_ids(update only), it bulk-updates all existing product listings for the videoWhen
product_idsorvariant_idsare provided withoutvideo_hidden, existing product listings preserve their currentvideo_hiddenstate; newly added products and variants default tofalse(visible)The
hiddenfield is not returned in the Video API response. It is returned in the Product API (GET /api/v1/products/:id/videos), scoped to the queried productDefault is
false(visible on PDP)
business_store_idbehavior:Optional. If absent, the system will use the first business store of the business
If provided, the system will use the specified business store to find the product(s)
6.7. External Media Schema
Used for social media attribution. Required when display_social_attributions is true.
source
string
✅
Platform: "tiktok", "instagram", "youtube", etc
url
string
✅
URL to the original social media post
username
string
✅
Creator's username/handle
navigation_enabled
boolean
❌
true
Whether the URL is clickable in the player
Example:
Validation Rules:
When
display_social_attributionsistrue,external_mediamust be provided with at leastsourceandurlFor updates: validation passes if the video already has an existing
external_mediaassociation
6.8. Create Video Response
Two different response shapes depending on the creation method:
6.8.1. File Upload / S3 Key / URL Import Sync Response (201 Created)
For file upload, S3 key, inline base64, and URL import (sync mode), the video is created synchronously and returns immediately.
The response is the full Video object — the same shape returned by Get Video (Section 8), Update Video (Section 7), and the archive/unarchive/publish/unpublish/poster endpoints. See the Video Object reference (Section 8.4) for the complete field list, including video_posters and the CTA action_* fields.
id
string
❌
Encoded video ID
access
string
❌
Video visibility level ("public", "private", "unlisted")
audio_disabled
boolean
❌
Whether audio is disabled for the video (default: false)
caption
string
✅
Video title/caption
content_generation_type
string
✅
"aigc" when the video is marked as AI-generated; otherwise null
description
string
✅
Video description
duration
number
✅
Duration in seconds; null until it is known
hashtags
string[]
❌
Array of hashtag strings (empty if none provided)
archived_at
string
✅
ISO 8601 timestamp when the video is/should be archived
published_at
string
✅
ISO 8601 publish time; null for an unpublished draft. A future value indicates a scheduled publication
is_published
boolean
❌
Whether the video is currently live (published_at set and not in the future). Computed at request time
action_type
string
✅
Video CTA action type (e.g. "shop_now", "custom")
action_type_translation
string
✅
Translated CTA display label; for custom actions, this is the custom label
action_url
string
✅
Video CTA destination URL
action_custom_label
string
✅
Custom CTA label (used when action_type is "custom")
product_ids
string[]
❌
Array of Firework-encoded product IDs
variant_ids
string[]
❌
Array of Firework-encoded product variant IDs
custom_fields
object
❌
Custom key-value metadata
display_social_attributions
boolean
✅
Whether social attribution is displayed
external_media
object
✅
Social media source metadata (see External Media Schema)
thumbnail_url
string
✅
CDN URL for the video thumbnail image (540x960)
watch_url
string
❌
Web URL where a viewer can watch the video
video_posters
array
❌
Array of video poster images (empty if none). See Video Poster Schema (Section 8.4)
6.8.2. URL Import Async Response (202 Accepted)
When "async": true is set, the video file is downloaded and processed asynchronously. The response returns a video import object — not a video. The video will be created in the background.
Tracking progress: Configure webhooks to receive
video_created,video_updated, andvideo_import_failedevents (recommended), or poll withGET /api/v1/videos/imports/{id}at 5–10 second intervals. Webhook payloads includeimport_idto correlate events to this job.
id
string
❌
Encoded import job ID. Use with GET /api/v1/videos/imports/{id}
status
string
❌
Import status (see Import Status Values below)
video_id
string
✅
Encoded video ID. null initially, populated once the video record is created (before transcoding completes)
created_at
string
❌
ISO 8601 timestamp when the import was created
completed_at
string
✅
ISO 8601 timestamp when the import completed. null while running
Import Status Values
running
Import is in progress: downloading URL, uploading to S3, creating video, or waiting for transcoding. video_id may already be populated during this phase
completed
Transcoding finished successfully. The video is fully ready
errored
Import failed (download error, invalid format, duration out of range, transcode error)
6.9. Create Video Error Responses
400 Bad Request
Invalid request parameters, malformed JSON, unsupported file type, file size exceeds 5GB limit, etc
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Channel not found or membership not found
422 Unprocessable Entity
Video validation errors (e.g., caption too long, duration out of range, invalid values)
429 Too Many Requests
Rate limit exceeded (20 videos per 5 minutes per channel)
6.10. Examples
6.10.1. Option 1: File Upload (multipart/form-data)
CURL Request
HTTP Request
6.10.2. Option 2a: URL Import — Sync (default)
Response: 201 Created — same as file upload (see Section 6.10.4)
6.10.2b. Option 2b: URL Import — Async
Response: 202 Accepted — see Section 6.10.5
6.10.3. Option 3: S3 Key Upload (application/json) - Recommended for Large Files
First, get an upload signature and upload the file to S3 (see Section 4. Upload Signature or Section 5. Multipart Upload), then create the video with the S3 key.
CURL Request
HTTP Request
6.10.3b. Option 4: Inline Base64 Upload (application/json) - Short Clips Only
Embed the video bytes as base64 in the JSON body. Only for clips whose decoded size is ≤ 5 MB.
Response: 201 Created — same as file upload (see Section 6.10.4)
6.10.4. Success Response (File Upload / S3 Key) - 201 Created
6.10.5. Success Response (URL Import Async) - 202 Accepted
7. Update Video
Update an existing video's data on the Firework platform.
Endpoint: PATCH /api/v1/videos/{video_id} Authentication: Bearer token required Scope: videos:write Content Type: application/json
7.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
Content-Type
Must be application/json
✅
7.2. URL Parameters
video_id
string
✅
Firework encoded video ID
7.3. Request Body
caption
string
❌
Video title/caption
description
string
❌
Video description
access
string
❌
Video visibility: "public" or "private"
archived_at
string
❌
ISO 8601 timestamp when the video should be archived
audio_disabled
boolean
❌
Whether audio is disabled for the video
hashtags
string[]
❌
Array of hashtag strings
business_store_id
string
❌
Encoded business store ID
product_ids
string[]
❌
Array of product identifiers, see products tagging rules
variant_ids
string[]
❌
Array of product variant identifiers, see products tagging rules
custom_fields
object
❌
Custom key-value metadata (replace mode)
display_social_attributions
boolean
❌
Display social media attribution on video
external_media
object
❌
Social media source metadata (see External Media Schema)
poster_url
string
❌
URL to custom poster. Set to null or "" to remove. Omit to preserve.
video_hidden
boolean
❌
Hide video from PDP. With product_ids or variant_ids: applies to all listings. Without: bulk-updates existing. Omit to preserve existing state
7.4. Update Video Response
Success Response: 200 OK
Returns the full Video object — the same shape as Get Video (Section 8) and Create Video (Section 6.8). See the Video Object reference (Section 8.4) for the complete field list.
id
string
❌
Encoded video ID
access
string
❌
Video visibility level ("public", "private", "unlisted")
audio_disabled
boolean
❌
Whether audio is disabled for the video
caption
string
✅
Video title/caption
content_generation_type
string
✅
"aigc" when the video is marked as AI-generated; otherwise null
description
string
✅
Video description
duration
number
✅
Duration in seconds; null until it is known
hashtags
string[]
❌
Array of hashtag strings (empty if none provided)
archived_at
string
✅
ISO 8601 timestamp when the video is/should be archived
published_at
string
✅
ISO 8601 publish time; null for an unpublished draft. A future value indicates a scheduled publication
is_published
boolean
❌
Whether the video is currently live (published_at set and not in the future). Computed at request time
action_type
string
✅
Video CTA action type (e.g. "shop_now", "custom")
action_type_translation
string
✅
Translated CTA display label; for custom actions, this is the custom label
action_url
string
✅
Video CTA destination URL
action_custom_label
string
✅
Custom CTA label (used when action_type is "custom")
product_ids
string[]
❌
Array of Firework-encoded product IDs
variant_ids
string[]
❌
Array of Firework-encoded product variant IDs
custom_fields
object
❌
Custom key-value metadata
display_social_attributions
boolean
✅
Whether social attribution is displayed
external_media
object
✅
Social media source metadata (see External Media Schema)
thumbnail_url
string
✅
CDN URL for the video thumbnail image (540x960)
watch_url
string
❌
Web URL where a viewer can watch the video
video_posters
array
❌
Array of video poster images (empty if none). See Video Poster Schema (Section 8.4)
7.5. Update Video Error Responses
400 Bad Request
Invalid request parameters, malformed JSON, or validation errors
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video not found
422 Unprocessable Entity
Video validation errors (e.g., caption too long, invalid values)
7.6. Update Examples
7.6.1. CURL Request
7.6.2. HTTP Request
7.6.3. Success Response
7.6.4. Remove Custom Poster
To remove a custom poster from a video, set poster_url to null or an empty string:
Or with an empty string:
8. Get Video
Retrieve a video's details from the Firework platform.
Endpoint: GET /api/v1/videos/{video_id} Authentication: Bearer token required Scope: videos:read Content Type: N/A (no request body)
8.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
8.2. URL Parameters
video_id
string
✅
Firework encoded video ID
8.3. Query Parameters
fields
string
❌
Comma-separated top-level Video fields to return. id is always included. Omit or leave blank for the full Video object
Whitespace and duplicate field names are ignored. Unknown field names return 400 Bad Request. Valid names are: id, access, audio_disabled, caption, content_generation_type, description, duration, hashtags, archived_at, published_at, is_published, action_type, action_type_translation, action_url, action_custom_label, product_ids, variant_ids, custom_fields, display_social_attributions, external_media, thumbnail_url, watch_url, and video_posters.
8.4. Get Video Response
Success Response: 200 OK
Note: This endpoint returns a video that has been created. For videos imported via URL, use
GET /api/v1/videos/imports/{id}to track import status. Once the import completes, thevideo_idfrom the import response can be used with this endpoint.
Video Object
This is the canonical Video object shape. Create, Update, archive, unarchive, publish, unpublish, and add-poster return all of these fields. Get returns all fields unless the fields query parameter requests a sparse response.
id
string
❌
Encoded video ID
access
string
❌
Video visibility level ("public", "private", "unlisted")
audio_disabled
boolean
❌
Whether audio is disabled for the video
caption
string
✅
Video title/caption
content_generation_type
string
✅
"aigc" when the video is marked as AI-generated; otherwise null
description
string
✅
Video description
duration
number
✅
Duration in seconds; null until it is known
hashtags
string[]
❌
Array of hashtag strings (empty if none)
archived_at
string
✅
ISO 8601 timestamp when the video is/should be archived
published_at
string
✅
ISO 8601 publish time; null for an unpublished draft. A future value indicates a scheduled publication
is_published
boolean
❌
Whether the video is currently live (published_at set and not in the future). Computed at request time
action_type
string
✅
Video CTA action type (e.g. "shop_now", "custom")
action_type_translation
string
✅
Translated CTA display label; for custom actions, this is the custom label
action_url
string
✅
Video CTA destination URL
action_custom_label
string
✅
Custom CTA label (used when action_type is "custom")
product_ids
string[]
❌
Array of Firework-encoded product IDs
variant_ids
string[]
❌
Array of Firework-encoded product variant IDs
custom_fields
object
❌
Custom key-value metadata
display_social_attributions
boolean
✅
Whether social attribution is displayed
external_media
object
✅
Social media source metadata (see External Media Schema)
thumbnail_url
string
✅
CDN URL for the video thumbnail image (540x960)
watch_url
string
❌
Web URL where a viewer can watch the video
video_posters
array
❌
Array of video poster images (empty if none). See Video Poster Schema
Video Poster Schema
Each object in the video_posters array contains:
id
string
❌
Encoded poster ID (pass to DELETE .../posters/{poster_id})
url
string
❌
CDN URL for the poster image
aspect_ratio
string
✅
Aspect ratio label (e.g. "9:16", "16:9", "1:1")
format
string
❌
Image format ("jpg", "webp", "gif", "png")
width
integer
❌
Image width in pixels
height
integer
❌
Image height in pixels
video_poster_type
string
❌
Poster type: "static" or "animated"
source
string
✅
System that generated the poster; API-created posters default to "api"
external_id
string
✅
Generating system's poster ID; unique within the video and usable for batch updates
weight
number
✅
Rotation weight from 0 to 1; higher-weight posters are served first
8.5. Get Video Error Responses
400 Bad Request
The fields parameter contains an unknown field
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video not found
8.6. Get Video Examples
8.6.1. CURL Request
8.6.2. Sparse-Fields HTTP Request
The sparse response contains id, even though it was not requested:
8.6.3. Full Success Response
9. List Videos
List the videos in a channel.
Returns a cursor-paginated list of a channel's videos. Results are ordered most-recently-created first (descending by ID) when no cursor is supplied.
Endpoint: GET /api/v1/videos Authentication: Bearer token required Scope: videos:read Content Type: N/A (no request body)
channel_idis optional when the token resolves to a single channel (an app token whose business has exactly one channel); otherwise it is required.
The
paginationobject includestotal_entries, the exact number of videos matching the current channel and filters across all cursor pages.
9.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
9.2. Query Parameters
channel_id
string
❌*
Encoded channel ID. Optional when the token's business has a single channel; otherwise required
status
string
❌
Filter by video status
access
string
❌
Filter by access level (public, private, unlisted)
video_type
string
❌
Filter by video type (e.g. live_stream)
hashtag
string
❌
Filter by one exact, case-insensitive hashtag. A leading # is significant; use the form returned in the video's hashtags array
q
string
❌
Case-insensitive substring search on the caption. % and _ are treated as literal characters
archived
boolean
❌
Omitted or false returns only non-archived videos; true returns only archived videos
published
boolean
❌
Filter by published state (true / false)
fields
string
❌
Comma-separated top-level Video fields to return. id is always included. Omit or leave blank for full objects
after
string
❌
Opaque cursor for the next page (from pagination.cursor or links.next). Ascending order
before
string
❌
Opaque cursor for the previous page. Descending order
page_size
integer
❌
Items per page. Range 1–100. Default 10. Values above the max are clamped
* Required unless the token's business has exactly one channel, in which case that channel is used by default.
9.3. List Videos Response
Success Response: 200 OK
The response is an object containing the videos array plus a links object and a pagination object (per the public API cursor-pagination standard). Each element of videos is a full Video object unless fields requests a sparse response — see the Video Object reference (Section 8.4). The fields parameter accepts the same names and behavior as Get Video (Section 8.3).
videos
array
❌
Array of Video objects (see the Video Object reference, Section 8.4)
links
object
❌
Pagination links (see below). Always present
pagination
object
❌
Pagination state (see below). Always present
paging
object
✅
Deprecated legacy pagination object (next/prev URLs), retained during the migration window. Prefer links + pagination
links object — this is a forward-only cursor feed, so only next is present (no prev):
next
string / null
✅
Relative path (including query string) to the next page, or null when there is no next page. Treat as opaque and follow verbatim
pagination object — cursor strategy:
cursor
string / null
✅
Opaque cursor for the next page (pass back as after); null when exhausted
has_more
boolean
❌
true when another page is available now
total_entries
integer
❌
Total videos matching the current channel and filters across all cursor pages
9.4. List Videos Error Responses
400 Bad Request
Invalid pagination/query parameter, or an unknown fields name
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions, or no access to the channel
404 Not Found
Channel not found
9.5. List Videos Examples
9.5.1. CURL Request
9.5.2. Search with Sparse Fields
9.5.3. Success Response
Each item in videos is a full Video object unless fields requests a sparse response (abbreviated below — see the Video Object reference, Section 8.4, for all fields). A deprecated paging object is also present in the response body during the migration window; prefer links and pagination.
Following pages: treat
links.nextas opaque and request it verbatim (it already carries the filters and cursor), or passpagination.cursorback as theafterquery parameter. Whenlinks.nextisnull(andpagination.cursorisnull), you have reached the last page.
10. Delete Video
Delete a video from the Firework platform.
Soft-deletes the video (it is marked deleted, not hard-deleted).
Endpoint: DELETE /api/v1/videos/{video_id} Authentication: Bearer token required Scope: videos:write
10.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
10.2. URL Parameters
video_id
string
✅
Firework encoded video ID
10.3. Delete Video Response
Success Response: 204 No Content
No response body.
10.4. Delete Video Error Responses
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video not found
10.5. Delete Video Example
Response: 204 No Content
11. Archive and Unarchive Video
Archive or restore a video.
Archiving sets the video's archived_at timestamp to the current time; unarchiving clears it (archived_at becomes null). Both return the full updated Video object.
Endpoints:
POST /api/v1/videos/{video_id}/archivePOST /api/v1/videos/{video_id}/unarchive
Authentication: Bearer token required Scope: videos:write Content Type: N/A (no request body)
11.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
11.2. URL Parameters
video_id
string
✅
Firework encoded video ID
11.3. Response
Success Response: 200 OK
Returns the full Video object (see the Video Object reference, Section 8.4). After archiving, archived_at is set to the time of the request; after unarchiving, archived_at is null.
11.4. Error Responses
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video not found
11.5. Examples
Archive a video:
Unarchive a video:
Response (archive): 200 OK — the Video object with archived_at populated:
12. Publish and Unpublish Video
Publish a video immediately, schedule it for later, or revert it to a draft.
Endpoints:
POST /api/v1/videos/{video_id}/publishPOST /api/v1/videos/{video_id}/unpublish
Authentication: Bearer token required Scope: videos:write Content Type: application/json
12.1. Publish
Publishes the video. The behavior depends on the optional published_at field in the request body:
Omit the body (or send
{}/published_at: null) → the video is published immediately.published_atis a future time → the video is scheduled. It becomes visible automatically once the time passes, with no further API call.is_publishedstaysfalseuntil then.published_atis in the past, or more than 28 days in the future →422 Unprocessable Entity. Scheduling is capped at 28 days from now.
Send the request with Content-Type: application/json.
12.1.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
Content-Type
Must be application/json
✅
12.1.2. URL Parameters
video_id
string
✅
Firework encoded video ID
12.1.3. Request Body
published_at
string
❌
ISO 8601 time to publish. A future time (within 28 days) schedules the video; a time in the past or beyond 28 days returns 422. Omit to publish now
12.1.4. Response
Success Response: 200 OK
Returns the full Video object (see the Video Object reference, Section 8.4). For an immediate publish, published_at is set to the request time and is_published is true. For a scheduled publish, published_at is the future time and is_published is false until that time passes.
12.1.5. Publish Error Responses
400 Bad Request
Malformed request (e.g. invalid JSON)
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video not found
422 Unprocessable Entity
published_at is not a valid ISO 8601 datetime, is in the past, or is more than 28 days out
12.1.6. Publish Examples
Publish immediately:
Schedule for a future time (within 28 days):
Response (scheduled): 200 OK
12.2. Unpublish
Reverts the video to an unpublished draft by clearing published_at. The video is hidden from feeds and product lookups until it is published again. Takes no request body.
12.2.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
12.2.2. URL Parameters
video_id
string
✅
Firework encoded video ID
12.2.3. Response
Success Response: 200 OK
Returns the full Video object (see the Video Object reference, Section 8.4) with published_at set to null and is_published set to false.
12.2.4. Unpublish Error Responses
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video not found
12.2.5. Unpublish Example
13. Video Subtitles
Add or remove subtitle tracks on a video.
13.1. Add Subtitle
Adds a subtitle track (.vtt or .srt, max 5MB). The subtitle source can be supplied in three ways:
Multipart file (
multipart/form-data) — upload the subtitle file directly.Inline content (
application/json) — pass the raw.vtt/.srttext in thecontentfield.URL (
application/json) — pass a publicurlthe server downloads.
Endpoint: POST /api/v1/videos/{video_id}/subtitles Authentication: Bearer token required Scope: videos:write Content Type: multipart/form-data or application/json
13.1.1. URL Parameters
video_id
string
✅
Firework encoded video ID
13.1.2. Request Body
Option 1: Multipart file (multipart/form-data)
language
string
✅
BCP-47 language code, e.g. en or en-US
file
file
✅
Subtitle file (.vtt or .srt, max 5MB)
is_cc
boolean
❌
Whether this is a closed-captions track (default false)
Option 2: Inline content (application/json)
language
string
✅
BCP-47 language code, e.g. en or en-US
content
string
✅
The subtitle file contents (.vtt or .srt text, max 5MB)
is_cc
boolean
❌
Whether this is a closed-captions track (default false)
Option 3: URL (application/json)
language
string
✅
BCP-47 language code, e.g. en or en-US
url
string
✅
HTTP(S) URL of a .vtt or .srt file (max 5MB)
is_cc
boolean
❌
Whether this is a closed-captions track (default false)
13.1.3. Add Subtitle Response
Success Response: 201 Created
id
string
❌
Encoded subtitle ID
language
string
❌
BCP-47 language code
is_cc
boolean
❌
Whether this is a closed-captions track
13.1.4. Add Subtitle Error Responses
400 Bad Request
Missing required fields, unsupported file (expected .vtt/.srt), or file/content over 5MB
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video not found
422 Unprocessable Entity
Subtitle validation error
13.1.5. Add Subtitle Examples
Multipart file upload:
Inline content (JSON):
From a URL (JSON):
Response: 201 Created
13.2. Delete Subtitle
Removes a subtitle track from a video.
Endpoint: DELETE /api/v1/videos/{video_id}/subtitles/{subtitle_id} Authentication: Bearer token required Scope: videos:write
13.2.1. URL Parameters
video_id
string
✅
Firework encoded video ID
subtitle_id
string
✅
Firework encoded subtitle ID
13.2.2. Delete Subtitle Response
Success Response: 204 No Content
No response body.
13.2.3. Delete Subtitle Error Responses
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video or subtitle not found (or subtitle not on this video)
13.2.4. Delete Subtitle Example
Response: 204 No Content
14. Video Posters
Add or remove poster images on a video.
14.1. Add Poster
Adds a poster image to the video by downloading it from a URL. The image is stored on Firework's CDN and appended to the video's video_posters.
Endpoint: POST /api/v1/videos/{video_id}/posters Authentication: Bearer token required Scope: videos:write Content Type: application/json
Poster vs.
poster_urlon create/update:POST .../postersadds a poster to the video's poster set and returns the video. Theposter_urlfield on Create/Update Video replaces the video's posters instead. Use whichever fits your flow.
14.1.1. URL Parameters
video_id
string
✅
Firework encoded video ID
14.1.2. Request Body
url
string
✅
HTTP(S) URL ending in .jpg, .jpeg, .png, or .webp
source
string
❌
Generating system; defaults to "api"
video_poster_type
string
❌
"static" or "animated"; derived from the file format when omitted
weight
number
❌
Rotation weight from 0 to 1
external_id
string
❌
Generating system's poster ID; must be unique within this video
14.1.3. Add Poster Response
Success Response: 201 Created
Returns the full Video object (see the Video Object reference, Section 8.4) with the new poster included in video_posters. Each poster has an id you can use to delete it (see Video Poster Schema, Section 8.4).
14.1.4. Add Poster Error Responses
400 Bad Request
Missing url, invalid/unsupported poster format, missing file extension, or the image could not be fetched
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video not found
422 Unprocessable Entity
Poster validation error
14.1.5. Add Poster Example
Response: 201 Created — the Video object with the new poster in video_posters:
14.2. Update One Poster Weight
Update the rotation weight of one poster. Use the encoded video_posters[].id returned by a Video response.
Endpoint: PATCH /api/v1/videos/{video_id}/posters/{poster_id}
Authentication: Bearer token required
Scope: videos:write
Content Type: application/json
14.2.1. Request
video_id
path
string
✅
Firework encoded video ID
poster_id
path
string
✅
Firework encoded poster ID
weight
body
number
✅
Rotation weight from 0 to 1
14.2.2. Response and Errors
Returns 200 OK with the full Video object and its updated video_posters array.
400 Bad Request
Missing or non-numeric weight
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video or poster not found, or poster is on another video
422 Unprocessable Entity
Weight is outside the accepted 0-to-1 range
14.3. Update Poster Weights in a Batch
Update up to 100 poster weights atomically. Every item must resolve and validate or no changes are applied. Address each poster by exactly one of its Firework id or its partner-supplied external_id; duplicate references are rejected.
Endpoint: PATCH /api/v1/videos/{video_id}/posters
Authentication: Bearer token required
Scope: videos:write
Content Type: application/json
14.3.1. Request Body
posters
object[]
✅
Non-empty array, maximum 100 entries
posters[].id
string
Conditional
Encoded poster ID; mutually exclusive with external_id
posters[].external_id
string
Conditional
Partner poster ID; mutually exclusive with id
posters[].weight
number
✅
Rotation weight from 0 to 1
14.3.2. Response and Errors
Returns 200 OK with the full Video object and the reordered, updated poster set. Invalid references, duplicate references, a batch over 100, or an item that supplies both or neither ID are rejected without applying any update.
14.4. Delete Poster
Removes a poster image from a video. Get the poster_id from the video_posters[].id field of any Video response.
Endpoint: DELETE /api/v1/videos/{video_id}/posters/{poster_id} Authentication: Bearer token required Scope: videos:write
14.4.1. URL Parameters
video_id
string
✅
Firework encoded video ID
poster_id
string
✅
Firework encoded poster ID
14.4.2. Delete Poster Response
Success Response: 204 No Content
No response body.
14.4.3. Delete Poster Error Responses
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Video or poster not found (or poster not on this video)
14.4.4. Delete Poster Example
Response: 204 No Content
15. Download Video
Get a CDN URL for the video's transcoded file, together with file facts. The returned file is the same rendition used by the business portal's download action.
Endpoint: GET /api/v1/videos/{video_id}/download
Authentication: Bearer token required
Scope: videos:read
Subscription feature: content_download
15.1. Request
video_id
path
string
✅
Firework encoded video ID
15.2. Download Response
Success Response: 200 OK
download_url
string
❌
CDN URL of the video's transcoded file
format
string
✅
Video format
width
integer
✅
Width in pixels
height
integer
✅
Height in pixels
duration
number
✅
Duration in seconds
15.3. Download Error Responses
401 Unauthorized
Invalid or missing authentication token
402 Payment Required
The business subscription does not enable content_download
403 Forbidden
Insufficient scope or no access to the video
404 Not Found
Video not found
15.4. Batch Download URLs
Get download URLs and file facts for multiple videos in one request. The response preserves the requested ID order and fails as a whole if any requested video is missing or inaccessible.
Endpoint: POST /api/v1/videos/download_urls
Authentication: Bearer token required
Scope: videos:read
Subscription feature: content_download
Content Type: application/json
15.4.1. Request Body
video_ids
string[]
✅
Non-empty array of 1–50 Firework encoded video IDs
15.4.2. Batch Download Response
Success Response: 200 OK
videos
array
❌
Download results in the same order as video_ids
Each result contains:
id
string
❌
Firework encoded video ID
download_url
string
✅
CDN URL of the transcoded file, or null when no downloadable source is available
format
string
✅
Video format
width
integer
✅
Width in pixels
height
integer
✅
Height in pixels
duration
number
✅
Duration in seconds
15.4.3. Batch Download Error Responses
400 Bad Request
video_ids is missing, empty, or contains more than 50 IDs
401 Unauthorized
Invalid or missing authentication token
402 Payment Required
The business subscription does not enable content_download
403 Forbidden
Insufficient scope, or at least one video is inaccessible
404 Not Found
At least one video does not exist
15.4.4. Batch Download Example
16. AI Product Matching
AI product matching is asynchronous: start a job, poll the match list, then accept the complete set of products you want to keep. Matching uses the business's max_product_matching job quota; reading existing matches has no subscription-feature gate.
GET /api/v1/videos/{video_id}/product_matches
videos:read
200
Read job status and scored recommendations
POST /api/v1/videos/{video_id}/product_matches
videos:write
202
Start matching; optional auto_accept
POST /api/v1/videos/{video_id}/product_matches/accept
videos:write
200
Accept the full desired subset of matches
The accept operation has replacement semantics: every current match whose product_id is not in the request becomes rejected. Unknown product IDs fail the whole request. See AI Content for complete request and response schemas, polling states, quota errors, and examples.
17. Get Video Import Status
Track the status of an async URL import.
Use this endpoint to check the progress of a video import initiated via the URL import method. Once the import completes successfully, the response includes the video_id which can be used with the Get Video (Section 8) and Update Video (Section 7) endpoints.
Tip: For real-time notifications instead of polling, configure webhooks. The
video_created,video_updated, andvideo_import_failedevents includeimport_idso you can correlate events back to this import job.
Endpoint: GET /api/v1/videos/imports/{id} Authentication: Bearer token required Scope: videos:read
17.1. Request Headers
Authorization
Bearer token: Bearer {ACCESS_TOKEN}
✅
17.2. URL Parameters
id
string
✅
Encoded import job ID (from the 202 response)
17.3. Get Import Status Response
Success Response: 200 OK
id
string
❌
Encoded import job ID
status
string
❌
Import status: "running", "completed", or "errored"
video_id
string
✅
Encoded video ID. null initially, populated once the video record is created (may appear while still running)
created_at
string
❌
ISO 8601 timestamp when the import was created
completed_at
string
✅
ISO 8601 timestamp when the import completed. null while running
17.4. Get Import Status Error Responses
401 Unauthorized
Invalid or missing authentication token
403 Forbidden
Insufficient permissions
404 Not Found
Import job not found
17.5. Get Import Status Examples
17.5.1. CURL Request
17.5.2. Response (Running)
17.5.3. Response (Completed)
Next step: Use the
video_idwithGET /api/v1/videos/{video_id}to get the full video details.
17.5.4. Response (Errored)
18. Custom Fields Extension
The Video API supports custom metadata through the custom_fields parameter. This allows you to attach arbitrary key-value pairs to videos for tracking and analytics purposes.
Key Points:
Replace Mode: Providing
custom_fieldsreplaces ALL existing custom fieldsPreserve Existing: Omit
custom_fieldsfrom request to keep existing valuesClear All: Use
custom_fields: {}to remove all custom fieldsValidation: Keys must match
^[a-z0-9_]{1,255}$, values max 1024 characters
Example with Custom Fields:
Last updated
Was this helpful?