Skip to content

KomplettPC API

Realistic request/response examples for every endpoint in the KomplettPC v1 API, drawn from live calls against the Itegra.se test environment. Model shapes and field-level descriptions live in the KomplettPC overview; this document focuses on what real responses look like across the interesting scenarios.

Bundle used across most examples: 1222702 — a KomplettPC bundle with 12 product groups (CPU, chassis, motherboard, GPU, RAM, drive, PSU, cooling, OS, packaging, “WHC Standard” AlwaysIncluded group, order-hold).


Bundle Discovery — GET /bundles/{bundleId}

Section titled “Bundle Discovery — GET /bundles/{bundleId}”

Bundle with a mix of Single selectable groups, an AlwaysIncluded group, and one group with no configured default.

Response — bundle structure (1222702)
{
"bundleId": "1222702",
"name": "Webhallen Config Pro - 7700X / 7900XT",
"assemblyTime": { "from": 8, "to": 10 },
"stock": { "status": "NotInStock", "description": "Inte i lager.", "availabilityDate": null },
"productGroups": [
{
"productGroupId": "1fc7b7bc-1765-5afb-9a0c-947e0cb264d3",
"name": "WHC CPU AMD",
"order": 0,
"defaultProductIds": ["1217408"],
"selectionType": "Single",
"requireSelection": false,
"stock": { "status": "InStock", "description": "52 st på lager.", "availabilityDate": null }
},
{
"productGroupId": "26e9bded-51ff-49be-dd2c-7d3848df4cb0",
"name": "WHC Chassis",
"order": 1,
"defaultProductIds": ["1221885"],
"selectionType": "Single",
"requireSelection": true,
"stock": { "status": "InStock", "description": "100+ st på lager.", "availabilityDate": null }
},
{
"productGroupId": "ce17be6a-92c0-ca9a-97ce-e1b11185a902",
"name": "WHC Graphics",
"order": 3,
"defaultProductIds": ["1243373"],
"selectionType": "Single",
"requireSelection": false,
"stock": {
"status": "UnconfirmedPurchaseOrder",
"description": "Preliminärt i lager 16 augusti (1 st osäkert datum)",
"availabilityDate": "2026-08-16T00:00:00Z"
}
},
{
"productGroupId": "1042ca60-8470-4278-1496-afe10a1e3e00",
"name": "WHC Standard",
"order": 10,
"defaultProductIds": ["200739", "200741"],
"selectionType": "AlwaysIncluded",
"requireSelection": false,
"stock": null
},
{
"productGroupId": "e714eebc-1de4-4e41-8fa8-bea61e269905",
"name": "Order Hold",
"order": 11,
"defaultProductIds": ["300468"],
"selectionType": "Single",
"requireSelection": false,
"stock": { "status": "InStock", "description": "Alltid på lager", "availabilityDate": null }
}
]
}

Key points:

  • productGroupId is per-bundle — the same GUID identifies the same slot on subsequent save/check-availability calls. Do not hardcode these across bundles.
  • defaultProductIds holds every product pre-selected in the group. For AlwaysIncluded groups that is every product the group holds — send all of them when saving a configuration (the WHC Standard row above needs both 200739 and 200741). For Single and Multiple groups it holds the one pre-selected product, and is [] when no bundle-level default is configured.
  • stock on a group is the stock of the pre-selected product, and only when defaultProductIds holds exactly one. It is null when the group has no default, when it has several — as the WHC Standard row does — or when the product was not found in inventory. For per-product stock in a group, call the product group endpoint. Top-level stock reflects the bundle’s own SKU.
  • selectionType: Single (pick one), Multiple (pick one or more), AlwaysIncluded (all products in the group are always part of the bundle — see the WHC Standard row).
Response — 404 (bundleId does not exist)
{
"type": "https://api.komplett.com/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "Bundle '9999999' not found.",
"instance": "/komplettpc/v1/bundles/9999999",
"code": "ERR_NOTFOUND",
"traceId": "00-0000000000000000000000000000000-0000000000000000-00"
}

Product Group Detail — GET /bundles/{bundleId}/{productGroupId}

