API Reference

Generate an image

The API uses the same generation workflow as the browser studio. Create an API key in the signed-in console, then send a prompt to the image generation route.

curl -X POST https://nanobananafree.app/api/nano-banana/generate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-YOUR_API_KEY" \
  -d '{
    "prompt": "a premium banana product poster in a clean studio",
    "model": "nano-banana-fast",
    "ratio": "1:1",
    "style": "studio",
    "negativePrompt": "blurry, distorted hands",
    "requestId": "demo-product-poster-001"
  }'

Request fields

  • prompt is required.
  • model may be nano-banana-fast, gpt-image-2, nano-banana-pro, or nano-banana-2.
  • ratio may be 1:1, 3:4, or 16:9.
  • style is an optional preset such as dreamy, studio, or retro.
  • image is an optional data URL for reference-image remixing.
  • images is an optional array of 1–5 image data URLs for multi-reference editing. If both image and images are provided, images wins. Multi- reference editing is currently APIMart-only on synchronous routes and is not accepted by asynchronous jobs.
  • mask is an optional PNG data URL for masked reference-image editing. It requires image, must be under 4MB, and is currently supported only by the APIMart-backed synchronous routes; it is not available for GPT Image 2 or asynchronous jobs.
  • negativePrompt is optional guidance for elements to avoid.
  • requestId is recommended and must be unique per intended generation.
  • Every successful request consumes the selected model's credits.

Response

Successful responses include an access-controlled imageUrl/assetUrl, generationUsageId, mimeType, model, provider, and requestId. Requests require a valid API key or signed-in session and are subject to the account's credits and model entitlements.

imageUrl and assetUrl point to the access-controlled generation asset route and are absolute when the deployment URL is configured. Keep the same Authorization: Bearer sk-... header when fetching a private asset URL. The API no longer returns the raw provider/storage URL to clients.

Idempotency and credits

Send a unique requestId for every intended generation. Repeating a request with the same user and requestId returns the original successful result and does not charge credits again. A request that cannot reserve credits does not call the image provider. If a provider call fails after reservation, the server records a refund ledger entry and marks the generation as failed.

The API key is read from Authorization: Bearer sk-...; browser sessions are also accepted. The response's entitlement.creditsRequired is the cost of that model for the request.

If a process stops before the provider starts, the generation remains marked as a safe-to-recover reservation. An administrator can reconcile those stale reservations from the generation review console. Records whose provider has already started are not automatically refunded, because doing so could create an untracked provider result.

Reference-image editing

Pass an image as a standard base64 data URL in image, or pass up to five images in images. The browser studio compresses uploads before sending them. Use images that you own or have permission to edit, and review generated text, logos, likenesses, and product claims before publishing.

For masked editing, pass a PNG mask data URL whose dimensions exactly match the compressed reference image. The browser studio supports either PNG upload or an on-image brush that exports the mask at the exact reference dimensions. White/transparent mask semantics are provider/model dependent, so verify the returned image before publishing. The server does not silently fall back to a provider that does not support masks.

Multi-reference editing cannot currently be combined with a mask. GPT Image 2, Gemini, and GRSAI do not silently receive a reduced single-image request; the server returns a provider capability error when APIMart is unavailable.

Synchronous batch variations

For up to four independent variations, call the batch route with one stable batchRequestId. Each item is charged and recorded independently. The response is 200 when every item succeeds and 207 when one or more items fail. This is a synchronous endpoint, not an async queue. Configure Generation webhooks separately when you need terminal callbacks for completed jobs.

curl -X POST https://nanobananafree.app/api/nano-banana/batch \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-YOUR_API_KEY" \
  -d '{
    "prompt": "a premium banana product poster in a clean studio",
    "model": "nano-banana-fast",
    "count": 3,
    "batchRequestId": "product-poster-v1"
  }'

Child request ids are product-poster-v1_1, product-poster-v1_2, and so on. Retrying the same batch id replays completed items without charging them again. The batch route accepts the same image, images, and mask fields as the synchronous route, with the same APIMart-only and size constraints.

Generation status

Poll GET /api/generation-usage/{generationUsageId} with the same API key to inspect processing, succeeded, or failed state. Successful responses include an authorized assetUrl; failed responses include a retryable error message for the owning account. This endpoint reports the current synchronous task record; it is not itself the webhook contract. Configure Generation webhooks separately when you need signed terminal callbacks.

Authorized asset URLs accept ?download=1 to return the original image as an attachment with a stable filename. This parameter does not claim format conversion, upscaling, or background removal.

The browser History workspace can download multiple selected assets one by one.

Generation records may include source_usage_id and source_operation when created from an authorized history asset or a Recraft operation. These fields describe direct lineage only; they do not expose private source images.

Batch image operations

