API Documentation External

Dalinea API

v1.0.0 External

Unified API for the Dalinea platform. All endpoints require a valid JWT bearer token. Tenant isolation is enforced via the x-tenant-id header extracted from the token.

Getting Started

Welcome to the Dalinea API. This guide covers the basics of making requests and understanding responses.

Base URL

All API requests are made to:

https://api.kloopify.com

Request Format

The API accepts JSON request bodies and returns JSON responses. Set the following headers on every request:

Content-Type: application/json
Authorization: Bearer <your-token>

Response Format

Successful responses return a 2xx status code with a JSON body. Error responses include a message describing the issue:

{
  "statusCode": 400,
  "message": "Validation failed",
  "error": "Bad Request"
}

Pagination

List endpoints support pagination via offset and limit query parameters:

Parameter Default Description
offset 0 Number of records to skip
limit 100 Number of records to return (max 100)

Rate Limiting

API requests are rate-limited per account. If you exceed the limit, you'll receive a 429 Too Many Requests response. Back off and retry after the duration indicated in the Retry-After header.

Authentication

The Dalinea API uses JWT Bearer tokens for authentication. Every request must include a valid token in the Authorization header.

Obtaining a Token

Tokens are issued by our identity provider. Authenticate with your credentials to receive an access token:

POST https://auth.kloopify.com/oauth/token
Content-Type: application/json

{
  "client_id": "<your-client-id>",
  "client_secret": "<your-client-secret>",
  "audience": "https://api.kloopify.com",
  "grant_type": "client_credentials"
}

The response includes an access_token and its expiry:

{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 86400
}

Using the Token

Include the token in the Authorization header of every API request:

Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

Token Expiry

Tokens expire after the duration specified in expires_in (in seconds). When a token expires, the API returns 401 Unauthorized. Request a new token and retry.

Scopes

Access is controlled by scopes embedded in the token. If your token lacks the required scope for an endpoint, the API returns 403 Forbidden.

Running a Cost Analysis

This guide walks through submitting a cost analysis job, tracking its progress, and retrieving the results.

Overview

A cost analysis is an asynchronous operation. You submit a request describing a product and its manufacturer, the system processes it in the background, and you poll for the result. Once complete, the result contains IDs you can use to fetch the full cost analysis, bill of materials, product, and manufacturer records.

Step 1: Submit the Job

Create a cost analysis by posting to the pipeline endpoint:

POST /pipeline/cost-analysis
Content-Type: application/json
Authorization: Bearer <your-token>
{
  "productName": "EcoBottle 500ml",
  "manufacturerName": "GreenPack Industries",
  "countryOfOrigin": "DE",
  "productContext": "Reusable water bottle made from recycled stainless steel",
  "pricesPaid": [
    { "price": 1250, "currency": "USD", "date": "2025-01-15" }
  ]
}

The only required fields are productName and manufacturerName. Providing additional context improves the accuracy of the analysis:

Field Type Description
productName string Required. Name of the product
manufacturerName string Required. Name of the manufacturer
supplierNames string[] Supplier name(s)
productWebsite string URL for the product page
manufacturerWebsite string URL for the manufacturer
productContext string Free-text description of the product
manufacturerContext string Free-text description of the manufacturer
supplierContext string Free-text description of the supplier(s)
purchaserContext string Context about the purchaser
countryOfOrigin string ISO country code (defaults to US)
pricesPaid object[] Historical prices — each with price (number, required), currency (string, required), and date (string, optional)

The response is 201 Created with a job object:

{
  "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "type": "cost-analysis",
  "status": "pending",
  "step": null,
  "result": null,
  "started": null,
  "completed": null
}

Save the id — you'll use it to check on the job.

Step 2: Poll for Completion

Check the status of your job by its ID:

GET /pipeline/cost-analysis/{id}
Authorization: Bearer <your-token>

The status field progresses through these values:

Status Meaning
pending Job is queued
in_progress Job is actively processing
completed Job finished successfully
failed Job encountered an error

Poll every 5–10 seconds until status is completed or failed. The step field provides a human-readable description of what the system is currently working on.

When the job completes, the response includes a result object with IDs for all generated records:

{
  "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "type": "cost-analysis",
  "status": "completed",
  "step": "done",
  "result": {
    "costAnalysisId": "ca-uuid-here",
    "bomId": "bom-uuid-here",
    "productId": "product-uuid-here",
    "manufacturerId": "manufacturer-uuid-here"
  },
  "started": "2025-06-01T12:00:00.000Z",
  "completed": "2025-06-01T12:01:30.000Z"
}

If the job fails, errorMessage describes what went wrong.

Step 3: Retrieve the Results

Use the IDs from the result to fetch the generated records.

Cost Analysis

GET /cost-analysis/{costAnalysisId}
Authorization: Bearer <your-token>

Returns the cost analysis record including the shouldCostAmount and shouldCostStdErr (both in minor currency units, e.g. cents), the currency, and the analysisDate.

Bill of Materials

GET /bom/{bomId}
Authorization: Bearer <your-token>

Returns the bill of materials with a components list. Each component includes its name, type, cost, quantity, unitType, and countryOfOrigin.

To retrieve the full component details separately:

GET /bom/{bomId}/components
Authorization: Bearer <your-token>

Product and Manufacturer

The productId and manufacturerId can be used to retrieve the product and manufacturer (company) records:

GET /product/{productId}
GET /company/{manufacturerId}

Error Handling

  • 404 Not Found — The job or record ID does not exist.
  • 401 Unauthorized — Token is missing or expired. See the Authentication guide.
  • status: "failed" — The job did not complete. Check errorMessage on the job for details and resubmit if appropriate.

Bill of Materials

Retrieve bills of materials and their component breakdowns.

GET /bom/{id}

Get bom by ID

Parameters

NameInTypeRequiredDescription
id path string<uuid> required
related query string[] optional Include related entities. Omit for all, "false" for none, or specify field names (repeatable, supports dot notation)

Responses

