SilkDock
APIImage Generation

Image Generation

Generate and edit images with the platform's stable model IDs.

Model access is account-specific. Use the model list endpoint as the source of truth for models available to your API key.

The endpoint generates an image from text by default. When image or image_urls is present, models that support references automatically use image-to-image mode.

Create an image task

Endpoint: POST /v1/images/generations

curl -X POST 'https://silkdock.ai/v1/images/generations' \
  -H 'Authorization: Bearer $SILKDOCK_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-image-2.5-sunburst",
    "prompt": "A cinematic lighthouse by the sea at sunset, warm colors",
    "size": "1:1",
    "quality": "xhigh",
    "n": 1
  }'

Image tasks are asynchronous by default. Save the returned task ID and poll the status endpoint until the task is completed or failed.

Request parameters

ParameterTypeRequiredDescription
modelstringYesA public model ID from the capability table. Do not add provider or deployment prefixes.
promptstringYesImage description or editing instruction.
sizestringNoOutput aspect ratio such as 1:1, 16:9, 9:16, or 4:3. Use /model_group/info → supported_aspect_ratios for the selected model's values.
resolutionstringNoImage clarity such as 1k, 1.5k, 2k, or 4k. Only send values listed in /model_group/info → supported_resolutions.
qualitystringNoAn independent image-quality tier. Send it only when supported_image_quality_levels is non-empty and supported_openai_params contains quality; never use it for clarity.
nintegerNoNumber of images. Default: 1; retrieve the account-specific limit from the model list endpoint.
imagestringNoOne reference image URL for image-to-image generation.
image_urlsstring[]NoMultiple reference image URLs; only supported by models marked for multi-image reference. Some models accept up to 10 images.
response_formatstringNoModel-specific response format. Send only when the selected model's documented contract supports it.
output_formatstringNoModel-specific output format. GPT Image 2 supports png, jpeg, and webp; Qwen Image 2.0 and Qwen Image 3 output PNG only.
wait_for_completionbooleanNofalse (default) creates an asynchronous task and returns its ID immediately; true blocks in the create request until completion.
polling_timeoutnumberNoPolling timeout when wait_for_completion is true; the underlying service default applies when omitted.

Sending image or image_urls to a model without image-to-image support returns 400. Remove the reference field or select a compatible model.

Multipart image editing

Use POST /v1/images/edits with multipart/form-data when the source image is a local file. model, image, and prompt are required; mask, n, size, resolution, quality, and response_format are optional and remain model-specific. The public size field carries an aspect ratio, while resolution carries clarity and quality remains an independent quality tier.

curl -X POST 'https://silkdock.ai/v1/images/edits' \
  -H 'Authorization: Bearer $SILKDOCK_API_KEY' \
  -F 'model=gpt-image-1' \
  -F 'image=@/path/to/image.png' \
  -F 'prompt=Change the sky to a warm sunset' \
  -F 'quality=medium'

Prompt enhancement

ModelsFieldValue
qwen-image-2.0, qwen-image-2.0-proextra_body.prompt_extendBoolean; defaults to true
qwen-image-3, qwen-image-3.0-proextra_body.prompt_extendBoolean; defaults to true
qwen-image-3, qwen-image-3.0-proextra_body.prompt_extend_modedirect (default), or agent for text-to-image only
qwen-image-3, qwen-image-3.0-proextra_body.enable_thinkingBoolean; defaults to true and applies only when prompt enhancement is enabled
seedream-v4.5, seedream-v5-liteextra_body.optimize_prompt_options.modestandard

These image models do not support think_level, thinking_level, or reasoning_effort. Qwen Image 3 supports its documented enable_thinking boolean; do not treat that as support for generic reasoning fields.

Parameters and values not listed here or on the selected model page are not part of the stable public API.

Build image controls from GET /model_group/info: show Size when supported_aspect_ratios is present, Clarity when supported_resolutions is present, and Quality only when the model explicitly supports it. Do not place resolution tiers in supported_image_sizes or expose them as quality values.

For example, gemini-3.1-flash-image-preview uses resolution values 512, 1k, 2k, and 4k; it no longer uses the older quality mapping. A model such as seedream-v5-pro keeps aspect ratio and clarity separate:

{
  "model": "seedream-v5-pro",
  "prompt": "rain rain go away",
  "size": "9:16",
  "resolution": "1k"
}

Asynchronous response

By default, the gateway returns a pollable task even when the underlying model exposes only a synchronous API. This avoids holding frontend requests open during generation.

{
  "created": 1720000000,
  "data": [],
  "id": "imggen_123",
  "object": "image.generation",
  "status": "processing",
  "model": "gpt-image-2"
}

Poll GET /v1/images/generations/{id} until status is completed, then read data[0].url or data[0].b64_json. Set wait_for_completion: true to retain blocking synchronous behavior:

{
  "created": 1720000000,
  "data": [
    {
      "url": "https://example.com/generated.png",
      "revised_prompt": "A cinematic lighthouse at sunset"
    }
  ]
}

