REST API for Developers

AI Video Generation API

Integrate AI video, voice, image, and clipping capabilities directly into your application. RESTful endpoints with rate limiting, webhook notifications, and consistent JSON responses.

Authentication

API Key Authentication

API access is available on the Enterprise plan ($199/mo). Create and manage keys in your dashboard.

1. Generate an API Key

Navigate to Dashboard > API Keys and click "Create Key". Give it a descriptive name. The key value (sk_live_...) is shown once — copy it immediately. You can revoke and rotate keys at any time.

2. Include Bearer Token

Include your API key in the Authorization header on every request. All requests must use HTTPS.

Authorization: Bearer sk_live_your_api_key_here

3. Security Best Practices

  • Never expose API keys in client-side code or public repositories
  • Use environment variables to store keys
  • Rotate keys periodically and revoke unused ones
  • Each key can be independently revoked without affecting others

Endpoints

Complete API Reference

All endpoints accept and return JSON. Generated files are delivered as signed R2 URLs. Credits are deducted before processing and refunded on failure.

Generation

POST/api/generate/image Auth 10 credits

Generate Image

Generate an image from a text prompt. Supports multiple AI models per plan tier.

Required Parameters

promptstringText prompt (1-2,000 chars)

Optional Parameters

widthnumberImage width 256-2048 (default 1024)
heightnumberImage height 256-2048 (default 1024)
stepsnumberInference steps 1-50 (default 4)
seednumberReproducibility seed
stylestringphotorealistic | illustration | 3d | flat
modelstringgrok-imagine | flux-2-dev | flux-2-pro | ideogram-v3 | flux-kontext-max
negativePromptstringWhat to avoid in the image

Response

{ "data": { "jobId": "uuid", "status": "queued", "message": "..." } }
POST/api/generate/video Auth 250 credits

Generate Video

Generate a video from a script. Optionally attach an avatar face image.

Required Parameters

scriptstringVideo script (1-5,000 chars)

Optional Parameters

avatarImagestringHTTPS URL of face image for avatar
voiceIdstringCloned voice ID
durationnumberMax seconds 3-60
resolutionstring720p | 1080p (default 720p)
stylestringprofessional | casual | energetic
modelstringwan-2.6 | kling-2.6-pro | kling-3.0-pro | veo-3.1

Response

{ "data": { "jobId": "uuid", "status": "queued", "message": "..." } }
POST/api/generate/voice Auth 80 credits

Generate Voice (TTS)

Convert text to speech using AI voices. Supports multiple TTS providers.

Required Parameters

textstringText to speak (1-10,000 chars)

Optional Parameters

voiceIdstringCustom voice ID (or default)
speednumberPlayback speed 0.5-2.0 (default 1.0)
languagestringISO language code (default en)
modelstringkokoro | elevenlabs-v3 | fish-audio-s1

Response

{ "data": { "jobId": "uuid", "status": "queued", "estimatedMinutes": 1, "message": "..." } }
POST/api/generate/voice-clone Auth 80 credits

Clone Voice

Create a custom voice clone from an audio sample. Requires Creator plan or higher.

Required Parameters

namestringVoice name (1-100 chars)
sampleAudioUrlstringHTTPS URL to 15-30s audio sample

Response

{ "voiceId": "string", "message": "Voice cloned successfully" }
POST/api/generate/avatar Auth 750 credits

Generate Avatar Video

Create a talking-head video from a photo and script or audio.

Required Parameters

imagestringHTTPS URL of spokesperson photo
resolutionstring480p | 720p | 1080p
modelstringveed-fabric | creatify-aurora | kling-avatar-v2 | omnihuman-1.5

Optional Parameters

audiostringPre-recorded audio URL
textstringText to speak (if no audio)
voiceIdstringVoice ID for TTS

Response

{ "data": { "jobId": "uuid", "status": "queued", "message": "..." } }
POST/api/generate/clip Auth 30 credits

Auto-Clip Video

Extract the best clips from a long video using AI viral scoring.

Required Parameters

sourceVideoUrlstringHTTPS URL of source video

Optional Parameters

maxClipsnumberMaximum clips to extract 1-20
minDurationnumberMin clip duration (seconds)
maxDurationnumberMax clip duration (seconds)
addCaptionsbooleanAdd auto-captions
aspectRatiostring9:16 | 1:1 | 16:9
viralScoreThresholdnumberMinimum score 1-10

Response

{ "data": { "jobId": "uuid", "status": "queued", "message": "..." } }
POST/api/generate/b-roll Auth 150 credits

Generate B-Roll

Generate cinematic B-roll footage from a text description.

