Skip to content

KomplettPC API Overview

The KomplettPC API gives partners access to Komplett’s PC configurator: browse bundles and product groups, validate compatibility between selected components, save a finished configuration, and check stock availability. It is the integration surface for building a custom configurator front end on top of Komplett’s configuration and production capabilities.

All request/response examples use placeholder values; field names and types match what the API accepts and returns.


https://<store-url>/public/komplettpc/v1

<store-url> is the unique base URL issued to your store as part of onboarding (see Getting Started → Base URL). All paths below are relative to it.


Every request must be authenticated. You need two credentials on each call:

Header Value Purpose
Authorization Bearer <access_token> OAuth 2.0 JWT access token
Ocp-Apim-Subscription-Key <your-subscription-key> Identifies your subscription at the API gateway
  • The access token must carry komplettpc:read for all read operations, or komplettpc:write to save configurations. A token without the required scope is rejected with 403 Forbidden.
  • Tokens are short-lived (currently 30 minutes). Request a new one when the old one expires. See Getting Started → Authentication for the token flow.

Method Path Scope Description
GET /bundles/{bundleId} komplettpc:read Get bundle structure
GET /bundles/{bundleId}/{productGroupId} komplettpc:read Get products in a product group
POST /compatibility/configuration komplettpc:read Validate a full product selection for compatibility
POST /compatibility/batch komplettpc:read Validate candidate products against a base configuration
POST /configurations komplettpc:write Save a finished configuration
POST /configurations/check-availability komplettpc:read Check availability and compatibility of a saved configuration
GET /games komplettpc:read Get all game titles known to the configurator
POST /games/details komplettpc:read Get cover and thumbnail artwork for a set of games
POST /games/performance komplettpc:read Calculate how a set of products performs against a set of games
GET /prices/components komplettpc:read Get your purchase price for every component you may buy

GET /bundles/{bundleId}

Returns the bundle structure: its product groups, the default product in each group, selection rules, and stock status.

Path parameters

Name Type Required Description
bundleId string yes Unique identifier of the bundle (numeric string).

Responses

Status Meaning
200 OK Bundle found. Body is a GetBundleResponse.
400 Bad Request bundleId is empty or invalid.
401 Unauthorized Missing or invalid token.
403 Forbidden Token lacks komplettpc:read.
404 Not Found No bundle exists with that identifier.
500 Internal Server Error Unexpected server error.

Example response (200 OK)

{
"bundleId": "1224896",
"name": "Komplett PC Gamer Pro",
"assemblyTime": { "from": 3, "to": 5 },
"stock": { "status": "in-stock", "description": "In stock", "availabilityDate": null },
"productGroups": [
{
"productGroupId": "a1b2c3d4-0000-0000-0000-000000000001",
"name": "Processor",
"order": 1,
"defaultProductIds": ["1321680"],
"selectionType": "Single",
"requireSelection": true,
"stock": { "status": "in-stock", "description": "In stock", "availabilityDate": null }
},
{
"productGroupId": "a1b2c3d4-0000-0000-0000-000000000002",
"name": "Standard Components",
"order": 2,
"defaultProductIds": ["200504", "836114"],
"selectionType": "AlwaysIncluded",
"requireSelection": false,
"stock": null
}
]
}

GET /bundles/{bundleId}/{productGroupId}

Returns the products available in a specific product group within a bundle.

Path parameters

Name Type Required Description
bundleId string yes Unique identifier of the bundle.
productGroupId string (GUID) yes Unique identifier of the product group.

Responses

Status Meaning
200 OK Product group found. Body is a GetBundleProductGroupResponse.
400 Bad Request A path parameter is empty or invalid.
401 Unauthorized Missing or invalid token.
403 Forbidden Token lacks komplettpc:read.
404 Not Found No bundle or product group exists with the given identifiers.
500 Internal Server Error Unexpected server error.

Example response (200 OK)