POST /api/generation-usage/bulk/operations applies one operation to up to 20 successful, non-archived assets owned by the caller. Supported operations are remove-background, crisp-upscale, and creative-upscale. Each asset runs through the same reservation, refund, idempotency, and private-asset path as a single operation. The response is 200 when all items succeed and 207 when some items fail. This v1 is synchronous and does not provide a background queue. For larger batches, use POST /api/generation-usage/bulk/operations/jobs. It returns 202 without charging credits; the protected operation worker processes items and GET /api/generation-operation-jobs/{id} exposes progress and partial results. A production scheduler must call the worker; without one, the job remains explicitly queued. Each download is independently authorized; the current API does not promise a ZIP archive or bypass private-asset access checks.

Asynchronous generation jobs (deployment opt-in)

For deployments with a configured worker scheduler, create a job with POST /api/nano-banana/jobs. It returns 202 and a jobId; poll GET /api/generation-jobs/{id} for queued, running, succeeded, partial, or failed. DELETE /api/generation-jobs/{id} can cancel only queued jobs.

The worker endpoint is internal and protected by GENERATION_WORKER_SECRET. The application does not claim automatic async execution until the deployment connects that endpoint to a cron/queue worker. Reference images are temporarily stored in the job payload and should move to short-lived object storage before high-volume production use. Signed-in browser users can monitor these jobs from the Generation jobs console page; that page also polls active jobs and can cancel queued work.

Saved workflows

Signed-in browser users can save a named workflow from the studio. A workflow stores only prompt, model, style, ratio, and negativePrompt; it does not store or promise permanent hosting for generated images. The saved Private workflows remain visible only to their owner. A workflow may also be saved into an accessible project; the project owner and active editors can create or delete those workflows, while active viewers can read and reuse them. Project membership is checked server-side and pending invitations have no access. Workflow owners/editors can update a workflow, inspect immutable version snapshots, and roll back by creating a new version.

From the Saved Workflows console, the workflow owner or any active member of the containing project can use Open workflow graph to inspect the linear v1 graph. Owners/editors can change Prompt, Generate, and the optional Variations node, then save a new graph version through PATCH /api/workflows/{id}/graph. The graph is compiled to the existing generation_jobs contract by POST /api/workflows/{id}/run; clients cannot override its prompt, model, style, ratio, negative prompt, or count. The endpoint returns 202 and creates a queued generation job without charging credits at submission time. Credits and entitlement are checked when the protected generation worker executes the job. This remains deployment opt-in: without a scheduler calling the worker, the job stays queued. v1 deliberately does not claim an infinite canvas, arbitrary DAG, image-input nodes, or post-processing nodes.

Workflow Graph v1 now also supports optional ordered operation nodes for remove-background, crisp-upscale, creative-upscale, and parameterized outpaint. The protected worker runs each operation after each generated variation through the same operation service used by the single-asset APIs. That service owns credits reservation, provider failure refunds, persisted derived assets, idempotency, and lineage. A failed variation does not cancel other variations, so the job can finish as partial. Outpaint uses the existing bounded prompt, target ratio, and zoom controls. Operation nodes do not accept masks; erase remains an explicit single-asset tool.

Graph v1 can also include one Reference asset node containing a successful History usage id. The queue route verifies that the asset belongs to the workflow owner and is active/not in Trash; shared project members can read the graph but cannot run a workflow that references the owner's asset. The worker rechecks the asset immediately before generation, fetches at most 10MB into a temporary in-memory image data URL, and passes it through the existing reference-edit and lineage path. The node accepts up to five comma-separated usage ids; legacy single usageId graphs are normalized automatically. The worker passes all authorized images through the existing multi-reference provider contract and uses the first id as the current lineage parent. The job snapshot stores only ids, not permanent image copies or external URLs. A future multi-parent lineage schema is required to represent every reference as a separate parent.

Asset sharing

Signed-in owners can create a read-only share link for a successful, active asset from Generation History. Links expire after 1, 7, or 30 days and can be revoked by the owner. A share link exposes only the image preview; it does not expose prompt, credits, provider metadata, generation history, download permission, or publication approval.

Remove background

Signed-in owners can create a new private asset with the background removed from a successful, active generation by calling POST /api/generation-usage/{generationUsageId}/remove-background. The operation costs 1 credit and uses Recraft when RECRAFT_API_KEY is configured; it does not modify the source asset. The response includes the new generation usage id and an authorized asset URL. Provider failure is recorded and the reserved credit is refunded. This is currently synchronous and does not promise batch processing, transparency-format conversion, or other editing tools.

Crisp upscale

Signed-in owners can create a new private crisp-upscaled asset from a successful, active generation with POST /api/generation-usage/{generationUsageId}/upscale. The operation costs 2 credits and uses Recraft when RECRAFT_API_KEY is configured; it does not modify the source asset. The operation currently exposes no scale or target dimension parameter and does not promise a specific output resolution, Creative Upscale, batch processing, or format conversion.

The same endpoint accepts mode: "crisp" | "creative"; both modes cost 2 credits. Creative mode uses Recraft creativeUpscale and may reconstruct fine details, so users should preview the derived asset before delivery.

Erase region

