API Reference

PaperBanana Open API documentation for image generation

Overview

The PaperBanana API allows you to programmatically generate images using our Standard (text/image-to-image) and Pipeline (AI-powered scientific illustration) models.

Base URL

https://open.paper-banana.org/api/v1

All requests must be made over HTTPS.


Authentication

API access requires a Team plan (Team Basic or Team Pro). You can generate team API keys from your team settings.

Authenticate using a Bearer token in the Authorization header:

curl -H "Authorization: Bearer sk-team-your-api-key" \
  https://open.paper-banana.org/api/v1/credits

All team API keys use the sk-team- prefix. Personal API keys (sk-) are no longer accepted for API access.


Team Plans

API access is available exclusively through Team plans:

PlanPriceCreditsAPI KeysRate Limit
Team Basic$999/year12,000/yearUp to 3120 RPM
Team Pro$1,499/year24,000/yearUp to 10300 RPM
  • Credits are shared across the team and consumed at full price (no resolution discounts on API calls).
  • Team members using PaperBanana on the web draw from the team credit pool and retain plan-level discounts.

Rate Limiting

Three layers of rate limiting are enforced:

LayerLimitScope
IP-based120 requests/minPer client IP (runs before authentication)
Key-based60 requests/minPer API key
Team-based120 or 300 requests/minPer team (Basic: 120, Pro: 300)

When any limit is exceeded, the API returns a 429 status with a Retry-After header.

Request Limits

ConstraintLimit
Request body size1 MB max
Content-Length headerRequired for POST requests
prompt length10,000 characters
options.content length100,000 characters
options.image_input items10 max

Endpoints

Check Credits

Returns the remaining credits for your account.

GET /api/v1/credits

Response

{
  "success": true,
  "data": {
    "remaining_credits": 450
  }
}

Generate Image

Creates an image generation task. The task runs asynchronously — use the Query Task endpoint to poll for results.

POST /api/v1/generate

Common Parameters

ParameterTypeRequiredDescription
typestringYes"standard" or "pipeline"
scenestringYes"text-to-image" or "image-to-image"
promptstringConditionalText prompt describing the desired image
modelstringConditionalModel name (Standard only)
optionsobjectNoAdditional options (see below)

Standard Mode

Uses Kie/Fal providers for general-purpose image generation.

ParameterTypeRequiredDescription
modelstringYes"nano-banana-pro" or "nano-banana-2"
promptstringYesText prompt
options.resolutionstringNo"1K" (default), "2K", or "4K"
options.aspect_ratiostringNoAspect ratio, default "auto"
options.output_formatstringNo"png" (default), "jpg", "jpeg", "webp"
options.image_inputstring[]image-to-imageArray of source image URLs (HTTPS only, max 10)
options.google_searchbooleanNoEnable Google search (nano-banana-2 only)

Image URL restrictions: All image_input URLs must use https://, must not point to private/internal network addresses, and must not use non-standard ports.

Example: Standard text-to-image

curl -X POST https://open.paper-banana.org/api/v1/generate \
  -H "Authorization: Bearer sk-team-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "standard",
    "scene": "text-to-image",
    "prompt": "A futuristic city skyline at sunset",
    "model": "nano-banana-pro",
    "options": {
      "resolution": "2K",
      "output_format": "png"
    }
  }'

Example: Standard image-to-image

curl -X POST https://open.paper-banana.org/api/v1/generate \
  -H "Authorization: Bearer sk-team-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "standard",
    "scene": "image-to-image",
    "prompt": "Make this more professional",
    "model": "nano-banana-2",
    "options": {
      "image_input": ["https://example.com/source.png"],
      "resolution": "1K"
    }
  }'

Pipeline Mode

Uses the DeepScience multi-step pipeline for AI-powered scientific illustrations, diagrams, and plots.

ParameterTypeRequiredDescription
promptstringtext-to-imageText prompt
options.contentstringYesPaper text or context for the pipeline
options.task_namestringNo"diagram" (default) or "plot"
options.resolutionstringNo"1K" (default), "2K", or "4K"
options.output_formatstringNo"png" (default), "jpg", "jpeg", "webp"
options.image_inputstring[]image-to-imageArray of source image URLs (HTTPS only, max 10)

Image URL restrictions: Same restrictions as Standard mode apply — HTTPS only, no private IPs, no non-standard ports.

Pipeline mode requires a Basic or Pro plan.

Example: Pipeline text-to-image

curl -X POST https://open.paper-banana.org/api/v1/generate \
  -H "Authorization: Bearer sk-team-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "pipeline",
    "scene": "text-to-image",
    "prompt": "Architecture diagram for transformer model",
    "options": {
      "content": "This paper presents a novel transformer architecture with multi-head attention...",
      "task_name": "diagram",
      "resolution": "2K"
    }
  }'

Example: Pipeline image-to-image

curl -X POST https://open.paper-banana.org/api/v1/generate \
  -H "Authorization: Bearer sk-team-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "pipeline",
    "scene": "image-to-image",
    "options": {
      "content": "This paper presents a novel transformer architecture...",
      "image_input": ["https://example.com/my-diagram.png"],
      "resolution": "2K"
    }
  }'

Generate Response

{
  "success": true,
  "data": {
    "task_id": "7655ed66-3a83-4a5a-9cb1-3b7c449ec4a9",
    "status": "pending",
    "cost_credits": 20
  }
}

