Introduction

Welcome to the BeamGo API documentation. Our API allows you to integrate powerful AI video generation features directly into your applications.

Core Concepts

Before you begin, it's important to understand a few core concepts about the API's design:

  • Asynchronous Nature: Video generation can take time. Our API is asynchronous. When you submit a request, we immediately return a job_id. You then use this ID to check the job's status until it's complete.
  • Workflows: A "workflow" defines a type of task you can perform, such as text_to_video. Each workflow has its own parameters and credit cost.
  • Jobs: A "job" represents a single, specific task you've requested, like generating a video from a particular prompt.
  • Webhooks: Instead of constantly checking a job's status (polling), we highly recommend using webhooks to receive a notification on your server as soon as a job is finished. This is more efficient and you'll get notified instantly when jobs complete.
API Base URL: https://api.beamgo.io
Try it Live! For a hands-on experience, you can explore and test our API endpoints interactively in our Swagger UI playground.

Authentication

All API requests require authentication using an API key. You can manage your API keys in your account dashboard.

Using Your API Key

Include your API key in the X-API-Key header of every request:

X-API-Key: your_api_key_here
Keep your API keys secure! Do not share them in publicly accessible areas such as GitHub, client-side code, or anywhere else.

Workflows

Workflows define the different AI tasks you can perform. Each workflow has a unique ID, specific parameters, and a credit cost.

GET /workflows

Retrieves a list of all available workflows, their descriptions, and credit costs.

Example Request

cURL
Python
curl "https://api.beamgo.io/workflows" \
  -H "X-API-Key: your_api_key_here"
import requests

url = "https://api.beamgo.io/workflows"
headers = {"X-API-Key": "your_api_key_here"}
response = requests.get(url, headers=headers)
print(response.json())

Response Body

{
  "workflows": [
    {
      "id": "text_to_video",
      "description": "Generate a video from a text prompt",
      "cost": 25
    },
    {
      "id": "image_to_video",
      "description": "Animate an image with optional text guidance",
      "cost": 25
    },
    {
      "id": "sound_to_video",
      "description": "Generate lipsync video from audio and image",
      "cost": 25
    }
  ]
}

Text-to-Video

POST /workflows/text_to_video/run

Generate a video from a text prompt.

Request Parameters

ParameterTypeRequiredDescription
promptstringYesDetailed description of the video content (max 1000 chars)
aspect_ratiostringNoOne of: "1:1", "landscape (16:9)", "portrait (9:16)". Default: "landscape (16:9)"
seedintegerNoSeed for generation (0 = random). Default: 0

Example Request

cURL
Python
Node.js
curl -X POST "https://api.beamgo.io/workflows/text_to_video/run" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A majestic dragon flying through a stormy sky",
    "aspect_ratio": "landscape (16:9)",
    "seed": 0
  }'
import requests