{
"id": "a1b2c3d4-0000-0000-0000-000000000001",
"name": "Processor",
"selectionType": "Single",
"defaultProductId": "1321680",
"products": [
{
"productId": "1321680",
"isRecommended": true,
"performanceScore": 85,
"stockStatus": { "status": "in-stock", "description": "In stock", "availabilityDate": null }
},
{
"productId": "1321681",
"isRecommended": false,
"performanceScore": 72,
"stockStatus": { "status": "low-stock", "description": "Low stock", "availabilityDate": "2026-11-10T00:00:00Z" }
}
],
"minimumAddedProfit": 300
}

POST /compatibility/configuration

Validates whether a given set of products forms a compatible configuration. Returns a validation result with any compatibility errors and warnings.

Request body (application/json)

Field Type Required Description
products ProductReference[] yes The full set of products to validate. Must contain at least one item.

Responses

Status Meaning
200 OK Validation complete. Body is a CompatibilityValidationResult. A 200 does not mean the configuration is valid — check isValid in the response body.
400 Bad Request products is empty or contains invalid entries.
401 Unauthorized Missing or invalid token.
403 Forbidden Token lacks komplettpc:read.
500 Internal Server Error Unexpected server error.

Example request

{
"products": [
{ "productId": "1321680" },
{ "productId": "1234567" }
]
}

Example response (200 OK)

{
"isValid": false,
"invalidProducts": ["1234567"],
"errors": [
{
"ruleName": "CpuSocketCompatibility",
"message": "The selected CPU is not compatible with the motherboard socket.",
"shortMessage": "Incompatible socket",
"severity": "Error",
"relatedProducts": ["1321680", "1234567"]
}
],
"warnings": []
}

POST /compatibility/batch

Validates each candidate product individually against a base configuration, returning per-product compatibility results. Use this to render compatible/incompatible states on a product list while a user is browsing replacement options.

Request body (application/json)

Field Type Required Description
baseConfiguration ProductReference[] yes The current build to validate against. Must contain at least one item.
productsToValidate ProductReference[] yes Candidate products to test individually. Must contain at least one item.
productIdToReplace string | null no If set, this product is removed from baseConfiguration before each candidate is tested — simulating a swap.

Responses

Status Meaning
200 OK Validation complete. Body is a ValidateCompatibilityBatchResponse.
400 Bad Request baseConfiguration or productsToValidate is empty, or contains invalid entries.
401 Unauthorized Missing or invalid token.
403 Forbidden Token lacks komplettpc:read.
500 Internal Server Error Unexpected server error.

Example request

{
"baseConfiguration": [
{ "productId": "1321680" },
{ "productId": "9876543" }
],
"productsToValidate": [
{ "productId": "1234567" },
{ "productId": "1234568" }
],
"productIdToReplace": "1321680"
}

Example response (200 OK)

{
"results": [
{
"productId": "1234567",
"validationResult": {
"isValid": true,
"invalidProducts": [],
"errors": [],
"warnings": []
}
},
{
"productId": "1234568",
"validationResult": {
"isValid": false,
"invalidProducts": ["1234568"],
"errors": [
{
"ruleName": "CpuSocketCompatibility",
"message": "The selected CPU is not compatible with the motherboard socket.",
"shortMessage": "Incompatible socket",
"severity": "Error",
"relatedProducts": ["9876543", "1234568"]
}
],
"warnings": []
}
}
]
}

POST /configurations

Persists a completed PC configuration and returns a unique configuration identifier. Pass this identifier to the Checkout API to place an order for the saved build.

A configuration that breaks a compatibility rule is refused with 400 and never stored, so a saved identifier always refers to a build that was buildable at save time. Call Validate compatibility configuration while the customer is still choosing parts, so the refusal here is only a safety net rather than the first time they hear about it.

Requires komplettpc:write scope.

Request body (application/json)

Field Type Required Description
bundleId string yes The bundle identifier for the PC build.
products SaveConfigurationProduct[] yes The selected components — one entry per product group. Must contain at least one item.

SaveConfigurationProduct

Field Type Required Description
productId string yes Product identifier (numeric string).
productGroupId string (GUID) yes The product group this product belongs to in the bundle. Must not be an empty GUID.