Section titled “Product Group Detail — GET /bundles/{bundleId}/{productGroupId}”

Group with full product list, stock, no performance scores configured

Section titled “Group with full product list, stock, no performance scores configured”

Real response for the CPU AMD group (1fc7b7bc-...) — 31 products. Only the first few rows shown here; the same shape repeats for every product.

Response — WHC CPU AMD group (1fc7b7bc-...)
{
"id": "1fc7b7bc-1765-5afb-9a0c-947e0cb264d3",
"name": "WHC CPU AMD",
"selectionType": "Single",
"products": [
{
"productId": "1133573",
"isRecommended": true,
"performanceScore": null,
"stockStatus": null
},
{
"productId": "1172139",
"isRecommended": false,
"performanceScore": null,
"stockStatus": { "status": "InStock", "description": "48 st på lager.", "availabilityDate": null }
},
{
"productId": "1157954",
"isRecommended": false,
"performanceScore": null,
"stockStatus": {
"status": "NotInStock",
"description": "Beställningsvara. Beställs vid order. Leveranstid 1-2 veckor.",
"availabilityDate": "2026-10-06T22:00:00Z"
}
},
{
"productId": "1189380",
"isRecommended": false,
"performanceScore": null,
"stockStatus": { "status": "InStock", "description": "19 st på lager.", "availabilityDate": null }
}
],
"defaultProductId": "1217408",
"minimumAddedProfit": 0
}

Key points:

  • id echoes the productGroupId from the request URL — safe to round-trip.
  • isRecommended is a group-level hint from the Komplett admin (typically the CPU/GPU family flagship) — independent of the bundle’s defaultProductIds.
  • performanceScore is null for every product when the group has no PerformanceComponentType configured in the admin. When configured, it is an integer where the bundle’s default scores 0 and higher values indicate better performance.
  • stockStatus is null when the product was not found in inventory (e.g. discontinued SKUs still listed in the group).
  • availabilityDate is the expected availability of the product as an ISO 8601 timestamp, and is null when inventory holds no date.
  • defaultProductId is the group’s pre-selected product and the baseline every price difference in the group is measured from.
  • minimumAddedProfit is the net profit an upgrade must add on top of what that default product earns. It is 0 when the group sets none.
Response — 404 (productGroupId not part of bundle)
{
"type": "https://api.komplett.com/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "Product group '00000000-0000-0000-0000-000000000000' not found in bundle '1222702'.",
"instance": "/komplettpc/v1/bundles/1222702/00000000-0000-0000-0000-000000000000",
"code": "ERR_NOTFOUND",
"traceId": "00-0000000000000000000000000000000-0000000000000000-00"
}

Compatibility Validation — POST /compatibility/configuration

Section titled “Compatibility Validation — POST /compatibility/configuration”

Submit the full component selection (component productIds only — never the bundle ID). Returns isValid, plus any rule errors/warnings and a list of products excluded from rule evaluation.

Combination 1217408 (CPU) + 1221629 (GPU) + 1224870 (PSU) triggers the PSU Power CPU and GPU rule on the Itegra.se test data.

Request + Response — 200, isValid:false

Request:

{
"products": [
{ "productId": "1217408" },
{ "productId": "1221629" },
{ "productId": "1224870" }
]
}

Response:

{
"isValid": false,
"invalidProducts": [],
"errors": [
{
"ruleName": "PSU Power CPU and GPU",
"message": "Den nuvarande kombinationen av grafikkort och processor större nätaggregat",
"shortMessage": "Nätaggregatet är för litet",
"severity": "Error",
"relatedProducts": ["1217408", "1221629", "1224870"]
}
],
"warnings": [
{
"ruleName": "PSU power sufficient for CPU and GPU",
"message": "",
"shortMessage": "",
"category": "Compatibility",
"relatedProducts": ["1217408", "1221629", "1224870"]
}
]
}

Key points:

  • isValid is false because at least one rule fired with severity Error.
  • relatedProducts on each error/warning identifies which submitted product IDs the rule evaluated. Use this to highlight the specific rows in the UI.
  • Warnings can arrive with empty message / shortMessage when the underlying rule has no localized text configured — treat empty strings as “advisory, no user-facing copy”.
  • severity is currently Error for blocking violations. Warnings do not populate this field — they use the warnings[] array instead.