List Tasks

Returns a paginated list of your generation tasks, with optional status filtering.

GET /api/v1/tasks

Query Parameters

ParameterTypeRequiredDescription
pagenumberNoPage number, default 1
limitnumberNoItems per page, default 20, max 100
statusstringNoFilter by status: "pending", "processing", "success", "failed", or "canceled"

Response

{
  "success": true,
  "data": {
    "tasks": [
      {
        "task_id": "7655ed66-3a83-4a5a-9cb1-3b7c449ec4a9",
        "type": "standard",
        "model": "nano-banana-pro",
        "scene": "text-to-image",
        "status": "success",
        "cost_credits": 10,
        "created_at": "2026-03-12T06:57:48.067Z",
        "output": {
          "images": [
            {
              "url": "https://storage.paper-banana.org/uploads/...",
              "type": "image/png"
            }
          ]
        },
        "error": null
      }
    ],
    "pagination": {
      "total": 42,
      "page": 1,
      "limit": 20,
      "total_pages": 3
    }
  }
}

Example

# List all tasks (page 1)
curl -H "Authorization: Bearer sk-team-your-api-key" \
  "https://open.paper-banana.org/api/v1/tasks"

# Filter by status with pagination
curl -H "Authorization: Bearer sk-team-your-api-key" \
  "https://open.paper-banana.org/api/v1/tasks?status=success&page=2&limit=10"

Query Task

Poll the status of a generation task. Keep polling until status is "success", "failed", or "canceled".

GET /api/v1/task/:taskId

Response (processing)

{
  "success": true,
  "data": {
    "task_id": "7655ed66-...",
    "type": "pipeline",
    "model": "pipeline",
    "scene": "text-to-image",
    "status": "processing",
    "cost_credits": 14,
    "created_at": "2026-03-12T06:57:48.067Z",
    "output": {
      "images": [],
      "current_stage": "stylist"
    },
    "error": null
  }
}

The current_stage field is available for Pipeline tasks and shows which step is currently executing (e.g. retriever, planner, stylist, visualizer, critic_round_0, etc.).

Response (completed)

{
  "success": true,
  "data": {
    "task_id": "7655ed66-...",
    "type": "standard",
    "model": "nano-banana-pro",
    "scene": "text-to-image",
    "status": "success",
    "cost_credits": 14,
    "created_at": "2026-03-12T06:57:48.067Z",
    "output": {
      "images": [
        {
          "url": "https://storage.paper-banana.org/uploads/...",
          "type": "image/png"
        }
      ]
    },
    "error": null
  }
}

Response (failed)

{
  "success": true,
  "data": {
    "task_id": "7655ed66-...",
    "type": "standard",
    "model": "nano-banana-pro",
    "scene": "text-to-image",
    "status": "failed",
    "cost_credits": 0,
    "created_at": "2026-03-12T06:57:48.067Z",
    "output": {
      "images": []
    },
    "error": "task failed"
  }
}

Credit Costs

Credits are consumed when a task completes successfully. The cost depends on the generation type, model, resolution, and your plan.

Standard Mode

Model1K2K4K
nano-banana-pro102040
nano-banana-251020

Pipeline Mode

Base cost: 6 credits at 1K resolution (default steps).

ResolutionMultiplier
1Kx1
2Kx2
4Kx4

Plan Discounts (Web Only)

Higher-tier plans receive discounts on high-resolution generation when using the web interface. API calls are always charged at full price with no resolution discounts.

PlanStandard 2KStandard 4KPipeline 2KPipeline 4K
HobbyFull priceFull priceFull priceFull price
BasicSame as 1K50% offSame as 1K50% off
ProSame as 1KSame as 1KSame as 1KSame as 1K
Team (API)Full priceFull priceFull priceFull price

Errors

All error responses follow the same format:

{
  "success": false,
  "error": {
    "message": "error description"
  }
}
HTTP StatusDescription
400Bad request — missing or invalid parameters
401Unauthorized — invalid or missing API key
402Payment required — insufficient credits
403Forbidden — API access requires a Team plan (personal sk- keys are not accepted)
404Not found — task does not exist or belongs to another user
411Length required — Content-Length header missing on POST request
413Payload too large — request body exceeds 1 MB
429Too many requests — rate limit exceeded
500Internal server error
503Service unavailable — provider temporarily unavailable

Quick Start

Here is a complete example that generates an image and polls for the result:

API_KEY="sk-team-your-api-key"
BASE_URL="https://open.paper-banana.org/api/v1"

# 1. Check your credits
curl -s -H "Authorization: Bearer $API_KEY" "$BASE_URL/credits"

# 2. Create a generation task
RESPONSE=$(curl -s -X POST "$BASE_URL/generate" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "standard",
    "scene": "text-to-image",
    "prompt": "A red apple on a white background",
    "model": "nano-banana-pro"
  }')

echo "$RESPONSE"
TASK_ID=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['task_id'])")

# 3. Poll until complete
while true; do
  RESULT=$(curl -s -H "Authorization: Bearer $API_KEY" "$BASE_URL/task/$TASK_ID")
  STATUS=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['status'])")
  echo "Status: $STATUS"
  if [ "$STATUS" = "success" ] || [ "$STATUS" = "failed" ] || [ "$STATUS" = "canceled" ]; then
    echo "$RESULT" | python3 -m json.tool
    break
  fi
  sleep 5
done