APIMart 图片 URL 过期怎么办?3步检查任务、下载与转存
简答:APIMart 图片 URL 过期后,先用 task_id 查询任务是否完成,并检查接口是否返回新的 result URL 和 expires_at;只要链接仍能下载,就应立即保存到本地或对象存储。若任务已完成但没有新地址,不能把原 URL 恢复视为必然,应检查本地记录、浏览器下载记录和存储系统,再决定是否重新生成。已核验的 Seedream 5.0 Pro 教程写明结果链接有效期为 72 小时,但其他模型不能直接套用这一时限。
定义:图片 URL 过期,是指接口返回的临时图片地址超过服务端允许访问的时间;它不等于任务记录、task_id 或已经下载到本地的文件同时消失。
先看三步速查:结果 URL 过期后先做什么
本文是围绕 AI API 接入问题整理的第三方指南,不是 APIMart 官方页面。具体模型、字段、链接有效期和任务状态,请以当前模型文档、接口实际返回和控制台记录为准。
| 第几步 | 操作 | 判断标准 |
|---|---|---|
| 1 | 用 task_id 查询任务 | 确认是 completed、仍在处理中,还是 failed/cancelled |
| 2 | 检查 result、图片 URL 和 expires_at | 看接口是否仍返回可用的新地址,而不是只盯着浏览器里的旧链接 |
| 3 | 能够下载就立即转存 | 检查 HTTP 状态码、Content-Type 和文件内容,再保存到自己的存储 |
一句话结论:如果任务已经完成且接口仍提供可下载地址,马上下载;如果旧地址已失效且任务查询没有新地址,不要假设原 URL 可以恢复,先查本地文件、下载记录和对象存储,再根据任务参数评估是否重新生成。
截至 2026-11-03 的本次核验,Seedream 5.0 Pro 图像教程明确写出图片链接有效期为 72 小时,并在结果对象中提供 expires_at。这项时限属于该页面明确说明的模型资料,不能直接推断所有图片模型都使用相同有效期。
先分清:结果图片 URL 过期,还是参考图 URL 失效
结果图片 URL 过期发生在任务已经生成完成之后。接口通常先返回 task_id,再通过任务查询取得 result.images 和图片地址。此时真正需要保存的是图片文件,而不是只保存一个可能临时失效的 URL。
参考图 URL 失效发生在提交图像编辑任务时。它是服务端读取输入图片的问题,不代表生成结果地址已经过期。处理方法是从不带登录态的环境测试参考图地址,确认返回成功状态、图片类型和可读取内容,再按照所用模型的要求重新提交。
不同模型的输入限制不能混用。例如,FLUX.1 Kontext 模型页面明确说明参考图 URL 必须能够从公网直接访问,并采用提交任务后轮询的异步流程;Seedream 5.0 Pro 页面则说明 image_urls 可以使用公网 URL 或 Base64 Data URI。也就是说,参考图是否必须公网可访问、最多能传几张以及是否支持 Base64,都要按具体模型页面核对。
因此,看到图片打不开时,先确认你保存的是哪一种地址:如果是输入参考图,排查源文件的访问权限;如果是输出结果图,排查任务状态、expires_at 和是否已经完成转存。
Seedream 5.0 Pro 示例:查询任务并立即下载
下面的代码是Seedream 5.0 Pro 专用示例,不是所有 APIMart 图片模型的通用兼容承诺。当前可核验页面给出的提交地址为 https://api.apimart.ai/v1/images/generations,任务查询地址为 GET /v1/tasks/{task_id};运行前仍应核对当前模型文档、模型 ID 和响应结构。
最短处理流程是:提交请求取得 task_id;每隔一段时间查询任务;状态为 completed 时读取 data.result.images[0].url[0] 和 expires_at;下载成功后再写入自己的文件系统或对象存储。官方教程建议每 5–10 秒轮询一次,并在 completed、failed 或 cancelled 时停止。
import os
import time
from pathlib import Path
import requests
BASE_URL = "https://api.apimart.ai"
HEADERS = {
"Authorization": f"Bearer {os.environ['APIMART_API_KEY']}",
"Content-Type": "application/json",
}
created = requests.post(
f"{BASE_URL}/v1/images/generations",
headers=HEADERS,
json={
"model": "seedream-5-0-pro",
"prompt": "A clean product poster, studio lighting",
"resolution": "1.5K",
"size": "1:1",
"output_format": "png",
},
timeout=30,
)
created.raise_for_status()
task_id = created.json()["data"][0]["task_id"]
for _ in range(60):
r = requests.get(
f"{BASE_URL}/v1/tasks/{task_id}",
headers=HEADERS,
timeout=30,
)
r.raise_for_status()
task = r.json()["data"]
status = task.get("status")
if status == "completed":
image = task["result"]["images"][0]
image_url = image["url"][0]
expires_at = image.get("expires_at")
img = requests.get(image_url, timeout=60)
img.raise_for_status()
content_type = img.headers.get("content-type", "")
if not content_type.startswith("image/"):
raise RuntimeError(f"unexpected content type: {content_type}")
Path(f"{task_id}.png").write_bytes(img.content)
print({"task_id": task_id, "expires_at": expires_at})
break
if status in {"failed", "cancelled"}:
message = task.get("error", {}).get("message", status)
raise RuntimeError(message)
time.sleep(5)
else:
raise TimeoutError("polling deadline exceeded")这段代码的成功标准不是“拿到了 URL”,而是同时满足:提交响应中存在 task_id;任务变为 completed;结果对象存在;下载请求返回成功状态;响应内容类型是图片;文件已经写入自己的存储。示例只保存到本地,生产环境可在文件校验通过后调用自己的对象存储上传函数,例如 upload_to_object_storage(local_path, task_id)。这个函数是伪代码,具体 SDK、桶名和权限配置需要按你的存储服务自行实现。
API Key 应只从环境变量或密钥管理服务读取,不能放入浏览器前端、公开仓库或普通业务日志。APIMart 页面也明确建议在服务端调用并避免在客户端代码中暴露密钥。
已经过期还能找回吗?按这个顺序排查
- 先查任务记录:使用原来的
task_id查询,确认任务是否为completed,并检查result.images中是否出现新的 URL 或新的expires_at。 - 再查本地保存位置:检查应用数据库、任务队列、浏览器下载目录、临时文件目录和对象存储。假如图片曾经成功下载,原 URL 失效并不影响已经保存的文件。
- 判断是否只是网络或权限问题:用服务端请求测试当前 URL 的 HTTP 状态码、Content-Type 和响应体大小。如果返回的是 JSON 错误,不要把错误响应保存成图片。
- 没有新地址时停止无限重试:已核验教程要求在链接有效期内下载并转存,但没有提供通过旧 URL 通用恢复图片的接口。因此不能承诺过期后一定能重新签发;应以当前任务接口、模型文档或支持渠道的实际答复为准。
- 最后评估重新生成:重新生成前重新核对 API Key、模型 ID、请求参数、账户配额、权限和当前费用。任务可查询,不代表当前账号一定拥有再次调用的权限。
如果任务仍是 submitted 或 processing,不要因为暂时没有图片 URL 就重复提交。按照当前模型页面的轮询建议继续查询,直到进入终态或达到你设置的最大等待时间。
对于批量任务,建议把流程设计为“完成事件→下载→校验→转存→记录”。数据库至少保存 task_id、模型 ID、图片序号、提交时间、expires_at、下载状态、HTTP 状态码和最终存储位置,并使用 task_id + image_index 作为幂等键,避免轮询重试产生重复文件。
保存流程的安全边界与核验清单
- 不要把 URL 当永久文件:只保存 URL 无法替代下载。能下载时应尽快写入自己的存储,并保存任务 ID 和过期时间。
- 不要套用统一时限:Seedream 5.0 Pro 教程明确写出 72 小时;FLUX.1 Kontext 页面也显示图片链接有效期为 72 小时,但其他模型仍需逐页核对,未核实的模型不要直接套用。
- 不要混淆输入和输出:参考图 URL 失效要检查源文件访问条件;结果图 URL 失效要检查任务结果和保存流程。
- 下载后校验文件:至少检查 HTTP 状态码、Content-Type 和文件大小;对重要素材还应验证图片是否能被图像库正常解析。
- 设置明确停止条件:轮询应有最大次数或截止时间。认证失败、参数错误、权限错误、任务失败和下载过期,不应全部使用同一种无限重试策略。
- 动态信息以当前页面为准:模型 ID、字段、价格、限速、失败处理和有效期都可能按模型或接口版本变化,本文只引用本次核验到的页面资料。
如果你只记住一个操作:任务变为 completed 后,立即读取结果对象并下载文件;如果已经过期,则回到 task_id、本地记录和存储系统逐项核查,不要只反复刷新旧链接。
常见问题
APIMart 图片 URL 过期后,可以直接通过原链接恢复吗?
不能把恢复视为必然结果。先用 task_id 查询任务,检查是否返回新的结果地址;如果没有新地址,再检查本地下载记录、浏览器文件、应用缓存和对象存储。当前已核验教程说明的是在有效期内下载并转存,没有提供通过旧 URL 通用恢复图片的接口。
APIMart 所有图片链接都是 72 小时过期吗?
不能一概而论。本次核验到的 Seedream 5.0 Pro 教程明确写出 72 小时,FLUX.1 Kontext 页面也显示图片链接有效期为 72 小时;其他模型应查看对应模型页面、接口返回的 expires_at 或实际下载结果,未核实前不要套用相同时间。
task_id 还在,但图片 URL 已经打不开,应该马上重新生成吗?
不建议马上重新生成。先确认 status 是否为 completed,再检查 result.images 是否有新的 URL;如果任务仍在处理中,继续轮询。如果已完成且没有可用新地址,再检查自己的存储和下载记录,最后根据当前模型权限、参数和费用评估是否重新提交。
参考图 URL 失效和结果图片 URL 过期有什么区别?
参考图 URL 是提交编辑任务时让服务端读取的输入地址,失效会影响任务处理;结果图片 URL 是生成完成后用于下载输出的地址,过期主要影响结果保存。两者分别检查输入图可访问性,以及 task_id、result 和 expires_at。
批量生成怎样避免图片链接过期后丢失?
不要让前端页面承担保存任务。让服务端 Worker 在任务完成后立即下载,检查 HTTP 状态码、Content-Type 和文件内容,校验通过后转存到自己的文件系统或对象存储,并记录 task_id、expires_at、下载状态和最终文件位置;同时用 task_id 加图片序号去重。
相关阅读
- 先看 APIMart 图片生成 API 的完整调用流程
- 任务完成但结果为空时的响应字段排查
- 轮询或下载超时时的 API 排查步骤
- 服务端配置 API Key,避免密钥暴露
- 重新生成前核对模型 ID 和接口类型
参考资料
- 如何使用 Seedream 5.0 Pro 生成图像|APIMart(apimart.ai)
- FLUX.1 Kontext API:AI 图像编辑|APIMart