Skip to content
GhostmotionGhostmotion / DevelopersOpen app
Model APIs

Images and video at the provider’s price

Call Seedream 5.0, Nano Banana 2.1 and Gemini Omni Flash 1.1 through your Ghostmotion workspace with a Ghostmotion API key. Each takes its provider’s own request body and costs exactly its provider’s list price, at one credit per US dollar. The same keys, workspace credits and spending limits apply as for the video API. They are available where your workspace has them; Integrations shows the ones it does.

Seedream 5.0

BytePlus’s image model, in Pro (dola-seedream-5-0-pro-260628), Lite (seedream-5-0-lite-260128) and Flash (dola-seedream-5-0-flash-260915). The body is BytePlus ModelArk’s images/generations request: prompt, up to 10 reference image URLs to edit or combine, and size: 1K, 1.5K or 2K for Pro and Flash, 2K or 4K for Lite, or WIDTHxHEIGHT. Lite also makes a set of related images with sequential_image_generation: "auto" and max_images. Priced per image made at BytePlus’s prices: Pro $0.045 up to 1.5K (2.61 million pixels) and $0.09 above, plus $0.003 for each reference image after the first; Lite $0.035; Flash $0.018. When BytePlus can’t make a task, the same task is made by another provider at BytePlus’s price.

Terminal
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/seedream/images/generations" \
  -H "Authorization: Bearer $GHOSTMOTION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "dola-seedream-5-0-pro-260628",
  "prompt": "A paper-cut lighthouse on a stormy coast, warm window light",
  "size": "2K",
  "request_id": "lighthouse-001"
}'
Terminal
export TASK_ID='ID_FROM_RESPONSE'

curl --fail-with-body "https://app.ghostmotion.ai/api/v1/seedream/images/generations/$TASK_ID" \
  -H "Authorization: Bearer $GHOSTMOTION_API_KEY"

At succeeded, data[].url are the images, as BytePlus returns them, and usage.generated_images is what was charged.

Nano Banana 2.1

Google’s image model (gemini-nano-banana-2.1), with the Gemini API’s own contents and generationConfig. Put the prompt in a text part and up to 14 images in file_data parts with a public https file_uri. Set imageConfig.imageSize (1K or 2K) and aspectRatio. Charged exactly what Google bills: the tokens Google counts for it (input, text and thinking, and the image) at its list prices, about $0.04 for a 1K image; usage.tokens shows them. 4K is not offered until Google publishes one price for it.

Terminal
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/gemini/models/gemini-nano-banana-2.1/tasks" \
  -H "Authorization: Bearer $GHOSTMOTION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Turn this sketch into a glossy product photo on white"
        },
        {
          "file_data": {
            "file_uri": "https://example.com/sketch.png",
            "mime_type": "image/png"
          }
        }
      ]
    }
  ],
  "generationConfig": {
    "imageConfig": {
      "aspectRatio": "1:1",
      "imageSize": "2K"
    }
  },
  "request_id": "sketch-001"
}'

Gemini Omni Flash 1.1

Google’s video model (gemini-omni-1.1-flash), on the same endpoints. Give a text part and up to 3 images and 3 reference videos as file_data parts. Set videoConfig.aspectRatio (16:9 or 9:16) and the length to ask for, durationSeconds (3–10; Google sets the final length), or task: "edit" or "extend" with one video. Made at 720p, the resolution Google publishes a price for, and charged the tokens Google counts for it, about $0.10 a second of video.

Terminal
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/gemini/models/gemini-omni-1.1-flash/tasks" \
  -H "Authorization: Bearer $GHOSTMOTION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "A paper boat drifting down a rainy street, close tracking shot"
        }
      ]
    }
  ],
  "generationConfig": {
    "videoConfig": {
      "aspectRatio": "16:9",
      "resolution": "720p",
      "durationSeconds": 6
    }
  },
  "request_id": "boat-001"
}'
Terminal
export TASK_ID='ID_FROM_RESPONSE'

curl --fail-with-body "https://app.ghostmotion.ai/api/v1/gemini/tasks/$TASK_ID" \
  -H "Authorization: Bearer $GHOSTMOTION_API_KEY"