url = "https://api.beamgo.io/workflows/text_to_video/run"
headers = {"X-API-Key": "your_api_key_here"}
data = {
    "prompt": "A majestic dragon flying through a stormy sky",
    "aspect_ratio": "landscape (16:9)",
    "seed": 0
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
// Using node-fetch: npm install node-fetch
import fetch from 'node-fetch';

const API_URL = "https://api.beamgo.io/workflows/text_to_video/run";
const API_KEY = "your_api_key_here";

const payload = {
    prompt: "A majestic dragon flying through a stormy sky",
    aspect_ratio: "landscape (16:9)",
    seed: 0
};

const response = await fetch(API_URL, {
    method: 'POST',
    headers: { 
        'X-API-Key': API_KEY, 
        'Content-Type': 'application/json' 
    },
    body: JSON.stringify(payload)
});

const data = await response.json();
console.log(response.status, data);

Response Body (202 Accepted)

{
  "job_id": "123e4567-e89b-12d3-a456-426614174000",
  "message": "Workflow job accepted."
}

Image-to-Video

POST /workflows/image_to_video/run

Animate an image or extend a video with optional text guidance. Supports images (PNG, JPEG, WebP) and videos (MP4, WebM). Files must be sent as multipart/form-data.

💡 New Feature: Video Extension
You can now extend existing videos by providing either:
• A video file directly (max 20MB, 30s) - the last frame will be extracted and animated
• An extend_from_job_id parameter to continue a previously generated video

Request Parameters

ParameterTypeRequiredDescription
input_filefileYes*Image file (PNG, JPEG, WebP, max 2MB) OR Video file (MP4, WebM, max 20MB, 30s). *Required unless using extend_from_job_id
promptstringNoOptional text prompt to guide the animation (max 1000 chars)
seedintegerNoSeed for generation (0 = random). Default: 0
extend_from_job_idstring (UUID)NoJob ID of a previously generated video to extend. When provided, the last frame of that video will be used as the starting point.

Example Request

cURL
Python
Node.js
# Example 1: Animate an image
curl -X POST "https://api.beamgo.io/workflows/image_to_video/run" \
  -H "X-API-Key: your_api_key_here" \
  -F "input_file=@/path/to/image.jpg" \
  -F "prompt=make the image snow lightly" \
  -F "seed=54321"

# Example 2: Extend an existing video
curl -X POST "https://api.beamgo.io/workflows/image_to_video/run" \
  -H "X-API-Key: your_api_key_here" \
  -F "extend_from_job_id=123e4567-e89b-12d3-a456-426614174000" \
  -F "prompt=continue the scene with more movement"

# Example 3: Upload a video directly
curl -X POST "https://api.beamgo.io/workflows/image_to_video/run" \
  -H "X-API-Key: your_api_key_here" \
  -F "input_file=@/path/to/video.mp4" \
  -F "prompt=extend this video smoothly"
import requests

url = "https://api.beamgo.io/workflows/image_to_video/run"
headers = {"X-API-Key": "your_api_key_here"}

# Example 1: Animate an image
with open("image.jpg", "rb") as f:
    files = {"input_file": f}
    data = {"prompt": "make the image snow lightly", "seed": 54321}
    response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())

# Example 2: Extend a video
data = {
    "extend_from_job_id": "123e4567-e89b-12d3-a456-426614174000",
    "prompt": "continue the scene"
}
response = requests.post(url, headers=headers, data=data)
print(response.json())

# Example 3: Upload video file
with open("video.mp4", "rb") as f:
    files = {"input_file": f}
    data = {"prompt": "extend this video"}
    response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())
// Using 'form-data': npm install form-data node-fetch
import FormData from 'form-data';
import fs from 'fs';
import fetch from 'node-fetch';

const API_URL = "https://api.beamgo.io/workflows/image_to_video/run";
const API_KEY = "your_api_key_here";

// Example 1: Animate an image
const form1 = new FormData();
form1.append('input_file', fs.createReadStream('./image.jpg'));
form1.append('prompt', "make the image snow lightly");
form1.append('seed', 54321);

let response = await fetch(API_URL, {
    method: 'POST',
    headers: { 'X-API-Key': API_KEY },
    body: form1
});
console.log(await response.json());

// Example 2: Extend a video
const form2 = new FormData();
form2.append('extend_from_job_id', '123e4567-e89b-12d3-a456-426614174000');
form2.append('prompt', 'continue the scene');

response = await fetch(API_URL, {
    method: 'POST',
    headers: { 'X-API-Key': API_KEY },
    body: form2
});
console.log(await response.json());

Response Body (202 Accepted)

{
  "job_id": "123e4567-e89b-12d3-a456-426614174000",
  "message": "Workflow job accepted."
}

Sound-to-Video

POST /workflows/sound_to_video/run

Generate a lipsync video by combining an audio file with a static image. The AI will animate the image to match the audio.

Request Parameters

ParameterTypeRequiredDescription
input_audiofileYesAudio file (WAV or MP3, max 1MB)
input_imagefileYesImage file (PNG, JPEG, WebP, max 2MB)
promptstringNoOptional text prompt to guide the animation (max 1000 chars)
durationstringNoVideo duration: "0:05" or "0:10" (paid plans only). Default: "0:05"
seedintegerNoSeed for generation (0 = random). Default: 0

Example Request

cURL
Python
Node.js
curl -X POST "https://api.beamgo.io/workflows/sound_to_video/run"   -H "X-API-Key: your_api_key_here"   -F "input_audio=@/path/to/speech.mp3"   -F "input_image=@/path/to/portrait.jpg"   -F "prompt=natural speaking animation"   -F "duration=0:05"   -F "seed=12345"
import requests

url = "https://api.beamgo.io/workflows/sound_to_video/run"
headers = {"X-API-Key": "your_api_key_here"}