Required Parameters

promptstringScene description

Optional Parameters

durationnumberDuration 3-6 seconds
resolutionstring480p | 720p
modelstringwan-2.6 | kling-2.6-pro

Response

{ "data": { "jobId": "uuid", "status": "queued", "message": "..." } }
POST/api/generate/text2video Auth 250 credits

Text to Video

Generate a video directly from a text script.

Required Parameters

scriptstringVideo script

Optional Parameters

durationnumberDuration in seconds
resolutionstring720p | 1080p
stylestringcinematic | documentary | animation | aerial
modelstringwan-2.6 | kling-2.6-pro | kling-3.0-pro | veo-3.1

Response

{ "data": { "jobId": "uuid", "status": "queued", "message": "..." } }
POST/api/generate/commercial Auth 3000 credits

Generate Commercial

AI-generated commercial with script, voiceover, visuals, and composition.

Required Parameters

productstringProduct name/description
platformstringtiktok | youtube | instagram | tv
durationnumber15 | 30 | 60 seconds
tonestringprofessional | energetic | casual | luxury | funny

Optional Parameters

targetAudiencestringTarget audience description
spokespersonImagestringURL for AI spokesperson
productImagesstring[]Array of product image URLs
voiceIdstringCustom voice ID
voiceModelstringTTS model to use
musicMoodstringBackground music mood
videoModelstringVideo generation model

Response

{ "data": { "jobId": "uuid", "status": "queued", "message": "..." } }
POST/api/generate/translate Auth 1800 credits

Translate Video

Translate a video to another language with lip-sync.

Required Parameters

videoUrlstringHTTPS URL of source video
outputLanguagestringTarget language ISO code

Optional Parameters

preserveOriginalVoicebooleanKeep original voice timbre

Response

{ "data": { "jobId": "uuid", "status": "queued", "message": "..." } }
POST/api/generate/instant-ad Auth 500-1,250 credits

Instant Ad from URL

Scrape a website URL and auto-generate ad creatives.

Required Parameters

websiteUrlstringProduct/landing page URL
platformstringtiktok | youtube | instagram | facebook | linkedin
countnumberNumber of variations 1-4
stylestringmodern | bold | minimal | luxury | playful

Optional Parameters

outputFormatstringimage | video | both
brandProfileIdstringSaved brand profile ID

Response

{ "data": { "jobId": "uuid", "status": "queued", "message": "..." } }
POST/api/generate/photoshoot Auth 30 credits

AI Product Photoshoot

Generate professional product photos with AI backgrounds and lighting.

Required Parameters

productImagestringUploaded product photo URL
backgroundstringstudio-white | lifestyle | outdoor | flat-lay | custom
anglestringfront | hero | 45-degree | top-down | lifestyle
lightingstringstudio | natural | dramatic | soft | golden-hour
countnumberNumber of photos 1-4

Optional Parameters

customBackgroundstringDescription if background=custom
modelstringImage model ID

Response

{ "data": { "jobId": "uuid", "status": "queued", "message": "..." } }

Voice Agent

POST/api/voice-agent/calls/outbound Auth 10/min credits

Start Outbound Call

Initiate an AI phone call to a target number using a configured agent.

Required Parameters

agentIdstringVoice agent ID
phoneNumberstringTarget phone number (E.164)

Response

{ "data": { "callId": "uuid", "status": "active" } }
GET/api/voice-agent/calls Auth

List Calls

List all voice agent calls for the current user.

Response

{ "data": [...calls] }
POST/api/voice-agent/agents Auth

Create Agent

Create a new voice agent with system prompt, greeting, and voice configuration.

Required Parameters

namestringAgent display name
systemPromptstringSystem prompt for the LLM
greetingstringOpening greeting text
ttsModelstringkokoro | elevenlabs-v3 | fish-audio-s1
llmModelstringLLM model for conversation

Response

{ "data": { "id": "uuid", "name": "...", ... } }

Management

GET/api/jobs Auth

List Jobs

List generation jobs for the current user. Returns status, output URLs, and metadata.

Response

{ "data": [...jobs] }
GET/api/usage Auth

Get Usage

Retrieve current credit balance, usage counts, and billing cycle info.

Response

{ "data": { "credits": 4500, "used": { "images": 12, ... }, "plan": "enterprise" } }
GET/api/keys Auth

List API Keys

List all API keys for the current user. Enterprise only.

Response

{ "data": [...keys] }
POST/api/keys Auth

Create API Key

Generate a new API key. Enterprise only. Key value is shown once on creation.

Required Parameters

namestringKey display name

Response