Response — 200, isValid:true
{
"isValid": true,
"invalidProducts": [],
"errors": [],
"warnings": []
}

A 200 OK with empty errors/warnings means “no known compatibility violations” — not a compatibility guarantee. Rules only fire for products that exist in Komplett’s compatibility catalog; see invalidProducts below.

Products not found in the compatibility catalog

Section titled “Products not found in the compatibility catalog”

Products submitted that have no entry in the catalog are listed in invalidProducts and silently excluded from rule evaluation. Their absence from the catalog does NOT count as an error — isValid can remain true.

Response — 200, isValid:true with invalidProducts
{
"isValid": true,
"invalidProducts": ["1204293", "1224896"],
"errors": [],
"warnings": []
}

Compatibility Batch — POST /compatibility/batch

Section titled “Compatibility Batch — POST /compatibility/batch”

Validate a set of candidate products against a base configuration. Common use: rendering a product picker where each option needs an inline compatible/incompatible label.

Only INCOMPATIBLE candidates appear in results. Compatible candidates produce no entry (compare against the products submitted in productsToValidate to know which passed).

One candidate incompatible, others compatible

Section titled “One candidate incompatible, others compatible”
Request + Response — 200, one PSU failure

Request:

{
"baseConfiguration": [{ "productId": "1217408" }, { "productId": "1221629" }],
"productsToValidate": [{ "productId": "1224870" }],
"productIdToReplace": null
}

Response:

{
"results": [
{
"productId": "1224870",
"validationResult": {
"isValid": false,
"invalidProducts": [],
"errors": [
{
"ruleName": "PSU Power CPU and GPU",
"message": "Den nuvarande kombinationen av grafikkort och processor större nätaggregat",
"shortMessage": "Nätaggregatet är för litet",
"severity": "Error",
"relatedProducts": ["1217408", "1221629", "1224870"]
}
],
"warnings": [
{
"ruleName": "PSU power sufficient for CPU and GPU",
"message": "",
"shortMessage": "",
"category": "Compatibility",
"relatedProducts": ["1217408", "1221629", "1224870"]
}
]
}
}
]
}

An empty results array means every candidate passed. This is not an error.

Response — 200, empty results
{
"results": []
}

Swap an existing component (productIdToReplace)

Section titled “Swap an existing component (productIdToReplace)”

Set productIdToReplace to the current product being swapped out. The engine removes it from the base configuration before running rules — so the candidate is evaluated as its replacement, not as an addition.

Request — replacing an existing GPU
{
"baseConfiguration": [
{ "productId": "1217408" },
{ "productId": "1221629" },
{ "productId": "1223222" }
],
"productsToValidate": [{ "productId": "1243373" }],
"productIdToReplace": "1221629"
}

Save Configuration — POST /configurations

Section titled “Save Configuration — POST /configurations”

Persists a selection and returns a stable identifier. Requires komplettpc:write scope.

Custom selection — GUID identifier returned

Section titled “Custom selection — GUID identifier returned”
Request + Response — 200 custom configuration

Request:

{
"bundleId": "1222702",
"products": [
{
"productId": "1189385",
"productGroupId": "1fc7b7bc-1765-5afb-9a0c-947e0cb264d3"
},
{
"productId": "1221885",
"productGroupId": "26e9bded-51ff-49be-dd2c-7d3848df4cb0"
},
{
"productId": "1219268",
"productGroupId": "3a6bcdf0-0b15-49ef-d9b4-6d6aac8f915b"
},
{
"productId": "1243373",
"productGroupId": "ce17be6a-92c0-ca9a-97ce-e1b11185a902"
},
{
"productId": "1219554",
"productGroupId": "1d86a9ca-1d65-c611-3c37-5abfb8346298"
},
{
"productId": "1218175",
"productGroupId": "44d73617-d4d7-a540-2c08-2e415c9af044"
},
{
"productId": "1223222",
"productGroupId": "00c5bc49-1900-d064-77f4-9f0ad6293f58"
},
{
"productId": "1200249",
"productGroupId": "1d85edb0-9233-15e3-3200-3d8a35abb1bf"
},
{
"productId": "200684",
"productGroupId": "ab994b03-788c-401c-1e67-0bf7427bd3b8"
},
{
"productId": "200739",
"productGroupId": "1042ca60-8470-4278-1496-afe10a1e3e00"
},
{
"productId": "200741",
"productGroupId": "1042ca60-8470-4278-1496-afe10a1e3e00"
},
{
"productId": "300468",
"productGroupId": "e714eebc-1de4-4e41-8fa8-bea61e269905"
}
]
}

