Skip to content
Β 
Β 

Repository files navigation

Flow2API

License Python FastAPI Docker

A full-featured OpenAI-compatible API service that provides a unified interface for Flow

✨ Core features

  • 🎨 Text-to-image / image-to-image
  • 🎬 Text-to-video / image-to-video
  • 🎞️ First-and-last-frame video generation
  • πŸ”„ Automatic AT/ST refresh - Refreshes expired access tokens automatically and renews expired session tokens through the browser in personal mode
  • πŸ“Š Credit display - Queries and displays VideoFX credits in real time
  • πŸš€ Load balancing - Multi-token rotation and concurrency control
  • 🌐 Proxy support - Supports HTTP and SOCKS5 proxies
  • πŸ“± Web administration interface - Intuitive token and configuration management
  • 🎨 Continuous image-generation conversations
  • 🧩 Official Gemini request compatibility - Supports generateContent, streamGenerateContent, systemInstruction, and contents.parts.text/inlineData/fileData
  • βœ… Verified official Gemini image output - Tested with a real token to confirm that /models/{model}:generateContent returns candidates[].content.parts[].inlineData

πŸš€ Quick start

Prerequisites

  • uv and Bun for the shortest local setup. uv installs Python 3.11 when necessary.
  • Docker and Docker Compose only when you want container deployment.

Repository layout

  • apps/api/: the installable flow2api Python package and backend tests
  • apps/admin-web/: the React administration interface
  • apps/captcha-extension/: the Chrome CAPTCHA/account-sync worker
  • apps/metadata-extension/: the TypeScript metadata extension
  • apps/agent-gateway/: the standalone remote browser agent gateway
  • infra/docker/ and infra/compose/: container images and Compose stacks
  • packages/api-contract/: TypeScript contracts generated from the backend OpenAPI snapshot
  • packages/extension-core/: stable browser-independent extension transport/storage primitives
  • .runtime/: local databases, browser profiles, generated files, and cache data

If you are upgrading a checkout created before this layout, stop Flow2API and move the old local runtime directories once:

mkdir -p .runtime
mv data .runtime/data
mv tmp .runtime/tmp

Skip a move when its legacy directory does not exist. Do not overwrite an existing .runtime/data; back up both directories and reconcile them first.