{ "data": { "id": "uuid", "key": "sk_live_...", "name": "..." } }

Webhooks

PATCH/api/settings Auth

Configure Webhook URL

Set or update the webhook URL for job completion notifications. URL is validated against SSRF.

Required Parameters

webhookUrlstringHTTPS URL to receive webhook events

Response

{ "data": { "webhookUrl": "https://..." } }

Code Examples

Quick Start

Copy-paste examples for common operations. Replace YOUR_API_KEY with your Enterprise API key.

cURL — Generate an Image
curl -X POST https://useapexstudio.com/api/generate/image \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A futuristic city skyline at sunset, photorealistic",
    "width": 1024,
    "height": 1024,
    "model": "flux-2-pro"
  }'

# Response:
# {
#   "data": {
#     "jobId": "abc123-...",
#     "status": "queued",
#     "message": "Image generation job queued"
#   }
# }
Python — Generate an Image
import requests
import time

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://useapexstudio.com"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

# 1. Submit generation job
resp = requests.post(f"{BASE_URL}/api/generate/image", headers=HEADERS, json={
    "prompt": "A futuristic city skyline at sunset, photorealistic",
    "width": 1024,
    "height": 1024,
    "model": "flux-2-pro",
})
resp.raise_for_status()
job_id = resp.json()["data"]["jobId"]

# 2. Check rate limit headers
print(f"Remaining requests: {resp.headers.get('X-RateLimit-Remaining')}")

# 3. Poll for completion (or use webhooks)
while True:
    status = requests.get(f"{BASE_URL}/api/jobs?id={job_id}", headers=HEADERS)
    job = status.json()["data"]
    if job["status"] in ("completed", "failed"):
        break
    time.sleep(2)

print(f"Output: {job.get('outputUrl')}")
Node.js / TypeScript — Generate an Image
const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://useapexstudio.com";

// 1. Submit generation job
const response = await fetch(`${BASE_URL}/api/generate/image`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    prompt: "A futuristic city skyline at sunset, photorealistic",
    width: 1024,
    height: 1024,
    model: "flux-2-pro",
  }),
});

const { data } = await response.json();
console.log("Job ID:", data.jobId);

// 2. Check rate limit headers
console.log("Remaining:", response.headers.get("X-RateLimit-Remaining"));
console.log("Reset at:", new Date(Number(response.headers.get("X-RateLimit-Reset")) * 1000));

// 3. Poll for completion (or use webhooks)
let job;
do {
  await new Promise((r) => setTimeout(r, 2000));
  const res = await fetch(`${BASE_URL}/api/jobs?id=${data.jobId}`, {
    headers: { Authorization: `Bearer ${API_KEY}` },
  });
  job = (await res.json()).data;
} while (job.status !== "completed" && job.status !== "failed");

console.log("Output URL:", job.outputUrl);

Rate Limiting

Request Limits

Current Limits