with open("speech.mp3", "rb") as audio, open("portrait.jpg", "rb") as image:
    files = {
        "input_audio": audio,
        "input_image": image
    }
    data = {
        "prompt": "natural speaking animation",
        "duration": "0:05",
        "seed": 12345
    }
    response = requests.post(url, headers=headers, files=files, data=data)
    
print(response.json())
// Using 'form-data': npm install form-data node-fetch
import FormData from 'form-data';
import fs from 'fs';
import fetch from 'node-fetch';

const API_URL = "https://api.beamgo.io/workflows/sound_to_video/run";
const API_KEY = "your_api_key_here";

const form = new FormData();
form.append('input_audio', fs.createReadStream('./speech.mp3'));
form.append('input_image', fs.createReadStream('./portrait.jpg'));
form.append('prompt', 'natural speaking animation');
form.append('duration', '0:05');
form.append('seed', 12345);

const response = await fetch(API_URL, {
    method: 'POST',
    headers: { 
        'X-API-Key': API_KEY 
        // Content-Type is set automatically by form-data
    },
    body: form
});

const data = await response.json();
console.log(response.status, data);

Response Body (202 Accepted)

{
  "job_id": "123e4567-e89b-12d3-a456-426614174000",
  "message": "Workflow job accepted."
}

Jobs

After submitting a workflow, you receive a job_id. Use this ID to track the job's progress and retrieve results when complete.

GET /jobs/{job_id}/status

Retrieves the current status and details of a specific job. Returns a pre-signed URL for completed results.

💡 Tip: Use webhooks instead of polling for better efficiency. Webhooks notify you instantly when jobs complete, eliminating the need for repeated status checks.

Example Request

cURL
Python
Node.js
curl "https://api.beamgo.io/jobs/123e4567-e89b-12d3-a456-426614174000/status"   -H "X-API-Key: your_api_key_here"
import requests

job_id = "123e4567-e89b-12d3-a456-426614174000"
url = f"https://api.beamgo.io/jobs/{job_id}/status"
headers = {"X-API-Key": "your_api_key_here"}
response = requests.get(url, headers=headers)
print(response.json())
// Using node-fetch: npm install node-fetch
import fetch from 'node-fetch';

const JOB_ID = "123e4567-e89b-12d3-a456-426614174000";
const API_URL = `https://api.beamgo.io/jobs/${JOB_ID}/status`;
const API_KEY = "your_api_key_here";

const response = await fetch(API_URL, {
    method: 'GET',
    headers: { 'X-API-Key': API_KEY }
});

const data = await response.json();
console.log(response.status, data);

Response Body

The response varies based on job status:

Status: PENDING or PROCESSING

{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "PROCESSING",
  "progress": 45,
  "created_at": "2024-05-20T12:00:00Z",
  "updated_at": "2024-05-20T12:01:30Z"
}

Status: COMPLETED

{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "COMPLETED",
  "progress": 100,
  "result_video_url": "https://storage.example.com/video.mp4?signature=...",
  "thumbnail_url": "https://storage.example.com/thumbnail.jpg?signature=...",
  "created_at": "2024-05-20T12:00:00Z",
  "updated_at": "2024-05-20T12:02:45Z"
}

Status: FAILED

{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "status": "FAILED",
  "error_message": "Content moderation check failed",
  "created_at": "2024-05-20T12:00:00Z",
  "updated_at": "2024-05-20T12:00:15Z"
}
Note: Pre-signed URLs expire after 24 hours. Download your video promptly or call this endpoint again to get a fresh URL.
GET /jobs/{id}/download

Get Download URL

Retrieves only the download URL for a completed job. This is a lightweight alternative to the full status endpoint if you only need the result URL.

Example Request

cURL
Python
Node.js
curl "https://api.beamgo.io/jobs/123e4567-e89b-12d3-a456-426614174000/download"   -H "X-API-Key: your_api_key_here"
import requests
API_KEY = "your_api_key_here"
JOB_ID = "123e4567-e89b-12d3-a456-426614174000"
API_URL = f"https://api.beamgo.io/jobs/{JOB_ID}/download"

response = requests.get(API_URL, headers={"X-API-Key": API_KEY})
print(response.json())
// Using node-fetch: npm install node-fetch
import fetch from 'node-fetch';