200
200 Response
FieldTypeDescription
data BomDto
id* string Unique identifier for the bill of materials record
versionLabel* string Per-lineage version label (MAJOR.MINOR), e.g., `v1.0`. MAJOR bumps on structural change (new AI generation, scenario fork, scenario promotion); MINOR bumps on revision (DLN-151). Assigned by the orchestrator at write time based on the most-recent prior BOM in the same `(productId, scenarioId)` lineage.
sourceType* string How this BOM came to exist. `ai_generation` is the initial BOM produced by the AI Step 3 Create-path (DLN-135). `ai_revision` is a diff applied by DLN-151. `import` is loaded from an external source. `human` is manually created. `scenario_fork` branches off an actual BOM into a scenario lineage (DLN-159). `scenario_promotion` is a scenario BOM promoted into actual lineage (DLN-280). The vocabulary is system-owned and small, so an enum constraint is appropriate (contrast `BOM_COMPONENT.type`, which is relaxed to allow orthogonal flag semantics).
enum: ai_generation, ai_revision, import, human, scenario_fork, scenario_promotion
scenarioId string Lineage discriminator. NULL signals the actual lineage; a non-NULL UUID identifies a scenario lineage. The Scenario entity is introduced by DLN-159; until then this is a plain UUID column (`scenario_id`) with no FK constraint. DLN-135 always writes NULL.
promotedFromBomId string When `sourceType = scenario_promotion`, the scenario BOM that was promoted into actual lineage. NULL otherwise. Plain UUID column (`promoted_from_bom_id`) with no FK constraint — same convention as `priorBomId` and the legacy `parentBomId`. Populated by DLN-280.
generationDate* string Date and time when the BOM was generated
status string Status of the BOM generation process (e.g., "pending", "completed", "failed")
enum: pending, completed, failed
components BomComponentDto[] List of components and their costs that make up the product - accepts array of full objects, id strings, or id numbers
id* string Unique identifier for the BOM component
priorBomComponentId string Optional predecessor BOM_COMPONENT row in the same temporal lineage. Set by revision flows (DLN-151) when this component evolved from a prior version. NULL for components on a newly generated BOM. Stored as a plain UUID column (`prior_bom_component_id`) with no FK constraint — same convention as `productId` / the existing `parentBomId` on BOM. Lineage integrity is enforced at the application layer.
bom any The parent BOM - accepts full object, id string, or id number
name* string Name of the component in the bill of materials
type* string Materiality classification for the component. One of: `sub-assembly` (has a populated `product` object and multi-entry `materials[]`), `direct-material` (raw input consumed into the finished product; no `product` object), `indirect-material` (packaging, consumable, or waste; paired with exactly one of `isPackaging` / `isConsumable` / `isWaste` set to true). Type and the `isPackaging`/`isConsumable`/`isWaste`/`isByproduct` flags are orthogonal axes: type answers materiality, flags answer cost treatment. DLN-286: enum-enforced at schema + DTO. The cost-analysis job normalizes the legacy value (`raw material`) before write on both create and revision paths; existing rows with non-canonical values stay readable (the DB CHECK add is warn-only via cruddy_constraint_warnings) but must be normalized before update.
enum: sub-assembly, direct-material, indirect-material
classification string DLN-286 (FR-R1): refresh classification — how the Data Refresh prices this node and (Phase 2) whether it recurses. Derived by the cost-analysis job from `type` + `makeVsBuy` and persisted: direct/indirect-material → `commodity`; sub-assembly + MAKE → `manufactured-sub-assembly`; sub-assembly + BUY/UNKNOWN/absent → `bought-sub-assembly` (conservative default — UNKNOWN never opts a node into recursion). A stored value is never overwritten by re-derivation.
enum: commodity, manufactured-sub-assembly, bought-sub-assembly
catalogEntityId string FK to CATALOG_COMMODITY.id or CATALOG_SUB_ASSEMBLY.id (see catalogEntityType). Plain uuid, not a validated schema relation — deferred-FK convention (matches rateSnapshotId on COST_ANALYSIS_COMPONENT_DRIVER): the two catalog tables are a discriminated union, so no single relation target applies. Set by the refresh pipeline (DLN-289) on first successful identity-match; reused on subsequent refreshes so a component never re-resolves identity every run.
catalogEntityType string Which catalog table catalogEntityId points into, when set.
enum: catalog-commodity, catalog-sub-assembly
cost* number Cost of the component in minor currency units (e.g., cents)
quantity* number Quantity of the component used in the product
unitType* string Unit of measurement for the component (e.g., piece, kilogram, liter)
estimatedGramsPerUnit number Estimated grams of this component per unit.
estimatedCostPerUnit number Estimated cost in minor currency units (e.g., cents) of this component per unit.
estimatedCostPerUnitStdErr number Approximation of the standard error of the estimated cost in minor currency units (e.g., cents) of this component per unit.
referenceCostPerUnit number DLN-377: universal list / spot / OEM reference price per unit, in minor currency units (cents) — the undiscounted commodity price BOM creation produces. The auditable baseline; never overwritten by downstream adjustments.
supplierCostPerUnit number DLN-377: the price this manufacturer/supplier actually faces per unit, in minor currency units (cents). Equals referenceCostPerUnit until a supplier-specific pricing mechanism computes it (factor-1 default).
supplierDiscountFactor number Scale-based discount factor applied to referenceCostPerUnit to produce supplierCostPerUnit (0 < factor <= 1; 1 = no discount). Computed by the supplier purchasing-power step from the buyer's annual commodity / category spend through a capped, saturating curve. Null when no discount has been computed.
supplierDiscountBasis string Spend basis behind the factor: commodity_scale for raw materials (buyer's spend on the commodity itself), supplier_leverage for bought whole units (buyer's spend on the part category; lower ceiling — only margin and conversion are negotiable).
enum: commodity_scale, supplier_leverage
supplierDiscountSource string Provenance of the financials scale signal the factor was derived from, from filed statements down to structural proxies.
enum: edgar_financials, reported_financials, ai_estimate, employees_proxy, supplier_tier, naics_default
supplierDiscountConfidence string Confidence in the discount, combining the scale-signal quality and the commodity-share source (AI-estimated shares cap at medium).
enum: high, medium, low
countryOfOrigin string Country where the component is most likely manufactured (two digit ISO country code, e.g., US, CN).
makeVsBuy string Whether the product's manufacturer makes this component in-house (`MAKE`) or buys it from an upstream supplier (`BUY`). `UNKNOWN` when it cannot be determined — do not guess. Classification only: this is an explicit, auditable input signal and drives no cost adjustment here. The implicit default mapping is sub-assembly→`BUY`, direct-material→`MAKE`; orthogonal to `type`.
enum: MAKE, BUY, UNKNOWN
buyDetails any Upstream-sourcing detail for `BUY` components. Omit for `MAKE`/`UNKNOWN`. The supplier here is who the part is purchased from, which is distinct from the sub-assembly `product.manufacturer` (who made it) even when they coincide.
beaCode string BEA IO commodity code identifying what this component is, as a commodity — the lookup key into the BEA×NAICS composition matrix (bea_composition dataset). Chosen from the controlled bea_commodities vocabulary at BOM generation and enforced against it before persistence: a code outside the vocabulary is nulled with beaUnmappedReason set. Null means unmapped; downstream composition lookups fall back to estimates. Sub-assemblies carry the commodity category of the purchased article, not their dominant raw material.
beaConfidence string Model-reported confidence in the beaCode mapping. Null when the component is unmapped.
enum: high, medium, low
beaUnmappedReason string Why beaCode is null — either the model found no vocabulary entry that covers the component, or a proposed code was rejected as outside the vocabulary. Null when beaCode is set.
isPackaging boolean Indicates if the component is packaging material used to contain, protect, or present the finished product (e.g., cartons, labels, shrink wrap). Packaging contributes to Indirect Materials with a positive cost.
isWaste boolean Indicates if the component is scrap or non-valuable residue generated during production that must be disposed of. Waste has its own cost category (positive price and cost). If a byproduct would require payment to dispose of, classify it as waste, not a byproduct.
isConsumable boolean Indicates if the component is an indirect process consumable used during manufacturing that does not end up in the final product (e.g., sterilization agents, cleaning solvents, process gases, water). Consumables contribute to Indirect Materials with a positive cost.
isByproduct boolean Indicates if the component is a valuable co-product of the manufacturing process that generates revenue or offsets cost (e.g., a chemical intermediate sold to another industry). Byproducts carry a positive price but a negative cost representing the credit received. They subtract from Direct Materials. If the component instead requires payment to dispose of, classify it as isWaste, not isByproduct.
sources string[] List of URIs to sources or references for the component information. This can be spec sheets, manufacturer websites, datasheets, etc.
confidence any Detailed confidence information about various aspects of the component data
justification string Explanation of the reasoning behind all of the mappings made in this component (e.g., sources, justification for assumptions, confidence, etc.). Keep this to less than 5000 characters. Can also include other considerations about this product.
materials RawMaterialEntryDto[] Estimated raw materials that make up this component. In the case that this component is just a single @raw-material-entry, this is just the one raw material itself in the array. In the case of a sub-assembly, this is the list of @raw-material-entries that make up the sub-assembly. - accepts array of full objects, id strings, or id numbers
productId string Optional reference to PRODUCT when this component represents a known sub-product. Cross-service reference — Cruddy does not emit a FK constraint (DLN-168 forbids cross-service FKs). Populated by recursive sub-product resolution (DLN-154); NULL otherwise.
product any Information about the @product if the component is a sub-assembly. If the component is a raw material, this can be omitted. If the product is a sub-assembly, but the manufacturer of the sub-assembly is unknown or the sub-assembly is a commodity, you can leave the manufacturer as GENERIC.
refQtyValue number Reference quantity of output product this BOM represents. Examples: 1 for finished goods (paired with `refQtyUnit: "piece"`); 1, 100, 1000 for chemicals/commodities (paired with `refQtyUnit: "kilogram"` or similar). Per-component `cost`/`quantity` values are calibrated against this reference batch.
refQtyUnit string Unit of measurement for `refQtyValue` (e.g., `kilogram`, `piece`, `liter`).
assumptions string[] Critical assumptions about process, material grade, formulation, yield, or other factors that influenced the BOM composition and component costs. Examples: assumed reaction route, catalyst choice, solvent grade, food-grade vs industrial-grade materials, assembly method, raw material form factor.
processParams any Manufacturing process classification for cost modeling. Used to apply yield, compliance, and setup adjustments in cost analysis.
productId string ID of the product this BOM was generated for. Enables direct querying of all BOMs for a given product.
priorBomId string Predecessor BOM in the same `(productId, scenarioId)` lineage. NULL on the first BOM in a lineage; set on every successor (generation, revision, scenario fork, scenario promotion). Establishes per-lineage chaining. Plain UUID column (`prior_bom_id`) with no FK constraint — same convention as the legacy `parentBomId` field this replaces.
revisionDiff object The structured diff that was applied to the parent BOM to produce this revision. Stored for auditability and lineage tracking. Contains operations (modify/add/remove), updatedAssumptions, and a summary of changes. Stored as opaque JSON.
meta object
404 Not found

Company

Look up company profiles and related information.

GET /company/{id}

Get company by ID

Parameters

NameInTypeRequiredDescription
id path string<uuid> required
related query string[] optional Include related entities. Omit for all, "false" for none, or specify field names (repeatable, supports dot notation)

Responses

200
200 Response
FieldTypeDescription
data CompanyDto
id string Unique identifier for the company record
name* string Legal or commonly known name of the company
nameNormalized string Deterministic normalization of `name` used for per-tenant deduplication (lowercase + trim + collapse-whitespace + strip-punctuation + strip common corporate suffixes + Unicode NFKC). Service-computed on write; not client-supplied. Indexed per-tenant by a partial unique index installed at service bootstrap. See DLN-133.
accountId string FK to the account that owns this company record. When null, the company is considered a public/shared record.
legalStructure string Legal entity type (e.g., LLC, Inc, GmbH, Pty Ltd)
identifiers object Official business registration identifiers as key-value pairs. Keys are identifier types (e.g., ein, vat, duns, crn) and values are the corresponding registration numbers.
country string Country of incorporation (ISO 3166-1 alpha-2 code, e.g., US, CA, GB, DE)
naicsIndustries string[] Two-digit NAICS sector codes describing the company's primary industries
naics string[] Six-digit NAICS codes describing the company's specific lines of business
founded string Date the company was founded or incorporated
domains string[] Company domain names (e.g., google.com, abc.xyz)
website string Primary corporate website URL
status string Current operational status of the company
enum: active, dissolved, merged, acquired
headquarters any Primary headquarters address - accepts full object, id string, or id number
employees number Approximate total number of employees
aliases string[] Alternative or former names the company is known by (e.g., trade names, DBAs, previous names)
logos LogosDto[] Company logos, past and present, with usage dates
logo* string URI to the logo image file (full GCS path)
status string Whether this logo is currently in use
enum: active, inactive
description string Label or context for this logo (e.g., primary, icon, wordmark)
start_date string Date this logo started being used
end_date string Date this logo stopped being used, if inactive
socials SocialsDto[] Social media profiles associated with the company
type* string Social media platform (e.g., linkedin, twitter, facebook)
url string Full URL to the company's profile on this platform
username string Company's username or handle on this platform
addresses AddressesDto[] Additional company locations beyond the headquarters (e.g., offices, branches, factories)
type* string Location type (e.g., office, branch, factory, warehouse)
address* any Physical address of this location - accepts full object, id string, or id number
ticker string Stock ticker symbol for a publicly-traded company (e.g., AAPL, BRK.A). Used to resolve the company's SEC CIK for EDGAR financial-statement lookups.
cik string SEC Central Index Key, 10-digit zero-padded. Populated on first successful EDGAR resolution for a US public filer.
financials CompanyFinancialsDto[] Annual financial snapshots (revenue, COGS, SGA components) for this company, one per fiscal year. Sourced from EDGAR filings or operator entry. See DLN-73. - accepts array of full objects, id strings, or id numbers
id string Unique identifier for the financials record
company any The parent company this snapshot describes - accepts full object, id string, or id number
fiscalYear* number Fiscal year covered by this snapshot
periodStart* string Start date of the reporting period (e.g., 2024-01-01)
periodEnd* string End date of the reporting period. Used by the cross-taxonomy validity guard to reject stale observations where values lag revenue's period by more than ~1 year.
statementType* string Filing type the snapshot was extracted from, or "manual" when entered by an operator.
enum: 10-K, 20-F, manual
currency* string ISO 4217 currency code (e.g., USD, JPY) for all numeric amounts in this row. Values are stored as-reported in this currency.
revenue* number Annual revenue, as reported in the filing, in units of `currency`.
cogs* number Annual cost of goods sold, as reported in the filing, in units of `currency`.
salesAndMarketing number Sales & Marketing expense component of "our SGA" (sum of S&M + G&A + R&D, deliberately excluding non-operational items). Nullable when the filer does not break it out.
generalAndAdministrative number General & Administrative expense component of "our SGA". Nullable when the filer does not break it out.
researchAndDevelopment number Research & Development expense component of "our SGA". Nullable when the filer does not break it out.
filingDate string SEC filing/accepted date of the underlying 10-K or 20-F. Drives the 300-day EDGAR refresh check. Null for manual rows.
accessionNumber string EDGAR accession number (e.g., 0000008670-24-000011) that sourced this row, for audit and per-run traceability. Null for manual rows.
retrievedAt string Timestamp at which this row was written (EDGAR fetch or manual entry).
lastCheckedAt string Last time EDGAR was probed for this row. Combined with a 30-day negative-cache window to prevent thrashing when filingDate has passed the 300-day fresh window but no newer filing exists.
source* string Provenance of this row. Only "edgar" and "manual" rows are persisted. LLM fallback responses are never persisted (returned directly to caller with source="llm" in the response envelope).
enum: edgar, manual
enteredBy string Operator who entered this row. Required when source="manual"; null for "edgar".
reason string Operator-supplied justification for a manual entry (e.g., "EDGAR extraction failed; numbers from investor presentation"). Required when source="manual".
commodityDiscounts CompanyCommodityDiscountDto[] Cached supplier purchasing-power discount factors for this company, one per (commodityCategory, fiscalYear). Written by the cost-analysis supplier-power step; a reusable derived value, recomputed when the underlying financials change. - accepts array of full objects, id strings, or id numbers
id string Unique identifier for the cached factor row
company any The company whose purchasing power the factor describes - accepts full object, id string, or id number
commodityCategory* string Commodity the factor applies to — the BEA IO commodity code carried on the discounted BOM components (the composition-matrix lookup key).
fiscalYear* number Fiscal year of the financials the factor was derived from.
factor* number Discount factor (0 < factor <= 1; 1 = no discount) applied to a reference price to produce the supplier-facing price.
basis* string Spend basis the factor was computed on.
enum: commodity_scale, supplier_leverage
source* string Provenance of the financials scale signal.
enum: edgar_financials, reported_financials, ai_estimate, employees_proxy, supplier_tier, naics_default
confidence* string Confidence in the factor.
enum: high, medium, low
spendUsd number The annual spend estimate (USD) that produced the factor, kept for auditability of the curve input.
computedAt string When the factor was last computed.
metadata object Additional metadata about the company as key-value pairs
meta object
404 Not found

