Skip to main content

Batch generation

TypeScript
import { BabySea, BabySeaError } from 'babysea';

const client = new BabySea({ apiKey: 'bye_...', region: 'us', maxRetries: 3 });

const prompts = [
  'A mountain landscape at dawn',
  'An underwater coral reef',
  'A futuristic city skyline',
];

const results = await Promise.allSettled(
  prompts.map((prompt) =>
    client.generate('bfl/flux-schnell', {
      generation_prompt: prompt,
      generation_ratio: '16:9',
      generation_output_format: 'png',
    }),
  ),
);

for (const [i, result] of results.entries()) {
  if (result.status === 'fulfilled') {
    console.log(`✓ "${prompts[i]}" → ${result.value.data.generation_id}`);
  } else {
    const err = result.reason;
    if (err instanceof BabySeaError) {
      console.log(`✗ "${prompts[i]}" → ${err.code}: ${err.message}`);
    }
  }
}

Video generation

TypeScript
// Text-to-Video
const video = await client.generateVideo('google/veo-2', {
  generation_prompt: 'A baby seal swimming in crystal clear ocean water',
  generation_ratio: '16:9',
  generation_duration: 5,
});

// Image-to-Video at high resolution (provide a reference image)
const video2 = await client.generateVideo('bytedance/seedance-1-pro', {
  generation_prompt: 'The camera slowly zooms in',
  generation_duration: 8,
  generation_resolution: '1080p',
  generation_input_file: ['https://example.com/photo.jpg'],
});

// Audio-capable model - audio enabled (default, charges audio rate)
const video3 = await client.generateVideo('bytedance/seedance-1.5-pro', {
  generation_prompt: 'A baby seal barking playfully on a beach',
  generation_ratio: '16:9',
  generation_duration: 8,
  generation_resolution: '720p',
  generation_generate_audio: true, // default; omit for same result
});

// Audio-capable model - audio disabled (charges lower no-audio rate)
const video4 = await client.generateVideo('bytedance/seedance-1.5-pro', {
  generation_prompt: 'A time-lapse of ocean waves',
  generation_ratio: '16:9',
  generation_duration: 8,
  generation_resolution: '1080p',
  generation_generate_audio: false,
});

console.log(video.data.generation_id);

Cost estimate before generation

TypeScript
const estimate = await client.estimate('bfl/flux-schnell', 3);

if (!estimate.data.credit_balance_can_afford) {
  console.log(
    `Not enough credits. Can afford at most ${estimate.data.credit_balance_max_affordable} generations.`,
  );
  process.exit(1);
}

const result = await client.generate('bfl/flux-schnell', {
  generation_prompt: 'A cute baby seal',
});

Credit balance check

TypeScript
const billing = await client.billing();

if (billing.data.billing_credit_balance < 1) {
  console.log('Low credits. Top up credits in your BabySea workspace before generating.');
  process.exit(1);
}

const result = await client.generate('bfl/flux-schnell', {
  generation_prompt: 'A cute baby seal',
});

Polling for results

Polling is a fallback pattern. Use webhooks for production workloads - they are more efficient, lower-latency, and avoid unnecessary API calls.
TypeScript
const gen = await client.generate('bfl/flux-schnell', {
  generation_prompt: 'A beautiful sunset',
});

let generation;
do {
  await new Promise((r) => setTimeout(r, 2000));
  const res = await client.getGeneration(gen.data.generation_id);
  generation = res.data;
} while (
  generation.generation_status === 'pending' ||
  generation.generation_status === 'processing'
);

if (generation.generation_status === 'succeeded') {
  console.log('Output:', generation.generation_output_file);
} else {
  console.log('Failed:', generation.generation_error);
}

Paginating all generations

TypeScript
const allGenerations = [];
let offset = 0;
const limit = 100;

while (true) {
  const res = await client.listGenerations({ limit, offset });
  allGenerations.push(...res.data.generations);

  if (allGenerations.length >= res.total) break;
  offset += limit;
}

console.log(`Fetched ${allGenerations.length} generations`);

Input file (img2img)

Pass public file URLs to models that support generation_input_file:
TypeScript
const res = await client.generate('google/nano-banana', {
  generation_prompt: 'In the style of a watercolor painting',
  generation_input_file: [
    'https://example.com/input.jpg',
  ],
});
Check client.library.models() to see which models support generation_input_file.

Provider order selection

Choose which providers to try and in what order. BabySea fails over automatically:
TypeScript
// Default order (BabySea chooses optimal order)
const res = await client.generate('bfl/flux-schnell', {
  generation_prompt: 'Ocean waves',
});

// Single-provider (resolution-critical models)
const res1 = await client.generateVideo('minimax/video-01-director', {
  generation_prompt: 'Ocean waves',
  generation_duration: 5,
  generation_provider_order: 'replicate',
});

// Prefer FAL, fall back to Replicate
const res2 = await client.generate('bfl/flux-schnell', {
  generation_prompt: 'Ocean waves',
  generation_provider_order: 'fal, replicate',
});

// BytePlus-supported models (seedream family) - 3-provider chain
const res3 = await client.generate('bytedance/seedream-4', {
  generation_prompt: 'Ocean waves',
  generation_provider_order: 'byteplus, replicate, fal',
});

// Cloudflare-supported models - 3-provider chain
const res4 = await client.generate('bfl/flux-schnell', {
  generation_prompt: 'Ocean waves',
  generation_provider_order: 'cloudflare, replicate, fal',
});

Health monitoring

TypeScript
// Check all provider statuses
const providers = await client.health.providers();

for (const p of providers.data.providers) {
  if (p.status !== 'healthy') {
    console.warn(`⚠ ${p.provider}: ${p.status} (${(p.failure_rate * 100).toFixed(1)}% failure rate)`);
  }
}

// Check infrastructure
const [storage, cache] = await Promise.all([
  client.health.storage(),
  client.health.cache(),
]);

console.log(`Storage: ${storage.data.healthy ? '✓' : '✗'} (${storage.data.latency_ms}ms)`);
console.log(`Cache: ${cache.data.healthy ? '✓' : '✗'} (${cache.data.latency_ms}ms)`);