Submit a new offer
const url = 'https://api-omni.linra.net/api/v1/vendor/offers';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"variantId":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","vendorSku":"example","vendorExternalId":"example","cost":1,"costIsVatInclusive":false,"declaredStockQuantity":1,"declaredInStock":true,"rawBrandName":"example","rawProductName":"example","rawConcentration":"example","rawSizeMl":1,"rawDescription":"example","saveAsDraft":false}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api-omni.linra.net/api/v1/vendor/offers \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "variantId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "vendorSku": "example", "vendorExternalId": "example", "cost": 1, "costIsVatInclusive": false, "declaredStockQuantity": 1, "declaredInStock": true, "rawBrandName": "example", "rawProductName": "example", "rawConcentration": "example", "rawSizeMl": 1, "rawDescription": "example", "saveAsDraft": false }'Submits a new offer through the SAME review workflow the Portal vendor UI uses — nothing
goes live without an internal reviewer’s approval. Idempotent when vendorExternalId is
set: re-submitting the SAME vendorExternalId returns the already-created offer unchanged
rather than creating a duplicate or erroring (a safe retry). Supply variantId for a
vendor-proposed match to an existing catalog variant, or rawBrandName/rawProductName
for an unmatched free-form entry. Requires the Offers capability.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
A vendor-proposed match to an existing, active catalog variant. Omit for an unmatched free-form entry.
Your own human-readable SKU for this item.
Opaque id reserved for API integrations — doubles as the idempotency key.
Wholesale cost Linra pays you, in SAR.
False (default) = exclusive (cost is net, VAT added on top); true = inclusive (cost is the VAT-inclusive gross; net cost + input VAT are back-derived).
Your declared quantity on hand, when you report a number rather than a bare yes/no.
Your declared availability.
Required when variantId is omitted — the brand name as you know it.
Required when variantId is omitted — the product name as you know it.
Save as a Draft (no review queue entry yet) instead of submitting for review immediately.
Responses
Section titled “Responses”The created (or idempotently replayed) offer.
object
object
object
Always the NET (ex-VAT) figure.
A cost change awaiting reviewer approval, if one is in flight. Null otherwise.
Always false. Pair Cost with this value (false) on a write to safely resubmit it unchanged — this is the one entry mode that can never re-interpret an already-net figure as a fresh gross one. See costEnteredVatInclusive for how you actually entered it.
Display-only — the vendor’s actual original entry-mode preference (how Cost was declared: exclusive/net or inclusive/gross). NEVER accepted on a write; use costIsVatInclusive (always false) for that.
Your own input VAT on the current cost, back-derived when costEnteredVatInclusive is true.
Optimistic-concurrency token (informational on this API — no vendor endpoint requires you to send it back).
Example
{ "state": "SUCCESS", "payload": { "status": "Draft", "source": "Manual" }}Request validation failed.
object
object
Example
{ "state": "NOT_FOUND_VENDOR_OFFER"}Your token doesn’t carry the capability this endpoint requires.
object
object
Examples
{ "state": "FORBIDDEN_CAPABILITY_NOT_GRANTED", "payload": null, "details": { "requiredCapability": "Orders" }}Too many requests. Retry after the Retry-After header (seconds).
object
object
Example
{ "state": "NOT_FOUND_VENDOR_OFFER"}Headers
Section titled “Headers”Seconds to wait before retrying.