Response:

{
"configurationId": "0b8a1dca-e651-4bf2-a2bd-4bde155a49f8"
}

Key points:

  • productGroupId values come straight from GET /bundles/{bundleId}. Do not substitute identifiers from other Komplett APIs.
  • AlwaysIncluded groups (here: 1042ca60-... “WHC Standard”) require every product the group holds — that’s why 200739 and 200741 both appear against the same productGroupId.
  • Groups with an empty defaultProductIds and selectionType != AlwaysIncluded (like “Instapak” in bundle 1222702) can be omitted from the payload when requireSelection is false.

Default selection short-circuit — numeric identifier returned

Section titled “Default selection short-circuit — numeric identifier returned”

When the submitted selection exactly matches the bundle’s default configuration, no storage write happens and the returned identifier is the numeric bundleId. Both forms are accepted identically by check-availability.

Response — 200 default selection
{
"configurationId": "1222702"
}

Product does not belong to the submitted group

Section titled “Product does not belong to the submitted group”

The product ID is valid, but is not part of the declared productGroupId’s catalog.

Response — 400
{
"type": "https://api.komplett.com/errors/validation",
"title": "Validation Failed",
"status": 400,
"detail": "The configuration is not valid for the given bundle.",
"instance": "/komplettpc/v1/configurations",
"code": "ERR_VALIDATION_0001",
"traceId": "00-0000000000000000000000000000000-0000000000000000-00",
"errors": [
{
"fieldName": "Body",
"message": "The configuration is not valid for the given bundle."
}
]
}

The API does not currently indicate which specific product caused the failure — surface a generic message to the customer and log the request payload for diagnosis.

Every product is for sale and sits in the right group, but the parts do not work together. Nothing is stored, so the caller gets no configuration identifier to retry with. Unlike the structural failure above, the message names the rule that refused the build.

Response — 400
{
"type": "https://api.komplett.com/errors/validation",
"title": "Validation Failed",
"status": 400,
"detail": "The configuration is not compatible: Chassit stöder inte en kylare på 360 mm. Välj en mindre kylare",
"instance": "/komplettpc/v1/configurations",
"code": "ERR_VALIDATION_0001",
"traceId": "00-0000000000000000000000000000000-0000000000000000-00",
"errors": [
{
"fieldName": "Body",
"message": "The configuration is not compatible: Chassit stöder inte en kylare på 360 mm. Välj en mindre kylare"
}
]
}

Call POST /compatibility/configuration while the customer is still picking parts, so this refusal is a safety net rather than the first time they hear about the problem. Only severity Error refuses a save; a Warning saves normally.

Response — 400
{
"type": "https://api.komplett.com/errors/validation",
"title": "Validation Failed",
"status": 400,
"detail": "Products list cannot be empty.",
"instance": "/komplettpc/v1/configurations",
"code": "ERR_VALIDATION_0001",
"traceId": "00-0000000000000000000000000000000-0000000000000000-00",
"errors": [
{ "fieldName": "Products", "message": "Products list cannot be empty." }
]
}

Check Availability — POST /configurations/check-availability

Section titled “Check Availability — POST /configurations/check-availability”

Verifies that every product in a saved configuration is currently in stock, and that the products still work together. Not cached — stock is calculated from child SKUs and changes constantly, and compatibility rules change too.

Request + Response — 200, isAvailable:true

Request:

{
"configurationId": "0b8a1dca-e651-4bf2-a2bd-4bde155a49f8"
}

