API Reference

CyberBara public API v1 reference

Overview

CyberBara public API is exposed under /api/v1 and supports:

  • Generate image tasks
  • Generate video tasks
  • Upload reference images and get reusable URLs
  • Query task status and outputs
  • Check credits balance
  • Check credits usage
  • Quote credits before creating a task
  • List public models

Provider details are intentionally hidden from clients.

Base URL

Use your own deployed domain.

https://<your-domain>

Example:

https://cyberbara-preview.iamzerolu.workers.dev

Authentication

Pass your API key in one of these headers:

Authorization: Bearer <API_KEY>

or

x-api-key: <API_KEY>

If missing or invalid, API returns 401.

Response Format

Success:

{
  "data": {}
}

Error:

{
  "error": {
    "code": "error_code",
    "message": "human readable message",
    "details": {}
  }
}

Models

GET /api/v1/models

Optional query:

  • media_type=image|video

Example:

curl -X GET 'https://<your-domain>/api/v1/models?media_type=video' \
  -H 'Authorization: Bearer <API_KEY>'

Response example:

{
  "data": {
    "models": [
      {
        "model": "sora-2",
        "media_type": "video",
        "supported_scenes": ["text-to-video", "image-to-video"]
      },
      {
        "model": "kling-2.6",
        "media_type": "video",
        "supported_scenes": ["text-to-video", "image-to-video"]
      }
    ],
    "total": 2
  }
}

Error example (invalid_media_type):

{
  "error": {
    "code": "invalid_media_type",
    "message": "media_type must be \"image\" or \"video\"."
  }
}

Uploads

POST /api/v1/uploads/images

Upload one or more reference images, then use returned URLs in options.image_input.

Request:

  • Content-Type: multipart/form-data
  • field name: files (or file for single upload)
  • max files per request: 10
  • max file size: 10MB each
  • supported mime types: image/jpeg, image/jpg, image/png, image/webp, image/gif, image/svg+xml, image/avif, image/heic, image/heif

Example:

curl -X POST 'https://<your-domain>/api/v1/uploads/images' \
  -H 'Authorization: Bearer <API_KEY>' \
  -F 'files=@./reference.png'

Response example:

{
  "data": {
    "files": [
      {
        "url": "https://cdn.example.com/uploads/api/v1/uploads/3e7e48e6/7f2f25f8d6c26f11b2a5bb6b3f7f4a28.png",
        "key": "api/v1/uploads/3e7e48e6/7f2f25f8d6c26f11b2a5bb6b3f7f4a28.png",
        "filename": "reference.png",
        "content_type": "image/png",
        "size": 245123,
        "deduped": false
      }
    ],
    "urls": [
      "https://cdn.example.com/uploads/api/v1/uploads/3e7e48e6/7f2f25f8d6c26f11b2a5bb6b3f7f4a28.png"
    ],
    "count": 1
  }
}

POST /api/v1/uploads/videos

Upload a reference video, then use returned URLs in options.video_input (or options.video_url for seedance-2-watermark-remover).

Request:

  • Content-Type: multipart/form-data
  • field name: files (or file for single upload)
  • max files per request: 1
  • max file size: 50MB
  • supported mime types: video/mp4, video/quicktime

Example:

curl -X POST 'https://<your-domain>/api/v1/uploads/videos' \
  -H 'Authorization: Bearer <API_KEY>' \
  -F 'files=@./reference.mp4'

Response example:

{
  "data": {
    "files": [
      {
        "url": "https://cdn.example.com/uploads/api/v1/uploads/3e7e48e6/2d9b18f0b5a0a9b4c65b7f6c3b2f7c32.mp4",
        "key": "api/v1/uploads/3e7e48e6/2d9b18f0b5a0a9b4c65b7f6c3b2f7c32.mp4",
        "filename": "reference.mp4",
        "content_type": "video/mp4",
        "size": 1245123,
        "deduped": false
      }
    ],
    "urls": [
      "https://cdn.example.com/uploads/api/v1/uploads/3e7e48e6/2d9b18f0b5a0a9b4c65b7f6c3b2f7c32.mp4"
    ],
    "count": 1
  }
}

