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

# Products accept a zero unit price

> unitPrice is now required when creating or updating a product, and 0 is a valid price.

<Update label="2026-08-11" tags={["Change","Breaking"]} description="Zero-price products">
  ## Breaking

  ### `unitPrice` is required on products

  `unitPrice` is now marked **required** on [create product](/api-reference/endpoint/products/create-product) and [update product](/api-reference/endpoint/products/update-product).

  It was previously documented as optional, but omitting it has always been rejected with `400 Product.InvalidPrice` — the schema simply did not say so. If you generate a client from our OpenAPI document, regenerating will now mark the field required, and any call site that omits it will fail to compile rather than failing at runtime.

  **Request behaviour is unchanged.** Omitting `unitPrice` returns the same `400 Product.InvalidPrice` it always has, so no request that works today starts failing.

  ## Updates

  ### A product can now cost nothing

  `unitPrice` accepts **0**, so you can create comped items, free shipping lines, and £0 trial products. Previously any price had to be greater than zero, which meant a genuinely free product could not be represented at all.

  Negative prices are still rejected with `400 Product.InvalidPrice`.

  Because zero is now a meaningful price, an omitted `unitPrice` is an error rather than a silent default — otherwise a forgotten field would quietly create a free product. That is the reason the field is now required.

  The rule is now published in the schema rather than left to be discovered: `unitPrice` carries `minimum: 0` and a description covering what zero means and what is rejected. The schema also no longer lists `null` as an accepted type — sending `unitPrice: null` returns `400 Product.InvalidPrice`, and now says so before you try it. If you generate a client from our OpenAPI document, regenerate to pick both up.

  ### Module entitlement is documented on every endpoint it applies to

  Endpoints belonging to a module your plan does not include return `403 Module.NotEntitled`. That has always been the behaviour; it is now declared in the API reference for each endpoint it can affect, so it appears in generated clients alongside the other error codes.

  ### Rate limits are documented

  The API's rate limits, how they are scoped, and how to handle a `429` are now written up in the [rate limits guide](/guides/rate-limits).
</Update>
