官方的 Adobe Firefly API 确实存在,难的不是调用它,而是先把它找出来。有三个名字总被混着用:Adobe Firefly Services 是平台,Adobe Firefly API 是你对接的那层 API,Adobe Firefly Image 5 是真正接单的模型。把这三层理清,剩下只有四步——拿凭证、换 token、发一条异步请求、轮询一次。

官方叫法到底是哪三个

Adobe 在自己的 guides 页面里把平台写得很清楚:Firefly Services includes Firefly APIs, Lightroom APIs, Photoshop APIs, and Content Tagging APIs. 搜索 adobe firefly api 落到的那一页,标题是 Adobe Firefly API - Firefly Services,开头一句是 The Adobe Firefly API makes it easy for you to integrate generative AI into your creative workflows.

平台底下那十个 API 的官方目录就在同一套文档里,凭证的名字也一并写死,叫 Firefly Services Client ID and Client Secret,属于平台级,不是某个模型的密钥。本文讲的是其中第一个 Firefly API

模型层的命名同样精确:The Image5 model is Firefly's latest model,带 native 4 MP resolution,另外还有 Instruct Edit——Adobe 的说法是用自然语言在同一个工作流里完成生成与修改。

官方 guides 页把平台下的 API 目录整份列了出来:Firefly APICreative Production APIExpress APILightroom APIPhotoshop APIAudio/Video APIInDesign APISubstance 3D APIIllustrator APIContent Tagging API。本文讲的是其中的 Firefly API,它内部再分三块:Custom Models、Composite Operations 与 Upscale。凭证的名字也一并写死,叫 Firefly Services Client ID and Client Secret,注意它是平台级凭证,不属于某一个模型。

有两处错误别写进工单和代码注释:这个 API 不叫 Adobe Firefly Services API,它的名字里也没有版本号。Adobe Firefly Image 主题总览页 承接了产品层之间的关系。

先拿凭证,再写代码

控制台里的管理员步骤

Adobe 把前提写得很直白:This tutorial assumes you have worked with your Adobe Representative and have the following: 一个 Developer Console 账号,以及 A project with Firefly API OAuth Server-to-Server credentials set up. 凭证页标着 [Admins only]:在控制台里搜 Adobe Firefly API,点 Create project,读出 client ID,再选 OAuth Server-to-Server 取得 client secret。如果看不到 Firefly API 的 product card,Adobe 给的指示是 Reach out to your Adobe liaison。官方还建议把 client ID 与 secret 交给需要接入的开发者,而不是共享 access token,因为 token 会过期。

用凭证换取 access token

Every request made to Firefly APIs must include an encrypted access token. token 在服务端向 Adobe Identity Management System(IMS)换取,用的就是上面这两个凭证。

# 需要 curl 与 jq。
export FIREFLY_CLIENT_ID=<your-client-id>
export FIREFLY_CLIENT_SECRET=<your-client-secret>

# 1. 用 Firefly Services 凭证换取 access token。
curl -s -X POST 'https://ims-na1.adobelogin.com/ims/token/v3' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials' \
  -d "client_id=${FIREFLY_CLIENT_ID}" \
  -d "client_secret=${FIREFLY_CLIENT_SECRET}" \
  -d 'scope=openid,AdobeID,session,additional_info,read_organizations,firefly_api,ff_apis' \
  | jq -r .access_token > firefly-token.txt

# 官方给出的响应形态:
# {"access_token":"yourExampleTokenAsdf123","token_type":"bearer","expires_in":86399}

Each access token is valid for 24 hours,所以常驻 worker 要做刷新,而不是启动时取一次就缓存到底。

发出第一条生成请求

异步已经是唯一路径。2025-10-03 Adobe 移除了废弃的非同步版本,原文是 Please use the async versions of these APIs instead:,涉及 v3 的生成、相似图、对象合成、扩图与填充五类端点。今天官方收录的异步接口是 Generate Image Async、Expand Image Async、Fill Image Async、Generate Object Composite Async 与 Generate Similar Images Async。还在写裸同步调用的教程已经过期。

# 2. 调用异步图像生成端点。
curl -X POST 'https://firefly-api.adobe.io/v3/images/generate-async' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H "x-api-key: ${FIREFLY_CLIENT_ID}" \
  -H "Authorization: Bearer $(cat firefly-token.txt)" \
  -d '{
    "prompt": "a red kite over wet sand at low tide, wide shot",
    "numVariations": 1,
    "size": { "width": 2688, "height": 1536 },
    "promptBiasingLocaleCode": "en-US",
    "contentClass": "photo"
  }'

异步不只是调用方式的差别,它决定你的代码怎么写。创建请求只负责排队,真正的结果与素材都要靠后面的 statusUrl 取回,所以客户端必须自己处理 job 的生命周期。官方对这三块能力的描述也很具体:Custom Models 用来 Train subject or style modelsGenerate images with a custom model,每个自定义模型都有独立的 asset ID 便于版本管理与复用;Composite 家族包含 Object Composite、Adaptive Composite 与 Precise Composite,官方称新的 ME 模型在物体边缘精度、光照真实度与场景上下文生成上明显强于旧的 MD 模型,开发方可以用 0–100% 的 harmonization strength 控制融合强度;Upscale 分 User Assets UpsamplerGenerated Image Upsampler 两类用途。

