> For the complete documentation index, see [llms.txt](https://lmile.gitbook.io/lmile-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lmile.gitbook.io/lmile-docs/webhooks/source-inventory.md).

# Source Inventory — 在庫変動通知

[出荷元（fulfillment source）](/lmile-docs/configuration/source-members.md)に紐づく在庫ロケーション（member）の在庫が[取込](/lmile-docs/ingestion-api/inventory-levels.md)で更新された結果、その**出荷元の合算 `available_qty` が `barcode` 単位で変わったとき**に通知します。合算在庫 = 出荷元に属する member 在庫ロケーションの `available_qty` の合計です。

> **Base URL** `https://api.lmile.io` · **認証** `x-ingest-secret` ヘッダー（[詳細](/lmile-docs/getting-started/authentication.md)） · `shop` はリクエストボディに含めます（省略するとキーのアカウント）

> 配信・リトライ・暗号化など共通の仕組みは [Webhooks 概要](/lmile-docs/webhooks/overview.md)を参照。

## エンドポイント

| Method | Path                                 | 用途                                       |
| ------ | ------------------------------------ | ---------------------------------------- |
| `POST` | `/api/routing/source-webhook-config` | 出荷元単位の在庫変動 webhook 送信先設定を登録 / 更新（upsert） |

***

## `POST` /api/routing/source-webhook-config

`shop + fulfillmentSourceLocationId` で設定を upsert します。

### リクエスト

```http
POST https://api.lmile.io/api/routing/source-webhook-config
x-ingest-secret: {INGEST_SECRET}
Content-Type: application/json
```

```json
{
  "shop": "demo-store.myshopify.com",
  "fulfillmentSourceLocationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "destinationUrl": "https://sync.example.com/inventory/aggregated",
  "authType": "bearer",
  "authSecret": "sync-api-token-xxxxx",
  "payloadTemplate": {
    "barcode": "{{barcode}}",
    "sku": "{{sku}}",
    "available": "{{availableTotalAfter}}",
    "location": "{{fulfillmentSourceLocationId}}"
  },
  "isActive": true
}
```

### ボディパラメータ

[共通パラメータ](https://lmile.gitbook.io/lmile-docs/webhooks/pages/OotbCjshtf2WFaZaqjCi#設定upsert)に加えて:

| パラメータ                         | 型             |  必須 | 説明                            |
| ----------------------------- | ------------- | :-: | ----------------------------- |
| `fulfillmentSourceLocationId` | string (uuid) |  ✓  | 通知対象の出荷元ロケーション（shop 内に実在すること） |

### ペイロードテンプレート

利用可能な変数:

| 変数                                | 説明                                                                            |
| --------------------------------- | ----------------------------------------------------------------------------- |
| `shop`                            | 店舗ドメイン                                                                        |
| `fulfillmentSourceLocationId`     | 出荷元ロケーション id                                                                  |
| `barcode` / `sku` / `productName` | 対象商品（`sku` / `productName` は `barcode` から商品マスターを解決して補完）                       |
| `releasedAt`                      | 商品の発売日時（ISO8601）。未設定なら `null`。発売前に在庫を公開しない運用では、この値が未来のイベントの在庫を `0` として扱ってください |
| `availableTotalAfter`             | 変動後の**合算** `available_qty`（絶対値）                                               |
| `availableTotalBefore`            | 前回送信した合算値（初回は `null`）                                                         |
| `changedAt`                       | 通知生成時刻（ISO8601）                                                               |

省略時の既定テンプレート:

```json
{
  "event": "fulfillment_source_inventory_changed",
  "shop": "{{shop}}",
  "fulfillmentSourceLocationId": "{{fulfillmentSourceLocationId}}",
  "barcode": "{{barcode}}",
  "sku": "{{sku}}",
  "productName": "{{productName}}",
  "releasedAt": "{{releasedAt}}",
  "availableTotal": "{{availableTotalAfter}}",
  "availableTotalBefore": "{{availableTotalBefore}}",
  "changedAt": "{{changedAt}}"
}
```

### レスポンス

```json
{ "ok": true, "id": "c0ffee00-...", "shop": "demo-store.myshopify.com",
  "fulfillment_source_location_id": "a1b2c3d4-...", "is_active": true, "has_secret": true }
```

| フィールド        | 説明                                                    |
| ------------ | ----------------------------------------------------- |
| `id`         | 設定行 id（`sot.lm_fulfillment_source_webhook_config.id`） |
| `has_secret` | 認証 secret が保存済か（secret 値そのものは返しません）                   |

### 挙動

* **合算と変動検知**: 在庫取込で member 在庫ロケーションが更新されると、その出荷元の `barcode` 単位の合算 `available_qty` を再計算し、**前回送信した値（`sot.lm_fulfillment_source_inventory_state`）と異なる `barcode` だけ**イベントを起票します。出荷元に属さないロケーションの更新は対象外です
* **送信は絶対値**: `availableTotalAfter` は差分ではなく合算の現在値です。受け手は冪等に上書きしてください
* **発売日時 (`releasedAt`)**: 各イベントに商品の発売日時が含まれます（未設定なら `null`）。発売前に在庫を公開しない運用では、`releasedAt` が未来のイベントは在庫を `0` として反映してください。発売日時を過ぎると通常の合算値が流れます
* **配信タイミング**: 次の 2 つの契機でバックグラウンド送信します。
  * [在庫取込](/lmile-docs/ingestion-api/inventory-levels.md)（`/api/ingest/inventory-snapshot` / `/api/ingest/inventory-available`）の成功直後
  * [出荷元↔在庫ロケーション マッピングの変更](/lmile-docs/configuration/source-members.md)（`/api/routing/source-members` の設定・解除）時。影響を受けた出荷元（付け替えは新・旧の両方）の合算を再計算して発火します。**メンバーを外して合算が減った（最後の1つを外して `0` になった場合を含む）変動も検知**されます
* **並列配信**: イベントは同時実行数の上限つきで並列送信します（全量再同期など大量変動時も滞留しません）。受け手は**複数 `barcode` の POST を同時に**受け取ることがあります。同一 `barcode` のイベントは順序を保持して送信します

## エラー

エンドポイント固有:

| Status | 条件                                                             | レスポンス例                                                                                                            |
| :----: | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|  `422` | 出荷元 location が shop 内に存在しない（`error_kind: location_unresolved`） | `{ "ok": false, "error_kind": "location_unresolved", "error": "fulfillment source location not found for shop" }` |

共通エラーは [Webhooks 概要](https://lmile.gitbook.io/lmile-docs/webhooks/pages/OotbCjshtf2WFaZaqjCi#エラー) / [Error Codes](/lmile-docs/reference/error-codes.md) を参照。

## データモデル

* `sot.lm_fulfillment_source_webhook_config` — 出荷元単位の送信設定（`UNIQUE (shop, fulfillment_source_location_id)`）
* `sot.lm_fulfillment_source_inventory_state` — `(shop, fulfillment_source_location_id, product_id)` ごとの前回送信した合算値（重複送信の抑止に使用）
* `sot.lm_fulfillment_source_inventory_events` — 変動イベント outbox + 送信ログ
* 合算の元: [`sot.lm_fulfillment_source_members`](/lmile-docs/configuration/source-members.md)（出荷元 → member 在庫ロケーション）+ `sot.inventory_levels.available_qty`


---

# 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://lmile.gitbook.io/lmile-docs/webhooks/source-inventory.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.