const JOB_ID = "123e4567-e89b-12d3-a456-426614174000";
const API_URL = `https://api.beamgo.io/jobs/${JOB_ID}/download`;
const API_KEY = "your_api_key_here";

const response = await fetch(API_URL, {
    method: 'GET',
    headers: { 'X-API-Key': API_KEY }
});

const data = await response.json();
console.log(response.status, data);

Responses

200OK
{
  "download_url": "https://s3.your-region.amazonaws.com/..."
}
400Bad Request
{
  "detail": "Video not ready. Current status: PROCESSING"
}
GET /jobs

List Jobs

Returns a paginated list of your most recent jobs.

Query Parameters

ParameterTypeDefaultDescription
limitinteger10Number of jobs to return (1-50).
offsetinteger0Number of jobs to skip for pagination.

Example Request

cURL
Python
Node.js
# Gets jobs 11 through 20
curl "https://api.beamgo.io/jobs?limit=10&offset=10"   -H "X-API-Key: your_api_key_here"
import requests
API_KEY = "your_api_key_here"
API_URL = "https://api.beamgo.io/jobs"

params = {"limit": 10, "offset": 10}
response = requests.get(API_URL, headers={"X-API-Key": API_KEY}, params=params)

# The total number of jobs is in the response headers
total_count = response.headers.get("X-Total-Count")

print(f"Total jobs: {total_count}")
print(response.json())
// Using node-fetch: npm install node-fetch
import fetch from 'node-fetch';

const API_URL = "https://api.beamgo.io/jobs";
const API_KEY = "your_api_key_here";

const params = new URLSearchParams({
    limit: '10',
    offset: '10'
});

const response = await fetch(`${API_URL}?${params}`, {
    method: 'GET',
    headers: { 'X-API-Key': API_KEY }
});

const totalCount = response.headers.get('x-total-count');
const data = await response.json();

console.log(`Total jobs: ${totalCount}`);
console.log(response.status, data);

Response Headers

The response includes an X-Total-Count header indicating the total number of jobs for your account, which is useful for building pagination controls.

DELETE /jobs/{id}

Delete a Job

Deletes a job. This action is irreversible and will also delete the associated result file from storage. You can only delete jobs that are in a terminal state (COMPLETED, FAILED) or PENDING.

Note: You cannot delete a job that is currently PROCESSING.

Example Request

cURL
Python
Node.js
# Use -i to see the status code in the response headers
curl -X DELETE -i "https://api.beamgo.io/jobs/123e4567-e89b-12d3-a456-426614174000"   -H "X-API-Key: your_api_key_here"
import requests
API_KEY = "your_api_key_here"
JOB_ID = "123e4567-e89b-12d3-a456-426614174000"
API_URL = f"https://api.beamgo.io/jobs/{JOB_ID}"

response = requests.delete(API_URL, headers={"X-API-Key": API_KEY})

if response.status_code == 204:
    print("Job deleted successfully.")
else:
    print(f"Error: {response.status_code} - {response.text}")
// Using node-fetch: npm install node-fetch
import fetch from 'node-fetch';

const JOB_ID = "123e4567-e89b-12d3-a456-426614174000";
const API_URL = `https://api.beamgo.io/jobs/${JOB_ID}`;
const API_KEY = "your_api_key_here";

const response = await fetch(API_URL, {
    method: 'DELETE',
    headers: { 'X-API-Key': API_KEY }
});

if (response.status === 204) {
    console.log("Job deleted successfully.");
} else {
    const errorData = await response.text();
    console.log(`Error: ${response.status} - ${errorData}`);
}

Response

A successful deletion returns a 204 No Content status code with no body.


Webhooks

Webhooks are the recommended way to get notified about job status changes. Instead of polling for status, you can provide a URL and we will send a POST request to it when an event occurs.

⚠️ CRITICAL - READ CAREFULLY:

Your webhook secret_token is automatically generated and returned ONLY ONCE when you create the webhook.

  • You MUST save this token immediately - there is no way to retrieve it later
  • If you lose the token, you must DELETE and RECREATE the webhook to get a new one
  • The secret token is used to verify webhook signatures and ensure notifications genuinely come from BeamGo

Webhook Events

You can subscribe to the following events:

  • job.completed: Triggered when a job finishes successfully.
  • job.failed: Triggered when a job fails.

Webhook Payload

All webhook requests are sent with a JSON body containing the following structure:

