The Nano Banana Video API is designed to get developers shipping fast. In this tutorial, we'll build a minimal but production-ready video generation endpoint in Next.js, complete with webhook handling, progress UI, and proper error handling. Let's ship it.

Prerequisites

  • A Nano Banana account with an API key (free tier works fine)
  • Node.js 20+
  • Basic familiarity with Next.js App Router

Step 1: Install the SDK

npm install @nanobanana/video

The official Nano Banana SDK is fully typed with TypeScript and works in both Node.js and Edge runtimes.

Step 2: Initialize the Client

Create a server-side utility file at lib/nanobanana.ts:

import { NanoBanana } from '@nanobanana/video';

export const nb = new NanaBanana({
  apiKey: process.env.NB_API_KEY!,
});

Step 3: Create the Generation Route

In app/api/generate/route.ts:

import { nb } from '@/lib/nanobanana';
import { NextResponse } from 'next/server';

export async function POST(req: Request) {
  const { prompt, duration = 5 } = await req.json();

  if (!prompt) {
    return NextResponse.json({ error: 'Prompt required' }, { status: 400 });
  }

  const job = await nb.video.generate({
    prompt,
    seconds: duration,
    resolution: '1080p',
    motion: 'medium',
  });

  return NextResponse.json({ jobId: job.id, status: job.status });
}

Step 4: Poll for Job Completion

Create a status polling endpoint at app/api/status/[jobId]/route.ts:

import { nb } from '@/lib/nanobanana';
import { NextResponse } from 'next/server';

export async function GET(
  req: Request,
  { params }: { params: { jobId: string } }
) {
  const job = await nb.jobs.get(params.jobId);

  return NextResponse.json({
    status: job.status,
    url: job.output?.url ?? null,
    progress: job.progress ?? 0,
  });
}

Step 5: Webhook for Production

For production apps, polling is wasteful. Register a webhook URL in your Nano Banana dashboard, then handle it:

// app/api/webhook/nanobanana/route.ts
export async function POST(req: Request) {
  const event = await req.json();

  if (event.type === 'job.completed') {
    const { jobId, output } = event.data;
    // Save to your DB, notify user via WebSocket, etc.
    await db.videos.update(jobId, { url: output.url, status: 'ready' });
  }

  return new Response('OK');
}

Step 6: Build the UI

A minimal React component that ties it all together, prompt input, loading state with progress, and a video player once the job completes. The key pattern is to kick off generation, store the jobId in state, and poll every 500ms until status === 'completed'.

What to Build Next

With this foundation, you can add: character consistency tokens for persistent AI actors, multi-scene sequencing to create full short films, watermark removal for white-label products, and usage metering for SaaS billing.

The full API reference covers all parameters and response schemas. Happy building!