CostBreakdown
Per-job cost itemization, additive to the authoritative executionCost scalar on Job. Assembled at read time by CostBreakdownAssembler (backend app/services/cost_breakdown_assembler_service.ts) from worker cost telemetry plus the backend's external_api_call_logs and execution_histories tables. Source of truth for the shape: backend lib/cost_breakdown_types.ts.
Reconciliation: itemized bricks[].cost_eur are non-cumulative own-contributions; container (compute) bricks have detail bricks' costs subtracted back out so that Σ bricks.cost_eur === executionCost holds without double counting (when status: "complete"). When the residual exceeds €0.0001 but stays within €0.01 a platform residue brick is appended; beyond €0.01 the bricks are still served but status becomes partial.
AVAILABILITY: the assembler is always invoked by the job-show handler, so the field is present on every GET /jobs/{job_id} response, but its status reflects the job state — pending (job in flight) and unavailable (pre-rollout job with no telemetry) carry an empty bricks[]. Consumers should fall back to the executionCost total in those cases. (LDS additionally treats pending/unavailable as null; see lds/lib/platform/jobs.ts.)
Lifecycle of the breakdown. complete: bricks reconcile within tolerance. partial: a failed job, or reconciliation delta exceeded €0.01 — bricks still served, delta reported. pending: job not yet terminal — empty bricks[]. unavailable: no worker cost telemetry (e.g. a pre-rollout job) — empty bricks[].
Possible values: [complete, partial, pending, unavailable]
Wire schema version for the breakdown payload (currently always 1).
1executionCost - Σ bricks.cost_eur, computed BEFORE any platform residue brick is appended, so consumers can audit the assembly arithmetic regardless of status. Rounded to 4 decimals.
bricks object[]required
Flat list of cost contributions. The tree is reconstructed by resolving parent_brick_id against id within this same response (ids are stable only inside one payload).
Deterministic brick id (brick_<sha1-prefix>), stable only within a single response payload.
brick_a1b2c3d4e5f6Brick category, used by consumers to group/colour the display.
Possible values: [llm, compute, connector, dataset, platform]
Workflow node this cost is attributed to (e.g. deepAgent-4, mcpServer-7), or platform for synthetic/residue attribution.
null for a root brick; otherwise the id of the enclosing brick within this response. compute container bricks are typically roots; llm/connector/dataset detail bricks point at their node's compute container.
This brick's own EUR contribution, rounded to 4 decimals. Container bricks are reduced as detail bricks attribute portions back, so the flat sum equals executionCost.
units object
Category-specific detail, intentionally open-ended on the wire (Record<string, unknown>) so new categories can extend it without a schema bump. Observed shapes by category:
llm:{ model, input_tokens, output_tokens, call_count }compute:{ node_type }(container)connector:{ connector_id, endpoint_id, billed_units, call_count, unit_price_cents, billed_units_unknown }dataset:{ dataset_id, access_count, unit_price_eur, proxy_paths[] }platform:{}(reconciliation residue)
llm: the model id.
llm: summed prompt tokens.
llm: summed completion tokens.
llm/connector: number of underlying calls aggregated into this brick.
compute: the workflow node type.
connector.
connector.
connector: total billed units.
connector: price per unit in cents.
connector: true when unit price was 0/unknown.
dataset.
dataset: number of accesses.
dataset: per-access price in EUR.
dataset: distinct proxy paths accessed.
Category-specific detail, intentionally open-ended on the wire (Record<string, unknown>) so new categories can extend it without a schema bump. Observed shapes by category:
llm:{ model, input_tokens, output_tokens, call_count }compute:{ node_type }(container)connector:{ connector_id, endpoint_id, billed_units, call_count, unit_price_cents, billed_units_unknown }dataset:{ dataset_id, access_count, unit_price_eur, proxy_paths[] }platform:{}(reconciliation residue)
{
"status": "complete",
"schema_version": 1,
"reconciliation_delta_eur": 0,
"bricks": [
{
"id": "brick_a1b2c3d4e5f6",
"category": "llm",
"node_id": "string",
"parent_brick_id": "string",
"cost_eur": 0,
"units": {
"model": "string",
"input_tokens": 0,
"output_tokens": 0,
"call_count": 0,
"node_type": "string",
"connector_id": 0,
"endpoint_id": 0,
"billed_units": 0,
"unit_price_cents": 0,
"billed_units_unknown": true,
"dataset_id": 0,
"access_count": 0,
"unit_price_eur": 0,
"proxy_paths": [
"string"
]
}
}
]
}