Prerequisites

Before you begin, you’ll need:
  1. A Bluma account (sign up here)
  2. An API key (create one here)
  3. 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

  1. Log in to your Bluma dashboard
  2. Navigate to API Keys
  3. Click Create API Key
  4. Choose Test environment for development
  5. 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"
{
  "id": "batch_abc123xyz",
  "status": "processing",
  "progress": 65,
  "template_id": "consumerclub-discord-zoomed",
  "created_at": "2025-11-03T10:30:00Z"
}
{
  "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 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: