# Get or update listing inventory (shop-scoped)

> Eto API reference for `GET /api/v1/shops/{shop_id}/listings/{listing_id}/inventory`. Base URL `https://eto.tools/api/v1/`. Authenticate with the `X-Eto-API-Key` header.

Part of the [Eto API reference](https://eto.tools/dev/docs/). The full reference in one file is at [llms-full.txt](https://eto.tools/dev/docs/llms-full.txt); the machine-readable schema is at [openapi.json](https://eto.tools/dev/docs/openapi.json).

## GET · PUT /api/v1/shops/{shop_id}/listings/{listing_id}/inventory

Get or update listing inventory (shop-scoped)

- Operation ID: `shop_listing_inventory_get`
- Slug: `shop-listing-inventory`
- Category: Listings
- Authentication: API key plus a connected store. Eto uses that store’s Etsy token, so the shop_id must belong to a store connected to your Eto account or the call answers 403 STORE_NOT_CONNECTED.
- HTML: https://eto.tools/dev/docs/#ep-shop-listing-inventory
- Markdown: https://eto.tools/dev/docs/listings/shop-listing-inventory.md
- Operation IDs by method: `shop_listing_inventory_get` = GET, `shop_listing_inventory_put` = PUT

Same as GET/PUT /api/v1/listings/{listing_id}/inventory, but the shop is named in the path, so Eto uses that store's token directly and skips finding the listing's shop. Use it when you already know the shop.
PUT replaces the whole inventory: GET it, change prices or quantities, PUT every product back with its sku and the *_on_property arrays unchanged.

Proxied to the Etsy API at `/v3/application/listings/{listing_id}/inventory`. Fields Etsy returns are passed through untouched.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `shop_id` | path | `integer` | yes | Your connected Etsy shop ID |
| `listing_id` | path | `integer` | yes | The Etsy listing ID |
| `products` | body | `array` | no | PUT only. Every product of the listing, each with sku, property_values and offerings [{price, quantity, is_enabled}]. |
| `price_on_property` | body | `array` | no | PUT only. Property ids that change price. |
| `quantity_on_property` | body | `array` | no | PUT only. Property ids that change quantity. |
| `sku_on_property` | body | `array` | no | PUT only. Property ids that change SKU. |
| `readiness_state_on_property` | body | `array` | no | PUT only. Property ids that change processing profile. |

### Request — GET

```bash
curl -X GET "https://eto.tools/api/v1/shops/12345678/listings/1234567890/inventory" \
  -H "X-Eto-API-Key: eto_your_key"
```

```python
import requests

url = "https://eto.tools/api/v1/shops/12345678/listings/1234567890/inventory"
headers = {"X-Eto-API-Key": "eto_your_key"}

response = requests.get(url, headers=headers, timeout=120)
response.raise_for_status()
print(response.json())
```

```javascript
const url = "https://eto.tools/api/v1/shops/12345678/listings/1234567890/inventory";

const response = await fetch(url, {
  method: "GET",
  headers: {
    "X-Eto-API-Key": "eto_your_key",
  },
});
if (!response.ok) throw new Error(`Eto API ${response.status}`);
const data = await response.json();
```

### Request — PUT

```bash
curl -X PUT -H "X-Eto-API-Key: eto_your_key" -H "Content-Type: application/json" -d '{"products": [...], "price_on_property": [], "quantity_on_property": [], "sku_on_property": []}' "https://eto.tools/api/v1/shops/12345678/listings/1234567890/inventory"
```

```python
import requests

url = "https://eto.tools/api/v1/shops/12345678/listings/1234567890/inventory"
headers = {"X-Eto-API-Key": "eto_your_key"}
payload = "{\"products\": [...], \"price_on_property\": [], \"quantity_on_property\": [], \"sku_on_property\": []}"

response = requests.put(url, headers=headers, data=payload, timeout=120)
response.raise_for_status()
print(response.json())
```

```javascript
const url = "https://eto.tools/api/v1/shops/12345678/listings/1234567890/inventory";
const payload = "{\"products\": [...], \"price_on_property\": [], \"quantity_on_property\": [], \"sku_on_property\": []}";

const response = await fetch(url, {
  method: "PUT",
  body: payload,
  headers: {
    "X-Eto-API-Key": "eto_your_key",
    "Content-Type": "application/json",
  },
});
if (!response.ok) throw new Error(`Eto API ${response.status}`);
const data = await response.json();
```

### Response

`application/json`, passed through from Etsy’s `/v3/application/listings/{listing_id}/inventory` verbatim. The field-by-field data model is in the [v2 preview reference](https://eto.tools/eto-dev-api-v2/), which documents these same routes alongside the whole Etsy schema.

### Errors

Failures answer with the shared error body described in the Errors section: `{"error": {"code", "status", "message", "hint", "docs"}}`. Branch on `code`, not on the message.

This endpoint can additionally return `STORE_NOT_CONNECTED` (403) when the shop is not linked to your account, and `STORE_TOKEN_EXPIRED` (503) when its Etsy authorisation has lapsed and needs reconnecting.
