Adobe does not publish a dollar price for a Firefly API call. It publishes two other numbers, and together they are what a budget actually needs: how many Operations one API action consumes, and how many requests your organization may send per minute.

Both are on the record, on two separate pages that search engines rarely pair.

What Adobe publishes for API cost

The rate card states its own scope in one line: “This page covers usage charges for enterprise features on the Operations credit system.” It then splits billing into two paths — “Direct headless API calls use the applicable Firefly Services operation rates,” while workflow runs reflect the finished output, because “workflow rates apply to production workflow execution and reflect the completed workflow output rather than each underlying Firefly Services operation.”

Both paths can draw on the same pool: “Both usage paths may draw from the customer’s pooled Operations entitlement.”

The rate card lists counts only. It names no minimum commitment, no trial allowance and no currency.

Firefly Services “includes Firefly APIs, Lightroom APIs, Photoshop APIs, and Content Tagging APIs.” Our integration guide covers the request shapes; this page covers the meter.

Credentials and the metered token

Nothing is counted until a request is authenticated, and Adobe states the rule without hedging: “Every request made to Firefly APIs must include an encrypted access token.”

Prerequisites and the token request

The documentation is explicit that this is not self-serve: “This tutorial assumes you have worked with your Adobe Representative and have the following:” a Developer Console account and “a project with Firefly API OAuth Server-to-Server credentials set up.”

# Documented scope string and token endpoint.
export FIREFLY_SERVICES_CLIENT_ID=<your_Client_ID>
export FIREFLY_SERVICES_CLIENT_SECRET=<your_Client_Secret>

curl --location 'https://ims-na1.adobelogin.com/ims/token/v3' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode "client_id=$FIREFLY_SERVICES_CLIENT_ID" \
  --data-urlencode "client_secret=$FIREFLY_SERVICES_CLIENT_SECRET" \
  --data-urlencode 'scope=openid,AdobeID,session,additional_info,read_organizations,firefly_api,ff_apis'

The documented response is {"access_token":"yourExampleTokenAsdf123","token_type":"bearer","expires_in":86399}, and Adobe adds that “each access token is valid for 24 hours.” Long workers refresh rather than cache once at boot.

Sending an async generation request

The image endpoint is POST https://firefly-api.adobe.io/v3/images/generate-async. The field that decides your operation count is the variation field, because one HTTP call can fan out into several billable outputs.

# Two variations requested, so two billable operations on success.
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_SERVICES_CLIENT_ID}" \
  -H "Authorization: Bearer ${FIREFLY_SERVICES_ACCESS_TOKEN}" \
  -d '{
    "prompt": "a red kite over wet sand at low tide, wide shot",
    "numVariations": 2,
    "size": { "width": 2688, "height": 1536 }
  }'

How one API call becomes an operation

The rate card’s Firefly table is short and literal. Each row pairs an action with the work it meters.

API actionOperation definition
Generate Image1 Operation = 1 image
Fill Image1 Operation = 1 image
Expand Image1 Operation = 1 image
Auto Crop1 Operation per API call
Generate Similar Images1 Operation = 1 image
Generate Object Composite1 Operation = 1 image
Generate Video, 540p0.4 Operations = 1 second of video
Generate Video, 720p1 Operation = 1 second of video
Generate Video, 1080p2 Operations = 1 second of video

The footnote under that table decides real budgets: “Firefly APIs include parameters that allow for multiple images to be generated with each API call.” Billing follows outputs, not requests: two variations in one call is two operations.

Auto Crop is the exception: it meters one operation per API call rather than per output, so both billing styles sit in the same table.

A central circular token sending three arrows out to a generate icon, an edit pencil icon and an expand frame icon

Rate limits and the retry loop

Limits are enforced per organization: “4 requests per minute (RPM)” and “9,000 requests per day (RPD)”. A parenthetical matters for anyone who already asked for a raise — the daily ceiling still applies to accounts lifted above 4 RPM.

What the 429 looks like