Responses

Status Meaning
200 OK Configuration saved. Body is a SaveConfigurationResponse.
400 Bad Request Request body failed validation (empty products, invalid GUID, etc.), the selection does not fit the bundle, or it breaks a compatibility rule. The message names the reason.
401 Unauthorized Missing or invalid token.
403 Forbidden Token lacks komplettpc:write.
404 Not Found The referenced bundle or product was not found.
500 Internal Server Error Unexpected server error.

Example request

{
"bundleId": "1224896",
"products": [
{ "productId": "1321680", "productGroupId": "a1b2c3d4-0000-0000-0000-000000000001" },
{ "productId": "9876543", "productGroupId": "a1b2c3d4-0000-0000-0000-000000000002" }
]
}

Example response (200 OK)

{
"configurationId": "kpc-abc123def456"
}

POST /configurations/check-availability

Checks whether all products in a saved configuration are currently in stock, and whether they still work together. Returns an overall flag, a per-product breakdown, and the reason the build was refused when it was.

Compatibility is re-checked here because rules change after a configuration is saved. A build that was fine at save time can break a rule added later, and this is the last call before the configuration reaches the cart.

rejectionReason says which kind of problem it was, not the detail. When it is NotCompatible, call Validate compatibility configuration with the same products for the rule name, the message and the parts that conflict.

Stock is calculated from child SKUs and changes frequently — do not cache this response.

Request body (application/json)

Field Type Required Description
configurationId string yes The configuration identifier returned by Save configuration.

Responses

Status Meaning
200 OK Check complete. Body is a CheckAvailabilityResponse.
400 Bad Request configurationId is empty or invalid.
401 Unauthorized Missing or invalid token.
403 Forbidden Token lacks komplettpc:read.
404 Not Found No configuration exists with the given identifier.
500 Internal Server Error Unexpected server error.

Example request

{
"configurationId": "kpc-abc123def456"
}

Example response (200 OK)

{
"isAvailable": false,
"products": [
{ "productId": "1321680", "productGroupId": "a1b2c3d4-0000-0000-0000-000000000001", "isAvailable": true },
{ "productId": "9876543", "productGroupId": "a1b2c3d4-0000-0000-0000-000000000002", "isAvailable": false }
]
}

GET /games

Returns every game title the configurator knows about. Use it to populate a game picker. alternativeTitles carries the aliases and alternate spellings a customer might type instead of the canonical title, so you can match user input without your own fuzzy-matching table.

The response carries no artwork — it is a plain title list. Fetch images for the handful of games you actually render with Get game details.

The list is global — it is not scoped to your store — and is cached upstream for one hour. Fetch it once per session rather than per interaction.

Path and query parameters

None.

Responses

Status Meaning
200 OK Body is a GetGamesResponse. Also returned, with an empty games array, when the catalogue has no entries.
401 Unauthorized Missing or invalid token.
403 Forbidden Token lacks komplettpc:read.
500 Internal Server Error Unexpected server error.

Example response (200 OK)

{
"games": [
{ "gameId": "elden ring", "title": "Elden Ring", "alternativeTitles": [] },
{ "gameId": "cyberpunk 2077", "title": "Cyberpunk 2077", "alternativeTitles": ["cp77"] }
]
}

POST /games/details

Returns the artwork for the given games — one entry per requested gameId, in request order. Pair it with Get games: fetch the catalogue once for search and titles, then call this for the handful of games you are about to render.

Two image variants come back, both absolute URLs on Komplett’s image host and both nullable:

Field Aspect ratio Typical use
coverImage Portrait, 2:3 (some titles are 5:7) Cover-art panels, detail views, hero images
thumbnailImage Square, 1:1 Grid tiles and picker cards — this is the variant Komplett’s own game picker renders

The ratios are what the catalogue holds for the overwhelming majority of titles, not a guarantee: a title with no proper cover art falls back to whatever image the source provides, which may be a logo or store banner at another ratio. Read the intrinsic dimensions if exact layout matters, and always handle null — see Get game details response.