Response:

{
"isAvailable": true,
"products": [
{
"productId": "1189385",
"productGroupId": "1fc7b7bc-1765-5afb-9a0c-947e0cb264d3",
"isAvailable": true
},
{
"productId": "1221885",
"productGroupId": "26e9bded-51ff-49be-dd2c-7d3848df4cb0",
"isAvailable": true
},
{
"productId": "1219268",
"productGroupId": "3a6bcdf0-0b15-49ef-d9b4-6d6aac8f915b",
"isAvailable": true
},
{
"productId": "1243373",
"productGroupId": "ce17be6a-92c0-ca9a-97ce-e1b11185a902",
"isAvailable": true
},
{
"productId": "1219554",
"productGroupId": "1d86a9ca-1d65-c611-3c37-5abfb8346298",
"isAvailable": true
},
{
"productId": "1218175",
"productGroupId": "44d73617-d4d7-a540-2c08-2e415c9af044",
"isAvailable": true
},
{
"productId": "1223222",
"productGroupId": "00c5bc49-1900-d064-77f4-9f0ad6293f58",
"isAvailable": true
},
{
"productId": "1200249",
"productGroupId": "1d85edb0-9233-15e3-3200-3d8a35abb1bf",
"isAvailable": true
},
{
"productId": "200684",
"productGroupId": "ab994b03-788c-401c-1e67-0bf7427bd3b8",
"isAvailable": true
},
{
"productId": "200739",
"productGroupId": "1042ca60-8470-4278-1496-afe10a1e3e00",
"isAvailable": true
},
{
"productId": "200741",
"productGroupId": "1042ca60-8470-4278-1496-afe10a1e3e00",
"isAvailable": true
},
{
"productId": "300468",
"productGroupId": "e714eebc-1de4-4e41-8fa8-bea61e269905",
"isAvailable": true
}
],
"rejectionReason": null
}

Top-level isAvailable flips to false when any single product is unavailable. Two common reasons:

  • The product has no active pricing (discontinued / end-of-life after the configuration was saved).
  • The product group has been removed from the bundle configuration since save time.

A third reason is covered separately below: every product is for sale, but together they break a compatibility rule.

Response — 200, isAvailable:false
{
"isAvailable": false,
"products": [
{
"productId": "1189385",
"productGroupId": "1fc7b7bc-1765-5afb-9a0c-947e0cb264d3",
"isAvailable": true
},
{
"productId": "1221885",
"productGroupId": "26e9bded-51ff-49be-dd2c-7d3848df4cb0",
"isAvailable": true
},
{
"productId": "1168127",
"productGroupId": "ce17be6a-92c0-ca9a-97ce-e1b11185a902",
"isAvailable": false
}
],
"rejectionReason": "ProductNotAvailable"
}

Every product is for sale, but the build breaks a compatibility rule

Section titled “Every product is for sale, but the build breaks a compatibility rule”

isAvailable is also false when the parts no longer work together, and rejectionReason is NotCompatible. Each entry in products stays isAvailable: true, because each part really is for sale on its own. It is the combination that is refused.

This happens on a configuration saved before a rule existed, since rules are added over time, and on one saved before the save endpoint started refusing incompatible builds.

Response — 200, isAvailable:false with rejectionReason NotCompatible

Chassis 1136152 is a case whose cooler mount does not take a 360 mm radiator, and 1224340 is a 360 mm cooler. Both are sold, and both belong to their product groups.

{
"isAvailable": false,
"products": [
{
"productId": "1136152",
"productGroupId": "68d36ae7-2f64-4104-b168-8f0f26fe2b19",
"isAvailable": true
},
{
"productId": "1224340",
"productGroupId": "b4033764-c3ff-4232-85cb-3182e6d1d7d5",
"isAvailable": true
}
],
"rejectionReason": "NotCompatible"
}

To tell the customer what is wrong, send the same products to POST /compatibility/configuration. That endpoint returns the rule name, the message, the short message and the parts that conflict. Show its shortMessage next to the components in relatedProducts, and keep the build out of the cart while rejectionReason is not null.

