> 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/oversell-api/oversell-reallocate.md).

# Oversell / Reallocate — 売越し・再引き当て

ルーティング確定後に **売越し**（システム上は在庫があったが、店舗で実物欠品 / 汚損 / 先行販売 等で実際には出荷できない）が起きたとき、該当の引き当て結果に **売越しフラグ** を立て、**同じ出荷元の別の在庫ロケーション** へ再引き当て（再ルーティング）します。

> **Base URL** `https://api.lmile.io` · **認証** `x-ingest-secret` ヘッダー または operator JWT（`Authorization: Bearer`）（[詳細](/lmile-docs/getting-started/authentication.md)） · `shop` はリクエストボディに含めます（API キーで呼ぶ場合は省略できます）

> `/api/routing/oversell` / `/api/routing/reallocate` は機械間 secret（`x-ingest-secret`）と倉庫スタッフの operator JWT のどちらでも呼べます（系統はヘッダの有無で明示判別。[詳細](https://lmile.gitbook.io/lmile-docs/oversell-api/pages/7cB70I8yeRnMpvcdLkNu#routing-write-の-2-系統認証)）。operator JWT 経由は操作スタッフを記録します。

## エンドポイント

| Method | Path                      | 用途                      |
| ------ | ------------------------- | ----------------------- |
| `POST` | `/api/routing/oversell`   | 引き当て結果に売越しフラグを立てる       |
| `POST` | `/api/routing/reallocate` | 売越し結果を同一出荷元の別メンバーへ再引き当て |

> 入力フィールドは **camelCase**（`routingOrderId` / `lineInstanceNo`）です。

***

## `POST` /api/routing/oversell

`routingOrderId` の **applied** な引き当て結果に売越しフラグ（`oversold = true`）を立てます。`barcode` / `locationId` / `lineInstanceNo` で対象を絞り込めます（未指定なら注文の applied 全件）。

### リクエスト

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

```json
{
  "shop": "demo-store.myshopify.com",
  "routingOrderId": "0f1e2d3c-4b5a-6789-0abc-def123456789",
  "barcode": "1234567890123",
  "locationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "reason": "店舗で実物欠品"
}
```

### ボディパラメータ

| パラメータ            | 型             |  必須 | 説明                                         |
| ---------------- | ------------- | :-: | ------------------------------------------ |
| `shop`           | string        |  ✓  | 店舗ドメイン（API キーで呼ぶ場合は省略できます）                 |
| `routingOrderId` | string (uuid) |  ✓  | 対象の routing order id                       |
| `barcode`        | string        |     | 対象 barcode で絞り込み                           |
| `locationId`     | string (uuid) |     | 引き当て先在庫ロケーション（`selected_location_id`）で絞り込み |
| `lineInstanceNo` | number        |     | 販売単位番号で絞り込み                                |
| `reason`         | string        |     | 売越し理由（`oversold_reason` に記録）               |

### レスポンス

```json
{ "ok": true, "shop": "demo-store.myshopify.com", "routingOrderId": "0f1e2d3c-...", "marked": 1 }
```

| フィールド    | 説明                                                          |
| -------- | ----------------------------------------------------------- |
| `marked` | 売越しフラグを立てた decision 件数（既に `oversold` の行・`applied` でない行は対象外） |

### 挙動

* 対象は `decision_status = applied` かつ `oversold = false` の行のみ。`oversold = true` / `oversold_at` / `oversold_reason` を更新します。
* 既に売越し済の行は二重マークしません（`marked` に含まれない）。
* フラグを立てただけでは引き当ては変わりません。実際の振り直しは `/api/routing/reallocate` を呼びます。

***

## `POST` /api/routing/reallocate

`routingOrderId` の **売越し（oversold）** な引き当て結果を、**同一出荷元の別の在庫ロケーション** へ再ルーティングします。旧結果は `superseded` にし後継へリンク、出荷指示を再構築して再 dispatch します。

### リクエスト

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

```json
{
  "shop": "demo-store.myshopify.com",
  "routingOrderId": "0f1e2d3c-4b5a-6789-0abc-def123456789"
}
```

### ボディパラメータ

| パラメータ            | 型             |  必須 | 説明                         |
| ---------------- | ------------- | :-: | -------------------------- |
| `shop`           | string        |  ✓  | 店舗ドメイン（API キーで呼ぶ場合は省略できます） |
| `routingOrderId` | string (uuid) |  ✓  | 再引き当て対象の routing order id  |

### レスポンス

```json
{
  "ok": true,
  "routingOrderId": "0f1e2d3c-4b5a-6789-0abc-def123456789",
  "status": "dispatched",
  "reallocated": 1,
  "unresolvedReallocations": 0,
  "skipped": 0,
  "shippingInstruction": { "shipments": [], "unroutableLines": [], "serviceLines": [], "decidedAt": "2026-06-02T03:40:00.000Z" },
  "dispatches": [ { "locationId": "a1b2c3d4-...", "status": "sent", "attempts": 1 } ]
}
```

| フィールド                     | 説明                                                                                                                                                                                                                                                                                                           |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ok`                      | 入力・認証が妥当で、かつ dispatch 送信が失敗しなかったことを示す。**再引き当て先の在庫が無くても（`status: no_stock` / `unresolvedReallocations > 0` / `skipped > 0`）`ok: true` のまま**返ります。`ok: false` になるのは入力不正（`400`）・注文不在（`404`）・dispatch 送信失敗（`status: failed`）のみ。**再引き当ての成否は `ok` ではなく `status` / `unresolvedReallocations` / `skipped` で判定してください** |
| `reallocated`             | 再引き当てした unit 数（旧 decision を superseded にし後継を生成した数）                                                                                                                                                                                                                                                           |
| `unresolvedReallocations` | 再引き当てしたが**他に在庫が無く引き当て不能**だった unit 数（`unroutableLines` 行き）                                                                                                                                                                                                                                                    |
| `skipped`                 | 出荷元 / barcode 情報を欠く旧 decision で再引き当て不能だった数（`oversold` のまま据え置き）                                                                                                                                                                                                                                               |
| `status`                  | 再構築後の注文ステータス（`dispatched` / `routed` / `failed` / `no_stock`）                                                                                                                                                                                                                                                |
| `shippingInstruction`     | 現在の applied 結果（健全分 + 再引き当て分）から再構築した出荷指示                                                                                                                                                                                                                                                                      |
| `dispatches`              | 引き当て先ロケーションごとの再送結果配列（[Dispatch Config](/lmile-docs/configuration/dispatch-config.md) の per-location 設定で送信）                                                                                                                                                                                                   |

売越し対象が無い場合は `{ "ok": true, "routingOrderId": "...", "reallocated": 0, "note": "no oversold decisions" }` を返します。

### 挙動・冪等性

* 再引き当ては **同一出荷元のメンバー在庫ロケーション内**で行い、**売越しになった在庫ロケーションは候補から除外**します。同 barcode の売越し location はすべて除外対象です。
* 在庫量を尊重するため `(出荷元, barcode)` 単位でまとめて再配分します（複数 unit の二重引き当てを防止）。
* 旧 decision は `decision_status = superseded` にし `superseded_by_decision_id` で後継へリンク。新 decision は `applied`。明細単位の `properties`（[Routing](/lmile-docs/routing-api/orders.md) の `lines[].properties`）は旧 decision から後継へ引き継がれ、再構築後の出荷指示にも含まれます。
* 出荷指示は `(shop, idempotencyKey)` で upsert されるため、再 dispatch は同一行を更新します（[Idempotency](/lmile-docs/reference/idempotency.md)）。
* 別メンバーにも在庫が無ければ該当 unit は `unroutableLines`（`no_stock_anywhere`）。全 unit 不能なら `status = no_stock`、dispatch は skip。
* **再引き当て不能（`no_stock` / `unresolvedReallocations` / `skipped`）は HTTP エラーにせず `200` + `ok: true` で返します**（行単位の結果として表現し silent skip しない）。`ok: false` は入力不正・注文不在・dispatch 送信失敗に限ります。在庫が見つかるまで現場で確保 → 再度 `/api/routing/reallocate` を呼ぶ運用を前提とします。

***

## エラー

エンドポイント固有:

| Status | 条件                               | レスポンス例                                                                           |
| :----: | -------------------------------- | -------------------------------------------------------------------------------- |
|  `400` | `routingOrderId` 欠落              | `{ "ok": false, "error": "routingOrderId required" }`                            |
|  `404` | routing order が存在しない（reallocate） | `{ "ok": false, "error_kind": "not_found", "error": "routing order not found" }` |

共通エラー（`401` / `400` / `403` / `405` / `500` / `503`）は [Error Codes](/lmile-docs/reference/error-codes.md) を参照。

## データモデル

* `sot.lm_routing_decisions` — 売越し列 `oversold` / `oversold_at` / `oversold_reason`、再引き当てリンク `superseded_by_decision_id`。出荷元は `fulfillment_source_location_id`、引き当て先は `selected_location_id`。
* `sot.lm_fulfillment_source_members` — 再引き当ての候補プール（同一出荷元の在庫ロケーション）。
* `sot.lm_shipping_instructions` — 再 dispatch ログ（`delivery_status`。UNIQUE `shop + idempotency_key`）。


---

# 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/oversell-api/oversell-reallocate.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.