Error example (invalid_file_type):

{
  "error": {
    "code": "invalid_file_type",
    "message": "Unsupported image type for file \"sample.pdf\".",
    "details": {
      "index": 0,
      "filename": "sample.pdf"
    }
  }
}

Then use upload URL for image-to-image:

{
  "model": "nano-banana-pro",
  "scene": "image-to-image",
  "prompt": "Keep composition, make it cinematic at night",
  "options": {
    "image_input": ["https://cdn.example.com/uploads/api/v1/uploads/...png"]
  }
}

Credits

GET /api/v1/credits/balance

Returns current credits balance.

curl -X GET 'https://<your-domain>/api/v1/credits/balance' \
  -H 'Authorization: Bearer <API_KEY>'

Response example:

{
  "data": {
    "user_id": "3e7e48e6-f2fa-4f66-abf8-db7a40eaf517",
    "remaining_credits": 44,
    "updated_at": "2026-03-03T04:08:19.320Z"
  }
}

Error example (invalid_api_key):

{
  "error": {
    "code": "invalid_api_key",
    "message": "Invalid API key."
  }
}

POST /api/v1/credits/quote

Estimate credits before creating a task.

Request body:

  • model required
  • media_type optional if model can infer it
  • scene optional but recommended
  • options optional
curl -X POST 'https://<your-domain>/api/v1/credits/quote' \
  -H 'Authorization: Bearer <API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "nano-banana-pro",
    "media_type": "image",
    "scene": "text-to-image",
    "options": { "resolution": "1k" }
  }'

Response example:

{
  "data": {
    "model": "nano-banana-pro",
    "media_type": "image",
    "scene": "text-to-image",
    "estimated_credits": 8,
    "remaining_credits": 44,
    "can_afford": true,
    "pricing_rule": "nano-banana-pro",
    "fallback_pricing": false
  }
}

Error example (unsupported_model):

{
  "error": {
    "code": "unsupported_model",
    "message": "Model is not supported."
  }
}

GET /api/v1/credits/usage

Query params:

  • page default 1
  • limit default 20, max 100
  • from optional, ISO datetime or YYYY-MM-DD
  • to optional, ISO datetime or YYYY-MM-DD
  • Date-only values are interpreted in UTC (from -> 00:00:00.000Z, to -> 23:59:59.999Z)
curl -X GET 'https://<your-domain>/api/v1/credits/usage?page=1&limit=20&from=2026-03-01&to=2026-03-03' \
  -H 'Authorization: Bearer <API_KEY>'

Response example:

{
  "data": {
    "summary": {
      "page": 1,
      "limit": 20,
      "total": 2,
      "total_pages": 1,
      "total_credits_consumed": 28,
      "from": "2026-03-03T00:00:00.000Z",
      "to": "2026-03-03T23:59:59.999Z"
    },
    "items": [
      {
        "id": "0a961844-e042-4a17-bf23-2a5f2680d375",
        "transaction_no": "79739092304928500",
        "credits_consumed": 20,
        "scene": "text-to-video",
        "description": "generate video",
        "media_type": "video",
        "task_id": "2fa99a50-fb96-407b-a562-82de8265f48e",
        "created_at": "2026-03-03T04:31:55.116Z"
      }
    ]
  }
}

Error example (invalid_date):

{
  "error": {
    "code": "invalid_date",
    "message": "Invalid date format. Use ISO datetime or YYYY-MM-DD."
  }
}

Error example (invalid_date_range):

{
  "error": {
    "code": "invalid_date_range",
    "message": "The \"from\" date must be earlier than the \"to\" date."
  }
}

Task Generation

POST /api/v1/images/generations

Request body:

  • model required
  • prompt required for most models
  • scene optional (text-to-image / image-to-image)
  • options optional
