Model Costs¶
Non Xumi Models¶
Image Generation¶
| Model Name | Version | Supported Features | Comments |
|---|---|---|---|
| GPT Image | gpt-image-1 | In/out token-based: Yes Hard coded rates: Yes Silent 0.0 costs: Yes | The token-based approach only activates for exactly 'gpt-image-1' model. The token-based pricing silently produces $0 when the API response lacks a usage field (defaulting both token counts to 0). |
| DALL-E | 2 | Static pricing table keyed by quality, size and model name | The lookup table quality mapping ("hd" vs "standard") doesn't align with the GPT-image-1 quality options (low/medium/high/auto), meaning if a non-gpt-image-1 model somehow received those quality values, it would always resolve to "standard" pricing |
| DALL-E | 3 (Default) | - | - |
| Image Fake | - | Cost value = $0.0 (constant value) | Skipped |
| Gemini | 2.5 Flash (Default) | Fixed price based on the model name | A flat per-image fixed price based on the model name |
| Gemini | 3 Pro | - | - |
| Gemini | 3.1 Flash | - | - |
| Kling | 2.5 Turbo | Inline const value = $0.10 No tokensIn / tokensOut | It is a hardcoded constant — $0.10 per image, every time, unconditionally. There is no function, no switch, no lookup — just a constant value with a comment acknowledging it's a placeholder. |
| Seedream (BytePlus) | 4.5 | hardcoded zero — $0.00 every time | Usage data is available but ignored. |
| Seedream (BytePlus) | 5.0 Lite | - | - |
Video Generation¶
| Model Name | Version | Supported Features | Comments |
|---|---|---|---|
| Google Veo | 3 | Static pricing table keyed by model, duration, quality, and videos count | The workflow function is missing all Veo 3.1 pricing entries, dramatically underpricing it. |
| Google Veo | 3.1 | - | - |
| Kling AI | 2.5 Turbo | Fixed price based on the mode (pro/std) and video duration multiplier | Mode is hardcoded to 'pro' in the workflow, standard mode and pricing is unreachable due to this. |
| Kling AI | 3 | - | - |
| Seedance (BytePlus) | 1.5 Pro | hardcoded zero — $0.00 every time | No comment, no TODO, no formula - just a bare zero. |
Xumi Models¶
Cost is a pass-through from the child workflow. If the child returns a cost field, it is used. If not, it defaults to 0.
| Image (xumi) | Video (xumi) | |
|---|---|---|
| Current models available | qwen-image-edit:1.0.0 | wan2.1-vace-image2video:2.0.1 |
| Output mapping for cost | None needed — raw pass-through | Missing from xumiConfig.output |
| mapOutputParameters called? | No | Yes — strips everything not explicitly listed |
| Cost value | From child workflow result, or 0 | Always 0 (never propagated) |
| Is it an issue? | No | Yes — child workflow cost is silently dropped |
GPT Image Cost Calculation¶
There are two cost calculation approaches, selected based on the model version:
const cost = model === 'gpt-image-1'
? calculateGptImageCostByTokens(result.usage?.input_tokens || 0, result.usage?.output_tokens || 0)
: calculateGptImageCost(size || '1024x1024', quality || 'auto');
Token-based Cost Calculation, i.e. calculateGptImageCostByTokens() function uses the usage object from the OpenAI API response:
| Property | Rate | Per-token cost |
|---|---|---|
| result.usage.input_tokens | $10.00 / 1M tokens | $0.00001 |
| result.usage.output_tokens | $40.00 / 1M tokens | $0.00004 |
Formula:
totalCost = (input_tokens × 0.00001) + (output_tokens × 0.00004)
- The result is rounded to 6 decimal places via parseFloat(toFixed(6)).
- If result.usage is missing, both token counts default to 0, yielding a cost of $0.
DALL-E Cost Calculation¶
The cost is computed based on the lookup-table.
calculateGptImageCost() function uses a static pricing table keyed by quality and size:
Lookup-table for DALL-E 3
| Quality | 1024x1024 | 1024x1792 | 1792x1024 |
|---|---|---|---|
| standard | $0.040 | $0.080 | $0.080 |
| hd | $0.080 | $0.120 | $0.120 |
Lookup-table for DALL-E 2
| Quality | 1024x1024 | 512x512 | 256x256 |
|---|---|---|---|
| default | $0.02 | $0.018 | $0.016 |
Fallbacks:
- Unknown model → warns and returns $0.04
- Known model but unknown size → warns and returns the model's 1024x1024 price, or $0.04
What is still NOT considered
- Style (vivid vs natural) — DALL-E 3 style has no pricing difference, which is correct per OpenAI's published pricing
- tokensIn / tokensOut — not populated, same as all other providers
- Actual API billing data — the OpenAI response object is never inspected for usage metadata; cost is computed purely from the input parameters
- The comment says "as of 2024" — these prices may be stale if OpenAI has updated its pricing since then
Summary
- DALL-E has the most rigorous cost calculation — a proper function with a structured pricing table, dual-axis lookup (model × size), quality adjustment for DALL-E 3 HD, and graceful fallbacks with warnings. It is still entirely hardcoded estimates rather than actuals from the API.
Gemini Cost Calculation¶
The cost is computed in geminiImageActivity.ts immediately after a successful image is extracted from the API response:
It uses a flat per-image fixed price based on the model name:
| Model | Cost per image |
|---|---|
| gemini-2.5-flash-image | $0.0025 |
| gemini-3-pro-image | $0.015 |
| any other / unknown | $0.0025 (defaults to Flash pricing) |
The result is formatted with parseFloat(...toFixed(6)) to avoid floating-point noise.
The cost calculation is simplified — it does not factor in:
- Token usage (tokensIn / tokensOut) — the GenerateImageResult type has these fields but the activity never populates them for Gemini (they remain undefined)
- Resolution (1k, 2k, 4k) — same flat price regardless of output quality
- Number of reference images in the request — cost is always for a single output image
- Action type (generate vs edit) — same price for both
- Actual API usage data from the response — the response object is never inspected for billing/usage metadata
Summary
- Cost is a static lookup table value — a hardcoded flat fee per generated image based solely on model name.
- It does not reflect actual token consumption, resolution, or any dynamic pricing signals from the Google API response.
Kling Cost Calculation¶
klingImageActivity.ts, after polling confirms the task succeeded and before returning the result:
// Calculate estimated cost (placeholder - adjust based on actual Kling pricing)
const estimatedCost = 0.10; // Estimated cost per image
It is a hardcoded constant — $0.10 per image, every time, unconditionally. There is no function, no switch, no lookup — just a permanent number with a comment acknowledging it's a placeholder.
What is NOT considered (same as Gemini)
- Action type (txt2img vs img2img) — same price for both
- Aspect ratio — no pricing difference
- Actual API billing data — the finalResult response is never inspected for usage/cost metadata
- tokensIn / tokensOut — GenerateImageResult has these fields but Kling never sets them
Summary
Kling's cost is even cruder than Gemini's — a single hardcoded $0.10 with no per-model branching and an explicit comment that it needs to be replaced with actual Kling pricing data.
Seedream Cost Calculation¶
Cost is calculated in byteplusImageActivity.ts after a successful response is parsed and before returning:
The calculation
It is a hardcoded zero — $0.00 every time, with a TODO comment explicitly acknowledging it is not implemented. Notable detail — usage data is available but ignored
The API response is logged and even passed through to metadata.parameters, yet is never used for cost:
log.info('✅ BytePlus image generation successful', {
...
usage: parsed.usage // ← usage data IS received from the API
});
// but cost = 0 regardless
parsed.usage is passed into metadata.parameters.usage in the returned result, so the raw data is preserved — it just is never translated into a cost figure.
Summary
BytePlus has the least complete cost tracking of the three — cost is always reported as $0, even though the API response likely contains a usage field that could inform real pricing. The TODO comment and the fact that parsed.usage is already being captured in the log/metadata suggest this was intentionally deferred.
Google Veo Cost Calculation (Video)¶
Two separate calculateVeoCost functions exist
This is the most notable finding — there are two independent implementations of calculateVeoCost, one in the activity and one in the workflow, with different signatures and different model pricing tables.
Function 1 — veoVideoActivity.ts (activity-level)¶
Signature: calculateVeoCost(model, duration, quality) — no videoCount
Used only for: the fake/test Veo model path (veo-3-fake).
Model pricing table:
| Model match | Base cost/second |
|---|---|
| veo-3.1-generate-preview / includes veo-3.1-generate | $0.15 |
| veo-3.1-fast-generate-preview / includes veo-3.1-fast | $0.10 |
| veo-3.0-generate-preview / veo-3.0-generate-001 | $0.12 |
| veo-3.0-fast-generate-preview / veo-3.0-fast-generate-001 | $0.08 |
| anything else | $0.06 |
Function 2 — videoGeneration.ts (workflow-level)¶
Signature: calculateVeoCost(model, duration, quality, videoCount = 1) — adds videoCount
Used for: all real Veo generation in the workflow, after polling confirms the operation
is completed:
const cost = calculateVeoCost(modelConfig.model_id, videoDuration, videoQuality,operationResult.videos.length);
Model pricing table:
| Model match | Base cost/second |
|---|---|
| model.startsWith('veo-3.0-generate') | $0.12 |
| model.startsWith('veo-3.0-fast') | $0.08 |
| anything else (incl. Veo 3.1) | $0.06 |
Both functions apply the same quality multiplier after the base rate:
| Metric | draft | standard | high | ultra | unknown/missing |
|---|---|---|---|---|---|
| Multiplier | × 0.5 | × 1.0 | × 1.5 | × 2.0 | × 1.0 |
Formula:
totalCost = duration (seconds) × baseCostPerSecond × qualityMultiplier × videoCount
Example: 8-second Veo 3.0 Premium at high quality, 2 videos = 8 × 0.12 × 1.5 × 2 = $2.88
Key problems
- Duplicate, divergent functions — the workflow function is missing all Veo 3.1 pricing entries. Any real Veo 3.1 generation falls through to the $0.06 catch-all, dramatically underpricing it (should be $0.15 or $0.10 per the activity version).
- The activity function is only used by the fake model — the more accurate and up-to-date pricing (with Veo 3.1 tiers) only runs in the test/fake path, never in production.
- estimatedTokens: 1000 is hardcoded in both the activity and workflow metadata — a placeholder never connected to any real token accounting.
- No API billing data used — the Vertex AI operation result is never inspected for actual cost/usage metadata; cost is computed purely from input parameters.
Kling Cost Calculation (Video)¶
Cost is calculated in klingVideoActivity.ts, inline after the polling loop confirms the task succeeded:
// Calculate estimated cost based on Kling pricing (adjust as needed)
const baseCost = mode === 'pro' ? 1.00 : 0.50; // Pro mode costs more
const durationMultiplier = duration / 5; // Base cost for 5 seconds
const estimatedCost = baseCost * durationMultiplier;
Formula
estimatedCost = baseCost × duration / 5
It is an inline 2-variable calculation — no separate function, no lookup table:
Base cost by mode:
| Mode | Base cost (for 5s) |
|---|---|
| pro | $1.00 |
| std | $0.50 |
Duration scaling:
| Duration | Multiplier | std cost | pro cost |
|---|---|---|---|
| 5s | × 1.0 | $0.50 | $1.00 |
| 10s | × 2.0 | $1.00 | $2.00 |
Critical mismatch: mode is hardcoded to 'pro' in the workflow
The activity supports both 'std' and 'pro' modes, but the workflow always passes mode: 'pro' at videoGeneration.ts:
const klingGenerationResult = await generateKlingVideo({
...
mode: 'pro', // ← hardcoded, std branch in cost calculation is unreachable
...
});
This means in practice the cost will always be $1.00 (5s) or \(2.00 (10s), and the std pricing branch (\)0.50 / $1.00) is dead code.
Summary
- Kling video is the only provider where the cost formula has more than one branch but one branch is structurally unreachable due to the workflow hardcoding mode: 'pro'. The formula itself is more meaningful than the image providers' flat constants — it scales with duration — but like all others it remains a hardcoded estimate with no data from the API response.
Seedance Cost Calculation (Video)¶
Cost is a zero number constant in seedanceVideoActivity.ts, inline in the success return, with no calculation whatsoever:
The calculation
There is none. $0.00, always, unconditionally. Unlike BytePlus image which at least has a // TODO comment, Seedance video has no acknowledgement that this is a placeholder at all.
How the workflow handles it
The workflow at videoGeneration.ts passes seedanceResult.cost through directly with no recalculation or override:
There is no workflow-level calculateSeedanceCost() equivalent of what Veo does — the zero from the activity flows straight through to WorkflowMetrics, logWorkflowMetrics, sendWorkflowMetrics, and the final result.
Summary
Seedance video has the least complete cost tracking of all providers — a silent $0.00 with no formula, no comment, no TODO, and no recalculation at the workflow level. The API response's polling result (getParsed) is never inspected for billing data either, even though the BytePlus/Seedance API likely returns usage information in the task status response.