开发者接入 · v1

API 文档

API 专供有持续、批量任务需求的商家与合作者使用,不面向任务量很少的个人使用者。个人使用者请勿申请。

页面上的标价是本站价格,不是接口结算价。接口价格请联系管理员谈具体消费折扣;开通后,由管理员手动私信发送密钥。

私信管理员开通 TG:@xubeifeng

接口地址
https://shanjierenyi-my.com/wp-json/site-api/v1

流程总览

  1. GET /account 读取当前可用功能、价格、余额和今日剩余额度(可选)。
  2. POST /tasks 提交任务:请求头携带密钥和 Idempotency-Key;成功返回 HTTP 202 和 task_code,此时已扣款。
  3. GET /tasks/{task_code} 每 5–10 秒轮询,直到 status 为 succeeded、failed 或 cancelled。
  4. status 为 succeeded 时下载 result_url(10 分钟有效,过期后重新查询获取新地址)。failed / cancelled 均已自动退款。

所有接口只接受服务器端调用;响应均为 JSON(下载地址除外),请求和响应均使用 UTF-8。同一账号内请串行提交创建请求:一个创建请求正在处理时,同账号的另一个创建请求会返回 409 account_busy,稍后按原编号重试即可。

密钥与鉴权

所有业务请求使用 HTTPS,并携带以下请求头。一个账号只有一个有效密钥;更换密钥请联系管理员,旧密钥在重置后失效。

Authorization: Bearer <管理员提供的密钥>

密钥格式为 sapi_ 加 64 位十六进制字符。请把密钥保存在服务器的环境变量中,供后端调用。不要放进网页 JavaScript、URL、公开代码或日志。账号停用、封禁后无法继续调用。

功能列表

API 只开放下表中的功能,每个 type 与站内同名页面使用同一套处理流程。金额见「本站价格」,那是网页标价,不是接口结算价。提交未开放或不存在的 type 会收到 400 unsupported_type(message 列出当前站点可用类型),不会扣款。

功能type必填素材prompt结果
文生图text_to_image无必填图片
人脸融合(文生图)text_to_image_faceimage必填图片
单图编辑image_editimage必填图片
双图编辑multi_image_editimage、image2必填图片
一键脱衣image_undressimage不需要图片
换衣clothing_changeimage不需要图片
图片换脸image_face_swapimage:人物照片(提供人脸);image2:目标图片(被替换人脸)不需要图片
视频换脸(自定义视频)video_face_swapimage:人物照片(提供人脸);video:目标视频不需要MP4 视频
视频换脸(站内模板)video_face_swap_templateimage:人物照片;template:站内模板 key(见 GET /account 的 options)不需要MP4 视频
文生视频text_to_video无必填MP4 视频
图生视频(自定义提示词)image_to_videoimage(或 source_task_code:本人文生图作品)必填MP4 视频
图生视频模板image_to_video_templateimage(或 source_task_code:本人文生图作品)不需要MP4 视频
图生长视频long_videoimage(或 source_task_code:本人文生图作品)不需要MP4 视频
视频脱衣video_undressvideo:已剪到 1–10 秒、不超过 30 MB 的视频不需要MP4 视频

创建任务

POST /tasks · 有文件时使用 multipart/form-data;无文件任务可使用 application/json。所有参数放在请求体中,URL 上不能带查询参数。

请求头

请求头说明
Authorization必填,Bearer <密钥>。
Idempotency-Key必填,8–128 位,仅允许字母、数字和 . _ : -,建议使用 UUID。每个新任务生成一个新编号;超时或网络错误后,使用相同编号、相同参数和相同文件重试,服务端会返回已创建的同一任务且不再扣款。同一编号搭配不同参数会返回 409 idempotency_conflict。
Content-Typemultipart/form-data 或 application/json。

请求体字段