{
  "id": "whk_1684678800.12345",
  "event": "job.completed",
  "created": "2024-05-21T11:00:00Z",
  "data": {
    "job_id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "COMPLETED",
    "workflow": "text_to_video",
    "created_at": "2024-05-21T10:55:00Z",
    "completed_at": "2024-05-21T11:00:00Z",
    "result_url": "https://s3.your-region.amazonaws.com/...",
    "error_message": null,
    "credits_cost": 25,
    "credits_deducted": true
  }
}

Verifying Signatures

To ensure that a webhook request genuinely came from us, we include a signature in the X-Webhook-Signature header. You should verify this signature using your webhook's secret token.

Python (FastAPI)
Node.js (Express)
import hmac
import hashlib
from fastapi import Request, HTTPException, Depends

WEBHOOK_SECRET = "whsec_your_secret_token_here"

async def verify_signature(request: Request):
    signature_header = request.headers.get("X-Webhook-Signature")
    if not signature_header:
        raise HTTPException(status_code=400, detail="Missing X-Webhook-Signature header")
    
    try: sig_type, signature = signature_header.split("=", 1)
    except ValueError: raise HTTPException(status_code=400, detail="Invalid signature format")
    if sig_type != "sha256": raise HTTPException(status_code=400, detail="Unsupported signature type")

    payload = await request.body()
    expected_signature = hmac.new(WEBHOOK_SECRET.encode(), payload, hashlib.sha256).hexdigest()

    if not hmac.compare_digest(expected_signature, signature):
        raise HTTPException(status_code=401, detail="Invalid signature")
    return True

# Usage: @app.post("/your-webhook-url", dependencies=[Depends(verify_signature)])
# async def handle_webhook(request: Request):
#     webhook_data = await request.json() ...
const crypto = require('crypto');
const express = require('express');

// Middleware to verify the signature
const verifySignature = (req, res, next) => {
    const signature = req.headers['x-webhook-signature'];
    if (!signature) return res.status(400).send('Missing signature');
    const [sigType, sig] = signature.split('=');
    if (sigType !== 'sha256') return res.status(400).send('Unsupported signature type');

    const WEBHOOK_SECRET = 'whsec_your_secret_token_here';
    const expectedSignature = crypto.createHmac('sha256', WEBHOOK_SECRET).update(req.body).digest('hex');

    if (!crypto.timingSafeEqual(Buffer.from(expectedSignature), Buffer.from(sig))) {
        return res.status(401).send('Invalid signature');
    }
    next();
};

const app = express();
// Use express.raw() to get the raw body, required for signature verification
app.post('/your-webhook-url', express.raw({ type: 'application/json' }), verifySignature, (req, res) => {
    const webhook_data = JSON.parse(req.body.toString());
    console.log('Received event:', webhook_data.event);
    res.status(200).send({ received: true });
});

Webhook Management Endpoints

POST/webhooks

Create Webhook

Creates a new webhook endpoint. A maximum of 10 webhooks are allowed per user. The secret_token is ONLY returned in this response.

Request Body
FieldTypeRequiredDescription
urlstring (URL)YesThe HTTPS URL to receive webhook events.
eventsarray[string]YesArray of events to subscribe to (e.g., ["job.completed", "job.failed"]).
descriptionstringNoAn optional description for your webhook.
Example Request
cURL
Python
Node.js
curl -X POST "https://api.beamgo.io/webhooks"   -H "X-API-Key: your_api_key_here"   -H "Content-Type: application/json"   -d '{
    "url": "https://myapp.com/api/ai-video-webhook",
    "events": ["job.completed", "job.failed"],
    "description": "Production notifications"
  }'
import requests
payload = {
    "url": "https://myapp.com/api/ai-video-webhook",
    "events": ["job.completed", "job.failed"],
    "description": "Production notifications"
}
response = requests.post(
    "https://api.beamgo.io/webhooks",
    headers={"X-API-Key": "your_api_key_here"},
    json=payload
)
result = response.json()

# SAVE THIS TOKEN IMMEDIATELY!
secret_token = result.get("secret_token")
print(f"Secret Token (save this!): {secret_token}")
// Using node-fetch: npm install node-fetch
import fetch from 'node-fetch';

const API_URL = "https://api.beamgo.io/webhooks";
const API_KEY = "your_api_key_here";