Product

Look up product profiles and related information.

GET /product/{id}

Get product by ID

Parameters

NameInTypeRequiredDescription
id path string<uuid> required
related query string[] optional Include related entities. Omit for all, "false" for none, or specify field names (repeatable, supports dot notation)

Responses

200
200 Response
FieldTypeDescription
data ProductDto1
id* string Unique identifier for the product
name* string Name of the product
description string Detailed description of the product
retailPrice number Approximate, current price of the product, in minor currency units (e.g., cents)
retailPriceCurrency string Currency code for the retail price (e.g., USD, EUR)
unitType string Unit of measurement for the @product (e.g., piece, kilogram, liter)
enum: piece, kilogram, gram, liter, milliliter, meter, foot, square meter, square foot, cubic meter, gallon, pound, ounce, ton, sheet, roll, barrel, board foot
status string Lifecycle status of the product
enum: in development, active, end-of-life
commoditized boolean Indicates if the product is classified as a commodity - very little differentiation between competitors
rawMaterial boolean Indicates if the product is considered a raw material used in manufacturing or production (e.g., steel, plastic, lumber)
parentProductId string FK to the parent @product, if applicable
categoryId string FK to the @product-category that classifies the product
countryOfOrigin string Country where the product is manufactured (ISO 3166 alpha-2 code, e.g., US, CN)
weightGrams number Product weight in grams
leadTimeDays number Typical lead time in days
minimumOrderQuantity number Minimum order quantity
metadata object Additional account-specific metadata about the product
identifiers any Various identifiers associated with the product
urls any Various URLs associated with the product
meta object
404 Not found

Pipeline

Submit asynchronous analysis jobs such as cost-analysis pipelines.

POST /pipeline/cost-analysis

Submit a cost analysis pipeline request

Parameters

NameInTypeRequiredDescription
x-firebase-uid header string optional Gateway-set Firebase UID of the calling user (Langfuse user attribution). Server-injected — clients never supply it; the gateway strips inbound copies.

Request Body

CostAnalysisRequestDto
FieldTypeDescription
id string Unique identifier for the pipeline request.
caVersion string The version of cost analysis generation process to use.
bomVersion string The version of bill of materials to use.
productName string Name of the product. Required for a normal run; for an iteration (previousAnalysisId set) it is derived from the prior run, so it may be omitted (DLN-197/ADR 0073). A new_analysis run (feedbackId without previousAnalysisId, DLN-196) is a normal run, so it must supply this.
manufacturerName string Name of the manufacturer. Required for a normal run; for an iteration (previousAnalysisId set) it is derived from the prior run, so it may be omitted (DLN-197/ADR 0073). A new_analysis run (feedbackId without previousAnalysisId, DLN-196) must supply this.
productId string ID of an existing product entity. When provided along with manufacturerId, skips AI company/product resolution and uses the existing entities.
manufacturerId string ID of an existing manufacturer entity. When provided along with productId, skips AI company/product resolution and uses the existing entities.
supplierNames string[] Supplier name(s). Each entry is resolved via a sequential AI company-resolution query, so the list is capped at 10.
supplierIds string[] IDs of existing supplier entities. When provided, skips AI resolution for supplierNames and links these existing suppliers directly.
productWebsite string Website of the product.
manufacturerWebsite string Website of the manufacturer.
productContext string Context about the product.
manufacturerContext string Context about the manufacturer.
supplierContext string Context about the supplier(s).
purchaserContext string Context about the purchaser.
countryOfOrigin string ISO 3166-1 alpha-2 country code for the product's country of origin.
pattern: ^[A-Z]{2}$
importCountry string ISO 3166-1 alpha-2 country code where the product is imported to.
pattern: ^[A-Z]{2}$default: "US"
annualVolume number Expected annual purchase volume of the finished product.
annualVolumeUnit string Unit for annualVolume (e.g., kg, liter, unit).
unitType string Base unit of measurement for the product (e.g., kilogram, piece, liter). Overrides AI inference when provided.
enum: piece, kilogram, gram, liter, milliliter, meter, foot, square meter, square foot, cubic meter, gallon, pound, ounce, ton, sheet, roll, barrel, board foot
countryOfOriginText string Raw, unnormalized country-of-origin text from a bulk import (e.g. 'China', 'P.R.C.'). Unlike countryOfOrigin, it is NOT validated to alpha-2; Product Resolution normalizes it. Used only by the import path — the form/API should send the strict countryOfOrigin.
unitTypeText string Raw, unnormalized unit-of-measure text from a bulk import (e.g. 'kg', 'tonne'). Unlike unitType, it is NOT validated to the closed enum; Product Resolution normalizes it. Used only by the import path — the form/API should send the strict unitType.
quantity number Quantity of the product for this cost analysis (e.g., 2 for 2 tons, 1000 for 1000 units). Decimals supported. Defaults to 1 if not specified.
pricesPaid PricesPaidItemDto[] Historical prices paid.
date string Date when the price was paid.
price* number Price paid in minor currency units (e.g., cents).
currency* string Currency code (e.g., USD, EUR).
enableBomJudge boolean If true, run the BOM Judge step (Step 3a) to validate and correct BOM component costs against retail prices and logical consistency. When false, BOM costs are used as-is from the BOM generation step.
default: true
enableTier1Adjustments boolean If true, apply Tier 1 process parameter adjustments (compliance overhead and batch setup amortization) derived from the BOM process parameters. When false, the ASM industry averages are used without process-level adjustments.
default: true
enableSupplierPower boolean If true (default), apply the supplier purchasing-power step: components are priced at the supplier-facing cost (reference price x a capped, scale-based discount factor). Set false to keep every component at the universal reference price.
default: true
supplierScaleTier string Optional explicit supplier scale tier, used as the purchasing-power signal when no financials are available (fallback of last resort before no-discount).
enum: enterprise, mid, small
enableProcessAssessment boolean If true, run a process assessment step that generates Tier 2 adjustments.
costAdjustments CostAdjustmentItemDto[] Explicit named adjustments to apply to cost-analysis components.
name* string Human-readable label for this adjustment.
category* string Cost category type to target.
enum: direct_materials, indirect_materials, labor, overhead
type string How to apply the adjustment.
enum: multiplicative, additivedefault: "multiplicative"
factor number Multiplicative factor (e.g., 1.1 for a 10% increase).
amount number Additive amount in minor currency units (cents).
enableQa boolean If true, run an AI-powered QA evaluation step after cost analysis.
enableAiTariffResolution boolean If true, run an AI-powered Tariff Resolution step (Step 3d) to determine the effective import tariff rate, replacing the static HTSUS dataset lookup. Supports non-US import countries when enabled.
default: false
annualRevenue number DEPRECATED (DLN-73): Manufacturer annual revenue. Prefer POST /company/{id}/financials with source=manual. Hard-overrides the EDGAR auto-fetch for this run.
annualCogs number DEPRECATED (DLN-73): Manufacturer annual cost of goods sold. Prefer POST /company/{id}/financials with source=manual.
annualSga number DEPRECATED (DLN-73): Manufacturer annual SG&A expenses. Prefer POST /company/{id}/financials with source=manual.
enableMonteCarlo boolean If true, run Monte Carlo simulation to compute costMin/costMax. Bounds derive from the MC P10/P90 but are widened where needed so the deterministic cost always lies within [costMin, costMax]; a widened side is a containment bound, not a strict percentile.
analysisConfig string Named analysis configuration preset (e.g., "basic").
existingBomId string ID of an existing bill of materials to reuse. When provided, the pipeline skips BOM generation and uses this BOM for downstream steps. If bomContext is also provided, the BOM is revised rather than reused as-is.
bomContext string Free-text instructions for revising an existing BOM. Only used when existingBomId is also provided. Describes what should change from the previous BOM (e.g., "change support legs from 2 to 4 pieces").
previousAnalysisId string DLN-197/ADR 0073: the cost analysis being iterated on (with-rerun). This field — together with feedbackId — is the iteration discriminator: when both are set, the orchestrator resolves the prior run via its computeInputs.sourceJobId, reuses its entities + BOM, and revises the BOM from the feedback corrections (so productName/manufacturerName are derived and may be omitted). Omit it for a normal or new_analysis run.
feedbackId string DLN-197/ADR 0073: the analysis-feedback record this run fulfils. With previousAnalysisId it drives an iteration rerun (the orchestrator reads its normalizedCorrections as the single source of truth for the BOM revision). Without previousAnalysisId it marks a new_analysis run (DLN-196) for audit: the orchestrator stamps this feedback record’s resultAnalysisId with the new CostAnalysis it creates.
includeBomPackaging boolean Include packaging components in the BOM. When false, the AI is instructed to omit packaging from the BOM and packaging costs use ASM industry averages.
default: true
includeBomWaste boolean Include waste components in the BOM. When false, the AI is instructed to omit waste from the BOM and waste removal costs use ASM industry averages.
default: true
includeBomConsumables boolean Include consumable components in the BOM. When false, the AI is instructed to omit consumables from the BOM and consumable costs use ASM industry averages.
default: true
includeBomByproducts boolean Include valuable byproduct/co-product components in the BOM. When false, the AI is instructed to omit byproducts and no cost credit is applied to Direct Materials.
default: true
importId string<uuid> Parent Import when this run is one row of a file import
uuid
rowIndex number Zero-based row index in the source import file
min: 0
rowData object Raw parsed source row (import provenance)

Responses

201
201 Response
FieldTypeDescription
data JobDto
id string Unique identifier for the job
parentJobId string FK to a parent job when this job is a sub-task of a pipeline job
importId string FK to the parent Import when this job is one row of a file import
rowIndex number Zero-based row index within the source import file (set for import rows)
type* string Job type identifier (e.g., bom_generation, cost_analysis)
status* string Current execution status of the job
enum: pending, in_progress, completed, failed, skipped
payload object Input data for the job (structure depends on job type)
result object Output data from the job (structure depends on job type)
step string Current step label for progress tracking (e.g., fetching_data, analyzing)
started string Timestamp when the job started executing
completed string Timestamp when the job completed successfully
errored string Timestamp when the job encountered an error, if applicable
errorMessage string Error message describing what went wrong, if applicable
meta object
403 Not available to external users — running a cost analysis is internal-only (DLN-321)
404 Referenced importId not found in the tenant
409 Duplicate job id, or referenced import is not PROCESSING
503 Product stub creation disabled in this environment
GET /pipeline/cost-analysis/{id}

Get a cost analysis or bom-refresh job by ID

Parameters

NameInTypeRequiredDescription
id path string<uuid> required

Responses

200
200 Response
FieldTypeDescription
data CostAnalysisJobDto
id string Unique identifier for the job
parentJobId string FK to a parent job when this job is a sub-task of a pipeline job
importId string FK to the parent Import when this job is one row of a file import
rowIndex number Zero-based row index within the source import file (set for import rows)
type* string Job type identifier (e.g., bom_generation, cost_analysis)
status* string Current execution status of the job
enum: pending, in_progress, completed, failed, skipped
payload object Input data for the job (structure depends on job type)
step string Current step label for progress tracking (e.g., fetching_data, analyzing)
started string Timestamp when the job started executing
completed string Timestamp when the job completed successfully
errored string Timestamp when the job encountered an error, if applicable
errorMessage string Error message describing what went wrong, if applicable
result any Result shape depends on the job type: cost_analysis jobs return this cost-analysis result; bom_refresh jobs return per-outcome refresh counts (update / ignore / flag-for-review / total) instead.
meta object
404 Not found

Cost Analysis

Retrieve completed cost-analysis results and component-level details.

GET /cost-analysis/{id}/feedback

List feedback submitted on a cost analysis (DLN-311)

Returns the feedback submissions for the analysis, newest-first, tenant-scoped. An analysis with no feedback yet returns an empty list. Responds 404 only when the cost analysis is unknown or belongs to another tenant.

Parameters

NameInTypeRequiredDescription
id path string<uuid> required
limit query number optional
offset query number optional
count query boolean optional Include totalCount of unbounded results in response meta

Responses