At succeeded, the image or video is a file_data part of candidates[0].content. When Google can’t make a task, the same task is made by another provider at Google’s price.

Links, failures and MCP

Output links are valid for one hour; read the task again for fresh ones. They follow a redirect to temporary storage and need no bearer header. A failed task’s error says why; it was not charged. Media must be public https URLs: data: URLs and inline_data are refused. Where your workspace has a model, MCP clients get its tools too: create_seedream_task and get_seedream_task, or create_gemini_task and get_gemini_task.

Reference

POST

Create Seedream images

POST /api/v1/seedream/images/generations

Generate or edit images with Seedream 5.0 (Pro, Lite or Flash) in BytePlus ModelArk's own images/generations request shape. Returns a task id at once; poll get_seedream_task until it succeeds or fails. Costs exactly BytePlus's list price per image, one credit per US dollar.

Required permission: videos:write

Unlike BytePlus's synchronous call, this returns a task to poll. BytePlus's prices: Pro $0.045 an image up to 2.61 million pixels (1.5K) and $0.09 above, plus $0.003 for each reference image after the first; Lite $0.035; Flash $0.018. Reference images are public https URLs (image, up to 10). Lite alone makes sets: with sequential_image_generation auto, up to max_images related images, each charged. When BytePlus can't make a task, the same task is made on another provider at BytePlus's price. Nothing made, nothing charged. Reuse request_id and the same body to retry.

Request body

request_idstring · optional

Optional retry identity: the same id and body returns the same task. Not part of BytePlus's API.

at least 1 character; up to 128 characters

modelstring · required

The Seedream 5.0 tier.

dola-seedream-5-0-pro-260628 · seedream-5-0-lite-260128 · dola-seedream-5-0-flash-260915

promptstring · required

What to make, or how to change the reference images.

at least 1 character; up to 5,000 characters

imagearray · optional

Reference images to edit or combine, as public https URLs. A single string is accepted too.

up to 10 items

sizestring · optional

Pro and Flash: 1K, 1.5K or 2K; Lite: 2K or 4K; or WIDTHxHEIGHT up to the tier's largest size (each side at least 256). Defaults to 2K. Pro is priced by size: above 2.61 million pixels costs $0.09.

seedinteger · optional

Seed for repeatable results; -1 for random.

minimum -1; maximum 2147483647

sequential_image_generationstring · optional

Lite only: auto makes a set of related images; disabled (the default) makes one.

disabled · auto

sequential_image_generation_optionsobject · optional

sequential_image_generation_options.max_imagesinteger · optional

The most images an auto set may make. Each is charged.

minimum 1; maximum 15

watermarkboolean · optional

Add a watermark. Defaults to false.

response_formatstring · optional

Always url: images are returned as links.

url

Example request

Terminal
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/seedream/images/generations" \
  -H "Authorization: Bearer $GHOSTMOTION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "dola-seedream-5-0-pro-260628",
  "prompt": "A paper-cut lighthouse on a stormy coast, warm window light",
  "size": "2K",
  "request_id": "lighthouse-001"
}'

Response · 200

Example response
{
  "id": "0190e2c4-1b2c-4d3e-8f40-223456789abc",
  "model": "dola-seedream-5-0-pro-260628",
  "status": "queued",
  "created": 1793361600,
  "size": "2K",
  "credits": {
    "price": null,
    "charged": null,
    "reserved": 0.09
  },
  "poll_after_seconds": 5
}
All response fields
idstring · required

The id returned when the task was created.

at least 1 character

modelstring · required

The Seedream tier.

statusstring · required

queued, running, then succeeded or failed.

queued · running · succeeded · failed

creatednumber · required

Unix seconds.

sizestring · optional

The size asked for.

dataarray · optional

The images, when it succeeded.

data[].urlstring · required

Absolute URL.

data[].sizestring · optional

WIDTHxHEIGHT, when known.

url_expires_atstring · optional

ISO 8601 UTC timestamp.

usageobject · optional

usage.generated_imagesnumber · required

Images made: what the price counts.