字段说明
type必填,见功能列表。
prompt文生图、人脸融合文生图、单图/双图编辑、文生视频、自定义图生视频必填,最多 6000 个 UTF-8 字节。只写画面内容。脱衣、换衣、换脸、模板、长视频、视频脱衣不使用此字段。不符合要求时返回 400 invalid_prompt,不会扣款。
negative_prompt可选,反向提示词,最多 3000 个 UTF-8 字节。要求和正向提示词一样,只写画面内容。
size仅文生视频、自定义图生视频、长视频:480x832(默认)或 704x1280(贵 5 金币,长视频按段另计)。视频时长固定 5 秒,与网页默认一致。其他类型请勿传。
ratio仅文生图、人脸融合文生图,可选,画面比例:9:16(默认,1088×1920)/ 1:1(1440×1440)/ 16:9(1920×1088)。不影响价格。
canvas仅双图编辑,可选,输出画布:follow1(跟随第一张图,默认)/ follow2(跟随第二张图)/ 16:9 / 1:1 / 9:16。不影响价格。
gender一键脱衣、图片换脸、视频换脸(自定义视频和站内模板)可选:female(默认)/ male。脱衣时指定处理的人物性别;换脸时只替换该性别的人物。
image / image2文件字段,随创建请求上传。JPG、PNG、WebP;每张最多 18 MB,单边 32–8192 像素,最多 1200 万像素。服务端会重新编码为 JPEG 并剥离元数据。
video文件字段。视频换脸:MP4 或 WebM,最多 50 MB、250 秒、1080p(长边不超过 1920)、60 FPS,只能包含一个视频轨。视频脱衣:请先剪到 1–10 秒、不超过 30 MB,最短边不低于 360 像素;服务端不代剪。
source_task_code自定义图生视频、图生视频模板、长视频可用本人已完成的文生图作品作为源图,替代 image。传该作品的 19 位任务 code(字符串),不能与 image 同时使用。作品需在 30 天内且未删除。
style一键脱衣必填:pingxiong / xiaonai / zhongnai / danai / chaoju。换衣必填:chiheidiao、rujiao、kunbang 等,完整列表见 GET /account 的 options。
hair / breast / outfit可选。脱衣的阴毛、换衣的身材/阴毛/服装、视频脱衣的奶子大小与阴毛;取值以 options 为准。图片阴毛:moren / wumao / youmao / maosheng。视频脱衣奶子:moren(跟随原视频,默认)/ pingxiong / xiaonai / zhongnai / danai / chaoju;视频阴毛:moren / wumao / shaomao(默认)/ youmao / maosheng。
body一键脱衣、换衣、视频脱衣可选,身材:moren(跟随原人物/原视频,默认)/ miaotiao(苗条)/ zhongdeng(中等)/ fengman(胖/丰满)。
template图生视频模板、站内视频换脸模板、长视频必填。必须使用 GET /account 返回的 key,未知模板拒绝。长视频的 template 是固定组合 key(如 classic_three),段落顺序由组合决定。
durations仅长视频,可选:每段秒数的整数数组(multipart 时传 JSON 字符串),如 [4,5,4],个数必须等于组合段数,每段 3–10 秒,每段的上下限以 options.long_video.presets[].min_durations / max_durations 为准(一次性动作段如脱衣、射精最多 6 秒)。不传则用组合默认秒数。长视频不再接受自由组合的 segments。
keep_shoes / keep_hands / keep_stockings仅视频脱衣,可选,取值 0 或 1。默认保留鞋子、不保留手和丝袜。旧字段 fullbody 仍可传但已不生效。

一键脱衣与换衣使用和网页相同的图片黑名单:同一账号此前因失败退款被拉黑的原图会返回 400 image_blocked,不扣款,请换图。

整个请求最多 70 MB。文档没有列出的字段和文件名会返回 400 invalid_parameter。文件数量、字段名必须与功能列表一致,否则返回 400 invalid_uploads。模板和选项请先调用 GET /account,按返回的 options 填写,不要自行编造。

受理成功:HTTP 202

{
  "task_code": "2026091209301234567",
  "replayed": false,
  "status_url": "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks/2026091209301234567"
}

task_code 与站内任务 code 一致,为 19 位字符串,请勿转成数字,以免丢失精度。replayed: true 表示返回了同一 Idempotency-Key 已创建的任务,没有再次扣款。幂等记录长期保留,不要复用旧编号发起新任务。

受理即扣款;扣款金额可在随后的查询响应 price 字段中看到。金币不足(402)或额度不足(429)时不会创建任务。

请求示例

示例中 $SITE_API_KEY 为管理员提供的密钥,$TASK_REQUEST_ID 为本次任务的唯一编号(请保存下来供重试使用)。

cURL:文生图(JSON)

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --header "Content-Type: application/json" \
  --data '{"type":"text_to_image","prompt":"雨后山间的木屋,柔和晨光","negative_prompt":"模糊,低画质","ratio":"9:16"}'

cURL:文生视频(JSON,指定尺寸)

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --header "Content-Type: application/json" \
  --data '{"type":"text_to_video","prompt":"海边日出,镜头缓慢推进","size":"704x1280"}'

cURL:单图编辑(multipart 上传图片)

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --form "type=image_edit" \
  --form "prompt=把背景换成黄昏的海边" \
  --form "image=@input.jpg;type=image/jpeg"