curl -X POST 'https://<your-domain>/api/v1/images/generations' \
  -H 'Authorization: Bearer <API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "nano-banana-pro",
    "prompt": "A cinematic portrait under neon rain",
    "scene": "text-to-image",
    "options": { "resolution": "1k" }
  }'

Response includes your internal task id:

{
  "data": {
    "task_id": "uuid",
    "status": "pending",
    "media_type": "image",
    "model": "nano-banana-pro",
    "scene": "text-to-image",
    "credits": {
      "cost": 8,
      "remaining": 36
    },
    "created_at": "2026-03-03T04:29:12.612Z"
  }
}

Error example (insufficient_credits):

{
  "error": {
    "code": "insufficient_credits",
    "message": "Insufficient credits."
  }
}

POST /api/v1/videos/generations

Request body:

  • model required
  • prompt required for most video models (including seedance-*, kling-2.6, veo-*)
  • prompt optional for sora-2-pro at API validation layer, but still recommended
  • scene optional (text-to-video / image-to-video / video-to-video)
  • options optional
curl -X POST 'https://<your-domain>/api/v1/videos/generations' \
  -H 'Authorization: Bearer <API_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "sora-2",
    "prompt": "A calm drone shot over snowy mountains at sunrise",
    "scene": "text-to-video",
    "options": { "duration": "10", "resolution": "standard" }
  }'

Response example:

{
  "data": {
    "task_id": "2fa99a50-fb96-407b-a562-82de8265f48e",
    "status": "pending",
    "media_type": "video",
    "model": "sora-2",
    "scene": "text-to-video",
    "credits": {
      "cost": 20,
      "remaining": 16
    },
    "created_at": "2026-03-03T04:31:55.116Z"
  }
}

Error example (insufficient_credits):

{
  "error": {
    "code": "insufficient_credits",
    "message": "Insufficient credits."
  }
}

Model-Specific Options (Complete Matrix)

This section lists all model-specific request options currently supported by the public API.

General request fields:

  • model required
  • prompt model-dependent (see each model below)
  • scene optional, but strongly recommended
  • options optional object

Scene inference (when scene is omitted):

  • Image API:
    • options.image_input has at least one URL -> image-to-image
    • otherwise -> text-to-image
  • Video API:
    • options.video_input has at least one URL -> video-to-video
    • else if options.image_input has at least one URL -> image-to-video
    • otherwise -> text-to-video

Shared option fields:

FieldTypeMeaning
options.image_inputstring[]Input/reference image URLs
options.video_inputstring[]Input/reference video URLs

Notes:

  • Public API accepts only options.* fields. Do not send provider-internal keys such as image_url, image_urls, input_images, or imageUrls (except options.video_url for seedance-2-watermark-remover).
  • For all models below, if both prompt and options are empty, API returns invalid_request.
  • Some models strictly validate options; others forward options to the model endpoint with minimal/no validation.
  • Unknown options for strict-validated models are ignored; unknown options for pass-through models are forwarded.

Image Models

nano-banana-2

Supported scenes: text-to-image, image-to-image. Validation level: strict keys + light normalization.

FieldTypeRequiredAllowed / DefaultNotes
promptstringYesnon-emptyRequired for both scenes
options.image_inputstring[]Required for image-to-imageURL arrayIf provided and non-empty, scene can be inferred as image-to-image
options.aspect_ratiostringNoany non-empty stringPassed through as-is
options.resolutionstringNonormalized: 1K / 2K / 4KInputs like 1k, 2k, 4k are normalized; other strings are passed through
options.output_formatstringNonormalized: jpg / pngjpeg becomes jpg; other strings are passed through
options.google_searchbooleanNodefault unsetOnly supported by nano-banana-2

nano-banana-pro

Supported scenes: text-to-image, image-to-image. Validation level: strict keys + light normalization.