errorobject · optional

error.codestring · required

Stable failure code.

error.messagestring · required

Why it failed; a failed task is not charged.

creditsobject · required

credits.pricenumber | null · required

The provider's list price for what was made, in credits (one per USD); null until it succeeds.

credits.chargednumber | null · required

Credits charged; null until the task ends.

credits.reservednumber · required

Credits held while the task runs.

poll_after_secondsnumber · optional

Present while queued or running: wait this long before checking again.

Errors

unauthorized, permission_denied, not_found, invalid_request, insufficient_credits, allowance_exhausted, cap_too_low, idempotency_conflict, rate_limited, internal_error, temporarily_unavailable.

GET

Check Seedream images

GET /api/v1/seedream/images/generations/{task_id}

Get a Seedream task: its status, and when it succeeded BytePlus's response shape (data[].url, usage.generated_images) and its price in credits.

Required permission: projects:read

Each data[].url is a Ghostmotion link that expires after one hour: read the task again for fresh ones. A failed task's error says why; it was not charged.

Path parameters

task_idstring · required

The id returned when the task was created.

at least 1 character

Query parameters

No query parameters required.

Example request

Terminal
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/seedream/images/generations/$TASK_ID" \
  -H "Authorization: Bearer $GHOSTMOTION_API_KEY"

Response · 200

Example response
{
  "id": "0190e2c4-1b2c-4d3e-8f40-223456789abc",
  "model": "dola-seedream-5-0-pro-260628",
  "status": "succeeded",
  "created": 1793361600,
  "size": "2K",
  "credits": {
    "price": 0.045,
    "charged": 0.045,
    "reserved": 0
  },
  "data": [
    {
      "url": "https://app.ghostmotion.ai/api/v1/media/example-token",
      "size": "2048x2048"
    }
  ],
  "url_expires_at": "2026-11-01T13:02:00.000Z",
  "usage": {
    "generated_images": 1
  }
}
All response fields
idstring · required

The id returned when the task was created.

at least 1 character

modelstring · required

The Seedream tier.

statusstring · required

queued, running, then succeeded or failed.

queued · running · succeeded · failed

creatednumber · required

Unix seconds.

sizestring · optional

The size asked for.

dataarray · optional

The images, when it succeeded.

data[].urlstring · required

Absolute URL.

data[].sizestring · optional

WIDTHxHEIGHT, when known.

url_expires_atstring · optional

ISO 8601 UTC timestamp.

usageobject · optional

usage.generated_imagesnumber · required

Images made: what the price counts.

errorobject · optional

error.codestring · required

Stable failure code.

error.messagestring · required

Why it failed; a failed task is not charged.

creditsobject · required

credits.pricenumber | null · required

The provider's list price for what was made, in credits (one per USD); null until it succeeds.

credits.chargednumber | null · required

Credits charged; null until the task ends.

credits.reservednumber · required

Credits held while the task runs.

poll_after_secondsnumber · optional

Present while queued or running: wait this long before checking again.

Errors

unauthorized, permission_denied, not_found, rate_limited, internal_error, temporarily_unavailable.

POST

Create a Nano Banana image or Omni Flash video

POST /api/v1/gemini/models/{model}/tasks

Generate an image with Nano Banana 2.1 (gemini-nano-banana-2.1) or a video with Gemini Omni Flash 1.1 (gemini-omni-1.1-flash), with the Gemini API's own contents and generationConfig. Returns a task id at once; poll get_gemini_task until it succeeds or fails. Costs exactly Google's list price, one credit per US dollar.

Required permission: videos:write

Media are file_data parts with a public https file_uri; inline_data is refused. Nano Banana takes generationConfig.imageConfig (aspectRatio, imageSize 1K or 2K); Omni Flash takes generationConfig.videoConfig (aspectRatio 16:9 or 9:16, resolution 720p, durationSeconds 3 to 10, task generate, edit or extend). Each is charged exactly what Google bills: the tokens Google counts for it (input, text and thinking, and the image or video) at Google's list prices, shown in usage.tokens. A 1K image is about $0.04; 720p video about $0.10 a second. Sizes and resolutions Google publishes no single price for are not offered yet. When Google can't make a task, the same task is made on another provider at Google's price. Nothing made, nothing charged.

