---
sidebar_position: 2
---
# Set and Update Prices
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
This guide shows you how to set and update pricing for your SKUs using `BatchUpsertPricing`. By the end, you'll have set the selling price and MSRP for one or more SKUs in a country, and you'll know how to confirm each change succeeded.
`BatchUpsertPricing` is an upsert: if pricing already exists for a `partner_sku` and `country_code` pair, the call updates it; if it does not exist, the call creates it.
## Prerequisites
- Authentication set up — see [Getting Credentials][getting-credentials] and [Authenticating Your Requests][authenticating-requests]
- A `partner_sku` that already exists in noon's catalog — see [How to use the Pricing APIs][pricing-intro]
- The country code each SKU is listed in: `ae`, `sa`, or `eg`
## Step 1 — Send the pricing update
`BatchUpsertPricing` (`POST /pricing/v1/pricing/upsert`) takes an `items` array. Each item identifies one SKU in one country and carries the fields you want to set.
Each item requires `partner_sku` and `country_code`. The `price`, `msrp`, and `is_active` fields are optional and nullable: include a field to set it, or omit it (or send `null`) to leave the existing value unchanged. Sending `null` does not clear a value.
The example below sets the price and MSRP for two SKUs in the UAE (`ae`).
```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", "price": 149.00, "msrp": 199.00},
{"partner_sku": "MY-SNK-43", "country_code": "ae", "price": 149.00, "msrp": 199.00},
],
},
headers={"User-Agent": "MyPricingApp/1.0.0"},
timeout=30,
)
response.raise_for_status()
items = response.json()["items"]
```
```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", price: 149.0, msrp: 199.0 },
{ partner_sku: "MY-SNK-43", country_code: "ae", price: 149.0, msrp: 199.0 },
],
},
{
headers: {
"Content-Type": "application/json",
"User-Agent": "MyPricingApp/1.0.0",
},
}
);
const items = response.data.items;
```
**Response:**
```json
{
"items": [
{
"partner_sku": "MY-SNK-42",
"country_code": "ae",
"status": {"status_id": 0, "status_code": "OK", "message": ""}
},
{
"partner_sku": "MY-SNK-43",
"country_code": "ae",
"status": {"status_id": 0, "status_code": "OK", "message": ""}
}
]
}
```
The response returns one item per request item, echoing the `partner_sku` and `country_code` so you can match each result back to what you sent. Each item carries its own `status`.
You'll know this worked when every item in the response has `status.status_code` set to `OK` and `status.status_id` set to `0`.
## Step 2 — Check each item
A `200` response does not mean every price was set. `BatchUpsertPricing` processes each item independently, so the batch can partially succeed. Check the result at two levels.
**HTTP level.** A non-2xx response means the whole request failed before any item was processed — for example an authentication failure or an exceeded quota. The body is an `rpcStatus` object; read `message` for the reason.
**Item level.** On a `200`, loop over `items` and inspect each `status`. A `status_code` of `OK` (with `status_id` `0`) means that item was applied. Any other `status_code` means that item failed and its price was not changed — read `status.message` for the reason and retry just the failed items.
```python
for item in items:
status = item["status"]
if status["status_code"] != "OK":
print(f"Failed: {item['partner_sku']} ({item['country_code']}): {status['message']}")
```
```javascript
for (const item of items) {
if (item.status.status_code !== "OK") {
console.log(`Failed: ${item.partner_sku} (${item.country_code}): ${item.status.message}`);
}
}
```
| Condition | What it means | What to do |
|---|---|---|
| Non-2xx response | The 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 updated; the rest of the batch may still have succeeded | Read `status.message`, fix the item, and resend only the failed items. |
:::warning
A `200` response does not mean all items succeeded. Always inspect `status` on every item — partial success is normal.
:::
## Field rules
- **`partner_sku` and `country_code` are required** on every item. `country_code` must be one of `ae`, `sa`, or `eg`.
- **`price`, `msrp`, and `is_active` are optional and nullable.** Include a field to set it; omit it or send `null` to leave the current value unchanged. `null` never clears a value.
- **`price`** is the selling price. **`msrp`** is the crossed-out reference price shown on the listing page.
- **`is_active`** controls whether the SKU is sold on the platform. Set it to `false` to stop selling without losing the configured price.
- The same `partner_sku` in two different countries is two separate items — set pricing per country.
## Next steps
- [Read Prices][pricing-read-prices] — confirm the prices you just set
- [Activate a Product][pricing-activate-product] — make a priced SKU available for sale
- [Go Live][pricing-go-live] — the full pricing-to-live sequence
- [BatchUpsertPricing Reference][upsert-pricing-noon] — full request and response schema