Skip to content

Submit a new offer

POST
/api/v1/vendor/offers
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.

Media typeapplication/json
object
variantId

A vendor-proposed match to an existing, active catalog variant. Omit for an unmatched free-form entry.

string format: uuid
nullable
vendorSku

Your own human-readable SKU for this item.

string
nullable
vendorExternalId

Opaque id reserved for API integrations — doubles as the idempotency key.

string
nullable
cost
required

Wholesale cost Linra pays you, in SAR.

number format: decimal
costIsVatInclusive

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).

boolean
declaredStockQuantity

Your declared quantity on hand, when you report a number rather than a bare yes/no.

integer
nullable
declaredInStock

Your declared availability.

boolean
rawBrandName

Required when variantId is omitted — the brand name as you know it.

string
nullable
rawProductName

Required when variantId is omitted — the product name as you know it.

string
nullable
rawConcentration
string
nullable
rawSizeMl
integer
nullable
rawDescription
string
nullable
saveAsDraft

Save as a Draft (no review queue entry yet) instead of submitting for review immediately.

boolean

The created (or idempotently replayed) offer.

Media typeapplication/json
object
state
required
string
payload
required
details
object
payload
required
object
id
string format: uuid
vendorId
string format: uuid
variantId
string format: uuid
nullable
status
string
Allowed values: Draft PendingMatch PendingReview Approved Rejected Withdrawn Suspended
source
string
Allowed values: Manual Import Api
vendorSku
string
nullable
vendorExternalId
string
nullable
cost

Always the NET (ex-VAT) figure.

number format: decimal
pendingCost

A cost change awaiting reviewer approval, if one is in flight. Null otherwise.

number format: decimal
nullable
costIsVatInclusive

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.

boolean
costEnteredVatInclusive

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.

boolean
inputVatAmount

Your own input VAT on the current cost, back-derived when costEnteredVatInclusive is true.

number format: decimal
pendingInputVatAmount
number format: decimal
nullable
declaredStockQuantity
integer
nullable
declaredInStock
boolean
rawBrandName
string
nullable
rawProductName
string
nullable
rawConcentration
string
nullable
rawSizeMl
integer
nullable
rawDescription
string
nullable
syncPaused
boolean
autoPublishEligible
boolean
reviewedByUserId
string format: uuid
nullable
reviewedAt
string format: date-time
nullable
reviewReason
string
nullable
importBatchId
string format: uuid
nullable
supplyOptionId
string format: uuid
nullable
version

Optimistic-concurrency token (informational on this API — no vendor endpoint requires you to send it back).

integer
createdDate
string format: date-time
nullable
lastModifiedDate
string format: date-time
nullable
Example
{
"state": "SUCCESS",
"payload": {
"status": "Draft",
"source": "Manual"
}
}

Request validation failed.

Media typeapplication/json
object
state
required
string
payload
details
object
Example
{
"state": "NOT_FOUND_VENDOR_OFFER"
}

Your token doesn’t carry the capability this endpoint requires.

Media typeapplication/json
object
state
required
string
payload
details
object
Examples
ExamplemissingCapability
{
"state": "FORBIDDEN_CAPABILITY_NOT_GRANTED",
"payload": null,
"details": {
"requiredCapability": "Orders"
}
}

Too many requests. Retry after the Retry-After header (seconds).

Media typeapplication/json
object
state
required
string
payload
details
object
Example
{
"state": "NOT_FOUND_VENDOR_OFFER"
}
Retry-After
integer

Seconds to wait before retrying.