Developer resources

Rhuan API 接入文档#

Rhuan 是独立 AI Photography Model。输入同一个人的参考照片、约定场景 scene_id 和少量参数即可获得成片。所有客户使用相同接口。

公共协议版本:v0.4。在线文档:rhuan.app/docs。

接入项 值
Base URL https://rhuan.app/v1
Model rhuan-photo-1
认证 Authorization: Bearer rhuan_sk_…
生图入口 POST /v1/images/edits,multipart/form-data
返回 同步 created + data[].b64_json

API key 由管理员交付,只在创建时显示一次。放在服务端环境变量或 secret 管理工具, 避免嵌入公开网页、提交 Git 或放入 URL。撤销后立即失效。

v0.5 运营后台可创建场景和 key;本公共协议仍为 v0.4,模型名和参数不变。 scene_id 创建后不可改;管理员可更新图片或停用场景。停用、未知与未授权场景 均返回同样的 404 scene_not_found。后台登录 cookie 不能替代 Bearer key。

开始接入#

  1. 向管理员获取 API key,以及这把 key 已获授权的 scene_id。
  2. 准备同一个人的 1–4 张 PNG、JPEG 或 WEBP 照片,把清晰正面照放在第一张。
  3. 按下方 Python 或 curl 示例上传;将示例场景 ID 换为管理员提供的 ID。
  4. 将响应的 b64_json 解码成图片;保留 X-Request-ID,用于查询请求结果或排障。

普通 Images API 的场景发布与 Key 授权是两个步骤。仅 Publish 场景不会自动让 现有 Key 获得此接口的权限。ID 和授权规则区分大小写,例如 GD_001 与 gd_001 不同。遇到 404 scene_not_found,请让管理员同时核对场景状态和 Key 权限。

Python SDK#

安装 openai 和用于识别成片格式的 pillow。已用 OpenAI Python SDK 3.36.1 的真实本地 HTTP 验证空 prompt、多文件、布尔扩展字段和响应解析。

import base64
import os
from io import BytesIO
from pathlib import Path

from openai import OpenAI
from PIL import Image

client = OpenAI(
    api_key=os.environ["RHUAN_API_KEY"],
    base_url="https://rhuan.app/v1",
    timeout=900,
    max_retries=0,
)

with open("person_front.jpg", "rb") as front, open("person_side.jpg", "rb") as side:
    result = client.images.edit(
        model="rhuan-photo-1",
        image=[front, side],
        prompt="",
        n=2,
        quality="high",
        size="auto",
        response_format="b64_json",
        extra_body={
            "scene_id": "lvpai_yulong_001",  # 替换为已获授权的场景 ID
            "allow_outfit_change": True,
            "aspect_ratio": "9:16",
        },
    )

for index, item in enumerate(result.data, 1):
    raw = base64.b64decode(item.b64_json)
    with Image.open(BytesIO(raw)) as photo:
        extension = {"PNG": "png", "JPEG": "jpg", "WEBP": "webp"}[photo.format]
    Path(f"output_{index}.{extension}").write_bytes(raw)

当前公共上传不标注角色,以第一张为主要身份参考,其余 原图保留用于追溯,不保证全部送入生成请求。请把最清晰的正面照片放在第一张。

单图可用 image=front。prompt="" 会正常编码为空字段,不需要自由提示词。 示例按实际格式保存原始图片字节,不做重新编码。max_retries=0 避免 SDK 自动重试 造成重复生成;本版没有幂等去重。超时、断线或部分失败后先凭 request ID 核查结果。

curl#

假设 RHUAN_API_KEY 已通过安全方式放入环境变量:

curl --fail-with-body --max-time 900 \
  https://rhuan.app/v1/images/edits \
  -H "Authorization: Bearer ${RHUAN_API_KEY}" \
  -F 'model=rhuan-photo-1' \
  -F 'image[]=@person_front.jpg' \
  -F 'image[]=@person_side.jpg' \
  -F 'prompt=' \
  -F 'scene_id=lvpai_yulong_001' \
  -F 'n=2' \
  -F 'quality=high' \
  -F 'size=auto' \
  -F 'response_format=b64_json' \
  -F 'allow_outfit_change=true' \
  -F 'aspect_ratio=9:16' \
  -o response.json

支持重复 image 或 image[] 文件字段。由 curl/SDK 自动生成 Content-Type boundary, 不要手填。只接受直接上传文件,不接受图片 URL、base64 JSON 或服务器路径。

模型接口#

print(client.models.list())
print(client.models.retrieve("rhuan-photo-1"))

GET /v1/models 返回:

{
  "object": "list",
  "data": [
    {"id": "rhuan-photo-1", "object": "model", "created": 1792627200, "owned_by": "rhuan"}
  ]
}

全部 /v1 实际业务请求需要 key;合法 CORS 预检 OPTIONS 不需要 key。POST /v1/images/generations 返回 400,提示使用带人物图 的 edits 接口。

参数#

字段 默认 / 限制 含义
model 必填,rhuan-photo-1 唯一公开模型
image / image[] 必填,1–4 个文件 同一个人的照片;最好正面照放第一张,无需标角色
scene_id 必填 提前注册且当前 key 获授权的稳定 ID
prompt 缺省、空字符串或固定 rhuan 不用于选场景,不支持自由提示词
n 默认 1,整数 1–6 期望成片数;场景素材不足时报错
quality 默认 high;low / medium / high 稳定质量选项
aspect_ratio 默认 9:16 1:1、3:2、2:3、4:3、3:4、16:9、9:16、21:9、auto
allow_outfit_change 默认 false false 尽量保留参考服装;true 允许按场景换装
size 仅 auto 不承诺精确像素;如 1024x1792 返回 unsupported_parameter
response_format 默认且仅 b64_json base64 图片字节