Path parameters

modelstring · required

The model, in the path.

gemini-nano-banana-2.1 · gemini-omni-1.1-flash

Request body

request_idstring · optional

Optional retry identity: the same id and body returns the same task. Not part of the Gemini API.

at least 1 character; up to 128 characters

contentsarray · required

One user turn: its parts are one text part and any file_data parts (Nano Banana: up to 14 images; Omni Flash: up to 3 images and 3 videos). inline_data is refused.

up to 1 items

contents[].rolestring · optional

Always user.

user

contents[].partsarray · required

A text part and file_data parts.

up to 18 items

contents[].parts[].textstring · optional

The prompt: exactly one part carries it.

up to 5,000 characters

contents[].parts[].file_dataobject · optional

contents[].parts[].file_data.file_uristring · required

Public https URL of an image or video. Fetched from a public address only.

up to 2,048 characters

contents[].parts[].file_data.mime_typestring · required

The file's type.

image/png · image/jpeg · image/webp · video/mp4 · video/quicktime

generationConfigobject · optional

generationConfig.responseModalitiesarray · optional

IMAGE for Nano Banana, VIDEO for Omni Flash; TEXT may be added.

up to 2 items

generationConfig.imageConfigobject · optional

generationConfig.imageConfig.aspectRatiostring · optional

Nano Banana's frame shape. Left out, the model chooses.

21:9 · 16:9 · 3:2 · 4:3 · 5:4 · 1:1 · 4:5 · 3:4 · 2:3 · 9:16

generationConfig.imageConfig.imageSizestring · optional

Nano Banana's size. Defaults to 1K. 4K is not offered until Google publishes one price for it.

1K · 2K

generationConfig.videoConfigobject · optional

generationConfig.videoConfig.aspectRatiostring · optional

Omni Flash's frame shape. Defaults to 16:9.

16:9 · 9:16

generationConfig.videoConfig.resolutionstring · optional

Omni Flash's resolution: 720p, the one Google publishes a price for.

720p

generationConfig.videoConfig.durationSecondsinteger · optional

The length to ask for (default 8). Google sets the final length, 3 to 10 seconds; you pay for what is delivered. Not for an edit or extension.

minimum 3; maximum 10

generationConfig.videoConfig.taskstring · optional

generate (the default), edit the one given video, or extend it.

generate · edit · extend

generationConfig.seedinteger · optional

Seed for repeatable results.

minimum 0; maximum 2147483647

Example request

Terminal
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/gemini/models/gemini-nano-banana-2.1/tasks" \
  -H "Authorization: Bearer $GHOSTMOTION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Turn this sketch into a glossy product photo on white"
        },
        {
          "file_data": {
            "file_uri": "https://example.com/sketch.png",
            "mime_type": "image/png"
          }
        }
      ]
    }
  ],
  "generationConfig": {
    "imageConfig": {
      "aspectRatio": "1:1",
      "imageSize": "2K"
    }
  },
  "request_id": "sketch-001"
}'

Response · 200

Example response
{
  "id": "0190e2c4-1b2c-4d3e-8f40-323456789abc",
  "model": "gemini-nano-banana-2.1",
  "status": "queued",
  "createTime": "2026-11-01T12:00:00.000Z",
  "credits": {
    "price": null,
    "charged": null,
    "reserved": 0.0504
  },
  "poll_after_seconds": 5
}
All response fields
idstring · required

The id returned when the task was created.

at least 1 character

modelstring · required

The model.

statusstring · required

queued, running, then succeeded or failed.

queued · running · succeeded · failed

createTimestring · required

ISO 8601 UTC timestamp.

candidatesarray · optional

The output, when it succeeded, as the Gemini API's candidate with file_data parts.

candidates[].contentobject · required

candidates[].content.rolestring · required

model

candidates[].content.partsarray · required

One file_data part per output.

candidates[].content.parts[].file_dataobject · required

candidates[].content.parts[].file_data.file_uristring · required