Like the catalogue, this endpoint is global rather than store-scoped, and the underlying data is cached upstream for one hour.

Request body (application/json)

Field Type Required Description
gameIds string[] yes Games to fetch. 1–50 items, each 1–200 characters. Use the gameId field from Get games.

Responses

Status Meaning
200 OK Body is a GetGameDetailsResponse, with exactly one entry per requested gameId, in request order.
400 Bad Request gameIds is empty, longer than 50 items, or contains a malformed id.
401 Unauthorized Missing or invalid token.
403 Forbidden Token lacks komplettpc:read.
500 Internal Server Error Unexpected server error.

Example request

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

Example response (200 OK)

{
"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
}
]
}

POST /games/performance

Estimates how a build performs against a list of games. Send the products the customer has selected and the games they care about; each game comes back with one of four verdicts.

Component matching covers CPU and GPU only. Products that aren’t recognised as a supported component are ignored rather than rejected, so a request containing a chassis and a power supply alongside a graphics card still produces a useful answer. If no product resolves to a recognised component, every game returns NotKnown.

Request body (application/json)

Field Type Required Description
productIds string[] yes Products in the build. 1–100 items, each 1–128 alphanumeric characters, underscores, or hyphens. Ids the catalogue does not know are ignored.
gameIds string[] yes Games to evaluate. 1–50 items, each 1–200 characters. Use the gameId field from Get games.

Responses

Status Meaning
200 OK Body is a CalculateGamePerformanceResponse, with exactly one entry per requested gameId, in request order.
400 Bad Request A list is empty, too long, or contains a malformed id.
401 Unauthorized Missing or invalid token.
403 Forbidden Token lacks komplettpc:read.
500 Internal Server Error Unexpected server error.

Example request

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

Example response (200 OK)

{
"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": "not-a-game",
"title": null,
"status": "NotKnown",
"coverImage": null,
"thumbnailImage": null
}
]
}

GET /prices/components

Returns customer-related price for every component the configurator offers and you are allowed to buy. This is the price you pay Komplett, not a retail price, so you set your own customer-facing prices on top of it.

Fetch it on a schedule and cache the result. Hourly is enough, and it is what the feed is designed for: the response is the whole component catalogue rather than a single lookup.

Path and query parameters

None.

Responses

Status Meaning
200 OK Body is a GetComponentPricesResponse.
401 Unauthorized Missing or invalid token.
403 Forbidden Token lacks komplettpc:read, or purchase prices are not enabled for your account.
422 Unprocessable Content No prices could be produced.
500 Internal Server Error Unexpected server error.

Example response (200 OK)

{
"prices": [
{ "productId": "1176353", "net": 7981.02, "gross": 9976.28, "vatRate": 25.00 },
{ "productId": "1201391", "net": 1284.07, "gross": 1605.09, "vatRate": 25.00 }
]
}

Used in POST /compatibility/configuration (products) and POST /compatibility/batch (baseConfiguration, productsToValidate).

Field Type Required Description
productId string yes Numeric product identifier (e.g. "1321680").

Field Type Description
bundleId string Bundle identifier.
name string Display name of the bundle.
assemblyTime AssemblyConfiguration | null Estimated assembly time in business days. null if not set.
stock StockStatus | null Overall bundle stock status. null if not available.
productGroups ProductGroupInBundle[] Product groups that make up the bundle, in display order.

AssemblyConfiguration

Field Type Description
from integer Minimum estimated assembly days.
to integer Maximum estimated assembly days.

ProductGroupInBundle

Field Type Description
productGroupId string (GUID) Unique identifier of the product group.
name string Display name.
order integer Display position within the bundle (ascending).
defaultProductIds string[] Every product pre-selected in this group. For AlwaysIncluded groups this is every product the group holds — include all of them when saving a configuration. For Single and Multiple groups it holds the one pre-selected product, and is empty when no default is configured.
selectionType ProductGroupSelectionType Selection rule for this group.
requireSelection boolean Whether a selection is mandatory before saving the configuration.
stock StockStatus | null Stock of the pre-selected product, when defaultProductIds holds exactly one. null when the group has no default, when it has several — as AlwaysIncluded groups usually do — or when the product was not found in inventory. Per-product stock for a group is on Get bundle product group.

Field Type Description
id string (GUID) Unique identifier of the product group.
name string Display name.
selectionType ProductGroupSelectionType Selection rule for this group.
defaultProductId string | null Identifier of the product pre-selected in this group and used as the price-difference baseline (zero diff on this product). Stock-adjusted at read time: if the admin-configured primary is out of stock, this transparently returns the configured alternative. null if no default is configured for the group.
products ProductInGroup[] Products available in this group.
minimumAddedProfit number Amount of net profit an upgrade in this group must add on top of what the default product earns before it is priced at the plain difference between the two prices. 0 when the group sets none.

ProductInGroup

Field Type Description
productId string Product identifier.
isRecommended boolean Whether this is the recommended choice in the group.
performanceScore integer | null Relative performance score (higher is better). null if not set.
stockStatus StockStatus | null Stock status for this product. null if not available.

Returned directly by POST /compatibility/configuration, and nested under each results[].validationResult by POST /compatibility/batch.

Field Type Description
isValid boolean true if the configuration has no errors. Warnings do not affect this flag.
invalidProducts string[] Product identifiers that caused compatibility errors. Empty when valid.
errors CompatibilityError[] Compatibility rule violations. Empty when valid.
warnings CompatibilityWarning[] Non-blocking compatibility notices.

CompatibilityError

Field Type Description
ruleName string Internal rule identifier.
message string Full human-readable error message.
shortMessage string Short message suitable for inline display.
severity string Severity level (e.g. "Error").
relatedProducts string[] Product identifiers involved in the rule violation.

CompatibilityWarning

Field Type Description
ruleName string Internal rule identifier.
message string Full human-readable warning message.
shortMessage string Short message suitable for inline display.
category string Warning category.
relatedProducts string[] Product identifiers relevant to the warning.

Field Type Description
results ProductValidationResult[] One entry per product in productsToValidate, in the same order.

ProductValidationResult

Field Type Description
productId string The candidate product identifier.
validationResult CompatibilityValidationResult Compatibility result for this product against the base configuration.

Field Type Description
configurationId string Unique identifier for the saved configuration. Pass this to the Checkout API to place an order for this build.

Field Type Description
isAvailable boolean true only if all products in the configuration are currently available and the configuration breaks no compatibility rule.
products ConfigurationProductStatus[] Per-product availability breakdown.
rejectionReason string | null null when isAvailable is true. Otherwise the single reason the build was refused: ProductNotAvailable, NotCompatible or ConfigurationNotValid, described in the table below.

ConfigurationProductStatus

Field Type Description
productId string Product identifier.
productGroupId string (GUID) Product group this product belongs to.
isAvailable boolean Whether this specific product is currently in stock. A compatibility error does not change this, because each part can be for sale while the combination is refused.

Rejection reasons

isAvailable is true only when none of these apply. At most one is reported, in the order below, so a build that trips two reasons names the first.

Value Meaning What the customer has to do
ConfigurationNotValid The saved configuration no longer fits the bundle, usually because a product group was removed since it was saved. Start a new build.
ProductNotAvailable At least one part is no longer for sale. products[].isAvailable names which. Swap that part.
NotCompatible Every part is for sale, but together they break a compatibility rule. Swap one of the conflicting parts. Send the same products to Validate compatibility configuration to find out which rule broke and which parts conflict.

Field Type Description
games GamePerformance[] One entry per requested gameId, in the order they were sent.

GamePerformance

Field Type Description
gameId string Echo of the gameId you sent, so entries can be correlated without re-normalising titles.
title string | null Canonical display title. null when the game id is not in the catalogue.
status GamePerformanceStatus The verdict for this game.
coverImage string | null Portrait cover artwork, the same 2:3 variant Get game details returns. null when the game is unknown or has no image on file.
thumbnailImage string | null Square 1:1 thumbnail, the same variant Get game details returns. null under the same conditions as coverImage; a game can have one variant and not the other.