不支持 resolution、URL 输出、mask、stream、output_format 或其他未列出的控制字段, 也不会静默降级。尺寸与比例不同,不会把精确尺寸偷换为某个比例。

scene_id 不是路径。运营先注册场景包,再授权 ID 或通配范围,例如 lvpai_*。 没有公共场景枚举、创建或上传接口;请使用双方约定的 ID。n 张场景沿用已有抽样方式, 服务端记录实际选中素材。示例中的 lvpai_yulong_001 仅作占位,不代表该 ID 已向你的 Key 授权。

响应与错误#

{"created": 1792627200, "data": [{"b64_json": "..."}, {"b64_json": "..."}]}

200 必须恰好返回 n 张图。请求四张而只成功三张时返回 502;内部产物保留供调查。 响应头 x-request-id 用于排障;联系运营时提供该 ID,不提供 key。

{
  "error": {
    "message": "scene_id is required",
    "type": "invalid_request_error",
    "param": "scene_id",
    "code": "missing_scene_id"
  }
}
HTTP code / 含义 处理
400 unsupported_parameter / invalid_parameter / missing_scene_id / model_not_found / invalid_request / upload_timeout / unsupported_endpoint 修正请求;上传超时可在确认未生成后重传
401 invalid_api_key 检查 Bearer key 是否有效或已撤销
404 scene_not_found / not_found 核对 ID;无权限、停用与未知场景响应相同
413 request_too_large 减少上传体积
422 invalid_image 使用有效 PNG/JPEG/WEBP
429 rate_limit_exceeded 返回 Retry-After: 5;等待现有生成结束再提交
500 internal_error 携 request ID 联系运营
502 upstream_generation_error 生成未完整成功,先核查
504 generation_timeout 已开始任务可能继续执行,先核查再重试

限制与数据保存#

  • 每张 PNG/JPEG/WEBP 最多 8 MiB、20,000,000 像素;总请求最多 34 MiB,含 multipart。 不支持动态图,恶意文件名、重复标量和嵌套扩展字段会被拒绝。
  • 当前单进程公共请求最多并行 2 个,每个 key 最多 1 个,每请求最多 6 张并发。 这是并发保护,不是计费或配额系统。
  • 应用上传总时限 30 秒;生成等待最多 780 秒,SDK 建议 900 秒。HTTP 超时后,实际任务结束才释放并发额度。
  • 人物图不加入人物库。输入、成片、prompt、metadata 保存在本次私有 job 工作目录 中,不通过公开 URL 或免登录 Web 历史提供访问。
  • 本版保留请求数据用于追溯,没有自动过期删除。账本保存状态与数量,不保存 明文 key 或图片;需删除数据时联系运营确认范围。
  • 不提供客户场景管理、注册或账单接口。

Browser Client / CORS#

官方Demo为 https://demo.rhuan.app,使用同一公开模型。v0.10无需登录,所有访客 共享服务器人物照片与生成历史,人物/场景/参数的选择只保存在各自浏览器。页面提供 共享Key编辑和用量入口,运行凭据保存于服务器且只显示掩码;普通使用无需自带Key。 支持全部可用已发布场景、首图缩略图、逐图评分与默认关闭的低分重做。 Demo单图上限20 MiB,普通Images API仍为8 MiB并执行原Key场景权限。 第三方服务端仍将自己的Key保存在secret配置中,通过下方SDK/curl调用 /v1/images/edits。保留的/v1/demo扩展仍需Bearer;官方网页不再从浏览器调用它。

浏览器跨域白名单唯一值是 https://demo.rhuan.app。无 Origin 的 SDK/server-to-server 请求保持现有行为;其他、空或重复 Origin 被拒绝,不要求 SDK 添加 Origin/Referer。 Admin 与旧 /api/* 不增加 CORS。

无需 key 的 Images 兼容接口预检支持:

  • OPTIONS /v1/models,请求方法 GET。
  • OPTIONS /v1/images/edits,请求方法 POST。

Demo 扩展另对白名单中的场景/缩略图/批次/成片 GET 和批次 POST 提供精确预检, 实际请求均重新验证 Bearer Key;Origin 不授予访问权,历史与成片按 Key 隔离。

验证 Origin、Access-Control-Request-Method 与 Access-Control-Request-Headers;请求头 仅允许 Authorization、Content-Type(大小写不敏感)。合法预检返回 204,并包含:

Access-Control-Allow-Origin: https://demo.rhuan.app
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Max-Age: 600
Vary: Origin

不返回通配 Origin 或 Allow-Credentials。合法来源的成功和错误响应均带允许头, Access-Control-Expose-Headers 使浏览器可读 X-Request-ID 与 Retry-After;预检 不计入业务 usage。网关返回的 413/502/504 同样只对允许来源添加 CORS。

multipart由FormData自动生成boundary;官方Demo不发送Cookie,不自动重试生成请求。 429 显示 Retry-After;504/网络中断应视为结果未知,服务器任务可能继续,联系运营 核查后再决定重新提交,避免重复付费。当前不提供 /v1/scenes。