Quickstart
This guide creates a text-to-image task, then polls the result.
1. Set your API key
export BUBLE_API_KEY="sk_your_api_key"
Use API keys only on the server side. Do not expose them in browser code.
2. List available media models
curl https://img2vid.net/api/v1/media_models \
-H "Authorization: Bearer $BUBLE_API_KEY"
Pick a media model and one of its operations[].mode values.
3. Create a text-to-image generation
curl https://img2vid.net/api/v1/generations \
-H "Authorization: Bearer $BUBLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "google/nano-banana-pro",
"mode": "text_to_image",
"prompt": "A premium product photo of a matte black wireless speaker on a marble table, cinematic studio lighting",
"aspect_ratio": "1:1",
"resolution": "1K",
"output_format": "png"
}'
The response contains a generation id.
4. Poll the task
curl https://img2vid.net/api/v1/generations/YOUR_GENERATION_ID \
-H "Authorization: Bearer $BUBLE_API_KEY"
Continue polling until data.status becomes success or failed.
5. Use uploaded files when needed
For image-to-image or image-to-video workflows, upload the source file first:
curl https://img2vid.net/api/v1/files \
-H "Authorization: Bearer $BUBLE_API_KEY" \
-F "file=@./reference.png" \
-F "file_type=image" \
-F "model=google/nano-banana-pro" \
-F "mode=image_to_image"
Then pass the returned data.url to image_urls, start_frame, or another input field supported by the selected mode.
6. Use an official SDK
The SDKs wrap the stable public API contract: model/app discovery, file upload, asynchronous generation creation, polling, and chat protocol calls. They do not hard-code every model's private options. Always discover model keys, modes, app parameters, and model-specific controls from the API.
The published SDK package names, client classes, and BUBLE_API_KEY environment variable are retained as compatibility identifiers. They continue to call the Img2Vid API at https://img2vid.net.
| Language | Install |
|---|---|
| JavaScript / TypeScript | npm install @buble/sdk |
| Python | pip install buble-ai |
| Go | go get github.com/bublehq/sdks/go |
| Rust | cargo add buble |
| Swift | .package(url: "https://github.com/bublehq/swift-sdk.git", from: "0.1.0") |
| Dart / Flutter | dart pub add buble or flutter pub add buble |
| Elixir | {:buble, "~> 0.1.0"} |
| Java | ai.buble:buble-sdk:0.1.0 |
| .NET | dotnet add package Buble.SDK --version 0.1.2 |
| PHP | composer require buble/sdk |
| Ruby | gem install buble |
All SDK examples below read BUBLE_API_KEY from the environment when the API key is omitted. Keep this key on your server.
JavaScript / TypeScript
import { Buble } from '@buble/sdk';
const buble = new Buble();
const task = await buble.generations.create({
model: 'google/nano-banana',
mode: 'text_to_image',
prompt: 'A cinematic product photo of a matte black espresso cup',
aspect_ratio: '1:1',
output_format: 'png',
});
const result = await buble.generations.wait(task.data.id);
console.log(result.data.result?.images?.[0]?.url);
Python
from buble_ai import Buble
client = Buble()
task = client.generations.create(
model="google/nano-banana",
mode="text_to_image",
prompt="A cinematic product photo of a matte black espresso cup",
aspect_ratio="1:1",
output_format="png",
)
result = client.generations.wait(task["data"]["id"])
print(result["data"]["result"]["images"][0]["url"])
Go
client := buble.NewClient()
task, err := client.Generations.Create(ctx, &buble.CreateGenerationRequest{
Model: "google/nano-banana",
Mode: "text_to_image",
Prompt: "A cinematic product photo of a matte black espresso cup",
Params: map[string]any{
"aspect_ratio": "1:1",
"output_format": "png",
},
})
if err != nil {
return err
}
result, err := client.Generations.Wait(ctx, task.Data.ID)
if err != nil {
return err
}
fmt.Println(result.Data.Result.Images[0].URL)
Rust
use buble::{Client, CreateGenerationRequest, WaitOptions};
let client = Client::from_env()?;
let task = client.generations().create(
CreateGenerationRequest::new("google/nano-banana")
.mode("text_to_image")
.prompt("A cinematic product photo of a matte black espresso cup")
.param("aspect_ratio", "1:1")?
.param("output_format", "png")?,
).await?;
let result = client
.generations()
.wait(&task.data.id, WaitOptions::default())
.await?;
Swift
import Buble
let client = try BubleClient.fromEnvironment()
let task = try await client.generations.create(
try CreateGenerationRequest(model: "google/nano-banana")
.mode("text_to_image")
.prompt("A cinematic product photo of a matte black espresso cup")
.param("aspect_ratio", "1:1")
.param("output_format", "png")
)
let result = try await client.generations.wait(task.data.id)
print(result.data.result?.images?.first?.url.absoluteString ?? "")
Dart / Flutter
import 'package:buble/buble.dart';
final client = BubleClient.fromEnvironment();
final task = await client.generations.create(
CreateGenerationRequest(
model: 'google/nano-banana',
mode: 'text_to_image',
prompt: 'A cinematic product photo of a matte black espresso cup',
).withParam('aspect_ratio', '1:1').withParam('output_format', 'png'),
);
final result = await client.generations.wait(task.data.id);
print(result.data.result?.images.firstOrNull?.url);
Elixir
client = Buble.Client.new!()
{:ok, task} =
Buble.Generations.create(client, %{
model: "google/nano-banana",
mode: "text_to_image",
prompt: "A cinematic product photo of a matte black espresso cup",
aspect_ratio: "1:1",
output_format: "png"
})
{:ok, result} = Buble.Generations.wait(client, task["data"]["id"])
IO.puts(result["data"]["result"]["images"] |> List.first() |> Map.fetch!("url"))
Java
BubleClient client = BubleClient.fromEnv();
Envelope<GenerationTask> task = client.generations().create(
CreateGenerationRequest.builder()
.model("google/nano-banana")
.mode("text_to_image")
.prompt("A cinematic product photo of a matte black espresso cup")
.param("aspect_ratio", "1:1")
.param("output_format", "png")
.build());
Envelope<GenerationTask> result = client.generations().wait(task.getData().getId());
.NET
using var client = BubleClient.FromEnv();
var task = await client.Generations.CreateAsync(new CreateGenerationRequest
{
Model = "google/nano-banana",
Mode = "text_to_image",
Prompt = "A cinematic product photo of a matte black espresso cup"
}.WithParam("aspect_ratio", "1:1").WithParam("output_format", "png"));
var result = await client.Generations.WaitAsync(task!.Data!.Id!);
PHP
use Buble\BubleClient;
use Buble\Generations\CreateGenerationRequest;
$client = BubleClient::fromEnv();
$task = $client->generations()->create(
CreateGenerationRequest::make(
model: 'google/nano-banana',
mode: 'text_to_image',
prompt: 'A cinematic product photo of a matte black espresso cup',
)->withParam('aspect_ratio', '1:1')
->withParam('output_format', 'png')
);
$result = $client->generations()->wait($task['data']['id']);
Ruby
require "buble"
client = Buble::Client.new
task = client.generations.create(
model: "google/nano-banana",
mode: "text_to_image",
prompt: "A cinematic product photo of a matte black espresso cup",
aspect_ratio: "1:1",
output_format: "png"
)
result = client.generations.wait(task.dig("data", "id"))
puts result.dig("data", "result", "images", 0, "url")