This example reuses the fetchWithPayment helper from /quickstart to replay the x402 payment
challenge automatically.
1. Request the video job
const baseUrl = process.env.HORIZON_BASE_URL ?? 'https://api.horizon.new/v1';
const videoResponse = await fetchWithPayment(`${baseUrl}/generate/videos`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'Camera glides through a floating lounge surrounded by aurora lights.',
durationSeconds: 8,
resolution: '1080p',
webhookUrl: 'https://example.com/webhooks/horizon/generation',
}),
});
const videoJob = await videoResponse.json();
console.log('video job', videoJob.jobId);
2. Handle synchronous completions
if (videoJob.status === 'completed' && videoJob.result) {
console.log('Video artifacts ready', videoJob.result.artifacts);
}
3. Poll and collect the output
const statusResponse = await fetchWithPayment(videoJob.statusUrl);
const status = await statusResponse.json();
if (status.state === 'processing') {
await new Promise((resolve) => setTimeout(resolve, 4000));
// fetch again or rely on your webhook
}
if (status.state !== 'succeeded') {
throw new Error(`Video generation failed: ${status.error?.code ?? 'unknown'}`);
}
const { artifacts } = status.result;
console.log('Primary asset URL', artifacts?.[0]?.url);
4. Distribute the clip
- Store URLs or binary payloads in your asset pipeline.
- Use your routing config (for example, campaign or channel identifiers) to send clips to schedulers automatically.
- If you need multiple cuts, track variants in your datastore so you can fan out downstream jobs.