# API changelog

What changed on the OLET public API, by version. Breaking changes ship as a new version path, so /v1 keeps its shape.

Source: https://getolet.com/resources/developers/changelog/
Updated: 2026-10-15

The OLET public API is versioned in the URL path. Breaking changes ship as a new version path; `/v1` keeps its current shape for as long as it is offered.

The version is still `1.0.0`. No response shape that existed before has changed since the first release; the entries below add fields and refusals.

## 2026-10-01, stock cost and reason rules

- A stock write can now carry `unit_cost`, an integer number of cents. On `PUT /products/{id}/inventory/{outlet_id}` and on a `set` line in a batch, it becomes the outlet's average cost. On `POST /inventory/adjustments` and on an `adjust` line, it is blended into the average when stock goes up and ignored otherwise. Leave it out to keep the current average.
- A stock write that names a system reason, or a reason that is turned off, now answers `422 REASON_NOT_ALLOWED`. A reason must be enabled and must not be a system reason.

## 2026-09-27, deleted outlets

- A stock write at an outlet that has been deleted answers `422 OUTLET_DELETED`. It used to answer the generic `UNPROCESSABLE`. Nothing is written, and a batch writes none of its lines.

## 1.0.0, 2026-09-23

The first public release. It covers catalog (products, brands, categories, tags, suppliers), inventory (stock reads, sets, relative adjustments, and batch writes), customers, sales and refunds (read only), and account and store settings, 44 operations in all.

Every list endpoint pages with a cursor and supports polling for changes; product and sale reads return the full document in one call rather than a slimmer summary with separate sub-resource reads. Money is always an integer number of cents. Writes to inventory endpoints support an `Idempotency-Key` for safe retries.

What shaped this release:

- **One product document.** A product read carries its `codes`, `tags` (with names), `suppliers` (with `supplier_name`), `variant_options`, `variant_attributes` and `components`. `POST /products` and `PATCH /products/{id}` accept the same document: leave a collection out to keep it, send `[]` to clear it, and the whole write is atomic. The separate endpoints for a product's codes, tags, suppliers, components and attributes were removed before release. See [write a whole product in one request](/resources/developers/write-a-product/).
- **Cursors and versions.** The `version` on a row and the list cursor follow the whole document, so a product comes back in a poll when anything attached to it changes. A cursor the server cannot read answers `400 VALIDATION_FAILED` instead of restarting at the first page, and an empty page returns `next_cursor: null`. See [pagination and polling](/resources/developers/pagination-and-polling/).
- **Scopes.** Catalog access uses `catalog:read` and `catalog:write`. Every scoped endpoint names the scope it needs.
- **Deletes.** `DELETE` exists for products, brands, categories, tags, suppliers and customers, and brands, categories and tags have `GET` by id. Deleting a customer permanently erases their personal details and cannot be undone. See [delete and erase](/resources/developers/delete-and-erase/).
- **Stock by SKU.** Stock adjustments and batch lines accept `sku` in place of `product_id`.
- **Images.** `image_url` imports a product image from an https address. A failed download answers `422 IMAGE_FETCH_FAILED` with the saved product in `data`.
- **OAuth.** Apps connect with the authorization code flow, and the spec describes both API keys and OAuth. See [authentication](/resources/developers/authentication/).
- **The spec.** `GET /openapi.json` under your store prefix serves the full OpenAPI document with your prefix in its server URL, and every operation description is written in markdown.

## Where to go next

See the [quickstart](/resources/developers/quickstart/) to make your first call, or the full [API reference](/resources/developers/reference/) for every operation this version covers.