FieldTypeRequiredAllowed / DefaultNotes
promptstringYesnon-emptyRequired for both scenes
options.image_inputstring[]Required for image-to-imageURL arrayIf provided and non-empty, scene can be inferred as image-to-image
options.aspect_ratiostringNoany non-empty stringPassed through as-is
options.resolutionstringNonormalized: 1K / 2K / 4KInputs like 1k, 2k, 4k are normalized; other strings are passed through
options.output_formatstringNonormalized: jpg / pngjpeg becomes jpg; other strings are passed through

Video Models

Except kling-video-o1, seedance-2-preview, seedance-2-fast-preview, and seedance-2-watermark-remover, models below do not support video-to-video, so options.video_input should not be sent.

sora-2

Supported scenes: text-to-video, image-to-video. Validation level: strict.

FieldTypeRequiredAllowed / DefaultNotes
promptstringYesnon-emptyRequired for both scenes
options.image_inputstring[]Required for image-to-videoURL arrayUsed as image references
options.aspect_ratiostringNolandscape / portrait (default landscape)Strictly validated
options.duration / options.n_framesstring or numberNo10 / 15 (default 10)Strictly validated
options.remove_watermarkbooleanNodefault trueStrictly validated
options.upload_methodstringNos3 / oss (default s3)Strictly validated

sora-2-pro

Supported scenes: text-to-video, image-to-video. Validation level: strict.

FieldTypeRequiredAllowed / DefaultNotes
promptstringNo for API validationoptionalRecommended
options.image_inputstring[]Required for image-to-videoURL arrayUsed as image references
options.aspect_ratiostringNolandscape / portrait (default landscape)Strictly validated
options.duration / options.n_framesstring or numberNo10 / 15 (default 10)Strictly validated
options.resolution / options.sizestringNostandard / high (default standard)Strictly validated

seedance-2-preview

Supported scenes: text-to-video, image-to-video, video-to-video. Validation level: strict.

FieldTypeRequiredAllowed / DefaultNotes
promptstringYesnon-emptyRequired for all scenes
options.image_inputstring[]Required for image-to-videoURL array (max 9)Used as image references in prompt (@image1, @image2, ...).
options.video_inputstring[]Required for video-to-videosingle URLSeedance 2.0 video edit mode. Exactly one URL.
options.durationstring or numberNo (ignored for video-to-video)5 / 10 / 15 (default 5)For video edit, output length equals input video length.
options.aspect_ratiostringNo16:9 / 9:16 / 4:3 / 3:4 (default 16:9)Aspect ratio is best-effort; image aspect ratio may override it.
options.parent_task_idstringNotask idExtend from a previous Seedance 2.0 task; missing fields may be inherited from the parent.

seedance-2-fast-preview

Supported scenes: text-to-video, image-to-video, video-to-video. Validation level: strict.

Fields are the same as seedance-2-preview.

seedance-2-watermark-remover

Supported scenes: video-to-video. Validation level: strict.

FieldTypeRequiredAllowed / DefaultNotes
promptstringNooptionalNot used by the watermark remover
options.video_inputstring[]Yessingle URLVideo URL to process
options.video_urlstringYessingle URLAlternative to options.video_input
options.durationstring or numberNoauto-detectedOptional hint; if omitted, duration is auto-detected by the processor

seedance-1-pro

Supported scenes: text-to-video, image-to-video. Validation level: strict + partial pass-through for some strings.

FieldTypeRequiredAllowed / DefaultNotes
promptstringYesnon-emptyRequired for both scenes
options.image_inputstring[]Required for image-to-videofirst image URL usedimage-to-video requires at least one image
options.resolutionstringNodefault 720pRecommended: 480p, 720p, 1080p
options.durationstring or numberNodefault 5Recommended: 5, 10
options.aspect_ratiostringNodefault 16:9Used for text-to-video; image-to-video ignores this field
options.camera_fixedbooleanNodefault unsetSupported
options.seed / options.seedsintegerNo-1 to 2147483647Strict range check
options.enable_safety_checkerbooleanNodefault unsetSupported

seedance-1-lite

Supported scenes: text-to-video, image-to-video. Validation level: strict + partial pass-through for some strings.