Asynchronous task state is stored in Redis and the proxy database. If Redis is unavailable, tasks can still be created and queried while the proxy database is available. If neither store is available, use wait_for_completion: true.

Model capabilities

ModelText to imageImage to imageMulti-imageAspect ratiosresolutionqualityReference field
gpt-image-2YesYesNo1:1, 4:3, 3:4, 3:2, 2:3, 16:9, 9:16standard, 1440p, 4klow, medium, highimage
gemini-3-pro-image-previewYesYesNo1:1, 5:4, 4:5, 4:3, 3:4, 3:2, 2:3, 16:9, 9:16, 21:9AutomaticAutomaticimage
gemini-3.1-flash-image-previewYesYesNo1:1, 5:4, 4:5, 4:3, 3:4, 3:2, 2:3, 16:9, 9:16, 21:9512, 1k, 2k, 4kDo not sendimage
seedream-v4.5YesYesNo1:1, 4:3, 3:4, 16:9, 9:16, 21:9Do not sendlow, medium, highimage
seedream-v5-liteYesYesNo1:1, 4:3, 3:4, 16:9, 9:16, 21:9Do not sendlow, medium, highimage
qwen-image-2.0YesYesYes1:1, 4:3, 3:4, 16:9, 9:16Do not sendAutomaticimage / image_urls
qwen-image-2.0-proYesYesYes1:1, 4:3, 3:4, 16:9, 9:16Do not sendAutomaticimage / image_urls
qwen-image-3YesYesYes, up to 31:8 through 8:1; public requests pass a ratio in sizeModel selects native dimensions within 512x512 through 2048x2048 total pixelsAutomaticimage / image_urls
qwen-image-3.0-proYesYesYes, up to 31:8 through 8:1; public requests pass a ratio in sizeModel selects native dimensions within 512x512 through 2048x2048 total pixelsAutomaticimage / image_urls

Image-to-image example

{
  "model": "seedream-v5-lite",
  "prompt": "Preserve the subject and convert the image to watercolor",
  "image": "https://example.com/reference.png",
  "size": "3:4",
  "resolution": "2k"
}

Code examples

curl -X POST 'https://silkdock.ai/v1/images/generations' \
  -H 'Authorization: Bearer sk-xxx' \
  -H 'Content-Type: application/json' \
  -d '{"model":"gpt-image-2.5-sunburst","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1:1"}'
const response = await fetch("https://silkdock.ai/v1/images/generations", {
  method: "POST",
  headers: { Authorization: "Bearer sk-xxx", "Content-Type": "application/json" },
  body: JSON.stringify({ model: "gpt-image-2.5-sunburst", prompt: "A white unicorn beneath a starry sky", n: 1, size: "1:1" }),
});
console.log(await response.json());
import OpenAI from "openai";
const client = new OpenAI({ apiKey: "sk-xxx", baseURL: "https://silkdock.ai/v1" });
const response = await client.images.generate({
  model: "gpt-image-2.5-sunburst", prompt: "A white unicorn beneath a starry sky",
  n: 1, size: "1:1", extra_body: { wait_for_completion: true },
});
console.log(response.data[0].url);
from openai import OpenAI
client = OpenAI(api_key="sk-xxx", base_url="https://silkdock.ai/v1")
response = client.images.generate(
    model="gpt-image-2.5-sunburst", prompt="A white unicorn beneath a starry sky",
    n=1, size="1:1", extra_body={"wait_for_completion": True},
)
print(response.data[0].url)
CURL *curl = curl_easy_init();
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Authorization: Bearer sk-xxx");
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, "https://silkdock.ai/v1/images/generations");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"model\":\"gpt-image-2.5-sunburst\",\"prompt\":\"A white unicorn beneath a starry sky\",\"n\":1,\"size\":\"1:1\"}");
curl_easy_perform(curl);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://silkdock.ai/v1/images/generations"]];
request.HTTPMethod = @"POST";
[request setValue:@"Bearer sk-xxx" forHTTPHeaderField:@"Authorization"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
NSDictionary *payload = @{ @"model": @"gpt-image-2.5-sunburst", @"prompt": @"A white unicorn beneath a starry sky", @"n": @1, @"size": @"1:1" };
request.HTTPBody = [NSJSONSerialization dataWithJSONObject:payload options:0 error:nil];
[[[NSURLSession sharedSession] dataTaskWithRequest:request] resume];
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://silkdock.ai/v1/images/generations"))
    .header("Authorization", "Bearer sk-xxx").header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString("{\"model\":\"gpt-image-2.5-sunburst\",\"prompt\":\"A white unicorn beneath a starry sky\",\"n\":1,\"size\":\"1:1\"}"))
    .build();
System.out.println(HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()).body());
payload := strings.NewReader(`{"model":"gpt-image-2.5-sunburst","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1:1"}`)
req, _ := http.NewRequest("POST", "https://silkdock.ai/v1/images/generations", payload)
req.Header.Set("Authorization", "Bearer sk-xxx")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
<?php
$ch = curl_init('https://silkdock.ai/v1/images/generations');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['Authorization: Bearer sk-xxx', 'Content-Type: application/json'],
  CURLOPT_POSTFIELDS => json_encode(['model' => 'gpt-image-2.5-sunburst', 'prompt' => 'A white unicorn beneath a starry sky', 'n' => 1, 'size' => '1:1'])]);