Flow now requires an additional CAPTCHA. You can solve it through a browser or a third-party service.

  • To use YesCaptcha, register here, obtain an API key, and enter it in the YesCaptcha API key field on the system settings page.

  • The admin UI supports these YesCaptcha task types: RecaptchaV3TaskProxyless, RecaptchaV3TaskProxylessM1, RecaptchaV3TaskProxylessM1S7, and RecaptchaV3TaskProxylessM1S9. M1S9 is currently recommended by default. S7 and S9 force minScore values of 0.7 and 0.9 respectively.

  • The default infra/compose/docker-compose.yml is intended for third-party solvers such as YesCaptcha, CapMonster, EzCaptcha, or CapSolver. For headed browser or personal solving inside Docker, use infra/compose/docker-compose.headed.yml below.

  • To test remote_browser mode locally, run the Node mock solver on the host. It verifies HTTP and authentication only and does not produce real reCAPTCHA tokens. See tools/remote-browser-mock/.

  • For the production Agent Gateway (Flow2API over HTTP, with jobs delivered to user PCs over WebSocket), see apps/agent-gateway/src/flow2api_gateway/README.md.

  • For asynchronous submission and polling through /v1/async/chat/completions and /v1/jobs/{job_id}, see docs/async-polling.md.

  • Runway web-task integration is available through the admin Runway tab, runway-* models, and /v1/runway/* routes. See docs/runway.md. It includes a manifest-backed model registry, live feature sync, real Runway uploads/datasets, image/video/audio/upscale task builders, OpenAI-compatible dispatch, voices, estimates, cancel, async polling, and cache mirroring.

  • Production performance, Railway Redis, WebSocket events, and seven-day retention are documented in docs/performance-redis-rollout.md. The PostgreSQL 16 bridge, migration, encrypted Google Drive backup, cutover, and rollback procedure is in docs/postgres-migration-runbook.md.

  • The bundled apps/captcha-extension/ supports CAPTCHA work, current-account import, scheduled ST/cookie synchronization, and token-bound refresh workers. Build it with bun run --cwd apps/captcha-extension build, then load apps/captcha-extension/dist/ in Chrome.

Chrome Extension per-key isolation setup

When using captcha method extension, Flow2API keeps one global captcha mode but isolates end-user workers per managed API key.

  1. Run bun install --frozen-lockfile and bun run --cwd apps/captcha-extension build, then load apps/captcha-extension/dist/ as an unpacked Chrome extension.
  2. Create a managed API key in API key manager. Add tokens:import if this extension may add or refresh the Google account signed in to its Chrome profile.
  3. Select End User Worker, enter the WebSocket URL and managed API key, then save the connection.
  4. Click Save / Import Current Google Account to create or update the dashboard token by Google email. The imported account is automatically assigned to that managed key, uses protocol refresh, and stores the required Google cookies.
  5. Optionally enable automatic account sync and choose its interval. This keeps the account current without a separate Refresh Worker profile.

Use Captcha Worker for server-wide CAPTCHA capacity, or Refresh Worker only when binding a dedicated Chrome profile to an already existing Token ID.

If a managed key has no matching extension worker online, requests wait up to extension_queue_wait_timeout_seconds and then fail (no gateway fallback).

Option 1: Docker deployment (recommended)

Standard mode (without a proxy)

# Clone the project
git clone https://github.com/agmmnn/flow2api.git
cd flow2api

# Start the service
docker compose -f infra/compose/docker-compose.yml up -d

# Follow the logs
docker compose -f infra/compose/docker-compose.yml logs -f

Compose mounts .runtime/tmp by default. Setting the cache timeout to 0 means files do not expire automatically. Keep this mount if cached files must survive container recreation.

WARP mode (with a proxy)

# Start with the WARP proxy
docker compose -f infra/compose/docker-compose.proxy.yml up -d

# Follow the logs
docker compose -f infra/compose/docker-compose.proxy.yml logs -f

Headed CAPTCHA mode in Docker (browser / personal)

Use this mode when you need a virtual desktop and headed browser-based CAPTCHA solving inside the container. It starts Xvfb + Fluxbox for an internal visual desktop and sets ALLOW_DOCKER_HEADED_CAPTCHA=true. Only the application port is exposed; no remote desktop port is provided. The built-in personal browser now starts headed by default. Set PERSONAL_BROWSER_HEADLESS=true to temporarily switch it back to headless mode.

# Start headed mode (use --build on the first run)
docker compose -f infra/compose/docker-compose.headed.yml up -d --build

# Follow the logs
docker compose -f infra/compose/docker-compose.headed.yml logs -f
  • API port: 8000
  • In the admin interface, set the CAPTCHA method to browser or personal

Cloudflare Tunnel (public API and separate admin hostnames)

Run cloudflared in Docker and expose the OpenAI-compatible API (/v1/...) and web administration interface (/ and /api/...) through two public subdomains backed by the same internal service. Both hostnames proxy to http://<service-name>:8000 inside Docker; the application remains a single process.

  1. In Cloudflare Zero Trust, open Networks β†’ Tunnels, create a named tunnel, and copy the TUNNEL_TOKEN from the cloudflared installation command.
  2. Configure two Public hostnames on the same tunnel (replace these examples with your own domains):
    • API only (no admin UI or frontend): https://flow-api.prismacreative.online β†’ http://flow2api:8000
    • Admin UI and frontend: https://admin-flow.prismacreative.online β†’ http://flow2api:8000 Docker resolves flow2api to the application container on the shared network. Do not use a host-mapped port such as 38000 as the tunnel origin.
  3. Run cp .env.example .env in the repository root and set TUNNEL_TOKEN=.... infra/compose/docker-compose.yml contains the main flow2api service. Merging infra/compose/docker-compose.agent.yml adds agent-gateway, redis, and cloudflared on the same tunnel. Configure agents.* in Cloudflare to use http://agent-gateway:9080. FLOW2API_API_ONLY_HOST is defined on the flow2api service. On that hostname, ApiOnlyHostMiddleware exposes only OpenAI-compatible routes (/v1/...), Gemini-style routes (/v1beta/models/...:generateContent, :streamGenerateContent, /models/...), cache files under /tmp, /openapi.json, and /health. It blocks the web UI, /api administration routes, and /assets. Always use a different hostname such as admin-flow.* for the admin UI. Override it with FLOW2API_API_ONLY_HOST=your-api-subdomain. Do not run another cloudflared connector with the same tunnel token on the host.
  4. Start the merged stack with docker compose -f infra/compose/docker-compose.yml -f infra/compose/docker-compose.agent.yml up -d. Add --build to build agent-gateway. To run only the local application without the tunnel or agent, use docker compose -f infra/compose/docker-compose.yml up -d. To build the main image from source, run docker build -t flow2api:local -f infra/docker/Dockerfile ., set the flow2api image in Compose to flow2api:local, and run up.
  5. Open the admin-flow hostname for administration and use the flow-api hostname as the OpenAI-compatible API base URL, for example https://flow-api.prismacreative.online/v1/.... See the Agent Gateway runbook for the public Agent Gateway.
  6. Set [cache].base_url in config/setting.toml to the public API URL, for example base_url = "https://flow-api.prismacreative.online". See the comments in config/setting_example.toml.
  7. Configure FLOW2API_API_ONLY_HOST as an environment variable. The default is shown in the flow2api service in infra/compose/docker-compose.yml; Docker Compose reads the root .env file.

If /login or another UI page remains accessible on the flow-api hostname: the current image does not contain this repository's ApiOnlyHostMiddleware, usually because it is an older ghcr.io/.../flow2api:latest image. Build and deploy from this repository with docker build -t flow2api:local -f infra/docker/Dockerfile ., set the Compose service image to flow2api:local, and run up -d again. Confirm that the startup log contains API-only host(s). The environment variable can also be set when running uv run flow2api directly. If the current image is deployed but the old page remains, disable aggressive HTML caching for that hostname or purge the Cloudflare cache.

For headed CAPTCHA solving, use infra/compose/docker-compose.headed.yml, which already includes Cloudflare Tunnel and flow2api-headed:

docker compose -f infra/compose/docker-compose.headed.yml up -d

In Zero Trust, set both public hostnames' origin to http://flow2api-headed:8000, matching the service name in infra/compose/docker-compose.headed.yml.

Option 2: Local deployment

# Clone the project
git clone https://github.com/agmmnn/flow2api.git
cd flow2api

# Create/sync the environment and build the frontend
uv run setup

# Start Flow2API
uv run flow2api

uv run setup installs Python 3.11 if needed, creates .venv, installs the exact versions from uv.lock, installs the locked workspace dependencies with Bun, and builds the admin UI into apps/api/static/. Run it after cloning or when frontend dependencies change.

uv run flow2api starts the backend without rebuilding the frontend. For development, update Python dependencies with uv add/uv remove, then commit both pyproject.toml and uv.lock.

For upgrades, database adoption, compatibility guarantees, verification evidence, and rollback boundaries, see docs/architecture-migration-release.md.

First visit

After startup, open the administration interface at http://localhost:8000. Change the default password immediately after your first login.

  • Username: admin
  • Password: admin

πŸ“ˆ Monitoring endpoints

  • GET /health: Public health check with service status and summaries for active, expiring, expired, and rate-limited tokens
  • GET /metrics: Prometheus metrics
  • GET /api/tokens: Admin endpoint with token state such as at_expires, at_expired, at_expiring_within_1h, ban_reason, and consecutive_error_count

Prometheus can scrape /metrics directly. For Kubernetes deployments, scrape it only inside the cluster and restrict external access at the Ingress or Gateway layer.

Model test page

Open http://localhost:8000/test to use the built-in model test page. It supports:

  • Browsing available models by category, including image generation, text/image-to-video, reference-image video, and video upscaling
  • One-click prompt testing with streamed generation progress
  • Image uploads for image-to-image and image-to-video requests
  • Direct image or video previews after generation

πŸ“‹ Supported models

Image generation

Model Description Orientation
gemini-2.5-flash-image-landscape Text/image-to-image Landscape
gemini-2.5-flash-image-portrait Text/image-to-image Portrait
gemini-3.0-pro-image-landscape Text/image-to-image Landscape
gemini-3.0-pro-image-portrait Text/image-to-image Portrait
gemini-3.0-pro-image-square Text/image-to-image Square
gemini-3.0-pro-image-four-three Text/image-to-image Landscape 4:3
gemini-3.0-pro-image-three-four Text/image-to-image Portrait 3:4
gemini-3.0-pro-image-landscape-2k Text/image-to-image (2K) Landscape
gemini-3.0-pro-image-portrait-2k Text/image-to-image (2K) Portrait
gemini-3.0-pro-image-square-2k Text/image-to-image (2K) Square
gemini-3.0-pro-image-four-three-2k Text/image-to-image (2K) Landscape 4:3
gemini-3.0-pro-image-three-four-2k Text/image-to-image (2K) Portrait 3:4
gemini-3.0-pro-image-landscape-4k Text/image-to-image (4K) Landscape
gemini-3.0-pro-image-portrait-4k Text/image-to-image (4K) Portrait
gemini-3.0-pro-image-square-4k Text/image-to-image (4K) Square
gemini-3.0-pro-image-four-three-4k Text/image-to-image (4K) Landscape 4:3
gemini-3.0-pro-image-three-four-4k Text/image-to-image (4K) Portrait 3:4
imagen-4.0-generate-preview-landscape Text/image-to-image Landscape
imagen-4.0-generate-preview-portrait Text/image-to-image Portrait
gemini-3.1-flash-image-landscape Text/image-to-image Landscape
gemini-3.1-flash-image-portrait Text/image-to-image Portrait
gemini-3.1-flash-image-square Text/image-to-image Square
gemini-3.1-flash-image-four-three Text/image-to-image Landscape 4:3
gemini-3.1-flash-image-three-four Text/image-to-image Portrait 3:4
gemini-3.1-flash-image-landscape-2k Text/image-to-image (2K) Landscape
gemini-3.1-flash-image-portrait-2k Text/image-to-image (2K) Portrait
gemini-3.1-flash-image-square-2k Text/image-to-image (2K) Square
gemini-3.1-flash-image-four-three-2k Text/image-to-image (2K) Landscape 4:3
gemini-3.1-flash-image-three-four-2k Text/image-to-image (2K) Portrait 3:4
gemini-3.1-flash-image-landscape-4k Text/image-to-image (4K) Landscape
gemini-3.1-flash-image-portrait-4k Text/image-to-image (4K) Portrait
gemini-3.1-flash-image-square-4k Text/image-to-image (4K) Square
gemini-3.1-flash-image-four-three-4k Text/image-to-image (4K) Landscape 4:3
gemini-3.1-flash-image-three-four-4k Text/image-to-image (4K) Portrait 3:4

Video generation

Text-to-video (T2V)

⚠️ Image uploads are not supported

Model Description Orientation
veo_3_1_t2v_fast_portrait Text-to-video Portrait
veo_3_1_t2v_fast_landscape Text-to-video Landscape
veo_3_1_t2v_fast_portrait_ultra Text-to-video Portrait
veo_3_1_t2v_fast_ultra Text-to-video Landscape
veo_3_1_t2v_fast_portrait_ultra_relaxed Text-to-video Portrait
veo_3_1_t2v_fast_ultra_relaxed Text-to-video Landscape
veo_3_1_t2v_portrait Text-to-video Portrait
veo_3_1_t2v_landscape Text-to-video Landscape
veo_3_1_t2v_lite_portrait Text-to-video Lite Portrait
veo_3_1_t2v_lite_landscape Text-to-video Lite Landscape
veo_3_1_t2v_landscape_4s Text-to-video, 4 seconds Landscape
veo_3_1_t2v_portrait_4s Text-to-video, 4 seconds Portrait
veo_3_1_t2v_landscape_6s Text-to-video, 6 seconds Landscape
veo_3_1_t2v_portrait_6s Text-to-video, 6 seconds Portrait
veo_3_1_t2v_fast_landscape_4s Fast text-to-video, 4 seconds Landscape
veo_3_1_t2v_fast_portrait_4s Fast text-to-video, 4 seconds Portrait
veo_3_1_t2v_fast_landscape_6s Fast text-to-video, 6 seconds Landscape
veo_3_1_t2v_fast_portrait_6s Fast text-to-video, 6 seconds Portrait
veo_3_1_t2v_lite_4s_portrait Text-to-video Lite, 4 seconds Portrait
veo_3_1_t2v_lite_4s_landscape Text-to-video Lite, 4 seconds Landscape
veo_3_1_t2v_lite_6s_portrait Text-to-video Lite, 6 seconds Portrait
veo_3_1_t2v_lite_6s_landscape Text-to-video Lite, 6 seconds Landscape

First/last-frame models (I2V - Image to Video)

πŸ“Έ Supports one or two images: one image is the first frame; two images are the first and last frames

πŸ’‘ Automatic selection: the system chooses the appropriate model_key from the image count.

  • Single-frame mode (one image): generates a video from the first frame
  • Two-frame mode (two images): generates a transition between the first and last frames
  • veo_3_1_i2v_lite_* supports only one first-frame image
  • veo_3_1_interpolation_lite_* supports exactly two first/last-frame images
Model Description Orientation
veo_3_1_i2v_s_fast_portrait_fl Image-to-video Portrait
veo_3_1_i2v_s_fast_fl Image-to-video Landscape
veo_3_1_i2v_s_fast_portrait_ultra_fl Image-to-video Portrait
veo_3_1_i2v_s_fast_ultra_fl Image-to-video Landscape
veo_3_1_i2v_s_fast_portrait_ultra_relaxed Image-to-video Portrait
veo_3_1_i2v_s_fast_ultra_relaxed Image-to-video Landscape
veo_3_1_i2v_s_portrait Image-to-video Portrait
veo_3_1_i2v_s_landscape Image-to-video Landscape
veo_3_1_i2v_lite_portrait Image-to-video Lite (first frame only) Portrait
veo_3_1_i2v_lite_landscape Image-to-video Lite (first frame only) Landscape
veo_3_1_interpolation_lite_portrait Image-to-video Lite (first/last-frame transition) Portrait
veo_3_1_interpolation_lite_landscape Image-to-video Lite (first/last-frame transition) Landscape
veo_3_1_i2v_s_landscape_4s Image-to-video, 4 seconds Landscape
veo_3_1_i2v_s_portrait_4s Image-to-video, 4 seconds Portrait
veo_3_1_i2v_s_landscape_6s Image-to-video, 6 seconds Landscape
veo_3_1_i2v_s_portrait_6s Image-to-video, 6 seconds Portrait
veo_3_1_i2v_s_fast_landscape_4s_fl Fast image-to-video, 4 seconds Landscape
veo_3_1_i2v_s_fast_portrait_4s_fl Fast image-to-video, 4 seconds Portrait
veo_3_1_i2v_s_fast_landscape_6s_fl Fast image-to-video, 6 seconds Landscape
veo_3_1_i2v_s_fast_portrait_6s_fl Fast image-to-video, 6 seconds Portrait
veo_3_1_i2v_lite_4s_portrait Image-to-video Lite, 4 seconds (first frame only) Portrait
veo_3_1_i2v_lite_4s_landscape Image-to-video Lite, 4 seconds (first frame only) Landscape
veo_3_1_i2v_lite_6s_portrait Image-to-video Lite, 6 seconds (first frame only) Portrait
veo_3_1_i2v_lite_6s_landscape Image-to-video Lite, 6 seconds (first frame only) Landscape
veo_3_1_interpolation_lite_4s_portrait Image-to-video Lite, 4 seconds (first/last-frame transition) Portrait
veo_3_1_interpolation_lite_4s_landscape Image-to-video Lite, 4 seconds (first/last-frame transition) Landscape
veo_3_1_interpolation_lite_6s_portrait Image-to-video Lite, 6 seconds (first/last-frame transition) Portrait
veo_3_1_interpolation_lite_6s_landscape Image-to-video Lite, 6 seconds (first/last-frame transition) Landscape

Reference images to video (R2V)

πŸ–ΌοΈ Supports multiple reference images

2026-03-06 update

  • Synchronized with the latest upstream R2V video request body
  • Replaced textInput with structuredPrompt.parts
  • Added top-level mediaGenerationContext.batchId
  • Added top-level useV2ModelConfig: true
  • Landscape and portrait R2V models now share the same request body
  • The upstream landscape videoModelKey now uses the *_landscape form
  • The current upstream protocol accepts at most three referenceImages
Model Description Orientation
veo_3_1_r2v_fast_portrait Reference-image-to-video Portrait
veo_3_1_r2v_fast_landscape Reference-image-to-video Landscape
veo_3_1_r2v_fast_portrait_ultra Reference-image-to-video Portrait
veo_3_1_r2v_fast_landscape_ultra Reference-image-to-video Landscape
veo_3_1_r2v_fast_portrait_ultra_relaxed Reference-image-to-video Portrait
veo_3_1_r2v_fast_landscape_ultra_relaxed Reference-image-to-video Landscape

Video upscaling models

These models first generate a video with the corresponding standard Veo 3.1 model and then submit a 1080p or 4K upscale request. They do not call an upstream upscaler model key directly.

Model Description Output
veo_3_1_t2v_landscape_4k Text-to-video upscale 4K
veo_3_1_t2v_portrait_4k Text-to-video upscale 4K
veo_3_1_t2v_landscape_1080p Text-to-video upscale 1080p
veo_3_1_t2v_portrait_1080p Text-to-video upscale 1080p
veo_3_1_t2v_landscape_4s_4k 4-second text-to-video upscale 4K
veo_3_1_t2v_portrait_4s_4k 4-second text-to-video upscale 4K
veo_3_1_t2v_landscape_4s_1080p 4-second text-to-video upscale 1080p
veo_3_1_t2v_portrait_4s_1080p 4-second text-to-video upscale 1080p
veo_3_1_t2v_landscape_6s_4k 6-second text-to-video upscale 4K
veo_3_1_t2v_portrait_6s_4k 6-second text-to-video upscale 4K
veo_3_1_t2v_landscape_6s_1080p 6-second text-to-video upscale 1080p
veo_3_1_t2v_portrait_6s_1080p 6-second text-to-video upscale 1080p
veo_3_1_t2v_fast_portrait_4k Text-to-video upscale 4K
veo_3_1_t2v_fast_4k Text-to-video upscale 4K
veo_3_1_t2v_fast_portrait_ultra_4k Text-to-video upscale 4K
veo_3_1_t2v_fast_ultra_4k Text-to-video upscale 4K
veo_3_1_t2v_fast_portrait_1080p Text-to-video upscale 1080p
veo_3_1_t2v_fast_1080p Text-to-video upscale 1080p
veo_3_1_t2v_fast_portrait_ultra_1080p Text-to-video upscale 1080p
veo_3_1_t2v_fast_ultra_1080p Text-to-video upscale 1080p
veo_3_1_i2v_s_fast_portrait_ultra_fl_4k Image-to-video upscale 4K
veo_3_1_i2v_s_fast_ultra_fl_4k Image-to-video upscale 4K
veo_3_1_i2v_s_fast_portrait_ultra_fl_1080p Image-to-video upscale 1080p
veo_3_1_i2v_s_fast_ultra_fl_1080p Image-to-video upscale 1080p
veo_3_1_i2v_s_landscape_4k Image-to-video upscale 4K
veo_3_1_i2v_s_portrait_4k Image-to-video upscale 4K
veo_3_1_i2v_s_landscape_1080p Image-to-video upscale 1080p
veo_3_1_i2v_s_portrait_1080p Image-to-video upscale 1080p
veo_3_1_i2v_s_landscape_4s_4k 4-second image-to-video upscale 4K
veo_3_1_i2v_s_portrait_4s_4k 4-second image-to-video upscale 4K
veo_3_1_i2v_s_landscape_4s_1080p 4-second image-to-video upscale 1080p
veo_3_1_i2v_s_portrait_4s_1080p 4-second image-to-video upscale 1080p
veo_3_1_i2v_s_landscape_6s_4k 6-second image-to-video upscale 4K
veo_3_1_i2v_s_portrait_6s_4k 6-second image-to-video upscale 4K
veo_3_1_i2v_s_landscape_6s_1080p 6-second image-to-video upscale 1080p
veo_3_1_i2v_s_portrait_6s_1080p 6-second image-to-video upscale 1080p
veo_3_1_r2v_fast_portrait_ultra_4k Reference-image video upscale 4K
veo_3_1_r2v_fast_landscape_ultra_4k Reference-image video upscale 4K
veo_3_1_r2v_fast_portrait_ultra_1080p Reference-image video upscale 1080p
veo_3_1_r2v_fast_landscape_ultra_1080p Reference-image video upscale 1080p

πŸ“‘ API examples (streaming required)

In addition to the OpenAI-compatible examples below, the service supports the official Gemini format:

  • POST /v1beta/models/{model}:generateContent
  • POST /models/{model}:generateContent
  • POST /v1beta/models/{model}:streamGenerateContent
  • POST /models/{model}:streamGenerateContent

Official Gemini requests support these authentication methods:

  • Authorization: Bearer <api_key>
  • x-goog-api-key: <api_key>
  • ?key=<api_key>

Official Gemini image requests support:

  • systemInstruction
  • contents[].parts[].text
  • contents[].parts[].inlineData
  • contents[].parts[].fileData.fileUri
  • generationConfig.responseModalities
  • generationConfig.imageConfig.aspectRatio
  • generationConfig.imageConfig.imageSize

Official Gemini generateContent (text-to-image)

Verified with a real token. For streaming output, replace the path suffix with :streamGenerateContent?alt=sse.

curl -X POST "http://localhost:8000/models/gemini-3.1-flash-image:generateContent" \
  -H "x-goog-api-key: han1234" \
  -H "Content-Type: application/json" \
  -d '{
    "systemInstruction": {
      "parts": [
        {
          "text": "Return an image only."
        }
      ]
    },
    "contents": [
      {
        "role": "user",
        "parts": [
          {
            "text": "A red apple on a wooden table, studio lighting, minimalist background"
          }
        ]
      }
    ],
    "generationConfig": {
      "responseModalities": ["IMAGE"],
      "imageConfig": {
        "aspectRatio": "1:1",
        "imageSize": "1K"
      }
    }
  }'

Text-to-image

curl -X POST "http://localhost:8000/v1/chat/completions" \
  -H "Authorization: Bearer han1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.1-flash-image-landscape",
    "messages": [
      {
        "role": "user",
        "content": "A cute cat playing in a garden"
      }
    ],
    "stream": true
  }'

Optional Flow project pinning

Native Flow image and video requests use automatic project rotation by default. To keep generated assets in a specific tracked project, give the managed API key the projects:read scope, list its available projects, and pass project_id with the generation request:

curl "http://localhost:8000/v1/projects?limit=100" \
  -H "Authorization: Bearer <managed-api-key>"

curl -X POST "http://localhost:8000/v1/chat/completions" \
  -H "Authorization: Bearer <managed-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.1-flash-image-landscape",
    "project_id": "<flow-project-id>",
    "messages": [{"role": "user", "content": "A cute cat playing in a garden"}],
    "stream": true
  }'

The project must be active, belong to that API key, and use an account assigned to the key. Omit project_id to retain automatic routing. Project pinning applies only to native Flow models, not Runway or GeminiGen providers.

Image-to-image

curl -X POST "http://localhost:8000/v1/chat/completions" \
  -H "Authorization: Bearer han1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.1-flash-image-landscape",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "Transform this image into a watercolor painting"
          },
          {
            "type": "image_url",
            "image_url": {
              "url": "data:image/jpeg;base64,<base64_encoded_image>"
            }
          }
        ]
      }
    ],
    "stream": true
  }'

Text-to-video

curl -X POST "http://localhost:8000/v1/chat/completions" \
  -H "Authorization: Bearer han1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo_3_1_t2v_fast_landscape",
    "messages": [
      {
        "role": "user",
        "content": "A kitten chasing butterflies across a meadow"
      }
    ],
    "stream": true
  }'

First-and-last-frame video

curl -X POST "http://localhost:8000/v1/chat/completions" \
  -H "Authorization: Bearer han1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo_3_1_i2v_s_fast_fl_landscape",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "Transition smoothly from the first image to the second image"
          },
          {
            "type": "image_url",
            "image_url": {
              "url": "data:image/jpeg;base64,<first_frame_base64>"
            }
          },
          {
            "type": "image_url",
            "image_url": {
              "url": "data:image/jpeg;base64,<last_frame_base64>"
            }
          }
        ]
      }
    ],
    "stream": true
  }'

Reference-images-to-video

The server assembles the current R2V request body automatically; callers continue to use OpenAI-compatible input. Landscape R2V requests are mapped to the latest upstream *_landscape model key. A request can currently include up to three reference images.

curl -X POST "http://localhost:8000/v1/chat/completions" \
  -H "Authorization: Bearer han1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo_3_1_r2v_fast_portrait",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "Create a portrait video with a smooth camera push based on the characters and setting in these three reference images"
          },
          {
            "type": "image_url",
            "image_url": {
              "url": "data:image/jpeg;base64/<reference_image_1_base64>"
            }
          },
          {
            "type": "image_url",
            "image_url": {
              "url": "data:image/jpeg;base64/<reference_image_2_base64>"
            }
          },
          {
            "type": "image_url",
            "image_url": {
              "url": "data:image/jpeg;base64/<reference_image_3_base64>"
            }
          }
        ]
      }
    ],
    "stream": true
  }'

πŸ“„ License

This project is licensed under the MIT License. See LICENSE for details.


πŸ™ Acknowledgements

Thanks to every contributor and user for their support.


πŸ“ž Contact


⭐ If this project helps you, please give it a star!

Star History

Star History Chart

About

Reverse-engineered Google Flow API and account pool manager. It lets users interface with Google Labs' AI video and image tools (such as VideoFX/Flow) programmatically. It handles multi-token load balancing, automated token refreshing, and proxy integration.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages