---
title: "Resolve a catalog selection"
method: POST
path: "/companies/{company}/products/{product}/resolve-selection"
tags: ["Products"]
---

# Resolve a catalog selection

`POST /companies/{company}/products/{product}/resolve-selection`

## Request

- Base URL: `https://api.factuarea.com/v1`
- URL: `https://api.factuarea.com/v1/companies/{company}/products/{product}/resolve-selection`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Resolve a partial or complete catalog selection into the combination that would be sold, with its price and open choices.
- A read that persists nothing; an incomplete selection returns 200 with `status` and `pending_option_groups`.
- Sending two values of the same group returns 422.

## Path parameters

- `company` string, uuid, required
- `product` string, uuid, required

## Headers

- `Factuarea-Version` string, date

## Request body

- ResolveCatalogSelectionRequest
  - `variant_id` string, uuid, nullable
  - `presentation_id` string, uuid, nullable
  - `options` object[], nullable: Options already chosen, ONE value per group: two values of the same group are an invalid request, not a partial selection.
    - `group_id` string, uuid, required
    - `value_id` string, uuid, required

## Response `200`

- object
  - `data` ResolvedCatalogSelection, required: Outcome of checking a (possibly partial) selection against a product catalog. An ambiguous or incomplete selection is NOT an error here: this operation exists to BUILD the line, so it answers 200 with what is still missing. The 422 is raised by whoever confirms the line.
    - `object` 'resolved_catalog_selection', required
    - `product_id` string, uuid, required
    - `mode` 'open' | 'allow_list' | 'legacy', required: `open` for explicit open availability, `allow_list` for explicit closed availability. `legacy` is retained only for backwards-compatible historical payloads.
    - `status` 'resolved' | 'incomplete' | 'ambiguous' | 'incompatible', required: `resolved`: the selection identifies one combination. `incomplete`: something is still to be chosen (see `pending_option_groups`). `ambiguous`: it matches several combinations at once. `incompatible`: no active combination admits it.
    - `compatible` boolean, required
    - `complete` boolean, required
    - `variant_id` string, uuid, nullable, required
    - `presentation_id` string, uuid, nullable, required
    - `selected_options` object[], required
      - `group_id` string, uuid, required
      - `value_id` string, uuid, required
    - `configuration_id` string, uuid, nullable, required
    - `configuration_name` string, nullable, required
    - `configuration_signature` string, nullable, required
    - `configuration_price` string, nullable, required: Own FINAL price of the resolved combination, per commercial unit. This is CONTEXT, not the final price of the line: the full precedence (exact price-list entry, combination, presentation, variant, product) is resolved by `POST /v1/companies/{company}/price-lists/resolve`.
    - `option_adjustment_total` string, required: Sum of the adjustments of the chosen option values. Always present, but INFORMATIONAL when `configuration_price` is set: that price already absorbs them and they are not added again.
    - `candidate_configuration_ids` string[], required
    - `compatible_variants` object[], required
      - `id` string, uuid, required
      - `name` string, required
    - `compatible_presentations` object[], required
      - `id` string, uuid, required
      - `name` string, required
    - `compatible_option_groups` object[], required: Groups still in play, each with ONLY the values some candidate combination still admits. That is the progressive filtering: a value no compatible combination contains disappears instead of being offered to end in a 422.
      - `group_id` string, uuid, required
      - `group_name` string, required
      - `selected_value_id` string, uuid, nullable, required
      - `values` object[], required
        - `id` string, uuid, required
        - `name` string, required
        - `price_adjustment` string, nullable, required
    - `pending_option_groups` object[], required: Groups that still need a choice before the line can be confirmed.
      - `group_id` string, uuid, required
      - `group_name` string, required
    - `reason_code` string, nullable, required: Machine-readable cause when the selection is not resolved.
    - `reason` string, nullable, required: Actionable Spanish message naming what is missing.

## Other responses

- `400`: `parameter_unknown` with `subcode` `retired_active_profile_header`: the retired `X-Active-Profile` header was sent; the company goes in the path. `parameter_invalid_format` on `Factuarea-Version`: the header is not a `YYYY-MM-DD` date. `unsupported_api_version`: the `Factuarea-Version` date is not a supported version.
- `401`: Missing or invalid API key.
- `403`: The request is authenticated but not allowed: the API key lacks the required scope (`insufficient_scope`), the plan does not include the public API or this feature (`addon_not_active`, `feature_not_available_in_plan`), or the module is not available with a test key (`module_not_available_in_sandbox`).
- `404`: The requested resource does not exist or belongs to another company.
- `422`: Validation failed. The `error.param` field identifies which input is invalid.
- `429`: Rate limit exceeded. Retry after the duration in `Retry-After`.
- `500`: Unexpected server error.

---

[API](https://skmtc.dev/factuarea/apis/factuarea-public-api.md) · [All operations](https://skmtc.dev/factuarea/apis/factuarea-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/factuarea/apis/factuarea-public-api/revisions/718e77934422?raw)