const payload = {
    url: "https://myapp.com/api/ai-video-webhook",
    events: ["job.completed", "job.failed"],
    description: "Production notifications"
};

const response = await fetch(API_URL, {
    method: 'POST',
    headers: {
        'X-API-Key': API_KEY,
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
});

const data = await response.json();
// SAVE THIS TOKEN IMMEDIATELY!
const secretToken = data.secret_token;
console.log(`Secret Token (save this!): ${secretToken}`);
console.log(response.status, data);
Example Response (Success)

The secret_token is only returned on creation. Save it immediately.

{
    "id": "e4a7a2a7-12d4-4f4c-83de-724f33a8b4a5",
    "url": "https://myapp.com/api/ai-video-webhook",
    "events": ["job.completed", "job.failed"],
    "description": "Production notifications",
    "is_active": true,
    "created_at": "2024-05-21T12:00:00Z",
    "secret_token": "whsec_..."
}
GET/webhooks

List Webhooks

Lists all of your currently configured webhooks. The secret token is not returned.

Example Request
cURL
Python
Node.js
curl "https://api.beamgo.io/webhooks" -H "X-API-Key: your_api_key_here"
import requests
response = requests.get("https://api.beamgo.io/webhooks", headers={"X-API-Key": "your_api_key_here"})
print(response.json())
// Using node-fetch: npm install node-fetch
import fetch from 'node-fetch';

const API_URL = "https://api.beamgo.io/webhooks";
const API_KEY = "your_api_key_here";

const response = await fetch(API_URL, {
    method: 'GET',
    headers: { 'X-API-Key': API_KEY }
});

const data = await response.json();
console.log(response.status, data);
DELETE/webhooks/{id}

Delete Webhook

Deletes the webhook configuration with the specified ID.

Example Request
cURL
Python
Node.js
curl -X DELETE "https://api.beamgo.io/webhooks/e4a7a2a7-12d4-4f4c-83de-724f33a8b4a5"   -H "X-API-Key: your_api_key_here"
import requests
WEBHOOK_ID = "e4a7a2a7-12d4-4f4c-83de-724f33a8b4a5"
response = requests.delete(
    f"https://api.beamgo.io/webhooks/{WEBHOOK_ID}",
    headers={"X-API-Key": "your_api_key_here"}
)
print(f"Status Code: {response.status_code}") # Expect 204 for success
// Using node-fetch: npm install node-fetch
import fetch from 'node-fetch';

const WEBHOOK_ID = "e4a7a2a7-12d4-4f4c-83de-724f33a8b4a5";
const API_URL = `https://api.beamgo.io/webhooks/${WEBHOOK_ID}`;
const API_KEY = "your_api_key_here";

const response = await fetch(API_URL, {
    method: 'DELETE',
    headers: { 'X-API-Key': API_KEY }
});

console.log(`Status Code: ${response.status}`); // Expect 204 for success
POST/webhooks/{id}/test

Test Webhook

Sends a test job.completed event to the specified webhook URL. The request body must be empty.

Example Request
cURL
Python
Node.js
curl -X POST "https://api.beamgo.io/webhooks/e4a7a2a7-12d4-4f4c-83de-724f33a8b4a5/test"   -H "X-API-Key: your_api_key_here"
import requests
WEBHOOK_ID = "e4a7a2a7-12d4-4f4c-83de-724f33a8b4a5"
response = requests.post(
    f"https://api.beamgo.io/webhooks/{WEBHOOK_ID}/test",
    headers={"X-API-Key": "your_api_key_here"}
)
print(response.status_code, response.json())
// Using node-fetch: npm install node-fetch
import fetch from 'node-fetch';

const WEBHOOK_ID = "e4a7a2a7-12d4-4f4c-83de-724f33a8b4a5";
const API_URL = `https://api.beamgo.io/webhooks/${WEBHOOK_ID}/test`;
const API_KEY = "your_api_key_here";

const response = await fetch(API_URL, {
    method: 'POST',
    headers: { 'X-API-Key': API_KEY }
});

const data = await response.json();
console.log(response.status, data);
Example Response
202Accepted
{
    "message": "Test webhook dispatch initiated. Check your endpoint for the payload.",
    "test_payload": {
        "job_id": "...", "status": "COMPLETED", ...
    }
}

Account

Manage your account, check credit balance, and view usage.

GET /users/me/profile

Retrieves your user profile and credit information.

Example Request

cURL
Python
Node.js
curl "https://api.beamgo.io/users/me/profile"   -H "X-API-Key: your_api_key_here"
import requests

url = "https://api.beamgo.io/users/me/profile"
headers = {"X-API-Key": "your_api_key_here"}
response = requests.get(url, headers=headers)
print(response.json())
// Using node-fetch: npm install node-fetch
import fetch from 'node-fetch';

const API_URL = "https://api.beamgo.io/users/me/profile";
const API_KEY = "your_api_key_here";

const response = await fetch(API_URL, {
    method: 'GET',
    headers: { 'X-API-Key': API_KEY }
});

const data = await response.json();
console.log(response.status, data);

Response Body

{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "username": "api_user_1",
  "plan_id": "pro",
  "created_at": "2024-05-20T12:00:00Z",
  "monthly_credits_allowance": 3500,
  "monthly_credits_balance": 3200,
  "purchased_credits_balance": 500,
  "reserved_credits": 50,
  "current_period_end": "2024-06-20T12:00:00Z",
  "next_plan_id": null,
  "available_credits": 3650
}

Rate Limits

To ensure platform stability, we apply several types of rate limits. Exceeding these limits will result in a 429 Too Many Requests error.

Job Creation Limits

Concurrent Jobs

This is the number of jobs you can have in PENDING or PROCESSING status at the same time.

PlanConcurrent Jobs
Free1
Basic2
Pro6
Enterprise20

Temporal Limits

These limits control the number of jobs you can create over a period of time.

PlanHourly LimitDaily Limit
Free22
Basic510
Pro1020
Enterprise100100

Polling Best Practices

If you choose to poll the GET /jobs/{id}/status endpoint to check job status, please follow these best practices:

Polling Rate Limits

To prevent server overload, we enforce the following limits on status polling:

PlanRequests per MinuteRequests per Hour
All Plans60 (1 req/sec)3600

⚠️ Polling Guidelines

  • Recommended interval: Poll every 5-10 seconds for active jobs
  • DO NOT poll faster than 1 request per second - this provides no benefit as videos take time to generate
  • Stop polling immediately once the job reaches a terminal state (COMPLETED, FAILED, or CANCELLED)
  • Use webhooks instead: Webhooks are more efficient, you'll get notified instantly, and you won't need to poll at all

Example: Polling with Proper Rate Limiting

import requests
import time

job_id = "123e4567-e89b-12d3-a456-426614174000"
url = f"https://api.beamgo.io/jobs/{job_id}/status"
headers = {"X-API-Key": "your_api_key_here"}

while True:
    response = requests.get(url, headers=headers)
    
    if response.status_code == 429:
        # Rate limited - wait before retrying
        retry_after = int(response.headers.get('Retry-After', 60))
        print(f"Rate limited. Waiting {retry_after} seconds...")
        time.sleep(retry_after)
        continue
    
    data = response.json()
    status = data.get('status')
    
    print(f"Job status: {status}")
    
    # Stop polling if job is complete
    if status in ['COMPLETED', 'FAILED', 'CANCELLED']:
        break
    
    # Wait 5 seconds before next check (well within limits)
    time.sleep(5)

Error Codes

The API uses standard HTTP status codes to indicate the success or failure of a request.

CodeStatusMeaning
200 OKSuccessThe request was successful.
202 AcceptedSuccessThe job was accepted for processing.
204 No ContentSuccessThe request was successful, and there is no content to return (e.g., after a DELETE).
400 Bad RequestClient ErrorThe request was malformed. Check your parameters, JSON body, or file uploads. This can also be triggered by our content moderation service.
401 UnauthorizedClient ErrorAuthentication failed. Check that your X-API-Key is correct and valid.
402 Payment RequiredClient ErrorYou do not have enough credits to perform this action.
404 Not FoundClient ErrorThe requested resource (e.g., a job) could not be found.
413 Payload Too LargeClient ErrorThe uploaded file exceeds the maximum allowed size.
429 Too Many RequestsClient ErrorYou have exceeded a rate limit (concurrent jobs, temporal limits, or polling limits).
500 Internal Server ErrorServer ErrorSomething went wrong on our end. Please try again later. If the problem persists, contact support.
503 Service UnavailableServer ErrorA required downstream service (like our moderation service) is temporarily unavailable.