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",
    "prompt": "A cinematic lighthouse by the sea at sunset, warm colors",
    "size": "1024x1024",
    "quality": "high",
    "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.
aspect_ratiostringNoAspect ratio written as width:height. Supported values are model-specific.
resolutionstringNoOutput resolution. Only send it when the model table explicitly lists values.
sizestringNoPixel dimensions such as 1024x1024, 1792x1024, or 1024x1792; some models also accept ratios such as 1:1, 16:9, 9:16, or 4:3. See the model page.
qualitystringNoModel-specific quality. Common values are low, medium, and high.
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.

Prompt enhancement

ModelsFieldValue
qwen-image-2.0, qwen-image-2.0-proextra_body.prompt_extendBoolean; defaults to true
qwen-image-3extra_body.prompt_extendBoolean; defaults to true
qwen-image-3extra_body.prompt_extend_modedirect (default), or agent for text-to-image only
qwen-image-3extra_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.

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:9Controlled by quality512, low, medium, highimage
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; use size for exact dimensionsVia size; total pixels from 512x512 through 2048x2048Automaticimage / image_urls

For gemini-3.1-flash-image-preview, quality maps to output specification as follows: 512 to 512 px, low to 1K, medium to 2K, and high to 4K.

Image-to-image example

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

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","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1024x1024"}'
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", prompt: "A white unicorn beneath a starry sky", n: 1, size: "1024x1024" }),
});
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", prompt: "A white unicorn beneath a starry sky",
  n: 1, size: "1024x1024", 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", prompt="A white unicorn beneath a starry sky",
    n=1, size="1024x1024", 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\",\"prompt\":\"A white unicorn beneath a starry sky\",\"n\":1,\"size\":\"1024x1024\"}");
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", @"prompt": @"A white unicorn beneath a starry sky", @"n": @1, @"size": @"1024x1024" };
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\",\"prompt\":\"A white unicorn beneath a starry sky\",\"n\":1,\"size\":\"1024x1024\"}"))
    .build();
System.out.println(HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()).body());
payload := strings.NewReader(`{"model":"gpt-image-2","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1024x1024"}`)
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', 'prompt' => 'A white unicorn beneath a starry sky', 'n' => 1, 'size' => '1024x1024'])]);
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", "prompt": "A white unicorn beneath a starry sky", "n": 1, "size": "1024x1024"])
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", prompt = "A white unicorn beneath a starry sky", n = 1, size = "1024x1024" });
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", prompt: "A white unicorn beneath a starry sky", n: 1, size: "1024x1024" }.to_json
puts Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }.body
val json = """{"model":"gpt-image-2","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1024x1024"}"""
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","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1024x1024"}))
    .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","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1024x1024"}
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', 'prompt': 'A white unicorn beneath a starry sky', 'n': 1, 'size': '1024x1024'}),
);
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", prompt = "A white unicorn beneath a starry sky", n = 1L, size = "1024x1024")) |>
  req_perform()
resp_body_json(response)
let body = {|{"model":"gpt-image-2","prompt":"A white unicorn beneath a starry sky","n":1,"size":"1024x1024"}|} 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

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