Signed-in owners can paint a PNG mask over a successful, active History asset and call POST /api/generation-usage/{generationUsageId}/erase with the mask data URL. The operation costs 2 credits and uses Recraft eraseRegion; the source image is unchanged and the result is stored as a new private asset. Masks must be PNG data URLs smaller than 4MB and should match the source image dimensions. This v1 operation does not accept a natural-language prompt and does not promise outpainting, batch editing, or format conversion.

Outpaint

Signed-in owners can extend a successful, active asset with POST /api/generation-usage/{generationUsageId}/outpaint. The request accepts a prompt, one of the supported canvas ratios, and a 10%, 25%, or 50% zoom-out choice. It costs 2 credits, uses Recraft, and stores the result as a new private asset without modifying the source. Custom canvas sizes, negative zoom, batch processing, and format conversion are not part of v1.

Browser export

Generation History provides an authorized browser-side export control for PNG, JPEG, and WebP. The browser loads the asset through the private asset proxy and converts it locally with Canvas; this does not create a second cloud asset or charge credits. JPEG exports use a white background. Server-side PDF/TIFF/SVG, ZIP delivery, and long-term export copies are not supported by this contract.

Project collaboration

Project owners can invite registered users by email from the Projects console as viewer or editor. Viewers can inspect the project and its successful active assets; editors can organize assets into the project. Only the owner can rename/delete the project, manage members, publish, archive, share, generate, or run post-processing operations. Unknown emails remain pending records and do not create accounts or send email automatically. Project collaboration now also includes shared workflows, styles, brand kit metadata, comments, activity, and member asset delivery. Organizations, billing, and invitation emails are still outside the current contract.

Invitation inbox

Pending project invitations are available at /project-invitations after the recipient signs in with the invited email. The recipient can accept or decline without exposing a user id; accepting binds the invitation to the current account and activates its viewer/editor project access. This v1 does not send email or support invitation transfer.

Project style library

Project owners and active editors can create, edit, and delete reusable style presets. Active project members can list and apply them in the generator by opening a URL with ?project=<id>. A preset stores a display name and the provider style/prompt value; it does not upload or expose private brand files.

Project Brand Kit

Each project may keep one private Brand Kit containing an HTTPS logo URL, primary and secondary colors, font family, and generation guidance. Owners and editors can update it; active members can read it. Opening the generator with ?project=<id> loads the kit, but brand guidance is added to a prompt only after the user explicitly chooses to apply it.

Project activity

Active project members can view the latest project activity, including member downloads and ZIP export creation. Activity metadata is intentionally limited to safe identifiers and counts; prompts, provider payloads, URLs, tokens, and comment text are not recorded in the activity stream.

Project summary

Active project members can read a private project summary with successful asset count, credits charged by those assets, member count, shared workflow/style counts, comment count, and latest activity time. It does not expose private prompts, asset URLs, per-user balances, or create a shared team wallet.

Asset comments

Project owners and active project members can read or add plain-text comments to a successful generation asset from History. Comments support one-level replies, author-only editing, and case-insensitive @email mentions of active project members. Mentioned members receive a private notification in the Notifications console. Members can add or remove a fixed set of emoji reactions. The project owner can pin one top-level comment per asset. Comment authors can delete their own comments; the project owner can delete any comment in that project. Comments are private workspace data and are not included in public gallery or share-link responses. This v1 provides in-app notifications, fixed emoji reactions, and one pinned top-level comment per asset; it does not provide email delivery or comment search.

Bulk ZIP delivery

Generation History can package up to 50 selected, successful, active assets into a temporary ZIP through POST /api/generation-usage/bulk/download. Every id is checked against the current owner or active project membership before any archive is returned; unavailable or unauthorized selections fail as a whole. The archive is limited to 100MB, preserves source MIME extensions, is not stored, and does not consume credits. Active project members may download assets assigned to their project, including through ZIP delivery. This v1 does not provide resume support or format conversion.

Generation webhooks

Signed-in API users can create HTTPS webhook subscriptions for generation.succeeded, generation.partial, and generation.failed. Delivery requests include X-NanoBanana-Event, X-NanoBanana-Timestamp, and an X-NanoBanana-Signature header. Verify the signature as HMAC-SHA256(secret, timestamp + '.' + raw_body). Secrets are shown only when the subscription is created. Delivery is bounded and retried by the protected worker; polling remains the source of truth.

Use POST /api/webhooks/{id}/test to queue a signed webhook.test event. It does not create a generation or charge credits. Run the protected worker to deliver it, then inspect the delivery record in the Webhooks console.

Async export jobs

For larger exports, History can queue a ZIP job with POST /api/generation-usage/bulk/download/jobs when object storage and the protected export worker are configured. Poll GET /api/generation-export-jobs/{id} until it returns succeeded, then use the owner-scoped download URL. Jobs use a lease/heartbeat worker and have the same 50-asset/100MB source limit. Without object storage the endpoint returns 503 instead of pretending the job is durable. Active project members may create exports for assets assigned to their project. v1 does not provide retention cleanup, resume support, or format conversion.