Skip to content
Linra Omni Vendor Docs

Changelog

What's shipped on the vendor API, going forward.

2026-10-10 — Strict query input, Gateway error envelopes, public Location

Section titled “2026-10-10 — Strict query input, Gateway error envelopes, public Location”
  • Live hosts — the vendor API is served at https://api-omni-vendors.linra.net (production) and https://api-omni-vendors-stg.linra.net (staging); the API reference servers list is updated accordingly.

  • Gateway errors use the envelope — every 401/403/404/405/415/502/503/504 the vendor Gateway produces now returns { "state", "payload": null, "details": { "message" } } instead of an empty body (or, for 415, application/problem+json). New codes: UNAUTHORIZED_MISSING_TOKEN, UNAUTHORIZED_INVALID_TOKEN, UNAUTHORIZED_TOKEN_EXPIRED, UPSTREAM_AUTH_FAILED (a server-side fault — retry later, don’t re-mint your token), FORBIDDEN, NOT_FOUND_ROUTE, METHOD_NOT_ALLOWED, UNSUPPORTED_MEDIA_TYPE, BAD_GATEWAY, SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT. WWW-Authenticate and Allow headers are unchanged.

  • Required fields — declaredInStock is required on PATCH /api/v1/scent/offers/{offerId}/stock (a typo such as {"quantity":5} used to take the offer out of stock), and it must agree with declaredStockQuantity. isActive is required on PATCH /api/v1/scent/webhooks/{id}/active and PATCH /api/v1/credentials/{id}/active. A body without them returns 400 VALIDATION_ERRORS and changes nothing.

  • Dates are UTC — a date filter without an offset is read as UTC and a date-only value means 00:00Z; an unparseable value returns 400 VALIDATION_INVALID_DATE.

  • Location is the public URL — every 201 now carries an absolute https://api-omni-vendors.linra.net/api/v1/... (staging https://api-omni-vendors-stg.linra.net/...) URL instead of a relative or internal one.

  • Token lifetime is exact — an access token stops working within at most 30 seconds of its 5-minute expiry.

  • Docs — your first credential comes from Linra: contact your Linra account manager. Further credentials: Portal dashboard https://omni-portal.linra.net → Administration → API Credentials (one address for staging and production; choose with the Environment selector).

  • Offers — breaking change, effective from this release — barcode (the product’s EAN/UPC: 8, 12, 13 or 14 digits with a valid check digit) is now required on POST /api/v1/scent/offers and as the Barcode column of the offer import; a create without it, or with a bad check digit, is a 400 VALIDATION_ERRORS (field Barcode). On PATCH /api/v1/scent/offers/{id} it may be omitted — the stored barcode is kept, never cleared. Offer responses carry it as product.barcode.
  • Offers — PATCH /api/v1/scent/offers/{id} is now a partial update — a field you omit (or send as null) keeps its stored value; it was previously cleared (and on an Approved offer a cleared vendorSku/vendorExternalId sent the offer back to review). "" clears an optional text field (vendorSku, vendorExternalId, rawConcentration, rawDescription; also rawBrandName/rawProductName on an offer matched to a catalog variant; whitespace-only counts as empty). With no price field in the body the stored price is kept, so a body such as {"barcode": "4006381333931"} or {"cost": 120, "costIsVatInclusive": false} is valid on its own. Request and response shapes are unchanged.
  • Compatibility — offers created before this release keep working unchanged (stock, cost and sale-price pushes, orders, payouts). Their stock and price can still be edited without a barcode; a barcode is needed before changing their product details, and before any edit that sends a Rejected or PendingRepricing offer back to review (every edit of a Rejected offer; a price change on a PendingRepricing one; this applies to the stock, cost and sale-price pushes too). In an offer import file, rows that update an existing offer may leave Barcode blank or omit the column; rows that create one need it. A retried create that reuses an old vendorExternalId must now carry a barcode too (the body is validated before the idempotent replay). Nothing else in v1 changes.

2026-09-28 — Return request read; evidence Location header

Section titled “2026-09-28 — Return request read; evidence Location header”
  • Returns — new GET /api/v1/scent/returns/{id} reads one of your own return requests (same ownership scope and Orders capability as the other return actions).
  • POST /api/v1/scent/returns/{id}/evidence now answers 201 with a Location header pointing at that public route (it previously named an internal path you could not call).

The current vendor API surface, as documented across this site:

  • Authentication — POST /api/v1/auth/token, capability-scoped, audience vendor-api.
  • Profile — GET /api/v1/profile, read-only.
  • Credentials — self-service credential management under /api/v1/credentials, gated by the Account capability (reads require no capability).
  • Offers — submit and edit product offers (/api/v1/scent/offers), gated by the Offers capability.
  • Stock — instant declared-availability/quantity pushes (/api/v1/scent/offers/{offerId}/stock), gated by the Stock capability.
  • Cost — approval-pipelined cost pushes (/api/v1/scent/offers/{id}/cost), gated by the Cost capability, independently of Offers.
  • Orders & fulfilment — poll assigned fulfilment groups with delta sync, and push fulfilment status (/api/v1/scent/orders/**), gated by the Orders capability.
  • Returns — confirm receipt, inspect, upload evidence, and propose an outcome for a model-A return (/api/v1/scent/returns/**), gated by the Orders capability.
  • Webhooks — subscription management and HMAC-signed push delivery for vendor.scent.order.assigned and vendor.scent.offer.review-decision (/api/v1/scent/webhooks/**), gated per event type.

From this point on, this changelog records only genuine changes to the live API — going forward.