echo curl_exec($ch);
var request = URLRequest(url: URL(string: "https://silkdock.ai/v1/images/generations")!)
request.httpMethod = "POST"
request.setValue("Bearer sk-xxx", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: ["model": "gpt-image-2.5-sunburst", "prompt": "A white unicorn beneath a starry sky", "n": 1, "size": "1:1"])
URLSession.shared.dataTask(with: request) { data, _, _ in print(String(data: data!, encoding: .utf8)!) }.resume()
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer sk-xxx");
var json = JsonSerializer.Serialize(new { model = "gpt-image-2.5-sunburst", prompt = "A white unicorn beneath a starry sky", n = 1, size = "1:1" });
var response = await client.PostAsync("https://silkdock.ai/v1/images/generations", new StringContent(json, Encoding.UTF8, "application/json"));
Console.WriteLine(await response.Content.ReadAsStringAsync());
uri = URI("https://silkdock.ai/v1/images/generations")
request = Net::HTTP::Post.new(uri, { "Authorization" => "Bearer sk-xxx", "Content-Type" => "application/json" })
request.body = { model: "gpt-image-2.5-sunburst", prompt: "A white unicorn beneath a starry sky", n: 1, size: "1:1" }.to_json
puts Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }.body
val json = """{"model":"gpt-image-2.5-sunburst","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1:1"}"""
val request = Request.Builder().url("https://silkdock.ai/v1/images/generations")
    .header("Authorization", "Bearer sk-xxx")
    .post(json.toRequestBody("application/json".toMediaType())).build()
OkHttpClient().newCall(request).execute().use { println(it.body?.string()) }
let response = reqwest::Client::new()
    .post("https://silkdock.ai/v1/images/generations").bearer_auth("sk-xxx")
    .json(&serde_json::json!({"model":"gpt-image-2.5-sunburst","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1:1"}))
    .send().await?;
println!("{}", response.text().await?);
POST /v1/images/generations HTTP/1.1
Host: silkdock.ai
Authorization: Bearer sk-xxx
Content-Type: application/json

{"model":"gpt-image-2.5-sunburst","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1:1"}
final response = await http.post(
  Uri.parse('https://silkdock.ai/v1/images/generations'),
  headers: {'Authorization': 'Bearer sk-xxx', 'Content-Type': 'application/json'},
  body: jsonEncode({'model': 'gpt-image-2.5-sunburst', 'prompt': 'A white unicorn beneath a starry sky', 'n': 1, 'size': '1:1'}),
);
print(response.body);
response <- request("https://silkdock.ai/v1/images/generations") |>
  req_headers(Authorization = "Bearer sk-xxx") |>
  req_body_json(list(model = "gpt-image-2.5-sunburst", prompt = "A white unicorn beneath a starry sky", n = 1L, size = "1:1")) |>
  req_perform()
resp_body_json(response)
let body = {|{"model":"gpt-image-2.5-sunburst","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1:1"}|} in
let headers = Cohttp.Header.of_list [("Authorization", "Bearer sk-xxx"); ("Content-Type", "application/json")] in
Lwt_main.run (Cohttp_lwt_unix.Client.post ~headers ~body:(Cohttp_lwt.Body.of_string body)
  (Uri.of_string "https://silkdock.ai/v1/images/generations"))

Pricing

All prices are in USD.

ModelBillingInputOutput
gpt-image-2TokensText $5/M; cached text $1.25/M; image $8/M image tokens; cached image $2/M image tokensText $10/M; image $30/M image tokens
gemini-3-pro-image-previewInput + imageText $2/M; reference image $0.0011/image$0.134/image; text output $12/M
gemini-3.1-flash-image-previewInput + output specificationText $0.25/MSee the specification table; text output $1.50/M
seedream-v4.5Per image-$0.040/image
seedream-v5-litePer image-$0.035/image
qwen-image-2.0Per image-$0.035/image
qwen-image-2.0-proPer image-$0.075/image
qwen-image-3Input references + output images$0.003125/reference image$0.031250/image at 1K or 2K
qwen-image-3.0-proInput references + output images$0.003125/reference image$0.031250/image at 1K or 2K

gpt-image-2 has no fixed per-image price because prompt, reference, output specification, and quality affect the actual token count.

gemini-3.1-flash-image-preview qualityOutputUSD/image
512512$0.0450
low1K$0.0672
medium2K$0.1008
high4K$0.1512

If quality is omitted, Gemini Flash uses its default 1K specification at $0.0672/image. Aspect ratio does not change this specification price.

Check an image task

Endpoint: GET /v1/images/generations/{task_id}

The task status is processing, completed, or failed. On completion, read the result from data[0].url or data[0].b64_json.

Last updated on

On this page