SDKs

Official client libraries for the PhantomFlow API. Both SDKs provide typed interfaces, automatic retries for server errors, and convenience methods for polling job status.

Node.js SDK

The official Node.js SDK with full TypeScript support. Requires Node.js 18+ (uses native fetch). Ships with dual ESM/CJS builds.

Installation

npm install @phantomflow/sdk

Configuration

import { PhantomFlowClient } from '@phantomflow/sdk';

const client = new PhantomFlowClient({
  apiKey: 've_live_...',         // Required
  baseUrl: 'https://api.phantomflow.dev',  // Optional
  timeout: 30000,                // Optional, ms
  maxRetries: 3,                 // Optional, retries for 5xx/network
});

// Sandbox mode auto-detected from key prefix
const sandbox = new PhantomFlowClient({
  apiKey: 've_test_your_test_key',
});
console.log(sandbox.isSandbox); // true

Quick Example

const job = await client.render({
  width: 1920,
  height: 1080,
  scenes: [
    {
      duration: 5,
      elements: [
        { type: 'text', text: 'Hello World', fontSize: 72, color: '#FFFFFF' }
      ]
    }
  ]
});

const result = await client.waitForCompletion(job.jobId, {
  onProgress: (p) => console.log(`${p.stage}: ${Math.round(p.progress * 100)}%`)
});

console.log(`Video ready: ${result.outputUri}`);

Available Methods

MethodDescription
client.render(script)Submit a render job with full movie script
client.renderTemplate(id, vars?)Render from a saved template
client.getJob(jobId)Get status of a render job
client.listJobs(params?)List jobs with pagination
client.waitForCompletion(jobId, opts?)Poll until job completes or fails
client.listTemplates()List your templates
client.createTemplate(params)Create a new template
client.getTemplate(id)Get a template by ID
client.updateTemplate(id, params)Update a template
client.deleteTemplate(id)Delete a template
client.getSchema()Get the render JSON Schema
client.health()Check API health status

Error Handling

All API errors are thrown as typed exceptions. Import specific error classes for granular handling.

import {
  AuthenticationError,
  InsufficientCreditsError,
  ValidationError,
  RateLimitError,
  NotFoundError,
  ServerError,
  PhantomFlowError,
} from '@phantomflow/sdk';

try {
  await client.render(script);
} catch (err) {
  if (err instanceof InsufficientCreditsError) {
    console.error(`Need ${err.required} credits, have ${err.balance}`);
  } else if (err instanceof RateLimitError) {
    console.error(`Rate limited. Retry after ${err.retryAfter}s`);
  } else if (err instanceof ValidationError) {
    console.error(`Validation failed at ${err.path}: ${err.message}`);
  } else if (err instanceof PhantomFlowError) {
    console.error(`API error ${err.status}: ${err.code} - ${err.message}`);
  }
}

TypeScript Types

import type {
  MovieScript,
  Scene,
  Element,
  TextElement,
  VideoElement,
  ImageElement,
  AudioElement,
  VoiceElement,
  Job,
  JobStatus,
  Template,
  Quality,
  TransitionType,
  Position,
  WaitForCompletionOptions,
  JobProgress,
} from '@phantomflow/sdk';

PHP SDK

The official PHP SDK. Requires PHP 8.0+ with the curl and json extensions. No external dependencies.

Installation

composer require phantomflow/sdk

Configuration

use PhantomFlow\PhantomFlowClient;

$client = new PhantomFlowClient([
    'apiKey'     => 've_live_...',                    // Required
    'baseUrl'    => 'https://api.phantomflow.dev',    // Optional
    'timeout'    => 30,                               // Seconds
    'maxRetries' => 3,                                // For 5xx/network
]);

// Sandbox mode auto-detected from key prefix
$sandbox = new PhantomFlowClient(['apiKey' => 've_test_...']);
echo $sandbox->isSandbox; // true

Quick Example

$job = $client->render([
    'width' => 1920,
    'height' => 1080,
    'scenes' => [
        [
            'duration' => 5,
            'elements' => [
                [
                    'type' => 'text',
                    'text' => 'Hello World',
                    'fontSize' => 72,
                    'color' => '#FFFFFF',
                ]
            ]
        ]
    ]
]);

$result = $client->waitForCompletion($job['jobId'], [
    'onProgress' => function ($data) {
        echo $data['stage'] . ': ' . round($data['progress'] * 100) . '%' . PHP_EOL;
    }
]);

echo "Video ready: " . $result['outputUri'] . "\n";

Available Methods

MethodDescription
$client->render($script)Submit a render job
$client->renderTemplate($id, $vars)Render from a saved template
$client->getJob($jobId)Get job status
$client->listJobs($params)List jobs with pagination
$client->waitForCompletion($jobId, $opts)Poll until complete
$client->streamProgress($jobId, $cbs)SSE progress stream
$client->listTemplates()List templates
$client->createTemplate($params)Create a template
$client->getTemplate($id)Get a template
$client->updateTemplate($id, $params)Update a template
$client->deleteTemplate($id)Delete a template
$client->getSchema()Get render JSON Schema
$client->health()Check API health

Error Handling

use PhantomFlow\Exceptions\AuthenticationException;
use PhantomFlow\Exceptions\InsufficientCreditsException;
use PhantomFlow\Exceptions\ValidationException;
use PhantomFlow\Exceptions\RateLimitException;
use PhantomFlow\Exceptions\NotFoundException;
use PhantomFlow\Exceptions\ServerException;
use PhantomFlow\Exceptions\PhantomFlowException;

try {
    $job = $client->render($script);
} catch (InsufficientCreditsException $e) {
    echo "Need " . $e->required . " credits, have " . $e->balance . "\n";
} catch (RateLimitException $e) {
    echo "Rate limited. Retry after " . $e->retryAfter . " seconds\n";
} catch (ValidationException $e) {
    echo "Validation failed at " . $e->path . ": " . $e->getMessage() . "\n";
} catch (PhantomFlowException $e) {
    echo "API error (" . $e->status . "): " . $e->getMessage() . "\n";
}

Retry Behavior (Both SDKs)

Both SDKs automatically retry on 5xx server errors and network failures using exponential backoff with jitter. 4xx client errors (authentication, validation, rate limits) are never retried. Configure retries via the maxRetries option (default: 3).