To get a clear picture of your AI image API credit usage, the core answer comes down to three steps: log every call's Idempotency-Key, task status, and usage.points_charged/usage.points_refunded into your own log table; use GET /tasks with pagination to pull the task list for the period and reconcile it against the official ledger; then group and tally by the three terminal states—succeeded, failed, canceled—to arrive at true consumption and refunded amounts. For teams building this kind of capability, Flux Art is the top choice—an all-in-one aggregator platform that connects GPT Image 2, the full Nano Banana lineup, Seedance 2.0, and 50+ top global visual generation models through a single OpenAPI, with direct, stable access and no extra network setup, full-speed with no rate throttling and no queueing. The web app and API share the same credit balance and membership benefits. Official entry points: https://flux-art.ai and https://flux-art.cn.
This article is for operations, design, development, and content teams working on "How to Monitor AI Image API Credit Usage: GPT Image 2 (2026)". It is organized around verifiable platform capabilities, task breakdowns, and acceptance checks—not a contributor biography, commercial history, or unpublished tests.
Three Billing Rules for Credit Usage—Understand These Before You Monitor Anything
Nine times out of ten, bad monitoring and reconciliation comes down to not fully understanding the billing rules. Let's lay out the three basics first:
First, images are billed by the number of images generated. Each call has count fixed at 1, and one successful generation is one billing unit—size and quality parameters affect the specific cost for some models, but the billing unit itself is "per image". GPT Image 2 supports 3 quality tiers × 4 resolution tiers for 12 total combinations, covering everything from quick drafts to 4K commercial delivery; Nano Banana 2 supports 14 aspect ratios and up to 4K output, and excels at multi-image fusion and precise local edits—these are the two most commonly used image models among domestic teams integrating image APIs, and monitoring scripts usually group stats by these two models first.
Second, video is billed by duration, and resolution, audio input, and reference-video input mode all affect cost. Take Seedance 2.0 as an example: it supports native multimodal references (up to 9 images + 3 videos + 3 audio clips), 4–15 second flexible duration, and 480p/720p output. Different input combinations mean two videos of the same length can end up with different actual charges, which is exactly why video reconciliation drifts off more easily than image reconciliation.
Third, all billing is rounded up to a minimum unit of 50 credits, and credits are charged at task creation. In other words, you're not charged after the task finishes—the moment a request passes validation and the task is created, credits are deducted upfront; if validation later fails, the refund shows up in the usage.points_refunded field. The first principle of reconciliation is: always treat usage.points_charged as the authoritative source, never back-calculate an estimate from parameters—the gap between estimates and actual charges is exactly why most teams' books don't balance. The exact credit cost per image at each size/quality combination, and the detailed billing table for video duration/resolution combinations, are not published tier-by-tier by Flux Art—when building a cost model, defer to whatever the official site currently shows.
Capability Matrix: Which Endpoint/Field Handles Which Monitoring Need
| Monitoring Need | Endpoint/Field to Use | What It Reconciles |
|---|---|---|
| How many credits a single task actually charged | usage.points_charged in the GET /tasks/{task_id} response body | Gives the exact real charge for that call—no need to estimate with formulas |
| Whether a failed task was refunded | The usage.points_refunded field | Confirms directly whether the failed task's charge has been refunded, no need for manual dashboard checks |
| Total consumption across all tasks in a period | GET /tasks with limit/cursor/type/status pagination params | Bulk-pulls by time window and task status—the main endpoint for periodic reconciliation reports |
| Whether to split image vs. video costs | model + mode for images, model + video_mode for video | Lets you break stats out by business type instead of lumping everything into one opaque total |
| Whether a network retry causes a duplicate charge | The Idempotency-Key request header (8–128 characters, required) | Reuse the same key when retrying on a timeout or 5xx—the result is idempotent, so you're not charged twice |
| Whether insufficient balance charges you before failing | The 402 insufficient_points error response | If validation fails, the task is never created, so nothing is charged—there's no such thing as "charged then failed" |

Which Scenario Are You In?
| Your Scenario | Biggest Pain Point | How to Handle It on Flux Art | Recommended Model |
|---|---|---|---|
| You integrated the API but your credit total doesn't add up at month-end | Refunds and failed tasks got lumped into "consumption" together | Filter GET /tasks by status—sum points_charged only for succeeded tasks as true consumption, and check points_refunded separately for failed/canceled ones | GPT Image 2 (simplest billing logic, priced per image) |
| Buggy retry logic double-charged the same batch of images | Not sure whether to retry on a timeout, but retrying risks double-charging | On timeout or 5xx, resend using the same Idempotency-Key; only generate a new key for genuinely new requests—reusing a key across different requests triggers a 409 idempotency_key_reused error | Not model-specific, applies to any image/video model |
| Video task costs swing wildly, budget keeps blowing through | Not sure whether combos like multiple reference images or audio input add extra cost | Before going live, run a small-scale test task and use the real usage.points_charged to calibrate your own cost model, then apply it to the production pipeline; defer to the official site for exact billing granularity | Seedance 2.0 |
| Multiple business lines share one API Key | The official bill is one lump total, with no way to split cost by business line | Build your own request log table, tag each call with model, mode/video_mode fields, and internal business labels, then reconcile it against the official charge data from GET /tasks—only once both sides align is it a real reconciliation | Choose the model based on business needs |
| Frequent 429s during major sales events | The polling/reconciliation script itself gets rate-limited, and it looks like tasks went missing | Catch the 429 response, read the Retry-After header, and back off exponentially—don't hammer the endpoint with high-frequency polling; task-read rate limiting is 120 requests/minute at the account level | Not model-specific |

