ai-chatbot/docs/nanobanana-browser-poc.md
Your Name 1fc37c4a8f
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
fix: improve style pro generation flow
2026-05-22 20:37:28 +08:00

4.8 KiB

Nano Banana Browser POC

This repo includes a small browser-driven POC for inspecting Nano Banana's free-tool flow without trying to bypass Turnstile, login, or rate limits.

What it does

  • Opens the Nano Banana page in a real browser
  • Optionally prefills a public image URL
  • Optionally clicks the primary action button
  • Captures requests and responses for the relevant private endpoints
  • Saves screenshots, console logs, downloads, and browser storage state

What it does not do

  • It does not bypass Cloudflare Turnstile
  • It does not bypass login
  • It does not try to evade rate limits
  • It is not a production API adapter

Commands

Remove background:

pnpm poc:nanobanana --mode remove-background --auto-submit

Upscale:

pnpm poc:nanobanana --mode upscale --auto-submit

Use a custom image URL:

pnpm poc:nanobanana \
  --mode upscale \
  --image-url "https://example.com/demo.jpg" \
  --auto-submit

Useful flags

  • --locale en
  • --headless
  • --no-auto-fill
  • --auto-submit
  • --close-on-success
  • --timeout-ms 300000
  • --out-dir /absolute/path/to/output

Output

By default, artifacts are written to:

playwright/nanobanana-poc/<mode>-<timestamp>/

The folder includes:

  • summary.json
  • session-plan.json
  • storage-state-initial.json
  • storage-state-final.json
  • requests/*.json
  • responses/*.json
  • logs/*.json
  • screenshots such as 01-loaded.png and 99-final.png

Current endpoints observed

  • /api/img/rmbg
  • /api/img/upscale
  • /api/img/result/{taskId}?type=img
  • /api/img/image-safety
  • /api/presigned-urls

Current findings (2026-05-21)

These findings were confirmed from the live frontend bundle and manual browser validation.

Remove background

Frontend schema:

  • imageSource: "upload" or "url"
  • imageUrl: optional string
  • turnstileToken: optional string

Observed request shape:

{
  "imageSource": "url",
  "imageUrl": "https://...",
  "turnstileToken": "..."
}

Observed endpoint behavior:

  • POST /api/img/rmbg
  • Content-Type: application/json
  • success path reads response.data as the final output image URL
  • after success the page clears turnstileToken
  • 403 with message === "nsfw" is handled as an NSFW block

Manual validation in the in-app browser produced a successful result and exposed a final image URL hosted on replicate.delivery, which suggests the private backend may fan out to third-party storage or processing before returning the final asset URL.

Image upscaler

Frontend schema:

  • imageSource: "upload" or "url"
  • imageUrl: optional string
  • scale: number, min 1, max 8, default 4
  • turnstileToken: optional string

Observed submit request shape:

{
  "imageUrl": "https://...",
  "scale": "4",
  "turnstileToken": "..."
}

Upload mode can also send an image field populated from the uploaded asset URL.

Observed endpoint behavior:

  • POST /api/img/upscale
  • Content-Type: application/json
  • success path reads taskId from response.data.taskId or response.taskId
  • the frontend then polls GET /api/img/result/{taskId}?type=img
  • polling treats code === 1 or status === 1 as success
  • final output is read from data.imgAfterSrc or imgAfterSrc
  • polling treats code === 2 or status === 2 as failure
  • the polling loop waits 2 seconds and retries up to 60 times
  • 402 is handled as an upgrade/paywall condition
  • 403 with message === "nsfw" is handled as an NSFW block

Turnstile

Observed Cloudflare site key:

  • 0x4AAAAAAAh8CLI0IWTYOWMY

Observed frontend behavior:

  • when turnstileToken is missing, the frontend renders or executes Turnstile before submitting
  • after a successful request, the frontend clears turnstileToken
  • this means the free-tool flow is not designed as a stable unattended API

Upload helper

Observed upload helper behavior:

  • POST /api/presigned-urls with JSON like { "count": 1, "fileType": "<mime>" }
  • response returns urls
  • the browser PUTs the file to the returned presigned URL
  • the frontend then derives a public asset URL in the form:
https://temp.videostudioai.com/<key>

Practical takeaway

This is enough to build an internal unofficial wrapper, but not enough to remove the core operational risk:

  • the flow still depends on Turnstile
  • Turnstile tokens are intentionally short-lived and cleared after use
  • the frontend contract may change at any time
  • upscaling still appears more likely to require session state than remove-background

Suggested use

Use this only as an internal validation tool to answer questions like:

  • Does the browser session create anonymous or guest state?
  • When does Turnstile appear?
  • Which cookies or local storage values appear before the request?
  • Does upscaling require an authenticated session?
  • What request and polling shape does the frontend use today?