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}”Full bundle structure
Section titled “Full bundle structure”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:
productGroupIdis per-bundle — the same GUID identifies the same slot on subsequent save/check-availability calls. Do not hardcode these across bundles.defaultProductIdsholds every product pre-selected in the group. ForAlwaysIncludedgroups that is every product the group holds — send all of them when saving a configuration (the WHC Standard row above needs both200739and200741). ForSingleandMultiplegroups it holds the one pre-selected product, and is[]when no bundle-level default is configured.stockon a group is the stock of the pre-selected product, and only whendefaultProductIdsholds exactly one. It isnullwhen 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-levelstockreflects 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).
Bundle not found
Section titled “Bundle not found”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:
idechoes theproductGroupIdfrom the request URL — safe to round-trip.isRecommendedis a group-level hint from the Komplett admin (typically the CPU/GPU family flagship) — independent of the bundle’sdefaultProductIds.performanceScoreisnullfor every product when the group has noPerformanceComponentTypeconfigured in the admin. When configured, it is an integer where the bundle’s default scores0and higher values indicate better performance.stockStatusisnullwhen the product was not found in inventory (e.g. discontinued SKUs still listed in the group).availabilityDateis the expected availability of the product as an ISO 8601 timestamp, and isnullwhen inventory holds no date.defaultProductIdis the group’s pre-selected product and the baseline every price difference in the group is measured from.minimumAddedProfitis the net profit an upgrade must add on top of what that default product earns. It is0when the group sets none.
Group not found in this bundle
Section titled “Group not found in this bundle”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.
Invalid — PSU cannot support CPU + GPU
Section titled “Invalid — PSU cannot support CPU + GPU”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:
isValidisfalsebecause at least one rule fired with severityError.relatedProductson 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/shortMessagewhen the underlying rule has no localized text configured — treat empty strings as “advisory, no user-facing copy”. severityis currentlyErrorfor blocking violations. Warnings do not populate this field — they use thewarnings[]array instead.
Valid — all products pass every rule
Section titled “Valid — all products pass every rule”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"] } ] } } ]}All candidates compatible
Section titled “All candidates compatible”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:
productGroupIdvalues come straight fromGET /bundles/{bundleId}. Do not substitute identifiers from other Komplett APIs.AlwaysIncludedgroups (here:1042ca60-...“WHC Standard”) require every product the group holds — that’s why200739and200741both appear against the sameproductGroupId.- Groups with an empty
defaultProductIdsandselectionType != AlwaysIncluded(like “Instapak” in bundle1222702) can be omitted from the payload whenrequireSelectionisfalse.
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.
Build breaks a compatibility rule
Section titled “Build breaks a compatibility rule”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.
Empty product list
Section titled “Empty product list”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.
All products available
Section titled “All products available”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}At least one product no longer available
Section titled “At least one product no longer available”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"}Configuration not found
Section titled “Configuration not found”Response — 404
HTTP/1.1 404 Not FoundBody is empty on 404 for this endpoint.
Games — GET /games
Section titled “Games — GET /games”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.
Full catalogue
Section titled “Full catalogue”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"] } ]}Empty catalogue
Section titled “Empty catalogue”An empty catalogue is a success, not a 404.
Response — 200, no games
{ "games": []}Game Details — POST /games/details
Section titled “Game Details — POST /games/details”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.
Both variants for a picker row
Section titled “Both variants for a picker row”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" } ]}Aliases resolve to nothing here either
Section titled “Aliases resolve to nothing here either”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 } ]}Empty game list
Section titled “Empty game list”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.
Mixed verdicts across a build
Section titled “Mixed verdicts across a build”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 } ]}An alternative title is not a game id
Section titled “An alternative title is not a game id”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 } ]}No recognisable components in the build
Section titled “No recognisable components in the build”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" } ]}Empty product list
Section titled “Empty product list”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." } ]}End-to-end sample flow
Section titled “End-to-end sample flow”Typical partner flow using the endpoints above:
GET /bundles/{bundleId}— discover which product groups the bundle has and pre-populate the UI withdefaultProductIdsper group.GET /bundles/{bundleId}/{productGroupId}— for each group the user opens, list the available products with stock and (when configured) performance scores.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.POST /compatibility/configuration— before letting the user save/checkout, validate the full selection as one final check.POST /configurations— persist the finished selection → keep theconfigurationId.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.