cURL:双图编辑(两张图片)

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --form "type=multi_image_edit" \
  --form "prompt=把图1人物的脸换成图2人物的脸" \
  --form "canvas=follow1" \
  --form "image=@first.jpg;type=image/jpeg" \
  --form "image2=@second.jpg;type=image/jpeg"

cURL:图片换脸(两张图片)

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --form "type=image_face_swap" \
  --form "gender=female" \
  --form "image=@face.jpg;type=image/jpeg" \
  --form "image2=@target.jpg;type=image/jpeg"

cURL:视频换脸(图片 + 视频)

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --form "type=video_face_swap" \
  --form "image=@face.jpg;type=image/jpeg" \
  --form "video=@target.mp4;type=video/mp4"

cURL:一键脱衣

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --form "type=image_undress" \
  --form "style=zhongnai" \
  --form "hair=moren" \
  --form "gender=female" \
  --form "image=@input.jpg;type=image/jpeg"

cURL:换衣

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --form "type=clothing_change" \
  --form "style=chiheidiao" \
  --form "breast=zhongnai" \
  --form "image=@input.jpg;type=image/jpeg"

cURL:站内视频换脸模板

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --form "type=video_face_swap_template" \
  --form "template=YOUR_TEMPLATE_KEY" \
  --form "image=@face.jpg;type=image/jpeg"

cURL:视频脱衣(请先剪到 1–10 秒、不超过 30MB)

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --form "type=video_undress" \
  --form "body=moren" \
  --form "breast=moren" \
  --form "hair=shaomao" \
  --form "keep_shoes=1" \
  --form "video=@clip.mp4;type=video/mp4"

cURL:图生视频(使用本人文生图作品)

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --header "Content-Type: application/json" \
  --data '{"type":"image_to_video","prompt":"云朵缓慢移动,镜头平稳推进","source_task_code":"2026091209301234567"}'

cURL:图生视频模板

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --header "Content-Type: application/json" \
  --data '{"type":"image_to_video_template","template":"xianyilouru","source_task_code":"2026091209301234567"}'

cURL:长视频(固定组合,可改每段秒数)

curl --request POST "https://shanjierenyi-my.com/wp-json/site-api/v1/tasks" \
  --header "Authorization: Bearer $SITE_API_KEY" \
  --header "Idempotency-Key: $TASK_REQUEST_ID" \
  --header "Content-Type: application/json" \
  --data '{"type":"long_video","template":"classic_three","durations":[4,5,4],"source_task_code":"2026091209301234567"}'

Python:创建、轮询、下载完整流程

import os
import time
import uuid
import requests

BASE = "https://shanjierenyi-my.com/wp-json/site-api/v1"
HEADERS = {"Authorization": "Bearer " + os.environ["SITE_API_KEY"]}


def create_task(fields, files=None, request_id=None):
    """request_id 每个业务任务生成一次;重试时必须复用同一个。"""
    request_id = request_id or str(uuid.uuid4())
    headers = dict(HEADERS, **{"Idempotency-Key": request_id})
    for attempt in range(5):
        try:
            if files:
                r = requests.post(BASE + "/tasks", headers=headers, data=fields, files=files, timeout=120)
            else:
                r = requests.post(BASE + "/tasks", headers=headers, json=fields, timeout=60)
        except requests.RequestException:
            time.sleep(2 ** attempt)
            continue
        if r.status_code == 202:
            return r.json()["task_code"]
        if r.status_code in (409, 429, 503):
            time.sleep(int(r.headers.get("Retry-After", 2 ** attempt)))
            continue
        raise RuntimeError(r.status_code, r.json())
    raise RuntimeError("创建任务重试次数用尽,请稍后用同一 request_id 重试")


def wait_result(task_code):
    while True:
        r = requests.get(BASE + "/tasks/" + task_code, headers=HEADERS, timeout=30)
        if r.status_code == 429:
            time.sleep(int(r.headers.get("Retry-After", 60)))
            continue
        r.raise_for_status()
        data = r.json()
        if data["status"] == "succeeded":
            return data
        if data["status"] in ("failed", "cancelled"):
            raise RuntimeError(data["message"])
        time.sleep(8)


def download(data, path):
    if not data.get("result_url"):
        raise RuntimeError("结果已过期或已删除")
    with requests.get(data["result_url"], stream=True, timeout=300) as r:
        r.raise_for_status()
        with open(path, "wb") as f:
            for chunk in r.iter_content(1024 * 1024):
                f.write(chunk)


task_code = create_task({"type": "text_to_image", "prompt": "雨后山间的木屋,柔和晨光"})
result = wait_result(task_code)
download(result, task_code + ".jpg")