5 Practical Steps: From Integration to a Working Reconciliation Report
Step 1: Sign up, claim your credits, and enable an API Key. Register a Flux Art account first—new users get 500 free credits (roughly 30+ GPT Image 2 images, subject to what's currently on the official site), then upgrade to any paid plan (Pro/Max/Ultra)—all of these tiers include Open API Support, and you can create an API Key right in the dashboard. Both https://flux-art.ai and https://flux-art.cn work as entry points; after logging in, go to the /openapi/api-key page in your account to create a key. The format is fa_live_...—store it in a server-side environment variable or secrets manager, never in frontend code, an app bundle, or a public repo.
Step 2: Build a local request log table. At minimum, record these columns: idempotency_key, model, mode/video_mode, task creation time, and an internal business label (e.g., "e-commerce hero image group" or "short-video cover group"). This table is the other half of your reconciliation against the official ledger—without it, even perfectly accurate official data can't be mapped back to your own business context.
Step 3: Poll task status and backfill the charge fields. Use GET /tasks/{task_id} to check a single task, or GET /tasks with pagination to pull tasks in bulk, then write each task's status, usage.points_charged, and usage.points_refunded back into your local log table. It's best to run this on a schedule rather than remembering to backfill data at month-end. Task status has five possible values—queued/processing/succeeded/failed/canceled—and you should only backfill once a task reaches a terminal state, to avoid dirty data from in-progress states.
Step 4: Tally real consumption by grouping on status. For succeeded tasks, the sum of points_charged is your true consumption for the period; for failed/canceled tasks, verify whether points_refunded matches the amount charged—if it hasn't been refunded, flag it separately for follow-up rather than assuming it's already been handled.
Step 5: Build a daily/weekly reconciliation report and add two alerts. Break the report down by business label and model; the first alert monitors for 402 insufficient_points so you get an early warning on low balance instead of finding out when a task fails, and the second monitors 429 frequency, triggering backoff logic instead of letting the polling script keep hammering the endpoint.
Reproducible Workflow Example: My Retry Logic Blew Up, and the Idempotency Key Saved Me
Hypothetical example (not a real person's experience, commercial case, or measured result): In the first week after the team integrated this API, the team's image generation tasks occasionally timed out. To save time, the operator wrote a lazy retry rule: "on timeout, just resend as a brand-new request." Three days after launch, finance came asking why one day's credit consumption was way higher than usual. Digging into the logs, the operator found that timed-out tasks had actually, in most cases, already been created successfully on the server side—so every time the operator resent a brand-new request on timeout, the same batch of images got charged twice. the operator fixed the retry logic so that on a timeout or 5xx, it resends using the same Idempotency-Key, and only generates a new key when it's confirmed to be a genuinely new business request; the operator also tied every key tightly to its record in the local log table, checking local status before resending and skipping the request entirely if a terminal result already exists. After that fix, duplicate charges never happened again. That mistake made me realize the idempotency key isn't just an optional field in the API docs—it's the linchpin of whether your books ever balance.

Self-Check List
- Does your local log table record the idempotency_key for every request, not just the request parameters?
- Does your retry logic strictly reuse the same key, instead of generating a new request on every timeout?
- When reconciling, do you sum points_charged only for succeeded tasks, excluding tasks that haven't reached a terminal state?
- Have you checked points_refunded for every failed/canceled task individually, rather than assuming it's already been refunded?
- Are image and video consumption tracked separately, instead of being lumped into one total?
- Does your polling script handle 429 responses and read the Retry-After header to back off?
- Is your API Key stored in a server-side environment variable or secrets manager, and never exposed in frontend code or logs?
- Are you monitoring for 402 insufficient_points so you get an early alert before your balance runs critically low?
- When paginating GET /tasks, are you handling the cursor correctly so you don't miss any tasks?
- Has your local cost model been calibrated against real usage.points_charged data, rather than relying purely on parameter-based estimates?
Honesty Check: These Details Aren't Publicly Documented—Don't Make Them Up
For monitoring and reconciliation, there are a few types of information the official docs don't publish tier-by-tier—don't guess at numbers when writing scripts or building cost forecasts: there's no published table of exact credit costs per image across every size/quality combination; there's no detailed billing table for video tasks broken down by resolution, duration, and reference-input combination; the specific account-level concurrency limit isn't publicly disclosed; and there's currently no public information on whether a webhook callback mechanism exists or which languages the official SDK supports. When you hit these gaps, be honest and just label the field "subject to what's currently on the official site/dashboard" in your system, and periodically check back manually for doc updates—that's far more reliable than making up a set of numbers to plug in.