A rule of severity Warning never produces NotCompatible, exactly as it never sets isValid to false on the compatibility endpoint.

Default configuration identifier — numeric bundleId works too

Section titled “Default configuration identifier — numeric bundleId works too”

The numeric identifier returned by the default-selection short-circuit is accepted here without any caller-side distinction.

Request — numeric configurationId
{
"configurationId": "1222702"
}
Response — 404
HTTP/1.1 404 Not Found

Body is empty on 404 for this endpoint.


The whole game catalogue in one call. Store-independent and cached upstream for an hour, so fetch it once per session. Responses are large; the samples below are truncated. Titles only — artwork comes from POST /games/details.

Response — game titles
{
"games": [
{
"gameId": "elden ring",
"title": "Elden Ring",
"alternativeTitles": []
},
{
"gameId": "cyberpunk 2077",
"title": "Cyberpunk 2077",
"alternativeTitles": ["cp77"]
},
{
"gameId": "counter-strike 2",
"title": "Counter-Strike 2",
"alternativeTitles": ["cs2", "cs 2"]
}
]
}

An empty catalogue is a success, not a 404.

Response — 200, no games
{
"games": []
}

Artwork for the games you are about to render. One entry per requested gameId, always in request order. coverImage is the portrait 2:3 cover, thumbnailImage the square 1:1 tile — pick whichever fits your layout, or take both.

Request + Response — 200, cover and thumbnail

Request:

{
"gameIds": ["elden ring", "cyberpunk 2077"]
}

Response:

{
"games": [
{
"gameId": "elden ring",
"title": "Elden Ring",
"coverImage": "https://images.komplett.no/games/elden-ring-cover.jpg",
"thumbnailImage": "https://images.komplett.no/games/elden-ring-thumb.jpg"
},
{
"gameId": "cyberpunk 2077",
"title": "Cyberpunk 2077",
"coverImage": "https://images.komplett.no/games/cyberpunk-2077-cover.jpg",
"thumbnailImage": "https://images.komplett.no/games/cyberpunk-2077-thumb.jpg"
}
]
}

Unknown game id — echoed as nulls, not dropped

Section titled “Unknown game id — echoed as nulls, not dropped”

The response array always has the same length as gameIds, so you can zip the two together.

Request + Response — 200, one unknown id

Request:

{
"gameIds": ["elden ring", "not-a-game"]
}

Response:

{
"games": [
{
"gameId": "elden ring",
"title": "Elden Ring",
"coverImage": "https://images.komplett.no/games/elden-ring-cover.jpg",
"thumbnailImage": "https://images.komplett.no/games/elden-ring-thumb.jpg"
},
{
"gameId": "not-a-game",
"title": null,
"coverImage": null,
"thumbnailImage": null
}
]
}

Known game with partial or missing artwork

Section titled “Known game with partial or missing artwork”

A game can resolve — title is populated — while one or both image variants are null. Render a placeholder for the missing variant rather than hiding the entry.

Response — 200, thumbnail only
{
"games": [
{
"gameId": "some obscure indie game",
"title": "Some Obscure Indie Game",
"coverImage": null,
"thumbnailImage": "https://images.komplett.no/games/some-obscure-indie-game-thumb.jpg"
}
]
}

Same rule as /games/performance: only the gameId from GET /games resolves. "cp77" comes back as an unknown id rather than an error.

Request + Response — 200, alias returns nulls

Request:

{
"gameIds": ["cp77"]
}

Response:

{
"games": [
{ "gameId": "cp77", "title": null, "coverImage": null, "thumbnailImage": null }
]
}
Response — 400, validation failed
{
"type": "https://docs.komplett.no/errors/validation-failed",
"title": "Validation Failed",
"detail": "Some fields have validation errors",
"status": 400,
"instance": "/komplettpc/v1/games/details",
"code": "ERR_VALIDATION_0001",
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"errors": [
{ "fieldName": "GameIds", "message": "GameIds cannot be empty." }
]
}

Game Performance — POST /games/performance

Section titled “Game Performance — POST /games/performance”

One verdict per requested gameId, always in request order.