Absolute URL.

candidates[].content.parts[].file_data.mime_typestring · required

The output's type.

candidates[].finishReasonstring · required

STOP

uri_expires_atstring · optional

ISO 8601 UTC timestamp.

usageobject · optional

usage.imagesnumber · optional

Images made (Nano Banana).

usage.secondsnumber · optional

Seconds of video made (Omni Flash).

errorobject · optional

error.codestring · required

Stable failure code.

error.messagestring · required

Why it failed; a failed task is not charged.

creditsobject · required

credits.pricenumber | null · required

The provider's list price for what was made, in credits (one per USD); null until it succeeds.

credits.chargednumber | null · required

Credits charged; null until the task ends.

credits.reservednumber · required

Credits held while the task runs.

poll_after_secondsnumber · optional

Present while queued or running: wait this long before checking again.

Errors

unauthorized, permission_denied, not_found, invalid_request, insufficient_credits, allowance_exhausted, cap_too_low, idempotency_conflict, rate_limited, internal_error, temporarily_unavailable.

GET

Check a Nano Banana or Omni Flash task

GET /api/v1/gemini/tasks/{task_id}

Get a Nano Banana or Omni Flash task: its status, and when it succeeded the image or video as file_data parts in the Gemini API's candidate shape, with usage and its price in credits.

Required permission: projects:read

Each file_uri is a Ghostmotion link that expires after one hour: read the task again for fresh ones. A failed task's error says why; it was not charged.

Path parameters

task_idstring · required

The id returned when the task was created.

at least 1 character

Query parameters

No query parameters required.

Example request

Terminal
curl --fail-with-body "https://app.ghostmotion.ai/api/v1/gemini/tasks/$TASK_ID" \
  -H "Authorization: Bearer $GHOSTMOTION_API_KEY"

Response · 200

Example response
{
  "id": "0190e2c4-1b2c-4d3e-8f40-323456789abc",
  "model": "gemini-nano-banana-2.1",
  "status": "succeeded",
  "createTime": "2026-11-01T12:00:00.000Z",
  "credits": {
    "price": 0.0504,
    "charged": 0.0504,
    "reserved": 0
  },
  "candidates": [
    {
      "content": {
        "role": "model",
        "parts": [
          {
            "file_data": {
              "file_uri": "https://app.ghostmotion.ai/api/v1/media/example-token",
              "mime_type": "image/png"
            }
          }
        ]
      },
      "finishReason": "STOP"
    }
  ],
  "uri_expires_at": "2026-11-01T13:02:00.000Z",
  "usage": {
    "images": 1
  }
}
All response fields
idstring · required

The id returned when the task was created.

at least 1 character

modelstring · required

The model.

statusstring · required

queued, running, then succeeded or failed.

queued · running · succeeded · failed

createTimestring · required

ISO 8601 UTC timestamp.

candidatesarray · optional

The output, when it succeeded, as the Gemini API's candidate with file_data parts.

candidates[].contentobject · required

candidates[].content.rolestring · required

model

candidates[].content.partsarray · required

One file_data part per output.

candidates[].content.parts[].file_dataobject · required

candidates[].content.parts[].file_data.file_uristring · required

Absolute URL.

candidates[].content.parts[].file_data.mime_typestring · required

The output's type.

candidates[].finishReasonstring · required

STOP

uri_expires_atstring · optional

ISO 8601 UTC timestamp.

usageobject · optional

usage.imagesnumber · optional

Images made (Nano Banana).

usage.secondsnumber · optional

Seconds of video made (Omni Flash).

errorobject · optional

error.codestring · required

Stable failure code.

error.messagestring · required

Why it failed; a failed task is not charged.

creditsobject · required

credits.pricenumber | null · required

The provider's list price for what was made, in credits (one per USD); null until it succeeds.

credits.chargednumber | null · required

Credits charged; null until the task ends.

credits.reservednumber · required

Credits held while the task runs.

poll_after_secondsnumber · optional

Present while queued or running: wait this long before checking again.

Errors

unauthorized, permission_denied, not_found, rate_limited, internal_error, temporarily_unavailable.