FieldTypeRequiredAllowed / DefaultNotes
promptstringYesnon-emptyRequired for both scenes
options.image_inputstring[]Required for image-to-videofirst image URL usedIf second image is provided, it is auto-used as end_image_url
options.resolutionstringNodefault 720pRecommended: 480p, 720p, 1080p
options.durationstring or numberNodefault 5Recommended: 5, 10
options.aspect_ratiostringNodefault 16:9Used for text-to-video; image-to-video ignores this field
options.camera_fixedbooleanNodefault unsetSupported
options.seed / options.seedsintegerNo-1 to 2147483647Strict range check
options.enable_safety_checkerbooleanNodefault unsetSupported for text-to-video only
options.end_image_urlstringNoURLSupported for image-to-video

seedance-1-pro-fast

Supported scenes: image-to-video. Validation level: strict + partial pass-through for some strings.

FieldTypeRequiredAllowed / DefaultNotes
promptstringYesnon-emptyRequired
options.image_inputstring[]Yesfirst image URL usedRequired
options.resolutionstringNodefault 720pRecommended: 720p, 1080p
options.durationstring or numberNodefault 5Recommended: 5, 10

kling-2.6

Supported scenes: text-to-video, image-to-video. Validation level: strict.

FieldTypeRequiredAllowed / DefaultNotes
promptstringYesnon-emptyRequired for both scenes
options.image_inputstring[]Required for image-to-videoURL arrayimage-to-video requires at least one image
options.durationstring or numberNo5 / 10 (default 5)Strictly validated
options.soundbooleanNodefault falseStrictly validated
options.aspect_ratiostringNo1:1 / 16:9 / 9:16 (default 16:9)Used for text-to-video; image-to-video ignores this field

veo-3.1-fast

Supported scenes: text-to-video, image-to-video. Validation level: strict.

FieldTypeRequiredAllowed / DefaultNotes
promptstringYesnon-emptyRequired
options.image_inputstring[]ConditionalURL arrayDepends on generationType rules below
options.generationTypestringNoTEXT_2_VIDEO / FIRST_AND_LAST_FRAMES_2_VIDEO / REFERENCE_2_VIDEOIf omitted, auto-inferred from image_input count
options.aspect_ratiostringNo16:9 / 9:16 / Auto (default 16:9)landscape -> 16:9, portrait -> 9:16; REFERENCE_2_VIDEO only allows 16:9
options.seed / options.seedsintegerNo10000 to 99999Strict range check
options.enableTranslationbooleanNodefault unsetOptional
options.watermarkstringNoany non-empty stringOptional

Rules:

  • TEXT_2_VIDEO: image_input must be empty
  • FIRST_AND_LAST_FRAMES_2_VIDEO: image_input must contain 1-2 images
  • REFERENCE_2_VIDEO: image_input must contain 1-3 images

veo-3.1-quality

Supported scenes: text-to-video, image-to-video. Validation level: strict.

Fields are the same as veo-3.1-fast, except:

  • options.generationType=REFERENCE_2_VIDEO is not supported

kling-video-o1

Supported scenes: video-to-video. Validation level: pass-through.

FieldTypeRequiredAllowed / DefaultNotes
promptstringYesnon-emptyRequired
options.video_inputstring[]Required in practicefirst video URL usedIf scene is omitted, non-empty video_input helps infer video-to-video
options.image_inputstring[]NoURL arrayOptional reference images
options.*anyNoprovider-definedAll extra keys are forwarded

kling-video-o1 is pass-through. Besides options.video_input, provider-defined fields under options.* may be required.

Quick Scene-to-Option Checklist

Image generation:

  • text-to-image: usually prompt only
  • image-to-image: include options.image_input

Video generation:

  • text-to-video: always include prompt
  • image-to-video: include options.image_input; for most models, also include prompt
  • video-to-video: include options.video_input; include prompt if the selected model requires it

If you want deterministic routing, always pass scene explicitly.

Task Query

GET /api/v1/tasks/{taskId}

Poll this endpoint until task reaches a final status.