上传文件时把 files 传给 create_task,例如:create_task({"type": "image_edit", "prompt": "..."}, files={"image": ("input.jpg", open("input.jpg", "rb"), "image/jpeg")})。

查询任务与下载结果

GET /tasks/{task_code},携带 API 密钥。建议每 5–10 秒查询一次,收到 429 后按 Retry-After 退避。查询不收费。只能查询本账号通过 API 创建的任务。

{
  "task_code": "2026091209301234567",
  "status": "succeeded",
  "price": 10,
  "charged_amount": 10,
  "refund_status": "none",
  "message": "",
  "result_url": "<短期有效下载地址>",
  "result_expires_in": 600,
  "result_retention_days": 30,
  "created_at": "2026-09-12T01:30:12+00:00"
}
status含义处理
queued已受理、排队中。继续轮询。
processing执行中,或失败后自动重试、退款核对中(此时 refund_status 可能为 pending)。继续轮询。
succeeded成功。下载 result_url。
failed最终失败,金币已按创建时价格退回(charged_amount 为 0,refund_status 为 refunded)。终态;如需重做请用新的 Idempotency-Key 创建。
cancelled任务在排队阶段被账号本人在站内“我的作品”取消,金币已退回。终态。

result_url 有效期 10 分钟(result_expires_in 秒),过期后重新查询即可获得新地址。下载结果地址时不要附带 API 密钥。结果为图片时通常是 PNG/JPG,视频为 MP4;请以下载响应的 Content-Type 或文件扩展名为准。

结果从受理时间起保留 30 天(result_retention_days),请及时下载;过期或已删除的结果 result_url 为 null。已结束任务的输入素材在 7 天后清理;仍在执行或重试的任务保留素材。

查询账户

GET /account,携带 API 密钥。返回余额、当前开放的功能与价格、网站时区与日期、每日消费上限、今日已消费和剩余额度。查询不收费。

{
  "balance": 1000,
  "currency": "金币",
  "date": "YYYY-MM-DD",
  "timezone": "<网站时区>",
  "daily_limit": 500,
  "today_spent": 100,
  "daily_remaining": 400,
  "discount_percent": 100,
  "types": ["text_to_image", "text_to_image_face", "image_edit", "multi_image_edit", "image_undress", "clothing_change", "image_face_swap", "video_face_swap", "video_face_swap_template", "text_to_video", "image_to_video", "image_to_video_template", "long_video", "video_undress"],
  "prices": {"text_to_image:default": 10, "image_undress:default": 10, "text_to_video:480x832": 20},
  "pricing_notes": {"video_face_swap": "按视频时长阶梯计价……", "long_video": "按段计价……"},
  "options": {"image_undress": {"style": ["pingxiong", "xiaonai", "zhongnai", "danai", "chaoju"]}, "image_to_video_template": [{"template": "xianyilouru", "label": "掀衣露乳"}]}
}

prices 的键为 type:size,图片类功能的 size 固定为 default。按时长/段数/模板文件计价的类型只出现在 pricing_notes。discount_percent 为本账户折扣(100 表示尚未打折),prices 已是折后实际扣费;按公式计价的类型先按本站价格算出原价,再乘以折扣,四舍五入到整数金币,最低 1 金币。options 给出当前站点可用的 style / template / 长视频组合(含段数、默认秒数和每段最小秒数)。以上金额仅为示例。下表是本站页面价格;本接口返回的 prices 才是该账户的接口扣费,折扣请联系管理员商谈。账户接口不返回个人联系方式等资料。

本站价格与退款

下表是本站页面价格,不是接口结算价。普通用户在网页上做一次,按这个价格扣金币。想接接口的合作方不要按这个价格估算成本。接口价格请联系管理员谈具体消费折扣,量大管饱,用量越大可以谈得更低。开通后,账户实际扣费以 GET /account 返回的折后价格为准。