Request + Response — 200, three verdicts

Request:

{
"productIds": ["1321680", "1189385", "1211235"],
"gameIds": ["elden ring", "cyberpunk 2077", "counter-strike 2"]
}

Response:

{
"games": [
{
"gameId": "elden ring",
"title": "Elden Ring",
"status": "RecommendedRequirementsMet",
"coverImage": "https://images.komplett.no/games/elden-ring.jpg",
"thumbnailImage": "https://images.komplett.no/games/elden-ring-thumb.jpg"
},
{
"gameId": "cyberpunk 2077",
"title": "Cyberpunk 2077",
"status": "MinimumRequirementsMet",
"coverImage": "https://images.komplett.no/games/cyberpunk-2077.jpg",
"thumbnailImage": "https://images.komplett.no/games/cyberpunk-2077-thumb.jpg"
},
{
"gameId": "counter-strike 2",
"title": "Counter-Strike 2",
"status": "RecommendedRequirementsMet",
"coverImage": "https://images.komplett.no/games/counter-strike-2.jpg",
"thumbnailImage": "https://images.komplett.no/games/counter-strike-2-thumb.jpg"
}
]
}

Unknown game id — echoed as NotKnown, not dropped

Section titled “Unknown game id — echoed as NotKnown, not dropped”

The response array always has the same length as gameIds, so you can zip the two together.

Request + Response — 200, one unknown id

Request:

{
"productIds": ["1321680"],
"gameIds": ["elden ring", "not-a-game"]
}

Response:

{
"games": [
{
"gameId": "elden ring",
"title": "Elden Ring",
"status": "MinimumRequirementsMet",
"coverImage": "https://images.komplett.no/games/elden-ring.jpg",
"thumbnailImage": "https://images.komplett.no/games/elden-ring-thumb.jpg"
},
{
"gameId": "not-a-game",
"title": null,
"status": "NotKnown",
"coverImage": null,
"thumbnailImage": null
}
]
}

GET /games reports "cyberpunk 2077" with alternativeTitles: ["cp77"]. Only the gameId matches here — resolve aliases yourself before calling.

Request + Response — 200, alias returns NotKnown

Request:

{
"productIds": ["1321680"],
"gameIds": ["cp77"]
}

Response:

{
"games": [
{ "gameId": "cp77", "title": null, "status": "NotKnown", "coverImage": null, "thumbnailImage": null }
]
}

Component matching covers CPU and GPU. A build of only a chassis and a PSU yields no verdict.

Request + Response — 200, all NotKnown

Request:

{
"productIds": ["1102030"],
"gameIds": ["elden ring"]
}

Response:

{
"games": [
{ "gameId": "elden ring", "title": "Elden Ring", "status": "NotKnown", "coverImage": "https://images.komplett.no/games/elden-ring.jpg", "thumbnailImage": "https://images.komplett.no/games/elden-ring-thumb.jpg" }
]
}
Response — 400, validation failed
{
"type": "https://docs.komplett.no/errors/validation-failed",
"title": "Validation Failed",
"detail": "Some fields have validation errors",
"status": 400,
"instance": "/komplettpc/v1/games/performance",
"code": "ERR_VALIDATION_0001",
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"errors": [
{ "fieldName": "ProductIds", "message": "ProductIds cannot be empty." }
]
}

Typical partner flow using the endpoints above:

  1. GET /bundles/{bundleId} — discover which product groups the bundle has and pre-populate the UI with defaultProductIds per group.
  2. GET /bundles/{bundleId}/{productGroupId} — for each group the user opens, list the available products with stock and (when configured) performance scores.
  3. POST /compatibility/batch — as the user browses replacements in a group, validate all candidates against the current selection so incompatible options can be labelled inline.
  4. POST /compatibility/configuration — before letting the user save/checkout, validate the full selection as one final check.
  5. POST /configurations — persist the finished selection → keep the configurationId.
  6. POST /configurations/check-availability — call this before adding the configuration to a cart or at any point where current availability must be confirmed. Do not cache.

The configurationId from step 5 is the identifier that flows on into Checkout / order placement — a single SKU that represents the whole build.