Images
OpenAI 兼容的图像生成与编辑接口。Sakrylle 把它们合并在一篇文档里,因为请求结构、错误处理、计费规则都一致,仅 endpoint 和编辑相关字段不同。
需要绑定图像分组
图像接口由 GPT-Image 分组提供,模型为 gpt-image-2,每次成功调用 ¥0.15。
调用前请到控制台创建绑定到 GPT-Image 分组的 API Key。用其他分组的 Key 调用图像接口会返回 403 permission_error。实际可用模型以 /v1/models 为准,详见模型与计费。
生成图像
Endpoint
POST https://api.sakrylle.com/v1/images/generations请求头
| 名称 | 必填 | 说明 |
|---|---|---|
Authorization | 是 | Bearer sk-xxxxxxxxxxxxxxxx |
Content-Type | 是 | application/json |
请求体参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 是 | 图像模型 ID,由分组配置决定 |
prompt | string | 是 | 描述提示词 |
n | integer | 否 | 生成张数,默认 1 |
size | string | 否 | 例如 1024x1024 / 1024x1792 / 1792x1024 |
quality | string | 否 | 质量挡位,由模型支持决定(如 standard / hd) |
response_format | string | 否 | url 或 b64_json |
user | string | 否 | 终端用户标识 |
style | string | 否 | 风格 |
background | string | 否 | 透明/非透明(部分模型) |
output_format | string | 否 | 输出格式(部分模型) |
output_compression | integer | 否 | 输出压缩等级(部分模型) |
网关只校验
model、prompt、size、response_format、n、quality、background、style、output_format、output_compression、moderation、input_fidelity、partial_images字段,未列字段不会进入上游。
请求体示例
json
{
"model": "gpt-image-2",
"prompt": "一只在樱花树下打坐的小猫,水彩风格",
"n": 1,
"size": "1024x1024",
"response_format": "url"
}响应示例
json
{
"created": 1716350400,
"data": [
{
"url": "https://cdn.example.com/generated/abc123.png",
"revised_prompt": "A small cat meditating under a cherry blossom tree, watercolor style"
}
]
}response_format=b64_json 时返回 b64_json 字段,内容为 base64 字符串。
编辑图像
Endpoint
POST https://api.sakrylle.com/v1/images/edits请求头
| 名称 | 必填 | 说明 |
|---|---|---|
Authorization | 是 | Bearer sk-xxxxxxxxxxxxxxxx |
Content-Type | 是 | multipart/form-data |
表单字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 是 | 图像编辑模型 ID |
image | file | 是 | 原图,PNG/JPEG/WebP |
prompt | string | 是 | 描述目标编辑结果 |
mask | file | 否 | 透明区域被替换的掩膜图(与 image 同尺寸) |
n | integer | 否 | 生成张数,默认 1 |
size | string | 否 | 输出尺寸 |
response_format | string | 否 | url 或 b64_json |
user | string | 否 | 终端用户标识 |
响应示例
与图像生成一致,包装在 data 数组里。
错误
400 invalid_request_error— 缺model/prompt,或字段格式不合法(例如n不是正整数)401 authentication_error— API Key 无效403 permission_error— API Key 未绑定到 GPT-Image 分组(或分组未开启图像能力)403 billing_error— 余额或订阅限额不足429 rate_limit_error— 并发或速率限制502 upstream_error— 上游连续失败,请稍后重试
更多错误码见 错误处理。
代码示例
bash
curl https://api.sakrylle.com/v1/images/generations \
-H "Authorization: Bearer sk-xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A cat under cherry blossoms, watercolor",
"size": "1024x1024",
"n": 1
}'bash
curl https://api.sakrylle.com/v1/images/edits \
-H "Authorization: Bearer sk-xxxxxxxxxxxxxxxx" \
-F model=gpt-image-2 \
-F image=@./input.png \
-F mask=@./mask.png \
-F prompt="把背景换成蓝色天空"python
from openai import OpenAI
client = OpenAI(
api_key="sk-xxxxxxxxxxxxxxxx",
base_url="https://api.sakrylle.com/v1",
)
# 生成
resp = client.images.generate(
model="gpt-image-2",
prompt="A cat under cherry blossoms, watercolor",
size="1024x1024",
n=1,
)
print(resp.data[0].url)
# 编辑
edit = client.images.edit(
model="gpt-image-2",
image=open("input.png", "rb"),
mask=open("mask.png", "rb"),
prompt="把背景换成蓝色天空",
)
print(edit.data[0].url)javascript
import OpenAI from "openai";
import fs from "node:fs";
const client = new OpenAI({
apiKey: "sk-xxxxxxxxxxxxxxxx",
baseURL: "https://api.sakrylle.com/v1",
});
// 生成
const resp = await client.images.generate({
model: "gpt-image-2",
prompt: "A cat under cherry blossoms",
size: "1024x1024",
});
console.log(resp.data[0].url);
// 编辑
const edit = await client.images.edit({
model: "gpt-image-2",
image: fs.createReadStream("input.png"),
mask: fs.createReadStream("mask.png"),
prompt: "把背景换成蓝色天空",
});
console.log(edit.data[0].url);go
package main
import (
"bytes"
"fmt"
"io"
"net/http"
)
func main() {
body := []byte(`{"model":"gpt-image-2","prompt":"A cat under cherry blossoms","size":"1024x1024"}`)
req, _ := http.NewRequest("POST",
"https://api.sakrylle.com/v1/images/generations",
bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer sk-xxxxxxxxxxxxxxxx")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}rust
use reqwest::Client;
use serde_json::json;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = Client::new();
let resp: serde_json::Value = client
.post("https://api.sakrylle.com/v1/images/generations")
.bearer_auth("sk-xxxxxxxxxxxxxxxx")
.json(&json!({
"model": "gpt-image-2",
"prompt": "A cat under cherry blossoms",
"size": "1024x1024"
}))
.send()
.await?
.json()
.await?;
println!("{resp:#}");
Ok(())
}java
import java.net.URI;
import java.net.http.*;
public class Images {
public static void main(String[] args) throws Exception {
String body = """
{"model":"gpt-image-2","prompt":"A cat under cherry blossoms","size":"1024x1024"}
""";
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.sakrylle.com/v1/images/generations"))
.header("Authorization", "Bearer sk-xxxxxxxxxxxxxxxx")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
}
}csharp
using System.Net.Http.Headers;
using System.Text;
var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "sk-xxxxxxxxxxxxxxxx");
var payload = """
{"model":"gpt-image-2","prompt":"A cat under cherry blossoms","size":"1024x1024"}
""";
var resp = await http.PostAsync(
"https://api.sakrylle.com/v1/images/generations",
new StringContent(payload, Encoding.UTF8, "application/json"));
Console.WriteLine(await resp.Content.ReadAsStringAsync());