200
200 Response
FieldTypeDescription
data AnalysisFeedbackDto[]
id* string Unique identifier for the analysis-feedback record
costAnalysis* any The cost analysis this feedback is for (the ticket's analysisId). Validated relation — accepts the related object or its id string (@ValidateRelatedOrId). - accepts full object, id string, or id number
submittedById* string User who submitted the feedback
submittedByName string Display name of the submitter, captured at submission time
submittedAt* string When the feedback was submitted
origin string Whether the iteration was submitted by a Dalinea-internal or an external (customer) user. Derived server-side at submit from the gateway-set x-user-type header (never the request body). Internal-origin iterations are excluded from the rerun count/cap and hidden from customer-facing history (DLN-334). Absent on rows predating DLN-334 → treated as external.
enum: internal, external
changeType* string Kind of change the feedback requests
enum: new_analysis, iteration_no_rerun, iteration_with_rerun
feedbackStatus* string Review lifecycle status
enum: auto_approved, submitted, under_review, approved, rejected
corrections any The user-submitted correction payload. Bundled rather than flattened: the individual values are reported on, not filtered. The concrete grammar of the free-form sub-objects is owned by the submit flow (DLN-194).
normalizedCorrections any The admin-normalized counterpart of `corrections`, produced during review (DLN-195). Same field set, plus `changeType` when the admin reclassifies the request.
reviewedById string Admin who reviewed the feedback
reviewedByName string reviewedByName
reviewedAt string reviewedAt
adminNotes string Free-text admin notes on the review decision
bomValidationOverrides string[] BOM validation rules the admin chose to override for this iteration. Each item identifies a rule and the override decision; shape owned by the admin review flow (DLN-195).
resultAnalysisId string Nullable pointer to the resulting cost analysis (the new v1 for new_analysis, or the new version for iterations). Stored as a plain uuid (deferred-FK) — a second validated relation to cost-analysis is deferred to avoid multi-relation disambiguation; AC requires only the submitted analysis FK to be validated.
evaluationMessage string System/admin message describing the evaluation outcome
meta object
totalCount integer Unbounded result count. Only present when ?count=true is passed.
404 Cost analysis not found
POST /cost-analysis/{id}/feedback

Submit category-manager feedback on a cost analysis (DLN-194)

For external submitters, the first submission claims the feedback-owner lock (403 for a different user). DLN-334: internal (Dalinea) submitters are exempt — they neither claim the lock nor are blocked by an existing owner (no 403), and their iterations do not count toward or hit the 3-round rerun cap. iteration_with_rerun and new_analysis enter the admin review queue (202, status → pending_review); iteration_with_rerun is rejected with 422 once the chain has consumed 3 rerun rounds (external only). iteration_no_rerun recomputes synchronously (no AI) and resolves immediately (200) with the auto-approved feedback pointing at the newly persisted version via resultAnalysisId.

Parameters

NameInTypeRequiredDescription
id path string<uuid> required
x-app-user-id header string required
x-user-type header string optional Gateway-set INTERNAL/EXTERNAL user type (DLN-334). Server-injected — clients never supply it; the gateway strips inbound copies. Absent → treated as external.

Request Body

FeedbackSubmissionDto
FieldTypeDescription
changeType* string Kind of change requested. iteration_no_rerun resolves immediately; iteration_with_rerun and new_analysis enter the admin review queue.
enum: new_analysis, iteration_no_rerun, iteration_with_rerun
submittedByName string Submitter display name, captured for the review queue. Non-authoritative — the identity used for the ownership lock comes from x-app-user-id.
corrections any The user-submitted correction payload (per the analysis-feedback grammar).

Responses

202
202 Response
FieldTypeDescription
data AnalysisFeedbackDto
id* string Unique identifier for the analysis-feedback record
costAnalysis* any The cost analysis this feedback is for (the ticket's analysisId). Validated relation — accepts the related object or its id string (@ValidateRelatedOrId). - accepts full object, id string, or id number
submittedById* string User who submitted the feedback
submittedByName string Display name of the submitter, captured at submission time
submittedAt* string When the feedback was submitted
origin string Whether the iteration was submitted by a Dalinea-internal or an external (customer) user. Derived server-side at submit from the gateway-set x-user-type header (never the request body). Internal-origin iterations are excluded from the rerun count/cap and hidden from customer-facing history (DLN-334). Absent on rows predating DLN-334 → treated as external.
enum: internal, external
changeType* string Kind of change the feedback requests
enum: new_analysis, iteration_no_rerun, iteration_with_rerun
feedbackStatus* string Review lifecycle status
enum: auto_approved, submitted, under_review, approved, rejected
corrections any The user-submitted correction payload. Bundled rather than flattened: the individual values are reported on, not filtered. The concrete grammar of the free-form sub-objects is owned by the submit flow (DLN-194).
normalizedCorrections any The admin-normalized counterpart of `corrections`, produced during review (DLN-195). Same field set, plus `changeType` when the admin reclassifies the request.
reviewedById string Admin who reviewed the feedback
reviewedByName string reviewedByName
reviewedAt string reviewedAt
adminNotes string Free-text admin notes on the review decision
bomValidationOverrides string[] BOM validation rules the admin chose to override for this iteration. Each item identifies a rule and the override decision; shape owned by the admin review flow (DLN-195).
resultAnalysisId string Nullable pointer to the resulting cost analysis (the new v1 for new_analysis, or the new version for iterations). Stored as a plain uuid (deferred-FK) — a second validated relation to cost-analysis is deferred to avoid multi-relation disambiguation; AC requires only the submitted analysis FK to be validated.
evaluationMessage string System/admin message describing the evaluation outcome
meta object
403 Cost analysis is owned by another feedback submitter (external submitters only; internal submitters are exempt)
404 Cost analysis not found
422 Rerun round limit reached
GET /cost-analysis/portfolio/summary

Portfolio Overview savings-potential summary

Aggregates the latest completed cost analysis per product into Likely/Possible/Unlikely/Unknown savings buckets (counts, percentages, summed savings potential in minor currency units) plus the top-N savings opportunities. V1: single-currency assumption, tenant-wide, cached briefly in memory.

Parameters

NameInTypeRequiredDescription
topLimit query integer optional Rows in topProducts (default 5)
recentLimit query integer optional Rows in recentAnalyses (default 5)

Responses

200
200 Response
FieldTypeDescription
data PortfolioSummaryDto
currency* string Single currency observed across analyzed products (V1 single-currency assumption)
totalProducts* number Products with >=1 completed cost analysis — the percentage denominator
buckets* PortfolioBucketsDto
likely* PortfolioBucketStatDto
possible* PortfolioBucketStatDto
unlikely* PortfolioBucketStatDto
unknown* any Products whose latest analysis has no savings opportunity or no usable should-cost
topProducts* PortfolioTopProductDto[]
productId* string<uuid> Product the opportunity is for
uuid
costAnalysisId* string<uuid> Latest completed cost analysis id
uuid
savingsOpportunityId* string<uuid> Savings opportunity id
uuid
shouldCostAmount* number Should-cost in minor currency units
savingsAmount* number Savings amount (reference price - should-cost) in minor units
savingsPct* number Savings as a fraction of should-cost (0..1)
bucket* string Bucket this product falls into
enum: likely, possible, unlikely, unknown
currency* string Currency code
recentAnalyses* PortfolioRecentAnalysisDto[]
productId* string<uuid> Product the analysis is for
uuid
costAnalysisId* string<uuid> Cost analysis id
uuid
analysisDate* string When the analysis was performed (ISO 8601)
shouldCostAmount* number Should-cost in minor currency units
savingsAmount* number Savings amount in minor units; null when the analysis has no opportunity
savingsPct* number Savings as a fraction of should-cost (0..1); null when no opportunity or no usable should-cost
currency* string Currency code
generatedAt* string When the summary was computed (ISO 8601)
meta object
400 topLimit or recentLimit is not a valid integer
GET /cost-analysis/by-product/{productId}

Get the most recent completed cost analysis for a product

Returns the latest completed cost analysis as a single merged object (run-level record + rollup buckets as components). Monetary values are in minor currency units. Responds 202 with job status when no completed analysis exists but a pipeline run is pending or in progress (the in-progress check is product-level and not constrained by filterScope). Responds 404 when neither exists, including when the pipeline service is unreachable.

Parameters

NameInTypeRequiredDescription
productId path string<uuid> required
filterScope query string optional Comma-separated dimension:value filters constraining which completed analyses qualify. Supported dimensions: countryOfOrigin, importCountry. Example: countryOfOrigin:CN,importCountry:US

Responses

200
200 Response
FieldTypeDescription
data CostAnalysisResultDto1
id* string<uuid> Cost analysis id
uuid
status* string Status of the cost analysis
enum: analysis_done
analysisDate* string When the analysis was performed (ISO 8601)
productId* string<uuid> Product the analysis belongs to
uuid
currency string Currency code for all monetary values (e.g., USD)
bomId string<uuid> Bill of materials the analysis was computed from
uuid
countryOfOrigin string ISO country code of origin
importCountry string ISO country code of import destination
shouldCostAmount number Theoretical production cost in minor currency units
shouldCostStdErr number Standard error of the should-cost estimate in minor currency units
qaVerdict object QA Evaluation verdict (DLN-158). Null when QA was not enabled for this analysis.
adjustments AdjustmentsDto[] Adjustments applied beyond the industry-average baseline
type* string Identifier for the kind of adjustment applied
enum: manufacturer_financials, yield_adjustment, compliance_overhead, setup_amortization, named_adjustment, tariff, indirect_tariff, volume_discount, supplier_purchasing_power
source* string Origin of this adjustment
enum: user_provided, ai_estimate, analyst_judgment, system, edgar_auto, operator_entry
label string Human-readable description of what was adjusted
metadata object Adjustment-specific qualitative context (no dollar amounts). For type="manufacturer_financials": may include - cogsRatioAdjusted (boolean) - profitMarginOverridden (boolean) - fiscalYear (integer): the FY the financials describe - companyFinancialsId (uuid): the specific company_financials row that fed this run, enabling audit even after the cache rolls to a newer filing - financialsSource ("edgar" | "manual" | "llm" | "dto"): where the financials came from for this run - sgaCompleteness ({found:[...], missing:[...]}): which SGA components were present vs missing from the source filing - operatingMarginSource ("edgar_sga" | "asm_industry_average"): whether annual SGA was available or the ASM industry average was used for the operating-margin component - llmCitations ([{field, url, note}]): present only when financialsSource == "llm" For type="tariff" (direct product-level import tariff): may include - importCountry (string) - countryOfOrigin (string) - ratePercent (number) For type="indirect_tariff" (tariffs on foreign-sourced BOM components): may include - components (object): per-component breakdown of the indirect tariff impact
components* CostComponentDto[] Cost breakdown by rollup bucket
id* string<uuid> Unique identifier of the bucket row
uuid
name* string Name of the cost component (e.g., "Direct Materials")
currency* string Currency code (e.g., USD)
cost* number Cost amount in minor currency units (e.g., cents)
costMin* number Minimum estimated cost in minor currency units
costMax* number Maximum estimated cost in minor currency units
meta object
202
202 Response
FieldTypeDescription
data CostAnalysisInProgressDto
jobId* string<uuid> Pipeline job id to poll via GET /pipeline/cost-analysis/:id
uuid
status* string Job status
enum: pending, in_progress
step string Current pipeline step label
meta object
400 Malformed filterScope or unsupported dimension
404 No completed cost analysis found for the product
GET /cost-analysis/{id}/versions

Get the full version history of a cost analysis

Returns every version in the analysis chain in chronological order (oldest first). Accepts ANY version id in the chain — it walks both backward (prior versions) and forward (later iterations) from the given id. Each entry is a summary; full data stays on GET /cost-analysis/:id. Responds 404 when the id is unknown or belongs to another tenant.

Parameters

NameInTypeRequiredDescription
id path string<uuid> required

Responses

200
200 Response
FieldTypeDescription
data CostAnalysisVersionDto[]
id* string<uuid> Cost analysis id for this version
uuid
versionLabel* string Human-readable label for this version
changeType* string Iterations changeType of the feedback that produced this version; null for the root (no driving feedback)
status* string Lifecycle status of this version
feedbackOwnerId* string<uuid> User who owns the feedback loop for this version
uuid
feedbackOwnerName* string Display name of the feedback owner
changeSummary* string Short summary of what changed in this version
feedbackSummary* string Short summary of the feedback that drove this version
createdAt* string When this version was created (ISO 8601)
hasBomValidationOverrides* boolean True when the driving feedback carries confirmed BOM validation overrides
meta object
totalCount integer Unbounded result count. Only present when ?count=true is passed.
404 Cost analysis not found
GET /cost-analysis/{id}

Get cost-analysis by ID

Parameters

NameInTypeRequiredDescription
id path string<uuid> required
related query string[] optional Include related entities. Omit for all, "false" for none, or specify field names (repeatable, supports dot notation)

Responses

200
200 Response
FieldTypeDescription
data CostAnalysisDto
id* string Unique identifier for the cost analysis record
status* string Status of the cost analysis lifecycle. analysis_done = an AI pipeline run finished (the former "completed"); pending_review / pending_feedback / iteration are the human-in-the-loop iterations states (DLN-190).
enum: pending, analysis_done, pending_review, pending_feedback, iteration, failed
analysisDate* string Date and time when the cost analysis was performed
productId string FK to the @product for which the cost analysis is performed
currency string Currency code for the cost analysis (e.g., USD, EUR)
bomId string FK to the bill of materials used as the basis for this cost analysis
countryOfOrigin string The country of origin for the product. This may impact the cost analysis due to factors like tariffs, shipping costs, and local market conditions.
importCountry string The country into which the product is imported. Used for tariff rate lookups. Defaults to US if not provided.
shouldCostAmount number Theoretical cost to produce the product, in minor currency units (e.g., cents)
shouldCostStdErr number Approximation of the standard error of the should-cost estimate, in minor currency units (e.g., cents)
scenarioContext string Named rate scenario this analysis ran under. Nullable.
analysisBasis string Basis of the analysis (e.g. 'should_cost').
priorCostAnalysisId string Self-FK to the previous CA in a temporal lineage. Nullable (DLN-152 writes).
changeType string Classification of why this CA exists: BOM_REVISION for a new/updated bill of materials, RATE_REFRESH for a rate-only re-run. DLN-152/153 write this field.
enum: BOM_REVISION, RATE_REFRESH
versionLabel string Human-readable label for this CA version.
rerunRoundCount number Denormalized count of with-rerun iteration rounds consumed on this chain. Defaults to 0; the feedback flow (DLN-194) increments it and enforces the round limit, rather than walking the chain on every check.
isInternalIteration boolean True when this CA version was produced by a Dalinea-internal iteration (DLN-334). Denormalized from the producing analysis-feedback's origin so the version-chain query can hide internal versions from external callers without re-deriving origin per row. Internal versions are excluded from the rerun count/cap. Defaults to false (rows predating DLN-334 and non-iteration analyses are external/customer-facing). Set only by the submit service / the orchestrator; immutable thereafter so a later PUT can't unhide/hide a version.
feedbackOwnerId string User who owns the feedback loop for this analysis (first-submitter lock). Nullable until claimed.
feedbackOwnerName string Display name of the feedback owner, captured at claim time. Nullable.
changeSummary string Short human-readable summary of what changed in this version. Nullable.
feedbackSummary string Short human-readable summary of the feedback that drove this version. Nullable.
qaVerdict object QA evaluation outcome. Nullable (DLN-158 writes; DLN-138 leaves null).
computeInputs any Snapshot of the run-time engine inputs NOT otherwise reconstructable from this analysis — raw financials scalars, the derived margins actually passed, and the option flags — plus the resolved tariff scalars for robust replay. Written by the orchestrator at the cost-analysis compute step (DLN-269). Makes the analysis self-describing so a recompute (iteration no-rerun, DLN-194) or audit can faithfully replay the run. Nullable on rows produced before this field existed. See ADR 0071.
userTariffOverride any A user-pinned HTS code and/or direct tariff rate that must survive AI pipeline reruns (DLN-202). Set from an iteration_no_rerun feedback submission and copied forward to every new version in the chain. The tariff-resolution step (orchestrator Step 3d) and the recompute engine read it as a CONSTRAINT before resolving: a pinned tariffRatePct is authoritative (used instead of dataset/AI resolution), while a pinned htsCode only overrides which code is looked up (the rate is still resolved). The resulting direct tariff adjustment is emitted with source=user_provided so GET /cost-analysis/:id distinguishes it from AI-estimated values. Nullable when the user has not pinned anything.
buckets CostAnalysisBucketDto[] Rollup buckets (Direct Materials, Salaries, Import Tariff, …) derived from component results. - accepts array of full objects, id strings, or id numbers
id* string Unique identifier for the cost analysis bucket record
name* string Name of the cost component (e.g., "direct materials", "production wages", etc.)
category* string Coarse classification (e.g. 'materials', 'labor', 'overhead', 'tariff', 'profit').
costAnalysis* any The parent cost analysis - accepts full object, id string, or id number
currency* string Currency code for the cost analysis (e.g., USD, EUR)
cost* number Cost amount for this component in minor currency units (e.g., cents)
costMin* number Minimum estimated cost for this component in minor currency units (e.g., cents)
costMax* number Maximum estimated cost for this component in minor currency units (e.g., cents)
supportingData object Additional supporting data for this cost component as key-value pairs (e.g., dataset references, assumptions, calculation notes)
componentResults CostAnalysisComponentResultDto[] Per-BOM-component cost results (baselineCost, finalCost, stdErr). - accepts array of full objects, id strings, or id numbers
id* string Unique identifier for the component result
costAnalysis* any The parent cost analysis - accepts full object, id string, or id number
bomComponentId* string FK to BOM_COMPONENT.id. Stored as a plain uuid (no $ref) because the BOM lives in a separate standalone service — same convention as COST_ANALYSIS.productId and COST_ANALYSIS.bomId.
currency* string Currency code (e.g. USD, EUR)
baselineCost* number Pre-adjustment cost for this component, in minor currency units (cents).
finalCost* number Post-adjustment cost for this component, in minor currency units (cents).
stdErr number Approximate standard error of finalCost, in cents. Nullable (populated when Monte Carlo ran).
costMin number Lower bound (≈P10) of finalCost in minor currency units (cents). Nullable — populated only when Monte Carlo ran (same condition as stdErr).
costMax number Upper bound (≈P90) of finalCost in minor currency units (cents). Nullable — populated only when Monte Carlo ran (same condition as stdErr).
rateSnapshots CostAnalysisRateSnapshotDto[] Frozen rate snapshots (tariff, labor, energy, localization) used in this analysis - accepts array of full objects, id strings, or id numbers
id* string Unique identifier for the rate snapshot
costAnalysis any The parent cost analysis - accepts full object, id string, or id number
rateType* string Kind of rate captured
enum: tariff, labor, energy, localization, manufacturer_financials
layer string base MFN rate, or a surcharge layered on top (e.g. Section 301)
enum: base, surcharge
source* string Authoritative source of the rate. USER = a user-pinned tariff (DLN-202): the pin is a recorded rate fact, emitted as a base-layer snapshot so the analysis stays reproducible (ADR 0047) and the pin is queryable.
enum: USITC HTS, WITS, AI, INTERNAL, EDGAR, USER
sourceTable string Dataset table the rate was read from (e.g. usitc_hts_10digit, wits_tariff_rates)
sourceVersionId string Source dataset version stamp (e.g. "2026HTSRev8" for USITC, "2023" for WITS)
lookupKey* string The HTS/HS6 code looked up
value* number Rate as a decimal fraction (e.g. 0.075 for 7.5%)
unit* string Unit of the value. "percent" = ad-valorem percent expressed as a decimal fraction (e.g. 0.075 for 7.5%). "ratio" = dimensionless multiplier (e.g. 1.25 = +25%, 0.80 = -20%).
enum: percent, ratio
currency string Currency for specific (per-unit) rates; omitted/null for ad-valorem (optional)
effectiveDate string Effective date of the rate (YYYY-MM-DD)
appliesToComponentName string BOM component this snapshot applies to (for indirect tariffs); omitted/null for the direct/product-level tariff (optional). DLN-138 maps this to the component FK at persist time.
componentDrivers CostAnalysisComponentDriverDto[] Driver-level cost attributions (tariff, labor, energy, localization, overhead, etc.) for this analysis - accepts array of full objects, id strings, or id numbers
id* string Unique identifier for the component driver
costAnalysis any The parent cost analysis - accepts full object, id string, or id number
driver* string The driver type this row attributes cost to
enum: tariff, labor, energy, commodity, localization, freight, overhead, volume_discount, process_adjustment, supplier_purchasing_power
amount* number Cost impact of this driver, in minor currency units (cents). Positive means the driver increased cost; negative means it decreased it.
stdErr number Approximate standard error of `amount`, in minor currency units (cents).
source* string How `amount` was derived
enum: rate_snapshot, manual_adjustment, model
rateSnapshotId string FK to COST_ANALYSIS_RATE_SNAPSHOT.id when the driver was derived from an ingested rate. Stored as a plain uuid (no $ref) following the deferred-FK convention. Nullable (overhead drivers have source=manual_adjustment with no snapshot; synthesized tariff drivers use source=model with no snapshot).
appliesToComponentName string BOM component this driver applies to, when component-specific. Absent = driver applies at the cost-analysis / product level (v1 default for labor / energy / localization / overhead). DLN-138 maps to the component FK at persist time when present.
metadata object Driver-specific qualitative context (e.g. localization sub-factor breakdown).
referencePrices CostAnalysisReferencePriceDto[] Reference prices (historical/benchmark) compared against should-cost for this analysis (DLN-189). - accepts array of full objects, id strings, or id numbers
id* string Unique identifier for the reference price
costAnalysis any The parent cost analysis this reference price was used for - accepts full object, id string, or id number
price* number Reference price in minor currency units (e.g., cents)
currency* string ISO 4217 currency code (e.g., USD, EUR)
pricedDate string Date the price was paid or observed (YYYY-MM-DD); optional
source* string How this reference price was obtained
enum: user_provided, ai_estimate
sourceReferencePriceId string When this row was carried over (cloned) from a prior cost analysis in the same product lineage, the id of the reference-price row it was cloned from. Stored as a plain uuid (no $ref) following the deferred-FK convention. Null for freshly-provided or estimated references.
savingsOpportunities SavingsOpportunityDto[] Savings opportunities derived from this analysis (DLN-247). At most one per run. - accepts array of full objects, id strings, or id numbers
id* string Unique identifier for the savings opportunity
costAnalysis any The cost analysis that identified this opportunity - accepts full object, id string, or id number
productId* string Product the opportunity is for. Plain uuid (no $ref) following the deferred-FK convention (product lives in another service).
amount* number Savings amount in minor currency units (cents): reference price minus should-cost. Positive = savings; may be zero or negative when the should-cost is at or above the reference price.
currency* string ISO 4217 currency code (matches the cost analysis run currency)
periodScope* string Basis the amount is expressed on
enum: per_unit, annual, total
status* string Lifecycle status; opportunities are created "open"
enum: open, closed
identifiedDate* string Date the opportunity was identified (the cost analysis date, YYYY-MM-DD)
comparisonBasis* string What the savings is measured against
enum: prices_paid, prior_analysis, external_benchmark, target_cost
comparisonReferenceId* string Id of the COST_ANALYSIS_REFERENCE_PRICE row this opportunity was computed against. Plain string (no $ref) per the ERD's non-polymorphic-FK convention.
assigneeUserId string User the opportunity is assigned to (deferred-FK to the user service). Not populated by the pipeline; set by a later workflow.
targetCloseDate string Target date to act on the opportunity. Populated by a later workflow.
notes string Free-text notes. Populated by a later workflow.
adjustments AdjustmentsDto[] Adjustments applied to the cost model beyond the industry-average ASM baseline. Records which factors shaped the analysis without capturing exact numeric deltas.
type* string Identifier for the kind of adjustment applied
enum: manufacturer_financials, yield_adjustment, compliance_overhead, setup_amortization, named_adjustment, tariff, indirect_tariff, volume_discount, supplier_purchasing_power
source* string Origin of this adjustment
enum: user_provided, ai_estimate, analyst_judgment, system, edgar_auto, operator_entry
label string Human-readable description of what was adjusted
metadata object Adjustment-specific qualitative context (no dollar amounts). For type="manufacturer_financials": may include - cogsRatioAdjusted (boolean) - profitMarginOverridden (boolean) - fiscalYear (integer): the FY the financials describe - companyFinancialsId (uuid): the specific company_financials row that fed this run, enabling audit even after the cache rolls to a newer filing - financialsSource ("edgar" | "manual" | "llm" | "dto"): where the financials came from for this run - sgaCompleteness ({found:[...], missing:[...]}): which SGA components were present vs missing from the source filing - operatingMarginSource ("edgar_sga" | "asm_industry_average"): whether annual SGA was available or the ASM industry average was used for the operating-margin component - llmCitations ([{field, url, note}]): present only when financialsSource == "llm" For type="tariff" (direct product-level import tariff): may include - importCountry (string) - countryOfOrigin (string) - ratePercent (number) For type="indirect_tariff" (tariffs on foreign-sourced BOM components): may include - components (object): per-component breakdown of the indirect tariff impact
meta object
404 Not found

User

User identity and profile records. Each user maps 1:1 to a Firebase Auth account.

GET /users/{id}

Get user by ID (scoped to caller membership)

Parameters

NameInTypeRequiredDescription
id path string<uuid> required

Responses

200
200 Response
FieldTypeDescription
data UserDto
id* string Unique identifier for the user
firebaseUid string Firebase Auth UID — links this record to the user's GCIP auth account. Unique across all non-null values. Server-set: for INTERNAL users, User.AfterCreate calls tenant.createUser() and writes the returned uid back to this row; for EXTERNAL (invited) users the uid is bound at first SSO sign-in via resolve-invite (DLN-266) and starts as null. Any value supplied on POST is rejected. Immutable after creation. Uniqueness on non-null values is enforced by a partial unique index (not a Cruddy-managed constraint); see scripts/dln-266-firebase-uid-partial-index.sql.
email* string User's email address. Unique across all users.
firstName* string User's first name
lastName* string User's last name
displayName* string Display name shown in the UI (may differ from firstName + lastName)
image string GCS filename for the user's profile picture
title string Job title or role at the user's organization
phone string Contact phone number
bio string Short biography or about text
userType* string Whether this user is a Dalinea employee (INTERNAL) or a client user (EXTERNAL). Immutable after creation.
enum: INTERNAL, EXTERNAL
status* string Lifecycle status of the user account
enum: ACTIVE, INACTIVE, SUSPENDED, DELETED
language* string Preferred language (ISO 639-1 two-character code, e.g. "en")
lastLogin string Timestamp of the user's most recent login
firebaseTenantId string GCIP tenant ID for the organization this user authenticates under. Present for tenant-scoped users (EXTERNAL, DALINEA_ANALYST); absent for platform-scoped INTERNAL users (DALINEA_ADMIN) who authenticate at the project level. Determines which GCIP tenant createUser targets.
meta object
404 Not found
PUT /users/{id}

Update user (scoped to caller membership)

Parameters

NameInTypeRequiredDescription
id path string<uuid> required

Request Body

UserDto
FieldTypeDescription
id* string Unique identifier for the user
firebaseUid string Firebase Auth UID — links this record to the user's GCIP auth account. Unique across all non-null values. Server-set: for INTERNAL users, User.AfterCreate calls tenant.createUser() and writes the returned uid back to this row; for EXTERNAL (invited) users the uid is bound at first SSO sign-in via resolve-invite (DLN-266) and starts as null. Any value supplied on POST is rejected. Immutable after creation. Uniqueness on non-null values is enforced by a partial unique index (not a Cruddy-managed constraint); see scripts/dln-266-firebase-uid-partial-index.sql.
email* string User's email address. Unique across all users.
firstName* string User's first name
lastName* string User's last name
displayName* string Display name shown in the UI (may differ from firstName + lastName)
image string GCS filename for the user's profile picture
title string Job title or role at the user's organization
phone string Contact phone number
bio string Short biography or about text
userType* string Whether this user is a Dalinea employee (INTERNAL) or a client user (EXTERNAL). Immutable after creation.
enum: INTERNAL, EXTERNAL
status* string Lifecycle status of the user account
enum: ACTIVE, INACTIVE, SUSPENDED, DELETED
language* string Preferred language (ISO 639-1 two-character code, e.g. "en")
lastLogin string Timestamp of the user's most recent login
firebaseTenantId string GCIP tenant ID for the organization this user authenticates under. Present for tenant-scoped users (EXTERNAL, DALINEA_ANALYST); absent for platform-scoped INTERNAL users (DALINEA_ADMIN) who authenticate at the project level. Determines which GCIP tenant createUser targets.

Responses

200
200 Response
FieldTypeDescription
data UserDto
id* string Unique identifier for the user
firebaseUid string Firebase Auth UID — links this record to the user's GCIP auth account. Unique across all non-null values. Server-set: for INTERNAL users, User.AfterCreate calls tenant.createUser() and writes the returned uid back to this row; for EXTERNAL (invited) users the uid is bound at first SSO sign-in via resolve-invite (DLN-266) and starts as null. Any value supplied on POST is rejected. Immutable after creation. Uniqueness on non-null values is enforced by a partial unique index (not a Cruddy-managed constraint); see scripts/dln-266-firebase-uid-partial-index.sql.
email* string User's email address. Unique across all users.
firstName* string User's first name
lastName* string User's last name
displayName* string Display name shown in the UI (may differ from firstName + lastName)
image string GCS filename for the user's profile picture
title string Job title or role at the user's organization
phone string Contact phone number
bio string Short biography or about text
userType* string Whether this user is a Dalinea employee (INTERNAL) or a client user (EXTERNAL). Immutable after creation.
enum: INTERNAL, EXTERNAL
status* string Lifecycle status of the user account
enum: ACTIVE, INACTIVE, SUSPENDED, DELETED
language* string Preferred language (ISO 639-1 two-character code, e.g. "en")
lastLogin string Timestamp of the user's most recent login
firebaseTenantId string GCIP tenant ID for the organization this user authenticates under. Present for tenant-scoped users (EXTERNAL, DALINEA_ANALYST); absent for platform-scoped INTERNAL users (DALINEA_ADMIN) who authenticate at the project level. Determines which GCIP tenant createUser targets.
meta object

Organization

Tenant organizations. Each owns a GCIP tenant and one or more email domains used for sign-in discovery.

GET /organizations/{id}

Get organization by ID (scoped to caller membership)

Parameters

NameInTypeRequiredDescription
id path string<uuid> required

Responses

200
200 Response
FieldTypeDescription
data OrganizationDto
id* string Unique identifier for the organization
name* string Display name of the organization
status* string Lifecycle status of the organization
enum: ACTIVE, ARCHIVED, SUSPENDED
legalEntityName string Full legal entity name (may differ from display name)
taxId string Tax identification number (EIN, VAT, etc.)
crmId string CRM system identifier for this organization
companyId string FK to the @company record linked to this organization
defaultCurrency string Default ISO 4217 currency code (e.g. USD, EUR)
fiscalYearStart* number Month in which the fiscal year starts (1 = January, 12 = December)
dateFormat* string Preferred date display format for this organization
enum: MM/DD/YYYY, DD/MM/YYYY, YYYY-MM-DD
defaultTimeZone* string Default time zone identifier for this organization (e.g. America/New_York, America/Chicago, Europe/Berlin, Asia/Tokyo)
domains* string[] Email domains associated with this organization (e.g. ["acme.com", "acme-legacy.com"]). Used for tenant discovery. Must be unique across all organizations.
firebaseTenantId string Google Cloud Identity Platform (GCIP) tenant ID for this organization. Auto-generated by GCIP (not a UUID). Set after org creation by the Firebase Admin SDK event listener. Required for EXTERNAL user authentication.
meta object
404 Not found
GET /organizations

List organization documents

Parameters

NameInTypeRequiredDescription
firebaseTenantId query string[] optional Filter by a set of values (repeatable param)
defaultTimeZone query string[] optional Filter by a set of values (repeatable param)
dateFormat query string[] optional Filter by a set of values (repeatable param)
fiscalYearStart query string[] optional Filter by a set of values (repeatable param)
defaultCurrency query string[] optional Filter by a set of values (repeatable param)
companyId query string[] optional Filter by a set of values (repeatable param)
crmId query string[] optional Filter by a set of values (repeatable param)
taxId query string[] optional Filter by a set of values (repeatable param)
legalEntityName query string[] optional Filter by a set of values (repeatable param)
status query string[] optional Filter by a set of values (repeatable param)
name query string[] optional Filter by a set of values (repeatable param)
id query string[] optional Filter by a set of values (repeatable param)
firebaseTenantId[contains] query string optional Case-insensitive substring match
defaultTimeZone[contains] query string optional Case-insensitive substring match
dateFormat[contains] query string optional Case-insensitive substring match
defaultCurrency[contains] query string optional Case-insensitive substring match
crmId[contains] query string optional Case-insensitive substring match
taxId[contains] query string optional Case-insensitive substring match
legalEntityName[contains] query string optional Case-insensitive substring match
status[contains] query string optional Case-insensitive substring match
name[contains] query string optional Case-insensitive substring match
count query boolean optional Include totalCount of unbounded results in response meta
related query string[] optional Include related entities. Omit for all, "false" for none, or specify field names (repeatable, supports dot notation)
sortOrder query string optional Sort direction (default: asc)
sortBy query string optional Field name to sort by
offset query number optional
limit query number optional

Responses

200
200 Response
FieldTypeDescription
data OrganizationDto[]
id* string Unique identifier for the organization
name* string Display name of the organization
status* string Lifecycle status of the organization
enum: ACTIVE, ARCHIVED, SUSPENDED
legalEntityName string Full legal entity name (may differ from display name)
taxId string Tax identification number (EIN, VAT, etc.)
crmId string CRM system identifier for this organization
companyId string FK to the @company record linked to this organization
defaultCurrency string Default ISO 4217 currency code (e.g. USD, EUR)
fiscalYearStart* number Month in which the fiscal year starts (1 = January, 12 = December)
dateFormat* string Preferred date display format for this organization
enum: MM/DD/YYYY, DD/MM/YYYY, YYYY-MM-DD
defaultTimeZone* string Default time zone identifier for this organization (e.g. America/New_York, America/Chicago, Europe/Berlin, Asia/Tokyo)
domains* string[] Email domains associated with this organization (e.g. ["acme.com", "acme-legacy.com"]). Used for tenant discovery. Must be unique across all organizations.
firebaseTenantId string Google Cloud Identity Platform (GCIP) tenant ID for this organization. Auto-generated by GCIP (not a UUID). Set after org creation by the Firebase Admin SDK event listener. Required for EXTERNAL user authentication.
meta object
totalCount integer Unbounded result count. Only present when ?count=true is passed.

Feature Flags

Feature flag configuration and resolution.

GET /feature-flags/defaults

Get system-wide default feature flag values

Responses

200

Imports

Upload files for sharing or to feed into batch workflows like cost analysis.

POST /imports/upload-url

Get a signed PUT URL for uploading an import file.

Validates the asserted MIME type against the registry for the given importType. Returns a fileLocation the client must echo back to POST /imports once the upload is complete.

Request Body

ImportUploadUrlRequestDto
FieldTypeDescription
originalFilename* string Original filename (used as the leaf of the object path).
mimeType* string Client-asserted MIME type. Validated against the cost-analysis allowlist.
sizeBytes* number Client-asserted file size in bytes. Rejected if FMS limit exceeded.

Responses

201
201 Response
FieldTypeDescription
data ImportUploadUrlResponseDto
uploadUrl* string
fileLocation* string GCS path of the form {bucket}/{tenantId}/{uuid}/{filename}.
expiresAt* string
contentType* string MIME type the PUT must declare (echoed as Content-Type).
requiredHeaders* object Headers the client MUST send verbatim on the PUT for the V4 signature to validate. Always includes content-type; includes x-goog-content-length-range when a size cap is set. Send exactly these — omitting one yields a 403 SignatureDoesNotMatch.
meta object
POST /imports/preview

Preview the columns + first few rows of an uploaded file.

For workflow imports the UI uses this to build column mappings. Streams the file through FMS, parses up to maxRows rows, and returns them.

Request Body

PreviewRequestDto
FieldTypeDescription
fileLocation* string fileLocation returned from upload-url, of the form {bucket}/{tenantId}/{uuid}/{filename}.
maxRows number Max sample rows to return. Default 5, max 50.

Responses

200
200 Response
FieldTypeDescription
data PreviewResponseDto
columns* string[]
sampleRows* object[]
totalRowsEstimate number Best-effort total-rows count, when the parser can compute it.
meta object
403 fileLocation belongs to another tenant
GET /imports

List import documents

Parameters

NameInTypeRequiredDescription
failedRowCount query string[] optional Filter by a set of values (repeatable param)
processedRowCount query string[] optional Filter by a set of values (repeatable param)
totalRowCount query string[] optional Filter by a set of values (repeatable param)
errorMessage query string[] optional Filter by a set of values (repeatable param)
approvedAt query string[] optional Filter by a set of values (repeatable param)
approvedByUserId query string[] optional Filter by a set of values (repeatable param)
uploadedByUserId query string[] optional Filter by a set of values (repeatable param)
status query string[] optional Filter by a set of values (repeatable param)
type query string[] optional Filter by a set of values (repeatable param)
sizeBytes query string[] optional Filter by a set of values (repeatable param)
mimeType query string[] optional Filter by a set of values (repeatable param)
originalFilename query string[] optional Filter by a set of values (repeatable param)
fileLocation query string[] optional Filter by a set of values (repeatable param)
description query string[] optional Filter by a set of values (repeatable param)
name query string[] optional Filter by a set of values (repeatable param)
id query string[] optional Filter by a set of values (repeatable param)
errorMessage[contains] query string optional Case-insensitive substring match
approvedByUserId[contains] query string optional Case-insensitive substring match
uploadedByUserId[contains] query string optional Case-insensitive substring match
status[contains] query string optional Case-insensitive substring match
type[contains] query string optional Case-insensitive substring match
mimeType[contains] query string optional Case-insensitive substring match
originalFilename[contains] query string optional Case-insensitive substring match
fileLocation[contains] query string optional Case-insensitive substring match
description[contains] query string optional Case-insensitive substring match
name[contains] query string optional Case-insensitive substring match
count query boolean optional Include totalCount of unbounded results in response meta
related query string[] optional Include related entities. Omit for all, "false" for none, or specify field names (repeatable, supports dot notation)
sortOrder query string optional Sort direction (default: asc)
sortBy query string optional Field name to sort by
offset query number optional
limit query number optional

Responses

200
200 Response
FieldTypeDescription
data ImportDto[]
id string Unique identifier for the import
name* string User-supplied display name for the import
description string Optional user-supplied description
fileLocation* string GCS path of the form "{bucket}/{tenantId}/{uuid}/{filename}"
originalFilename* string Filename as supplied by the user at upload time
mimeType* string Actual MIME type reported by GCS at create time
sizeBytes* number Actual size in bytes reported by GCS at create time
type* string Import type (single supported type today; registry returns when a second lands).
enum: COST_ANALYSIS_IMPORT
status* string Import lifecycle status
enum: PENDING_CONFIG, PENDING_APPROVAL, PROCESSING, COMPLETED, PARTIALLY_COMPLETED, FAILED, REJECTED
uploadedByUserId* string ID of the user that uploaded this import (from the request's auth context)
approvedByUserId string ID of the internal admin that approved this import (set on approval)
approvedAt string Timestamp the import was approved
config object Type-specific configuration. Validated by the service layer per type.
errorMessage string Error message if the import failed during processing
totalRowCount number Total rows the processor identified in the file
processedRowCount number Number of rows the processor has finished (successfully or otherwise)
failedRowCount number Number of rows that failed processing
meta object
totalCount integer Unbounded result count. Only present when ?count=true is passed.
POST /imports

Create an Import record from an uploaded file.

Request Body

CreateImportRequestDto
FieldTypeDescription
name* string
description string
fileLocation* string fileLocation returned from POST /imports/upload-url.
originalFilename* string
config object Cost-analysis configuration. Validated against CostAnalysisImportConfig.

Responses

201
201 Response
FieldTypeDescription
data ImportDto
id string Unique identifier for the import
name* string User-supplied display name for the import
description string Optional user-supplied description
fileLocation* string GCS path of the form "{bucket}/{tenantId}/{uuid}/{filename}"
originalFilename* string Filename as supplied by the user at upload time
mimeType* string Actual MIME type reported by GCS at create time
sizeBytes* number Actual size in bytes reported by GCS at create time
type* string Import type (single supported type today; registry returns when a second lands).
enum: COST_ANALYSIS_IMPORT
status* string Import lifecycle status
enum: PENDING_CONFIG, PENDING_APPROVAL, PROCESSING, COMPLETED, PARTIALLY_COMPLETED, FAILED, REJECTED
uploadedByUserId* string ID of the user that uploaded this import (from the request's auth context)
approvedByUserId string ID of the internal admin that approved this import (set on approval)
approvedAt string Timestamp the import was approved
config object Type-specific configuration. Validated by the service layer per type.
errorMessage string Error message if the import failed during processing
totalRowCount number Total rows the processor identified in the file
processedRowCount number Number of rows the processor has finished (successfully or otherwise)
failedRowCount number Number of rows that failed processing
meta object
GET /imports/{id}

Get import by ID

Parameters

NameInTypeRequiredDescription
id path string<uuid> required
related query string[] optional Include related entities. Omit for all, "false" for none, or specify field names (repeatable, supports dot notation)

Responses

200
200 Response
FieldTypeDescription
data ImportDto
id string Unique identifier for the import
name* string User-supplied display name for the import
description string Optional user-supplied description
fileLocation* string GCS path of the form "{bucket}/{tenantId}/{uuid}/{filename}"
originalFilename* string Filename as supplied by the user at upload time
mimeType* string Actual MIME type reported by GCS at create time
sizeBytes* number Actual size in bytes reported by GCS at create time
type* string Import type (single supported type today; registry returns when a second lands).
enum: COST_ANALYSIS_IMPORT
status* string Import lifecycle status
enum: PENDING_CONFIG, PENDING_APPROVAL, PROCESSING, COMPLETED, PARTIALLY_COMPLETED, FAILED, REJECTED
uploadedByUserId* string ID of the user that uploaded this import (from the request's auth context)
approvedByUserId string ID of the internal admin that approved this import (set on approval)
approvedAt string Timestamp the import was approved
config object Type-specific configuration. Validated by the service layer per type.
errorMessage string Error message if the import failed during processing
totalRowCount number Total rows the processor identified in the file
processedRowCount number Number of rows the processor has finished (successfully or otherwise)
failedRowCount number Number of rows that failed processing
meta object
404 Not found
PATCH /imports/{id}

Partial-update name/description/config. Recomputes status from config.

Allowed only while the import is PENDING_CONFIG or PENDING_APPROVAL. Setting config recomputes status: valid → PENDING_APPROVAL, invalid → PENDING_CONFIG.

Parameters

NameInTypeRequiredDescription
id path string<uuid> required

Request Body

UpdateImportRequestDto
FieldTypeDescription
name string
description string
config object Replaces the previous config. The resulting status is recomputed from validity.

Responses

200
200 Response
FieldTypeDescription
data ImportDto
id string Unique identifier for the import
name* string User-supplied display name for the import
description string Optional user-supplied description
fileLocation* string GCS path of the form "{bucket}/{tenantId}/{uuid}/{filename}"
originalFilename* string Filename as supplied by the user at upload time
mimeType* string Actual MIME type reported by GCS at create time
sizeBytes* number Actual size in bytes reported by GCS at create time
type* string Import type (single supported type today; registry returns when a second lands).
enum: COST_ANALYSIS_IMPORT
status* string Import lifecycle status
enum: PENDING_CONFIG, PENDING_APPROVAL, PROCESSING, COMPLETED, PARTIALLY_COMPLETED, FAILED, REJECTED
uploadedByUserId* string ID of the user that uploaded this import (from the request's auth context)
approvedByUserId string ID of the internal admin that approved this import (set on approval)
approvedAt string Timestamp the import was approved
config object Type-specific configuration. Validated by the service layer per type.
errorMessage string Error message if the import failed during processing
totalRowCount number Total rows the processor identified in the file
processedRowCount number Number of rows the processor has finished (successfully or otherwise)
failedRowCount number Number of rows that failed processing
meta object
409 Import is not in an editable state
DELETE /imports/{id}

Delete an Import and its GCS object. Rejected while PROCESSING.

Parameters

NameInTypeRequiredDescription
id path string<uuid> required
hard query string required

Responses

204 Deleted
409 Cannot delete while PROCESSING
GET /imports/{id}/jobs

List child pipeline job rows for an import with their own status (paginated).

Parameters

NameInTypeRequiredDescription
id path string<uuid> required
pageSize query number optional Default 50, max 200
page query number optional Default 1

Responses

200
ImportJobsResponseDto
FieldTypeDescription
data* ImportJobItemDto[]
importJobId* string
pipelineJobId* string
rowIndex* number
rowData* object
submissionError string
pipelineStatus* string Live status from the Pipeline Service.
pipelineStep string
meta* ImportJobsResponseMetaDto
totalCount* number
aggregate* ImportJobsAggregateDto
total* number
completed* number
failed* number
inProgress* number
GET /imports/{id}/errors

List row-level errors for an import (paginated). Empty list when none.

Returns the failed job rows recorded during processing (rows with status "failed" and an error message). These cover both pre-submission and execution failures; live pipeline execution status is on GET /imports/:id/jobs.

Parameters

NameInTypeRequiredDescription
id path string<uuid> required
pageSize query number optional Default 50, max 200
page query number optional Default 1

Responses

200
ImportErrorsResponseDto
FieldTypeDescription
data* ImportRowErrorDto[]
rowIndex* number
rowData* object
errorMessage* string Why the row failed during processing.
meta* ImportErrorsResponseMetaDto
totalCount* number
404 Import not found
POST /imports/{id}/download-url

Sign a download URL for the import file. Tenant-scoped.

Parameters

NameInTypeRequiredDescription
id path string<uuid> required

Responses

200
200 Response
FieldTypeDescription
data ImportDownloadUrlResponseDto
downloadUrl* string
expiresAt* string
meta object
404 Import not found