---
title: "Validate a selection and decide the completion path"
method: POST
path: "/v1/checkout/validate"
tags: ["Checkout"]
---

# Validate a selection and decide the completion path

`POST /v1/checkout/validate`

Checks a customer's chosen Product Versions and answers whether they can be submitted and by which path. This is the **authoritative** Checkout-vs-Handoff decision: the automated-switch signal lives in the catalogue, so it cannot be derived client-side.

A selection that breaks a rule is a valid answer, not a bad request — it returns `200` with `valid: false` and every reason under `issues`. A `4xx` means the request itself was malformed.

A Product Version is published for one month, so the catalogue month is read off the ids you send rather than asked for — there is no month parameter, and no way for it to disagree with the selection. That is what keeps this endpoint aligned with `POST /v1/comparisons`: the versions validated here are the ones the customer was shown, including in the first days of a month before the catalogue is refreshed.

Judged against the catalogue month Vwala is currently serving, not against today's date. Refreshing every product for a new month takes days, so for much of the first week of a month the catalogue being served is still the previous one — and that is the catalogue the customer is choosing from.

Two things can make a selection too old, both reported per fuel so a client knows which half to re-run. `PRODUCT_VERSION_SUPERSEDED` means a newer version of that product is now being served: the price on screen has moved, and the customer should compare again rather than switch at it. A newer version that exists but is not yet being served supersedes nothing — nobody is being shown it. `COMPARISON_MONTH_OUT_OF_RANGE` means the version is more than a month away from the served catalogue with nothing newer behind it, which in practice means a discontinued product.

What is *not* an error: fuels sitting in different months, and a version that is simply the newest one there is. The refresh does not land for all fuels at once, so this month's electricity beside last month's gas is exactly what a customer may have been shown — and next month's prices, often loaded before the month turns over, do not supersede today's.

## Request body

- object
  - `selection` object[], required — The chosen Product Versions. Two entries claiming the same energy type are accepted here and reported as a domain issue.
    - `energyType` 'ELECTRICITY' | 'GAS', required
    - `productVersionId` string, uuid, required
  - `context` object, required — The customer context needed by the Selection rules.
    - `meterType` 'Digital' | 'Analog', nullable — The electricity meter. Required when the selection includes electricity; omit for a gas-only selection.
    - `currentMerchants` object — The customer's current merchant per energy type, identified by canonical name.
      - `electricity` string, nullable
      - `gas` string, nullable

## Response `200`

Default Response

- CheckoutValidationResult
  - `valid` boolean, required — Whether the Selection satisfies every domain rule.
  - `flow` 'CHECKOUT' | 'HANDOFF', required — The authoritative completion path.
  - `selection` object[], required — The entries that resolved against the Catalogue.
    - `energyType` 'ELECTRICITY' | 'GAS', required
    - `productVersionId` string, uuid, required
    - `submissionMethod` 'MANUAL' | 'REDIRECT', required — How this choice reaches the merchant.
    - `automatedSwitch` boolean, required — Whether Vwala can manage this merchant's switch.
  - `issues` object[], required — Every reason the Selection is invalid.
    - `code` 'SELECTION_EMPTY' | 'DUPLICATE_ENERGY_TYPE' | 'METER_TYPE_REQUIRED' | 'DYNAMIC_METER_REQUIRES_DIGITAL' | 'SAME_MERCHANT' | 'ENERGY_VISION_GAS_ONLY' | 'PRODUCT_VERSION_NOT_AVAILABLE' | 'ENERGY_TYPE_MISMATCH' | 'EAN_REQUIRED' | 'COMPARISON_MONTH_OUT_OF_RANGE' | 'PRODUCT_VERSION_SUPERSEDED', required
    - `message` string, required
    - `energyType` 'ELECTRICITY' | 'GAS'
    - `productVersionId` string, uuid

## Other responses

- `400` — Default Response
- `401` — Default Response
- `403` — Default Response
- `5XX` — Default Response

## Changes

- **2026-08-18** `0faefa545909` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/vwala/apis/energy-platform-api/changes/v1/checkout/validate/post.md)

---

[API](https://skmtc.dev/vwala/apis/energy-platform-api.md) · [All operations](https://skmtc.dev/vwala/apis/energy-platform-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/vwala/energy-platform-api/revisions/86688c4fea92/schema)