Field Type Description
games Game[] All game titles known to the configurator. Empty when the catalogue has no entries.

Game

Field Type Description
gameId string Stable identifier of the game — the canonical title in lower case, e.g. "elden ring". This is the value Get game details and Calculate game performance expect in gameIds.
title string Canonical display title.
alternativeTitles string[] Aliases and alternate spellings, for mapping free-text customer input onto gameId. Empty when the game has none. Not accepted as input by Get game details or Calculate game performance — send gameId there.

Field Type Description
games GameDetails[] One entry per requested gameId, in the order they were sent.

GameDetails

Field Type Description
gameId string Echo of the gameId you sent, so entries can be correlated without re-normalising titles.
title string | null Canonical display title. null when the game id is not in the catalogue.
coverImage string | null Portrait cover artwork, 2:3 for most titles and 5:7 for a few. null when the game is unknown or has no artwork on file.
thumbnailImage string | null Square 1:1 thumbnail, sized for grid tiles. null under the same conditions as coverImage; a game can have one variant and not the other.

Both fields are absolute URLs. The ratios above describe the catalogue’s normal content rather than a contract — where a title has no proper cover art the source image (a logo or store banner) is used as is, at whatever ratio it happens to be. Constrain with CSS, or read the intrinsic dimensions, if your layout depends on the exact shape.


Field Type Description
prices ComponentPrice[] One entry per component you may buy and Komplett holds a cost for. Never empty on a 200.

ComponentPrice

Field Type Description
productId string Numeric product identifier, the same value used in a product group’s products and in Save configuration.
net decimal Your purchase price excluding VAT, in the currency of the store on your token.
gross decimal The same price including VAT, rounded to two decimals. Derived from net and vatRate, never stored separately.
vatRate decimal VAT as a percentage, so 25.00 means 25 percent. Not an amount.

Field Type Description
status string Stable machine-readable stock discriminator. Closed enum: "in-stock", "low-stock", "out-of-stock".
description string | null Localized, display-only stock description. null if not available.
availabilityDate string (date-time) | null Expected availability of the product, as an ISO 8601 timestamp. null if not available.

Controls how a user may select products within a product group.

Value Meaning
Single Exactly one product must be selected.
Multiple One or more products may be selected.
AlwaysIncluded The product group is always included and cannot be deselected.

The verdict for one game against one build. Serialized as a string. Closed enum — treat any unrecognised value as NotKnown.

Value Meaning
RecommendedRequirementsMet The build meets or exceeds the game’s recommended requirements.
MinimumRequirementsMet The build meets the minimum requirements but not the recommended ones.
RequirementsNotMet The build does not meet the game’s minimum requirements.
NotKnown No verdict could be reached — the game id is unknown, the game has no requirements on file, or no submitted product resolved to a supported CPU or GPU.

All errors use the RFC 9457 / RFC 7807 Problem Details JSON format.

Problem Details

Field Type Description
type string (URI) Identifies the error category.
title string Short, human-readable summary.
detail string Explanation specific to this occurrence.
status integer HTTP status code.
instance string The request path that produced the error.
code string Stable machine-readable error code.
traceId string Correlation id; also in the X-Trace-Id response header. Quote it when contacting support.

Validation errors (400) include an additional errors array, one entry per invalid field:

{
"type": "...",
"title": "Validation Failed",
"detail": "Some fields have validation errors",
"status": 400,
"instance": "/komplettpc/v1/configurations",
"code": "ERR_VALIDATION_0001",
"traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"errors": [
{ "fieldName": "Products", "message": "Products must not be empty." }
]
}

Status / code reference

HTTP status code When it happens
400 Bad Request ERR_VALIDATION_0001 A request field failed validation. See errors[].
401 Unauthorized — Missing, malformed, or expired token.
403 Forbidden ERR_ACCESS Token lacks the required scope.
404 Not Found ERR_NOTFOUND The referenced bundle, product group, or configuration was not found.
500 Internal Server Error InternalServerError Unexpected server error. Retry later; quote the trace id if it persists.