--- sidebar_position: 2 --- # Activate a Product for Sale import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; This guide shows you how to activate a priced product for sale in a country by setting `is_active` through `BatchUpsertPricing`. By the end, you'll have flipped a product to active and confirmed whether it is actually live to customers. ## Prerequisites - Authentication set up — see [Getting Credentials][getting-credentials] and [Authenticating Your Requests][authenticating-requests] - A `partner_sku` already priced in the country you are activating — see [Set and Update Prices][pricing-set-prices] ## Step 1 — Activate the offer `BatchUpsertPricing` (`POST /pricing/v1/pricing/upsert`) creates or updates pricing for one or more SKUs. To activate a SKU for sale in a country, send an item with `is_active: true` for that `partner_sku` and `country_code`. Each item targets one SKU in one country and is processed independently, so a single call can activate many SKUs across countries. `country_code` must be one of `ae`, `sa`, or `eg`. ```python # get_authenticated_session() is provided in docs/snippets/auth.mdx — see Authenticating Your Requests session = get_authenticated_session() response = session.post( "https://noon-api-gateway.noon.partners/pricing/v1/pricing/upsert", json={ "items": [ {"partner_sku": "MY-SNK-42", "country_code": "ae", "is_active": True} ] }, headers={"User-Agent": "MyCatalogApp/1.0.0"}, timeout=30, ) response.raise_for_status() items = response.json()["items"] for item in items: status = item["status"] if status["status_code"] != "OK": print(f"Failed: {item['partner_sku']} ({item['country_code']}): {status['message']}") ``` ```javascript // getAuthenticatedClient() is provided in docs/snippets/auth.mdx — see Authenticating Your Requests const client = await getAuthenticatedClient(); const response = await client.post( "https://noon-api-gateway.noon.partners/pricing/v1/pricing/upsert", { items: [ { partner_sku: "MY-SNK-42", country_code: "ae", is_active: true }, ], }, { headers: { "Content-Type": "application/json", "User-Agent": "MyCatalogApp/1.0.0", }, } ); for (const item of response.data.items) { if (item.status.status_code !== "OK") { console.log(`Failed: ${item.partner_sku} (${item.country_code}): ${item.status.message}`); } } ``` **Response:** ```json { "items": [ { "partner_sku": "MY-SNK-42", "country_code": "ae", "status": {"status_id": 0, "status_code": "OK", "message": ""} } ] } ``` You'll know the activation was accepted when the matching entry in `items` returns `status.status_code` of `OK` (`status_id` `0`). A `200` does not mean every item succeeded — check the result at two levels: - **HTTP level.** A non-2xx response means the whole request failed before any item was processed. The body is an `rpcStatus` object; read `message` for the reason. - **Item level.** On a `200`, inspect `status` on each item. Any `status_code` other than `OK` means that item was not activated — read `status.message` and resend only the failed items. | Condition | What it means | What to do | |---|---|---| | Non-2xx response | Request failed entirely before processing — auth error or quota exceeded | Read `message` on the `rpcStatus` body. For quota errors, the message states your limit and period. | | `status_code` other than `OK` on an item | That SKU was not activated; the rest of the batch may still have succeeded | Read `status.message`, fix the item, and resend only the failed items. A `NOT_FOUND` here means the SKU has no pricing record yet — set its price first via [Set and Update Prices][pricing-set-prices]. | :::note `is_active` is nullable, and only the fields you send are changed. Include `is_active` to set activation, and add `price` or `msrp` in the same item to set them too; omitting a field leaves its existing value untouched. Sending `is_active: false` deactivates the SKU so it is no longer sold in that country. ::: ## Step 2 — Confirm the offer is live Activation is one go-live gate, not the whole story. `is_active: true` is your declared intent to sell; the offer only reaches customers once every other condition is met. Read the result through `GetProductOffers` in the Offer API — `BatchUpsertPricing` cannot return live status. - **`is_active`** — the activation state you set through Pricing. Your declared intent to sell. - **`live_status`** — whether the offer is actually visible to customers on the storefront. - **`offer_issues`** — an array of blocking issues that keep an offer from going live. When `live_status` is `false`, inspect each issue's `reason`, `subreason`, and `description`. The array is empty when the offer is live. An offer can be `is_active: true` and `live_status: false` when blocking issues remain — for example missing stock, content gaps, or QC. You'll know the product is live when `GetProductOffers` returns `live_status: true` for the offer. | Offer state | What it means | What to do | |---|---|---| | `is_active: true`, `live_status: true` | Activated and visible to customers | Nothing — the offer is live. | | `is_active: true`, `live_status: false`, `offer_issues` non-empty | Activated, but something else is blocking go-live | Read each entry in `offer_issues` (`reason`, `subreason`, `description`) and resolve it. | | `is_active: false` | Not activated for sale in this country | Return to Step 1 and send `is_active: true`. | To read activation status back through Pricing alone (without live status), use `BatchGetPricing` — see [Read Prices][pricing-read-prices]. ## Next steps - [Go Live][pricing-go-live] — the full path from priced SKU to a live offer - [Read Prices][pricing-read-prices] — confirm price, MSRP, and `is_active` per country - [Offer Introduction][offer-intro] — read `live_status` and `offer_issues` for an offer - [BatchUpsertPricing Reference][upsert-pricing-noon] — full request and response schema - [BatchGetPricing Reference][get-pricing-noon] — full request and response schema