功能尺寸本站价格接口价格
文生图默认10 金币 / 次联系管理员
人脸融合(文生图)默认15 金币 / 次联系管理员
单图编辑默认10 金币 / 次联系管理员
双图编辑默认10 金币 / 次联系管理员
一键脱衣默认10 金币 / 次联系管理员
换衣默认8 金币 / 次联系管理员
图片换脸默认8 金币 / 次联系管理员
文生视频480x83220 金币 / 次联系管理员
文生视频704x128025 金币 / 次联系管理员
图生视频(自定义提示词)480x83220 金币 / 次联系管理员
图生视频(自定义提示词)704x128025 金币 / 次联系管理员
图生视频模板默认27 金币 / 次联系管理员
视频换脸(自定义视频)按时长按视频时长阶梯计价:前 60 秒每秒 0.6 金币,60–180 秒每秒 0.5 金币,180–250 秒每秒 0.38 金币,向上取整,最低 15 金币。例:30 秒 18 金币,60 秒 36 金币,120 秒 66 金币,250 秒 123 金币。时长由服务器读取。联系管理员
视频换脸(站内模板)按模板按站内模板发布时写入的价格扣费;未知模板直接拒绝,不会回退到默认价联系管理员
图生长视频按段按段计价:首段 27 金币,每多一段 +15;704x1280 每段再 +5;单段超过 4 秒后每多 1 秒 +1。段数与段落顺序由组合固定,单段 3–10 秒(一次性动作段最多 6 秒)。例:2 段各 4 秒 480x832 为 42 金币。联系管理员
视频脱衣按时长按视频时长计价:每秒 5 金币,按 0.1 秒精度四舍五入,最短 1 秒、最长 10 秒。例:1 秒 5 金币,5.9 秒 30 金币,10 秒 50 金币。时长由服务器读取。联系管理员

使用本站金币余额。任务受理时扣款,排队和执行中的任务计入当日 API 消费;查询任务与账户不收取金币。

最终失败或取消的任务按创建时的价格退回金币,并回退原扣款日的 API 消费额度。重试中的任务等待最终结果后结算。价格变动不影响已经受理的任务。

每日消费上限按网站时区自然日统计,只累计 API 消费;超出时创建请求返回 429 daily_limit_exceeded,次日自动恢复,需要调整请联系管理员。

请求限制

安全策略与自动停用

密钥只用于本文档列出的三个接口,以及上面表格里的字段。请只提交这些字段,只查询本账号通过 API 创建的 task_code。出现以下情况时,密钥会被立即停用,之后的请求返回 403 api_disabled,需要联系管理员才能恢复:

按文档接入不会触发这些规则。联调时先用少量请求确认参数,再批量提交。遇到 400 时先改正参数,不要用同一个错误请求反复重试。安全测试请先联系管理员,并使用管理员指定的测试账号。

错误处理

错误响应为 JSON,code 为稳定的机器可读错误码,message 为说明文字(可能调整,请勿用于程序判断)。

{"code":"invalid_api_key","message":"请提供有效 API 密钥","data":{"status":401}}
HTTPcode含义与处理
400unsupported_typetype 不存在或本站未开放;message 中列出可用类型。
400invalid_parameter包含不支持的字段、URL 带查询参数或参数类型错误。
400invalid_prompt / invalid_size / invalid_source提示词、尺寸或 source_task_code 不符合要求。
400invalid_uploads / invalid_upload / invalid_image / invalid_video文件数量或字段名不对、上传失败、图片或视频格式/尺寸/时长不合规。
400image_blocked该图片在本账号的脱衣/换衣黑名单中,请换一张图片。
400upload_not_allowed当前站点禁止上传外部素材,请改用本人文生图 source_task_code。
400idempotency_required / invalid_body缺少合法的 Idempotency-Key,或请求体为空(常见于超过服务器上传限制)。
401invalid_api_key密钥缺失或错误;确认是否已被管理员重置。
402insufficient_balance金币不足,请充值后用同一 Idempotency-Key 重试。
403api_disabled / https_required / invalid_download授权已停用、账号不可用或因异常请求被自动停用(见安全策略,需联系管理员);未使用 HTTPS;下载链接无效或过期。
404task_not_found / source_not_found / result_unavailable任务、源作品或结果不存在、不属于当前账号,或已过期删除。
409account_busy同账号另一个请求正在处理,稍后用原 Idempotency-Key 重试。
409idempotency_conflict同一编号对应的参数或文件发生了变化;为新任务换一个编号。
409account_deleting账号正在注销,不能创建任务。
413request_too_large / file_too_large / image_too_large请求或文件过大,请压缩后重试。
415unsupported_media_typeContent-Type 不是 multipart/form-data 或 application/json。
429rate_limited请求过于频繁,按 Retry-After 退避。
429daily_limit_exceeded今日 API 消费额度不足,等待新的一天或联系管理员调整上限。
503service_unavailable / storage_unavailable / storage_error 等服务暂时不可用。创建请求保留原 Idempotency-Key 重试,不会重复扣款;持续异常时联系管理员。

网络超时时无法确定请求是否已受理:请始终用同一 Idempotency-Key 重试创建,服务端会返回已存在的任务(replayed: true)或继续创建。