Skip to content
Linra Omni Vendor Docs

Getting started

From a credential to your first authenticated vendor API call in about five minutes.

New to Linra Omni? Platform overview covers the multi-product framing (Scent is the first product you can supply through) and the platform-wide contracts (versioning, envelope, pagination) before you write any code — worth a skim first, but not required to follow the steps below.

Your FIRST credential is always issued by Linra during onboarding — to get it, contact your Linra account manager. Self-service generation has no baseline to work from yet and is rejected until you hold at least one active credential (422 BUSINESS_VENDOR_FIRST_CREDENTIAL_REQUIRES_ONBOARDING). If you don’t yet have a dashboard login or a first credential at all, see Vendor onboarding & credentials for the full invite → activate → first-credential sequence before continuing here.

Once you have that first credential, further credential management IS self-service — directly on THIS API, via POST /api/v1/credentials (requires the Account capability), or on the Linra Omni Portal dashboard at https://omni-portal.linra.net — one address for both staging and production; pick the environment with the Environment selector in the top bar, then open Administration → API Credentials in the sidebar and select Generate. Generate additional credentials for the environment (staging or production) you need: a second environment, or a replacement after rotating a compromised secret. Self-service generation can only ever match the capabilities your existing active credentials already hold — it can never grant a NEW capability beyond that union; ask your Linra account manager for that. See the Vendor Integration Standard §11 for the full sequence.

Either way, you’ll end up with:

Client ID: vnd_9f8c2a1b4e6d4a7c9b0e3f2d1c8a5b6e
Client Secret: •••••••••••••••••••••••••••••••••••••••••••••• (shown once — copy it now)
Environment: Staging
Capabilities: Offers, Stock

Store both values in your own secret manager immediately — there is no “reveal secret” endpoint.

2. Exchange the credential for an access token

Section titled “2. Exchange the credential for an access token”
Terminal window
curl -X POST https://api-omni-vendors-stg.linra.net/api/v1/auth/token \
-H "Content-Type: application/json" \
-d '{
"clientId": "vnd_9f8c2a1b4e6d4a7c9b0e3f2d1c8a5b6e",
"clientSecret": "your-secret-here"
}'
{
"state": "SUCCESS",
"payload": {
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"tokenType": "Bearer",
"expiresIn": 300
}
}

The token is valid for 5 minutes (exactly — an expired token is rejected within at most 30 seconds of clock skew, with 401 UNAUTHORIZED_TOKEN_EXPIRED) and carries exactly the capabilities your credential was issued with, baked into the token itself — see Authentication & capabilities for the caching pattern you should build around this, and for what happens when you call an endpoint your token doesn’t have the capability for.

A wrong clientId/clientSecret (or an inactive vendor) fails this call with 401 (generic UNAUTHORIZED_INVALID_CREDENTIALS/UNAUTHORIZED_VENDOR_INACTIVE — the two are never distinguished, so a caller can’t enumerate valid client ids); calling this endpoint too often fails with 429 (10 requests per 60 seconds, Retry-After header) — see Rate limits & errors.

Every other request carries the token as a bearer credential — offers/stock/orders live under the /api/v1/scent product segment, everything else (profile, credentials, webhooks) is directly under /api/v1:

Terminal window
curl https://api-omni-vendors-stg.linra.net/api/v1/scent/offers?pageSize=5 \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
{
"state": "SUCCESS",
"payload": {
"items": [],
"pagination": { "page": 1, "pageSize": 5, "totalCount": 0, "totalPages": 0 }
}
}

An empty list is expected for a brand-new credential — nothing has been submitted yet.

Terminal window
curl -X POST https://api-omni-vendors-stg.linra.net/api/v1/scent/offers \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{
"rawBrandName": "Example Brand",
"rawProductName": "Example EDP 100ml",
"cost": 145.00,
"costIsVatInclusive": false,
"declaredInStock": true,
"declaredStockQuantity": 25
}'

This submission enters the SAME review queue an internal Linra catalog reviewer already works — nothing you submit goes live until it’s approved. The example above assumes you’re on the CostPlusMargin (“Model 1”) commercial model — check GET /api/v1/scent/agreement first if you’re not sure; a PercentageOfSale (“Model 2”) vendor submits salePrice/salePriceIsVatInclusive instead of cost/costIsVatInclusive. See Offers, pricing and stock for the full field-ownership model (what applies instantly vs. what waits for review) and the per-model field reference.

Prefer to explore the API in Postman before writing any code? Download the collection and environment below, import both into Postman, fill in your clientId/clientSecret in the environment, run the Get access token request, then call any other request in the collection.

Remember: your first credential is always Linra-issued during onboarding — see Vendor onboarding & credentials if you don’t have one yet. The environment’s credential-list/generate requests also require an X-Linra-Environment header (already set in the downloaded environment) — see List my vendor credentials.