> ## Documentation Index
> Fetch the complete documentation index at: https://developer.sodacards.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> Changes to the SODACARDS developer API, and what counts as a breaking change.

<Update label="2026-08-04">
  **Discover a product's purchase input fields.** `GET /v1/catalog` and `GET /v1/products/{id}` now
  return an `inputFields` array on each product, describing the purchase-form fields it requires (key,
  type, whether required, an optional regex, and a select's options). You can now build and validate
  an order line before placing it. Additive: products that need nothing omit the field. See
  [Purchase input fields](/input-fields).

  **Consistent order status.** `POST /v1/orders` now reports an order's status in the same public
  vocabulary as `GET /v1/orders/{id}` (`pending`, `processing`, `completed`, `failed`, `refunded`). A
  freshly placed order and the same order read back now carry the same word. See
  [Order lifecycle](/order-lifecycle).
</Update>

<Update label="Earlier">
  * **Webhook secret rotation.** `POST /v1/webhooks/{id}/rotate` issues a new signing secret while the
    previous one keeps verifying for a grace window, so you can roll a secret without dropping events.
  * **Wallet balance.** `GET /v1/balance` returns the key's spendable balance.
  * **Truthful sandbox.** A sandbox order is fulfilled to a real terminal status with deterministic
    `TEST-` codes, and a test key may force an error path with the `X-Test-Scenario` header.
</Update>

## Versioning policy

The API is versioned in its path (`/v1`). We add to it often and remove from it rarely.

**Non-breaking changes** ship at any time on `/v1`, and your integration should tolerate them:

* a new endpoint;
* a new optional field in a request;
* a new field in a response;
* a new value in an enum, a new error `code`, or a new webhook event type;
* a new, optional request header.

Build your client to ignore response fields it does not recognize, and to treat an unknown error
`code` by its HTTP status.

**Breaking changes** do not happen silently on `/v1`. Any of the following is announced here with
advance notice, and, when unavoidable, carried on a new version path:

* removing or renaming a field, endpoint, error `code` or event type;
* changing a field's type or the meaning of a value;
* making an optional request field required, or tightening validation;
* changing authentication or the signature scheme.

Your API keys, the `operationId` of each endpoint (the name our SDKs generate), and the machine
`code` on each error are stable contracts we treat as breaking to change.
