Flow Studio API Docs · v1
Developer Console Get API Key

Flow Studio Developer API

Generate 1K/2K/4K images (Nano Banana Pro, Nano Banana 2, Imagen 4) and 720p/1080p AI videos (Veo 3.1 Lite: Text-to-Video, Image-to-Video, Reference-to-Video) over a clean REST API with automatic wallet refunds on any failed job.

Base URL https://api.shahzaibmalik.com/v1

Authentication & Headers

Authenticate every request using your secret API key in the Authorization header. Create or roll your key anytime from the Developer Console.

Authorization: Bearer fsk_live_your_secret_key_here
Content-Type: application/json
Idempotency-Key: optional-unique-request-id-123
Rate Limit & Balance Headers

Every response returns X-Balance-USD, X-RateLimit-Limit-RPM, X-RateLimit-Remaining-RPM, and X-RateLimit-Reset. Default limit: 150 requests per minute for creating images / videos and uploading references; status checks and file downloads (GET) have their own, larger limit.

100% Automatic Refunds

Wallet funds are reserved when a job is queued and automatically refunded in full if Google rejects or fails a generation.

Models & Per-Call Pricing (USD)

Minimum wallet deposit is $10 USD. Balance never expires while your account is active.

Kind Model ID Name Resolutions / Modes Default Price (USD)
Image nano-banana-pro Nano Banana Pro (Default) 1K, 2K, 4K · Aspects: 1:1, 16:9, 9:16, 4:3, 3:4 · Up to 10 refs $0.004 (1K) · $0.008 (2K) · $0.015 (4K)
Image nano-banana-2.1 Nano Banana 2 1K, 2K, 4K · Up to 10 reference images $0.004 (1K) · $0.008 (2K) · $0.015 (4K)
Image nano-banana-2-lite Imagen 4 1K, 2K, 4K · Fast photorealistic generation $0.004 (1K) · $0.008 (2K) · $0.015 (4K)
Video veo-3.1-lite Veo 3.1 Lite Modes: t2v (4s/6s/8s), i2v (start frame), r2v (8s, up to 3 refs), fl (start & end frame) · Aspects: 16:9, 9:16 $0.040 (720p · $40/1K) · $0.050 (1080p · $50/1K)

Live API Tester

Paste your fsk_live_... key below to test your wallet connection and inspect live JSON responses right from your browser.

// Click "GET /v1/account" or "GET /v1/models" above to test your key live.

1. Check Wallet & Concurrency

GEThttps://api.shahzaibmalik.com/v1/account

Returns your live USD balance, total spent, enabled permissions (images_enabled, video_enabled), concurrency threads, rate limits, and per-call USD pricing.

2. List Models, Aspects & Prices

GEThttps://api.shahzaibmalik.com/v1/models

Returns all supported image & video models, aspect ratios, durations, and your account's active USD rate card.

3. Generate Images

POSThttps://api.shahzaibmalik.com/v1/images/generations

Queues 1 to 100 images in a batch, or pass "wait": true on a single-prompt call to wait synchronously (up to 75s) and receive the completed media_url in one response.

Request Body (JSON)
{
  "prompt": "editorial product photo of a matte black perfume bottle on wet basalt",
  "model": "nano-banana-pro",
  "aspect": "1:1",
  "resolution": "1K",
  "refs": [],
  "wait": true
}

4. Generate Videos (Veo 3.1 Lite)

POSThttps://api.shahzaibmalik.com/v1/videos/generations

Queues one or more Veo 3.1 Lite video clips. Supports Text-to-Video (t2v), Start-Frame Image-to-Video (i2v via start_ref), Reference Ingredients-to-Video (r2v via refs, up to 3 images, 8s duration), and Start & End Frame ("mode": "fl" with "frames": [start_ref, end_ref]: every clip opens on the first image and ends on the second, 4s/6s/8s).

Request Body (JSON)
{
  "prompts": ["slow cinematic drone shot over misty emerald mountains at sunrise"],
  "mode": "t2v",
  "aspect": "16:9",
  "duration": 8,
  "resolution": "720p"
}

5. Upload Reference Image

POSThttps://api.shahzaibmalik.com/v1/refs

Upload a PNG/JPEG/WebP image via multipart/form-data (file field) or JSON ({"base64": "...", "mime": "image/png"}). Returns {"ok": true, "ref": {"id": "..."}} which can be passed in refs or start_ref.

6. Get Job Status

GEThttps://api.shahzaibmalik.com/v1/jobs/{job_id}

Poll a single job. When job.status === "done", download the generated image or MP4 video from job.media_url.

7. Upscale Completed Job (2K / 4K / 1080p)

POSThttps://api.shahzaibmalik.com/v1/jobs/{job_id}/upscale

Upscales a completed 1K/2K image to 2K or 4K, or a 720p video to 1080p. Charges only the price difference between the current resolution and target resolution.

{ "resolution": "4K" }

8. Poll & Cancel Batches

GEThttps://api.shahzaibmalik.com/v1/batches/{batch_id}
DELhttps://api.shahzaibmalik.com/v1/batches/{batch_id}

GET returns aggregate status counts (queued, running, done, failed, cancelled) and all jobs in the batch. DELETE cancels any remaining queued jobs and immediately refunds their reserved USD to your wallet.

9. Download Generated Media

GEThttps://api.shahzaibmalik.com/v1/files/{job_id}

Streams the generated PNG/JPEG/WebP image or MP4 video binary. Files are retained for 6 hours after completion.

Quickstart Code Examples

cURL — Generate Image
curl -X POST "https://api.shahzaibmalik.com/v1/images/generations" \
  -H "Authorization: Bearer fsk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "editorial product photo of a matte black perfume bottle on wet basalt",
    "model": "nano-banana-pro",
    "aspect": "1:1",
    "resolution": "1K",
    "wait": true
  }'
Python — Generate & Download Image
import requests

API_BASE = "https://api.shahzaibmalik.com/v1"
HEADERS = {"Authorization": "Bearer fsk_live_YOUR_KEY"}

r = requests.post(
    f"{API_BASE}/images/generations",
    headers=HEADERS,
    json={
        "prompt": "cinematic neon alley in Tokyo after rain, 35mm photograph",
        "model": "nano-banana-pro",
        "aspect": "16:9",
        "resolution": "2K",
        "wait": True,
    },
    timeout=90,
)
data = r.json()
job = data["jobs"][0]
if job["status"] == "done" and job["media_url"]:
    img = requests.get(job["media_url"], headers=HEADERS, timeout=60).content
    with open("output.png", "wb") as f:
        f.write(img)
    print("Saved output.png! Remaining balance: $", data["balance_usd"])
Node.js / TypeScript — Generate Video & Poll
const API_BASE = "https://api.shahzaibmalik.com/v1";
const headers = {
  "Authorization": "Bearer fsk_live_YOUR_KEY",
  "Content-Type": "application/json",
};

const sub = await fetch(`${API_BASE}/videos/generations`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    prompts: ["aerial drone shot over turquoise ocean waves crashing on black sand"],
    mode: "t2v",
    aspect: "16:9",
    duration: 8,
    resolution: "720p",
  }),
}).then(r => r.json());

const jobId = sub.jobs[0].id;
while (true) {
  await new Promise(r => setTimeout(r, 4000));
  const { job } = await fetch(`${API_BASE}/jobs/${jobId}`, { headers }).then(r => r.json());
  if (job.status === "done") {
    console.log("Video ready:", job.media_url);
    break;
  }
  if (job.status === "failed" || job.status === "cancelled") {
    throw new Error(job.error || job.status);
  }
}