Endpoint TypeRateWindow
Generation endpoints (POST /api/generate/*)5 requests10 seconds
Read endpoints (GET /api/jobs, /api/usage, etc.)20 requests10 seconds
File uploads (/api/upload/*)10 requests60 seconds
Destructive operations (DELETE)10 requests60 seconds
Outbound calls (Enterprise)200 calls1 hour

Rate Limit Headers

Every response includes rate limit headers so you can track your usage in real-time:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingNumber of requests remaining in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the current window resets
Retry-AfterSeconds to wait before retrying (only on 429 responses)

When You Hit a 429

When rate limited, the API returns HTTP 429 with a JSON body:

{
  "error": "Too many requests",
  "code": "RATE_LIMITED"
}

Read the Retry-After header to know how many seconds to wait before retrying. Implement exponential backoff in your client for best results.

Webhooks

Real-Time Job Notifications

Instead of polling, configure a webhook URL to receive notifications when generation jobs complete or fail.

Setup

Configure your webhook URL in Dashboard > Settings. The URL must be a public HTTPS endpoint. All webhook URLs are validated against SSRF protections (private IPs, internal hostnames, and cloud metadata endpoints are blocked).

Webhook Payload (Job Completed)

When a job finishes, we POST the following JSON to your webhook URL:

{
  "event": "job.completed",
  "timestamp": "2026-03-16T12:00:00Z",
  "data": {
    "jobId": "550e8400-e29b-41d4-a716-446655440000",
    "type": "image",
    "status": "completed",
    "outputUrl": "https://cdn.useapexstudio.com/outputs/550e.../output.png",
    "outputType": "image/png",
    "metadata": {
      "model": "flux-2-pro",
      "width": 1024,
      "height": 1024,
      "durationMs": 8200
    },
    "createdAt": "2026-03-16T11:59:50Z",
    "completedAt": "2026-03-16T12:00:00Z"
  }
}

Webhook Payload (Job Failed)

{
  "event": "job.failed",
  "timestamp": "2026-03-16T12:00:00Z",
  "data": {
    "jobId": "550e8400-e29b-41d4-a716-446655440000",
    "type": "video",
    "status": "failed",
    "error": "Generation failed",
    "creditsRefunded": 250,
    "createdAt": "2026-03-16T11:59:50Z",
    "failedAt": "2026-03-16T12:00:00Z"
  }
}

Credits are automatically refunded on job failure. The errorfield contains a generic message — internal details are never exposed.

Example Payloads by Job Type

Job TypeoutputTypeExtra Metadata
imageimage/pngmodel, width, height
videovideo/mp4model, durationSeconds, resolution
voiceaudio/wavmodel, durationSeconds, language
avatarvideo/mp4model, durationSeconds, resolution
clipvideo/mp4clipCount, viralScores[]
commercialvideo/mp4sceneClips[], platform, duration
translatevideo/mp4outputLanguage, durationSeconds
instant-adimage/png or video/mp4variationCount, platform, format
photoshootimage/pngphotoCount, background, lighting

Retry Behavior

  • Failed webhook deliveries are retried up to 3 times
  • Retries use exponential backoff: 10s, 60s, 300s
  • Your endpoint must return a 2xx status code within 10 seconds
  • After all retries are exhausted, the webhook is marked as failed (check job status via API)

Error Handling

Error Responses

All errors follow a consistent JSON shape. Internal details are never exposed.

Error Response Shape

{
  "error": "Human-readable error message",
  "code": "MACHINE_READABLE_CODE"
}

Error Codes

HTTP StatusCodeDescription
400BAD_REQUESTInvalid input parameters. Check the error message for specifics.
401UNAUTHORIZEDMissing or invalid API key.
402PAYMENT_REQUIREDInsufficient credits. Purchase more at Dashboard > Billing.
403FORBIDDENModel or feature not available on your plan. Upgrade required.
429RATE_LIMITEDToo many requests. Check Retry-After header.
500INTERNAL_ERRORServer error. Credits are auto-refunded. Retry after a short delay.
503SERVICE_UNAVAILABLETemporary outage. Retry with exponential backoff.

Platform Features

Enterprise-Grade Infrastructure

Low Latency

Images in under 10 seconds. Voice in 5-15 seconds. Avatar videos in 30-90 seconds. All on dedicated GPU infrastructure.

Webhooks

Real-time notifications when jobs complete or fail. Retries with exponential backoff. Configurable in dashboard.

Enterprise Security

Rate limiting, SSRF protection, input validation with Zod, webhook URL validation, and CSP headers.

Global CDN

Generated assets served via Cloudflare R2 with global edge caching. Signed URLs valid for 24 hours.

99.9% Uptime SLA

Enterprise plan includes a 99.9% uptime SLA. Dedicated GPU pools ensure consistent generation times.

Data Privacy

All data encrypted at rest and in transit. Voice samples and generated content are never used for training. GDPR compliant.

FAQ

Frequently Asked Questions

How do I get API access?

API access is available on the Enterprise plan ($199/mo). Sign up, navigate to Dashboard > API Keys, and generate your first API key. You can also contact our team for a custom Enterprise agreement with higher rate limits.

What authentication method does the API use?

The API uses Bearer token authentication. Include your API key in the Authorization header: 'Authorization: Bearer your_api_key'. API keys can be rotated and revoked from your dashboard at any time.

Is there a rate limit?

Enterprise plan includes 5 generation requests per 10 seconds (strict limit) and 20 read requests per 10 seconds (standard limit). Rate limit information is returned in response headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset). Contact us for higher limits.

How do webhooks work?

Register a webhook URL in Dashboard > Settings. When a job completes or fails, we POST a JSON payload to your URL. Webhooks retry up to 3 times with exponential backoff. All webhook URLs are validated against SSRF protections.

What response format does the API use?

All API responses are JSON. Success responses use { data: ... } and errors use { error: string, code: string }. Generated files (video, audio, images) are returned as signed R2 URLs valid for 24 hours.

What happens when a job fails?

Credits are automatically refunded on failure. The job status updates to 'failed' and a webhook notification fires if configured. You can check job status via GET /api/jobs.

Build AI Video Into Your Product

Enterprise API access with dedicated GPU infrastructure, webhooks, and SLA. Contact our team to get started.