> For the complete documentation index, see [llms.txt](https://docs.pyck.cloud/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pyck.cloud/shopify-app/stock.md).

# Warehouse stock

Letting pyck drive the stock counts your Shopify locations show

Audience: Logistics Manager

pyck knows what is actually on the shelf. This feature copies that count into Shopify so your storefront sells what you really have.

It is off until you switch it on.

{% hint style="danger" %}
**pyck decides the stock count at every paired location.** Each sync writes pyck's number over whatever Shopify holds. Any on-hand quantity you edit by hand in the Shopify admin is overwritten at the next sync and the change is lost. Correct stock in pyck, not in Shopify.

In pull mode a hand edit survives less than one interval. In push mode it can be gone within seconds.
{% endhint %}

## 1. Pair each location with a storage area

Nothing happens until a Shopify location is paired with the pyck **storage area** that holds its stock.

Pairing lives on the **Stock sync** page, in the **Locations and storage areas** card: choose **Pair locations**. The storage areas always come from your production connection — no other tenant may write your stock. Without a production connection the card says "No production warehouse yet" and nothing can be paired.

The rules are strict, and the app will refuse a pairing that breaks them:

* **One storage area stocks one location.** An area cannot feed two locations. A location has one area: choosing a different area for it replaces the old pairing.
* **An area nested inside another cannot be paired alongside it.** A pyck area's count includes everything below it, so pairing both a parent and its child would count the same goods towards two Shopify locations. Areas sitting side by side are fine.
* A **virtual** storage area — one pyck uses to record movements rather than to hold goods on a shelf — can be paired, but the app warns you. What it counts is unlikely to match what is in the location.

## 2. Choose how stock reaches Shopify

The **Stock sync** card on the same page offers three options. Pick one and choose **Save** — they cannot run together, because each would overwrite the other's work at unpredictable moments.

| Option                                         | What happens                                                                                                                                |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Off**                                        | Nothing reads pyck and nothing writes stock. Your Shopify quantities stay exactly as they are.                                              |
| **On — this app reads pyck every hour** (pull) | The app reads each paired storage area once an hour and writes the counts onto its Shopify location. Every run is checked before it writes. |
| **On — pyck reports each change** (push)       | Nothing runs on a timer. Your pyck workflow calls the app whenever stock moves and the app writes that one quantity straight to Shopify.    |

The preview approval and the safety limits described below apply to pull mode. Push mode writes one quantity at a time, so there is no whole warehouse being read at once to check. Push also does not use the pairings: the workflow names the Shopify location itself, and without one the app writes to the first location the product is stocked at.

## 3. Approve the first sync for each location

A location that has never synced will not be written to until you say so.

On the **Stock sync** page, choose **Check what pyck holds**. The app reads the whole paired storage area while you wait, reports how many products it found counts for, and writes nothing. A large warehouse can take a few minutes. When the numbers look right, choose **Approve first sync**.

The approved sync is queued and starts within a minute; you can close the page. An approved sync that has not started within an hour is dropped as "Never started", and you approve again. After the first sync succeeds, syncing carries on by itself.

The first sync of a large warehouse may also have to switch thousands of products on at that location in Shopify first, one request each. That work is spread across several later syncs, so stock arrives in batches until it is done.

## What actually gets written

These three rules are the heart of the feature.

| What pyck reports for a SKU            | What happens in Shopify                                                  |
| -------------------------------------- | ------------------------------------------------------------------------ |
| A number, **including 0**              | It is written. Zero is a real sell-out and has to reach your storefront. |
| **No entry at all**                    | The SKU is **skipped**. It is never set to zero and never touched.       |
| pyck errors, or cannot be reached      | The run writes **nothing at all**. Not partially, not zeroes.            |
| Shopify refuses some of the quantities | The rest are written. The next sync writes the whole count again.        |

The second rule is the important one. It means a pyck outage, an expired key, a pairing pointing at a deleted storage area or a mis-scoped tenant cannot empty your catalogue — all of them produce *absences*, and absences write nothing.

So anything you do not keep in the paired storage area is left exactly as it is in Shopify.

A SKU that more than one Shopify variant uses is also skipped rather than guessed at. The app will not decide for you which of two variants a count belongs to. The same goes for a variant that does not track inventory in Shopify.

## Why your available quantity can look wrong

The app writes Shopify's **on-hand** count — the physical number of units in the warehouse.

Shopify works out **available** itself, by subtracting the units already committed to open orders. So:

```
available = on-hand − committed to open orders
```

That is why a location can legitimately show a **negative available**: pyck says there are 3 units on the shelf, Shopify has 5 already promised to customers, so 2 are owed. That is accurate, not a bug — you are oversold and the number is telling you by how much.

It is also why the app writes on-hand rather than available. Writing a physical count into available would add the committed units back and let you sell them twice.

In push mode, a workflow can also send a change instead of a count ("3 fewer"). That change is applied to available, which moves on-hand by the same amount.

## A sync that stops is the safety net working

Every stopped run means the same thing: **nothing was written and your stock was left alone.** On the Stock sync page, stopped runs are shown in orange, not red, for exactly this reason. **Activity** lists them as failed.

A run stops when:

| Reason                                | What it means                                                                                                                                                                                                                                           |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Waiting for your approval             | The location has never synced. Approve it on the Stock sync page.                                                                                                                                                                                       |
| Would have emptied the location       | pyck reported more of this location's stock as zero than one sync may write: more than 50 products, and more than 5% of the products in stock there. Far more often a storage area that was emptied, re-seeded or renamed in pyck than a real sell-out. |
| The paired storage area is gone       | The area no longer exists in pyck. Pair the location with one that does.                                                                                                                                                                                |
| pyck reported far less than last time | This run found more than 30% less stock than the last successful one (and at least 50 products fewer). Usually a pyck-side problem rather than a real fall.                                                                                             |
| The run took too long                 | Its counts were already out of date by the time it was ready to write, and writing them would have moved your stock backwards.                                                                                                                          |
| The sync stopped part-way             | The app restarted mid-sync. Nothing partial was left behind; the next sync starts over.                                                                                                                                                                 |

Apart from the approval and a missing storage area, these clear themselves. Once pyck reports normal counts again, the next sync goes through without anyone doing anything.

A run can also end in red, as "Did not finish": the sync could not read pyck or write Shopify, or Shopify would not stock some products at that location (usually a location switched off in Shopify), or Shopify refused some quantities. Activity names the products and Shopify's reason.

### Overriding the emptying limit

When a run would set too much of a location to zero, it stops and offers **Let this sync through once…**. Use it only if the warehouse really is empty — every one of those products stops being sellable from that location the moment it is written. The app asks you to confirm how many SKUs it will set to zero.

The override applies to one sync. The next sync is checked in exactly the same way, so if pyck is still reporting the area as empty it stops again, which is what you want.

## Prerequisites checklist

For pull mode, stock will not move unless all of these are true:

* You have a **production connection**, and it is switched on.
* The Shopify location is **paired** with a pyck storage area.
* **On — this app reads pyck every hour** is chosen and saved.
* The location's **first sync has been approved**.

For push mode, you need a switched-on production connection — the stock has to come from it — and **On — pyck reports each change** chosen and saved. It needs no pairing.

If something looks wrong, see [When something looks wrong](/shopify-app/troubleshooting.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.pyck.cloud/shopify-app/stock.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