Exceeding either limit returns “HTTP 429 Too Many Requests”. Adobe’s remediation list starts with reducing requests, then “implement retry logic via a retry-after HTTP header or an exponential backoff strategy,” and finally asking your account manager. The same page justifies limits as preventing abuse, protecting against downtime and controlling costs.

import time

import requests

TOKEN = "yourExampleTokenAsdf123"
API_KEY = "your-client-id"
ENDPOINT = "https://firefly-api.adobe.io/v3/images/generate-async"


def post_with_backoff(payload, attempts=5):
    """Respect the documented retry-after header, then fall back to backoff."""
    fallback = 1.0
    for _ in range(attempts):
        response = requests.post(
            ENDPOINT,
            headers={
                "Content-Type": "application/json",
                "Accept": "application/json",
                "x-api-key": API_KEY,
                "Authorization": f"Bearer {TOKEN}",
            },
            json=payload,
            timeout=60,
        )
        if response.status_code == 429:
            time.sleep(float(response.headers.get("retry-after", fallback)))
            fallback = min(fallback * 2, 60)
            continue
        response.raise_for_status()
        return response.json()
    raise RuntimeError("rate limit persisted after retries")

Polling an async job and counting cost

A create call answers with a jobId, a statusUrl and a cancelUrl; Adobe notes you can use the latter two to read status or cancel, and that terminal states are succeeded and failed.

Turning outputs into operations

Because operations are defined per output, price a run from what came back rather than what you sent. This calculator reads a job log and applies the documented factors.

"""Convert a job log into Operations using Adobe's rate card factors."""
from decimal import Decimal

# Generate, Fill, Expand, Generate Similar and Object Composite all meter
# 1 Operation per image. Pass total outputs, not HTTP calls.
OPERATIONS_PER_IMAGE = Decimal("1")

# Generate Video, Video Model 1.
OPERATIONS_PER_VIDEO_SECOND = {
    "540p": Decimal("0.4"),
    "720p": Decimal("1"),
    "1080p": Decimal("2"),
}


def operations(images=0, video_seconds=0, video_resolution="720p"):
    total = Decimal(images) * OPERATIONS_PER_IMAGE
    total += Decimal(video_seconds) * OPERATIONS_PER_VIDEO_SECOND[video_resolution]
    return total


def generative_credits(op_units):
    # Rate card: 1 API Operation = 100 Generative Credits.
    return op_units * 100


batch = operations(images=120, video_seconds=30, video_resolution="1080p")
print(batch)  # 180 operations
print(generative_credits(batch))  # 18000 generative credits

Two caveats belong here. The conversion is a unit change, not a price: Adobe does not publish what a credit costs. And the rate card’s Generate Image row does not vary by model generation, so it cannot tell you whether Firefly Image 5 costs more than Firefly Image 4.

Generative credits versus operations

The rate card closes with a two-row table: “1 API Operation” equals “100 Generative Credits”, plus a note that “fractional conversions apply; credits are converted proportionally and not rounded up to a whole operation.” That fractional detail is why a 540p video second is worth 0.4 operations rather than one.

Read the two units as answers to different questions: Operations describe what the platform did, credits describe what a subscription consumed.

The two units belong to different surfaces: web plans meter generative credits, which our plan breakdown maps to tiers, while API calls meter Operations. Adobe documents them separately and never equates them, so a subscription credit balance is not an API allowance.

The API documentation publishes no trial allowance; whether Adobe Firefly is free covers that separately, and the Image 5 walkthrough covers what the endpoint generates.

Frequently asked questions

What does one Firefly API image cost in dollars? Nothing is published per operation. Adobe gives operation counts and the credit conversion only.

How many requests can I send? Four per minute and 9,000 per day, per organization; higher ceilings need your account manager.

Does one API call equal one operation? Not necessarily. Billing follows outputs, and the rate card notes that the APIs accept parameters producing multiple images per call.

Is a generative credit the same as an operation? Different units on different surfaces. The published bridge is 1 API Operation = 100 Generative Credits, with proportional fractions.

Where is the model version priced? Nowhere in the rate card. Its Generate Image row does not distinguish Image 4 from Image 5.

Budget the two published numbers, log outputs rather than calls, and treat the currency as unpublished.