API changelog
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
Section titled “2026-10-01, stock cost and reason rules”- A stock write can now carry
unit_cost, an integer number of cents. OnPUT /products/{id}/inventory/{outlet_id}and on asetline in a batch, it becomes the outlet’s average cost. OnPOST /inventory/adjustmentsand on anadjustline, 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
Section titled “2026-09-27, deleted outlets”- A stock write at an outlet that has been deleted answers
422 OUTLET_DELETED. It used to answer the genericUNPROCESSABLE. Nothing is written, and a batch writes none of its lines.
1.0.0, 2026-09-23
Section titled “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(withsupplier_name),variant_options,variant_attributesandcomponents.POST /productsandPATCH /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. - Cursors and versions. The
versionon 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 answers400 VALIDATION_FAILEDinstead of restarting at the first page, and an empty page returnsnext_cursor: null. See pagination and polling. - Scopes. Catalog access uses
catalog:readandcatalog:write. Every scoped endpoint names the scope it needs. - Deletes.
DELETEexists for products, brands, categories, tags, suppliers and customers, and brands, categories and tags haveGETby id. Deleting a customer permanently erases their personal details and cannot be undone. See delete and erase. - Stock by SKU. Stock adjustments and batch lines accept
skuin place ofproduct_id. - Images.
image_urlimports a product image from an https address. A failed download answers422 IMAGE_FETCH_FAILEDwith the saved product indata. - OAuth. Apps connect with the authorization code flow, and the spec describes both API keys and OAuth. See authentication.
- The spec.
GET /openapi.jsonunder 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
Section titled “Where to go next”See the quickstart to make your first call, or the full API reference for every operation this version covers.