Image5 结构里该写哪些字段

路由信息都在请求头里,模型选择也上移到了这一层,官方原句是 Model selection is now at a higher level, in the header. 请求体里,numVariations 取代了旧的张数字段,contentClass 区分 photo 与 art,promptBiasingLocaleCode 钉住提示词语言,visualIntensity 调整结果强度,negativePrompt 用来去掉不想要的内容。modelSpecificPayload.prompt_reasonerqualityspeed,取 quality 时响应里会多出一个 altText 字段。

轮询任务直到结束

官方把异步流程拆成五拍:发请求、拿到带 URL 的 job ID、查询任务、成功后拿到含 URL 的结果、再把素材取回来。创建调用的响应里有 jobIdstatusUrlcancelUrl,形如 urn:ff:jobs:eso851211:86ffe2ea-d765-4bd3-b2fd-568ca8fc36acyou can use statusUrl and cancelUrl to get the latest status of your request or to cancel the request. 终态只有两个:succeededfailed

# 3. 轮询上一步返回的 statusUrl,直到任务落定。
STATUS_URL='https://firefly-api.adobe.io/v3/status/urn:ff:jobs:eso851211:86ffe2ea-d765-4bd3-b2fd-568ca8fc36ac'

while true; do
  body=$(curl -s "${STATUS_URL}" \
    -H "x-api-key: ${FIREFLY_CLIENT_ID}" \
    -H "Authorization: Bearer $(cat firefly-token.txt)")
  state=$(printf '%s' "$body" | jq -r .status)
  if [ "$state" = 'succeeded' ] || [ "$state" = 'failed' ]; then
    printf '%s' "$body" | jq .
    break
  fi
  sleep 5
done

Image5 是一次破坏性升级

The old and new schemas are not compatible, and migration requires rewriting the request payload. Adobe 把它定义为 a major version upgrade with non-backwards-compatible changes,并警告 Payloads that do not conform to the new schema will be rejected by the API. 其中几项删除没有直接替代品。

Adobe 官方展示的 Firefly Image 5 扩展示意:红色背景上一头身披花卉的鲸鱼与一名宇航员,光标箭头指向被扩展出的画面区域
Adobe
变更项旧结构新结构
出图张数nnumVariations
自定义模型modelIdcustomModelId——语义已变,不是直接改名
画面比例aspectRatio已删除——Only size is supported.
模型版本modelVersion已删除——No version selection in the API.
模型载荷modelSpecificPayload已删除
CAI 元数据output.cai已删除
存储输入output.storeInputs已删除
生成元数据generationMetadata已删除——不再由客户端提供
提示词推理modelSpecificPayload.prompt_reasoner

有个坑值得单独点出:这些变更只写在总览页与迁移指南里,changelog 中没有任何 Image5 条目,只盯 changelog 的团队会整段错过,而且旧结构不会报「字段已废弃」,是直接拒收。Firefly Image 5 上手指南 讲的是同一个模型在界面里的用法。

限流、存储与官方未公布的部分

限流按 organization 计:4 requests per minute (RPM)9,000 requests per day (RPD)。超限会返回 HTTP 429 Too Many Requests,官方建议 Implement retry logic via a retry-after HTTP header or an exponential backoff strategy. 提额要走你的 account manager。

官方另注明,日限 RPD 对已经把速率提到高于 4 RPM 的账号仍然适用,提额并不等于取消日限。

Image Model 5 端点 /v4/images/generate-async 允许五个存储域:amazonaws.comwindows.netdropboxusercontent.comstorage.googleapis.comfrontdoor.prod.azure.cxp.adobe.com。合成类操作要先用 /v2/storage/image 上传,响应返回 uploadId;Object Composite 的输入上限是 10MB。Upscale 支持 2×、4×、6×;2026-04-24 它由 beta 转 GA,且只是改名,creative_upsampler_v1 现在会返回 422,默认值变成 precise_upsampler_v1

有一个数字是故意留空的:API 每图单价官方未公布。Custom Models 的口径同样一分为二,一处是已经文档化的 API 能力,另一处是 waitlist 报名。作为对照,我们的 Recraft API 笔记 讲的是一个官方公布单张价格的厂商。

常见问题

Adobe Firefly API 是官方的吗? 是。文档在 developer.adobe.com 的 Adobe Firefly Services 之下,有 API Reference,也有 changelog。

我能自助开通账号吗? 文档里没有这条路。官方写明的前提是先与 Adobe 代表接洽,凭证页还标着 [Admins only]

一定要轮询吗? 是。异步流程没有同步拿结果的选项,创建请求只返回 job ID 与 statusUrl,必须查到 succeededfailed 才算结束。

代码该调哪个端点? POST https://firefly-api.adobe.io/v3/images/generate-async,然后轮询返回的 statusUrl。同步版本已在 2025-10-03 移除。

旧 payload 为什么被拒? Image5 改了结构:n 变成 numVariationsmodelId 变成 customModelIdaspectRatiomodelVersionoutput.cai 被删除。

通过 API 生成一张图要多少钱? 官方未公布。Adobe 公布的是限流,而不是单张价格。

把凭证当成第一个交付物,把 token 刷新放进 worker,动旧 payload 之前再读一遍迁移指南。第一次接入最常见的返工不是代码写错,而是凭证没到位、请求体用的还是 Image5 之前的结构。