curl -X GET 'https://<your-domain>/api/v1/tasks/<TASK_ID>' \
  -H 'Authorization: Bearer <API_KEY>'

Response example (pending):

{
  "data": {
    "task": {
      "id": "2fa99a50-fb96-407b-a562-82de8265f48e",
      "status": "pending",
      "media_type": "video",
      "model": "sora-2",
      "scene": "text-to-video",
      "prompt": "A cinematic wide shot of waves hitting black volcanic beach at sunrise",
      "credits": { "cost": 20 },
      "output": { "images": [], "videos": [] },
      "created_at": "2026-03-03T04:31:55.116Z",
      "updated_at": "2026-03-03T04:32:08.511Z"
    }
  }
}

Error example (task_not_found):

{
  "error": {
    "code": "task_not_found",
    "message": "Task not found."
  }
}

Status values:

  • pending
  • processing
  • success
  • failed
  • canceled

success responses include media URLs under:

  • data.task.output.images
  • data.task.output.videos

Task Output Examples

Image task success:

{
  "data": {
    "task": {
      "id": "20b061f3-d051-4795-b355-856325d08f7c",
      "status": "success",
      "media_type": "image",
      "model": "nano-banana-pro",
      "scene": "text-to-image",
      "prompt": "A cinematic portrait under neon rain",
      "credits": { "cost": 8 },
      "output": {
        "images": [
          "https://static.nanobananaproprompts.com/cyberbara_uploads/kie/image/21075dc0-7968-46fd-93fe-e366f558325b.png"
        ],
        "videos": []
      },
      "created_at": "2026-03-03T04:29:12.612Z",
      "updated_at": "2026-03-03T04:29:31.475Z"
    }
  }
}

Video task success:

{
  "data": {
    "task": {
      "id": "2fa99a50-fb96-407b-a562-82de8265f48e",
      "status": "success",
      "media_type": "video",
      "model": "sora-2",
      "scene": "text-to-video",
      "prompt": "A cinematic wide shot of waves hitting black volcanic beach at sunrise",
      "credits": { "cost": 20 },
      "output": {
        "images": [],
        "videos": [
          "https://static.nanobananaproprompts.com/cyberbara_uploads/kie/video/b55bf86d-e3a3-4b81-ae28-a1cff40a71db.mp4"
        ]
      },
      "created_at": "2026-03-03T04:31:55.116Z",
      "updated_at": "2026-03-03T04:34:22.836Z"
    }
  }
}

Task failed:

{
  "data": {
    "task": {
      "id": "341ab8cd-1296-4a5d-968a-cccf60c9caab",
      "status": "failed",
      "media_type": "video",
      "model": "sora-2",
      "scene": "text-to-video",
      "prompt": "A calm drone shot over snowy mountains at sunrise",
      "credits": { "cost": 20 },
      "output": {
        "images": [],
        "videos": []
      },
      "created_at": "2026-03-03T04:30:18.041Z",
      "updated_at": "2026-03-03T04:31:01.420Z"
    }
  }
}

Suggested Flow

  1. Call GET /api/v1/models
  2. If needed, call POST /api/v1/uploads/images for reference URLs
  3. Call POST /api/v1/credits/quote
  4. Create a task via image/video generation endpoint
  5. Poll GET /api/v1/tasks/{taskId} until final
  6. Check billing impact via GET /api/v1/credits/usage

Common Error Codes (Non-Exhaustive)

  • api_key_required
  • invalid_api_key
  • too_many_requests
  • invalid_json
  • invalid_multipart
  • invalid_date
  • invalid_date_range
  • files_required
  • too_many_files
  • invalid_file_type
  • invalid_file_size
  • file_too_large
  • invalid_model
  • unsupported_model
  • invalid_model_for_media_type
  • invalid_scene
  • scene_not_supported
  • invalid_media_type
  • invalid_request
  • service_unavailable
  • insufficient_credits
  • upload_failed
  • generation_failed
  • invalid_task_id
  • task_not_found
  • task_not_ready
  • query_failed
  • internal_error