/** * Minimal VideoGenAPI client for Node 18+ (native fetch). * Last reviewed: 16 August 2026. */ const BASE = 'https://videogenapi.com/api/v1'; const KEY = process.env.VIDEOGENAPI_KEY || ''; export async function generate(prompt, model = 'kling-3', duration = 5) { const res = await fetch(`${BASE}/generate`, { method: 'POST', headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ model, prompt, duration }), }); if (!res.ok) { throw new Error(`generate failed: ${res.status} ${await res.text()}`); } return res.json(); } export async function wait(generationId, timeoutMs = 300000) { const deadline = Date.now() + timeoutMs; while (Date.now() < deadline) { const res = await fetch(`${BASE}/status/${generationId}`, { headers: { Authorization: `Bearer ${KEY}` }, }); if (!res.ok) { throw new Error(`status failed: ${res.status}`); } const data = await res.json(); const status = (data.status || data.data?.status || '').toLowerCase(); if (['completed', 'success', 'failed', 'error'].includes(status)) { return data; } await new Promise((r) => setTimeout(r, 3000)); } throw new Error('generation timed out'); } if (import.meta.url === `file://${process.argv[1]}`) { if (!KEY) { console.error('Set VIDEOGENAPI_KEY'); process.exit(1); } const prompt = process.argv[2] || 'A ceramic mug on a sunlit table, slow camera push-in'; const job = await generate(prompt); const id = job.generation_id || job.id || job.data?.id; console.log('queued', id); console.log(await wait(id)); }