Prerequisites
Before you begin, you’ll need:
A Bluma account (sign up here )
An API key (create one here )
A command line tool like curl or an HTTP client
New to APIs? Don’t worry! This guide will walk you through everything step by step.
Step 1: Get Your API Key
Log in to your Bluma dashboard
Navigate to API Keys
Click Create API Key
Choose Test environment for development
Copy and save your API key (it’s only shown once!)
Never commit your API key to version control or share it publicly. Store it as an environment variable.
Step 2: Explore Available Templates
Let’s see what video templates are available:
curl https://api.getbluma.com/api/v1/templates \
-H "Authorization: Bearer YOUR_API_KEY"
{
"templates" : [
{
"id" : "consumerclub-discord-zoomed" ,
"name" : "ConsumerClub Discord Zoomed" ,
"description" : "Discord conversation style video" ,
"category" : "entertainment" ,
"credits_per_video" : 2 ,
"duration_range" : { "min" : 30 , "max" : 60 }
},
{
"id" : "cat-explainer-v2" ,
"name" : "Cat Explainer V2" ,
"description" : "Educational content explained by cats" ,
"category" : "educational" ,
"credits_per_video" : 2 ,
"duration_range" : { "min" : 30 , "max" : 60 }
},
{
"id" : "rick-morty-explainer" ,
"name" : "Rick & Morty Meme Explainer" ,
"description" : "Meme-style explainer videos" ,
"category" : "entertainment" ,
"credits_per_video" : 2 ,
"duration_range" : { "min" : 30 , "max" : 60 }
},
{
"id" : "steel-griffin-explainer" ,
"name" : "Steel Griffin Explainer" ,
"description" : "Educational explainer format" ,
"category" : "educational" ,
"credits_per_video" : 2 ,
"duration_range" : { "min" : 30 , "max" : 60 }
},
{
"id" : "ugc-text-overlay" ,
"name" : "UGC Text Overlay" ,
"description" : "User-generated content style with text" ,
"category" : "ugc" ,
"credits_per_video" : 2 ,
"duration_range" : { "min" : 15 , "max" : 30 }
}
],
"total" : 5
}
Step 3: Generate Your First Video
Now let’s create a video using the consumerclub-discord-zoomed template:
curl -X POST https://api.getbluma.com/api/v1/videos \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "consumerclub-discord-zoomed",
"context": {
"prompt": "Create a Discord conversation about discovering a great product"
}
}'
{
"id" : "batch_abc123xyz" ,
"status" : "queued" ,
"template_id" : "consumerclub-discord-zoomed" ,
"created_at" : "2025-11-03T10:30:00Z" ,
"estimated_completion" : "2025-11-03T10:32:00Z" ,
"status_url" : "/v1/videos/batch_abc123xyz" ,
"credits_charged" : 2
}
Test Mode : Videos generated with test API keys are watermarked and don’t consume credits. Perfect for development!
Step 4: Check Video Status
Video generation is asynchronous. Check the status using the id from the response:
curl https://api.getbluma.com/api/v1/videos/batch_abc123xyz \
-H "Authorization: Bearer YOUR_API_KEY"
View Response (Processing)
{
"id" : "batch_abc123xyz" ,
"status" : "processing" ,
"progress" : 65 ,
"template_id" : "consumerclub-discord-zoomed" ,
"created_at" : "2025-11-03T10:30:00Z"
}
View Response (Completed)
{
"id" : "batch_abc123xyz" ,
"status" : "completed" ,
"progress" : 100 ,
"template_id" : "consumerclub-discord-zoomed" ,
"url" : "https://cdn.getbluma.com/videos/batch_abc123xyz.mp4" ,
"thumbnail_url" : "https://cdn.getbluma.com/thumbnails/batch_abc123xyz.jpg" ,
"duration" : 45 ,
"size_bytes" : 8453120 ,
"created_at" : "2025-11-03T10:30:00Z" ,
"completed_at" : "2025-11-03T10:31:45Z"
}
Step 5: Download Your Video
Once the status is completed, get a signed download URL:
curl https://api.getbluma.com/api/v1/videos/batch_abc123xyz/download \
-H "Authorization: Bearer YOUR_API_KEY"
{
"download_url" : "https://cdn.getbluma.com/videos/batch_abc123xyz.mp4?signed=..." ,
"expires_at" : "2025-11-03T11:31:45Z"
}
The download_url is a temporary signed URL that expires in 1 hour. Download your video before it expires!
Code Examples
Node.js / TypeScript
const BLUMA_API_KEY = process . env . BLUMA_API_KEY ;
async function generateVideo () {
// Create video
const createRes = await fetch ( 'https://api.getbluma.com/api/v1/videos' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ BLUMA_API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
template_id: 'consumerclub-discord-zoomed' ,
context: {
prompt: 'Create a fun personality quiz about food'
}
})
});
const { id } = await createRes . json ();
console . log ( 'Video queued:' , id );
// Poll for completion
let status = 'queued' ;
while ( status !== 'completed' && status !== 'failed' ) {
await new Promise ( resolve => setTimeout ( resolve , 5000 )); // Wait 5s
const statusRes = await fetch ( `https://api.getbluma.com/api/v1/videos/ ${ id } ` , {
headers: { 'Authorization' : `Bearer ${ BLUMA_API_KEY } ` }
});
const data = await statusRes . json ();
status = data . status ;
console . log ( `Status: ${ status } ( ${ data . progress } %)` );
}
if ( status === 'completed' ) {
// Get download URL
const downloadRes = await fetch (
`https://api.getbluma.com/api/v1/videos/ ${ id } /download` ,
{ headers: { 'Authorization' : `Bearer ${ BLUMA_API_KEY } ` } }
);
const { download_url } = await downloadRes . json ();
console . log ( 'Video ready:' , download_url );
}
}
generateVideo ();
Python
import requests
import time
import os
BLUMA_API_KEY = os.getenv( 'BLUMA_API_KEY' )
BASE_URL = 'https://api.getbluma.com/api/v1'
HEADERS = {
'Authorization' : f 'Bearer { BLUMA_API_KEY } ' ,
'Content-Type' : 'application/json'
}
# Create video
response = requests.post(
f ' { BASE_URL } /videos' ,
headers = HEADERS ,
json = {
'template_id' : 'consumerclub-discord-zoomed' ,
'context' : {
'prompt' : 'Create a fun personality quiz about food'
}
}
)
video_id = response.json()[ 'id' ]
print ( f 'Video queued: { video_id } ' )
# Poll for completion
while True :
response = requests.get(
f ' { BASE_URL } /videos/ { video_id } ' ,
headers = HEADERS
)
data = response.json()
status = data[ 'status' ]
progress = data.get( 'progress' , 0 )
print ( f 'Status: { status } ( { progress } %)' )
if status == 'completed' :
# Get download URL
response = requests.get(
f ' { BASE_URL } /videos/ { video_id } /download' ,
headers = HEADERS
)
download_url = response.json()[ 'download_url' ]
print ( f 'Video ready: { download_url } ' )
break
elif status == 'failed' :
print ( 'Video generation failed' )
break
time.sleep( 5 ) # Wait 5 seconds
Next Steps
Common Issues
Make sure your API key is correct and included in the Authorization header as Bearer YOUR_API_KEY.
Check your credit balance at /v1/credits/balance. Upgrade your plan or purchase more credits.
Video generation is taking too long
Video generation typically takes 2-5 minutes depending on the template. Complex templates with AI generation may take longer. Consider using webhooks instead of polling.
Support
Need help? We’re here: