> ## Documentation Index
> Fetch the complete documentation index at: https://apidocs.returnhelper.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Return Inventories 一覧（ページネーション付き）

<Warning>
  本エンドポイントは返品在庫の状態を追跡する方法として **推奨されません**。Return Helper API における在庫ライフサイクルの真実のソースは [Webhook イベントストリーム](/ja/webhooks) で、`markShipmentArrive`、`newInventoryCreated`、`vasUpdated`、在庫ハンドリング完了イベント、`notifyUserRmaSwapped` などが状態変更のたびにエンドポイントへ配信されます。統合は webhook を中心に構築してください。本リストエンドポイントは一回限りのバックフィルおよびオペレーション照合のためだけに用意されています。
</Warning>

返品在庫レコードのページング付き一覧——倉庫側のアイテム単位の状態——を返します。各レコードは、現在のハンドリング決定、RMA、SKU マッピング、倉庫割当を含む 1 件の受領アイテムを表します。

<h2 id="when-and-only-when-to-call">
  呼び出してよいタイミング（それ以外では呼ばないでください）
</h2>

* **一回限りのバックフィル** — 初回統合時、webhook 購読の前にローカル DB に既存の在庫を書き込むため。
* **定期的な整合性チェック** — webhook 配信の漏れや順序ずれを検知するため。ローカルキャッシュとこのエンドポイントの結果を差分してください。

継続的な状態（パーセルがログされた、ハンドリングが完了した、RMA が再割当された など）には webhook を購読してください。本エンドポイントを状態変更検知のためポーリングする運用はサポートされず、高負荷時には古いデータを返します。

<h2 id="required-parameters">
  必須パラメータ
</h2>

* **`createFrom` / `createTo`** — どちらも必須、ISO 8601 タイムスタンプ。範囲の上限は **62 日**（`SearchConfig.simpleRecordsMaxDays`）。それ以上はソフトエラーで拒否されます。「62 日」の正確な意味は下の [ウィンドウのセマンティクス](#window-semantics) を参照してください。
* **`pageSize`** — `1` から `50` の間。
* **`offset`** — 非負整数。`pageSize` と組み合わせてオフセットページングを行います。

<h2 id="response-notes">
  レスポンスの注意
</h2>

* `totalNumberOfRecords`（`data` と同じ階層のトップレベルフィールド）が現在のウィンドウの総件数です——ページングループの終了条件として使用してください。
* `handlingCode` は当該アイテムの現在のハンドリング決定を表します——変更するには [返品在庫ハンドリングを更新](/ja/api-reference/returninventory/update-return-inventory-handling) を呼び出してください。
* `handlingStatusCode` はそのハンドリングの状態を表します。[すべてのハンドリングステータスを取得](/ja/api-reference/handlingstatus/get-all-handling-statuses) で変換できます。
* アイテムの RMA（`rma`）は倉庫が割り当てた識別子で、セラー側の参照番号ではありません。

<h2 id="backfilling-historical-inventory">
  履歴在庫のバックフィル
</h2>

本エンドポイントを使って、過去に発生したすべての返品在庫レコードをローカル DB に取り込み、その後は webhook で継続的に更新します。API は 1 リクエストあたり最長 62 日に制限されているため、タイムラインを 62 日ウィンドウで遡り、各ウィンドウ内でページングを行い、アカウントの開設日まで進みます。

<h3 id="window-semantics">
  ウィンドウのセマンティクス
</h3>

ループを書き始める前に、以下 2 つのルールを把握しておいてください——これがクリーンなバックフィルと「気づかぬうちに 1 日漏らす」バックフィルの境目です。

1. **バリデータの規則（日単位の差）:**
   ```
   createTo.Date − createFrom.Date  ≤  62
   ```
   比較前に時刻部分は切り落とされます。よって `createFrom = 2024-03-13T15:00:00Z`、`createTo = 2024-05-14T09:00:00Z` のリクエストは有効です（`May 14 − Mar 13 = 62` 日）。実時刻差が 62 × 24 時間より短くても問題ありません。

2. **データのフィルタ（両端の日付を丸ごと含む）:**
   ```
   createOn ≥ createFrom.BeginOfDay()   AND   createOn ≤ createTo.EndOfDay()
   ```
   つまりサーバ側は `createFrom` を当日 `00:00:00.000` に、`createTo` を当日 `23:59:59.999` に拡張してからフィルタを適用します。したがって、**1 回の有効なリクエストは連続する 63 日分のデータをカバーします**（createFrom の日付の全日、createTo の日付の全日、およびその間のすべての日）。

スライディングウィンドウ・バックフィルへの実務的な影響: ウィンドウ N の `createFrom` をそのままウィンドウ N+1 の `createTo` として使うと、その境界日が両方の結果に現れます。これは **重複** であって **欠落** ではありません——アルゴリズムが行を漏らすことは決してなく、各ウィンドウの継ぎ目で約 1 日分を多めに取得するだけです。ローカル ストアが `returnInventoryId` を主キーとし UPSERT（または INSERT IGNORE）で書き込む限り、重複は自動的に解決され最終状態は完全に正確になります。

完全に重複なしで取得したい場合は、毎回 `windowEnd = windowStart` ではなく `windowEnd = windowStart − 1 day` に進めてください。各ウィンドウが重なりなく 63 日ぴったりのスライスになります。どちらの実装も正しいですが、下記のサンプルはクライアント／サーバ間の時計ずれに寛容な「継ぎ目を許容する」版を推奨デフォルトとして採用しています。

<h3 id="backfill-algorithm">
  バックフィルのアルゴリズム
</h3>

1. `historyStart` を決める（例: アカウント開設日）。
2. `windowEnd = now()` から開始。
3. `windowStart = max(windowEnd − 62 日, historyStart)` を計算。
4. ウィンドウ内で `offset = 0` から `pageSize` 単位でページングし、`offset ≥ totalNumberOfRecords` になるまで続ける。各レコードを `returnInventoryId` を主キーとしてローカル DB に UPSERT する。
5. `windowEnd = windowStart` にして手順 3 へ戻り、`windowEnd ≤ historyStart` になるまで繰り返す。
6. 以降は `newInventoryCreated` webhook（およびその他の在庫ライフサイクル イベント）でローカル ストアを維持。webhook のデータ欠落が疑われない限り、再バックフィルは不要です。

<h3 id="sample-code">
  サンプルコード
</h3>

<CodeGroup>
  ```java Java theme={null}
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import java.time.Instant;
  import java.time.temporal.ChronoUnit;

  // Requires a JSON library on the classpath. Below uses org.json for brevity:
  //   <dependency><groupId>org.json</groupId><artifactId>json</artifactId></dependency>
  import org.json.JSONArray;
  import org.json.JSONObject;

  class Main {
    static final String BASE_URL  = "https://api.returnhelpercentre.com/v1/user"; // production
    // sandbox: "https://api.returnshelper.com/uat/user"
    static final String API_KEY   = "<your api key>";
    static final String API_TOKEN = "<your api token>";

    static final int PAGE_SIZE   = 50;
    static final int WINDOW_DAYS = 62; // server cap: createTo.Date - createFrom.Date <= 62

    public static void main(String[] args) throws Exception {
      Instant historyStart = Instant.parse("2024-01-01T00:00:00Z"); // backfill anchor
      Instant windowEnd    = Instant.now();                         // walk backwards from now

      HttpClient http = HttpClient.newHttpClient();

      while (windowEnd.isAfter(historyStart)) {
        Instant windowStart = windowEnd.minus(WINDOW_DAYS, ChronoUnit.DAYS);
        if (windowStart.isBefore(historyStart)) {
          windowStart = historyStart;
        }

        int offset = 0;
        int total  = Integer.MAX_VALUE;

        while (offset < total) {
          String url = BASE_URL + "/api/ReturnInventory/list"
                     + "?pageSize="   + PAGE_SIZE
                     + "&offset="     + offset
                     + "&createFrom=" + windowStart
                     + "&createTo="   + windowEnd;

          HttpRequest req = HttpRequest.newBuilder()
              .uri(URI.create(url))
              .header("x-rr-apikey",   API_KEY)
              .header("x-rr-apitoken", API_TOKEN)
              .header("Accept",        "application/json")
              .GET()
              .build();

          HttpResponse<String> resp = http.send(req, HttpResponse.BodyHandlers.ofString());
          JSONObject body = new JSONObject(resp.body());

          // Standard envelope: business status is in meta.status, not HTTP status.
          JSONObject meta = body.optJSONObject("meta");
          if (meta == null || meta.optInt("status") != 200) {
            System.err.println("list call failed: " + (meta == null ? "no meta" : meta.toString()));
            return;
          }

          total = body.optInt("totalNumberOfRecords", 0);
          JSONArray rows = body.optJSONArray("data");
          if (rows != null) {
            for (int i = 0; i < rows.length(); i++) {
              JSONObject inv = rows.getJSONObject(i);
              // TODO: UPSERT into your DB with returnInventoryId as primary key.
              //       Adjacent windows share a seam day, so the same row may be
              //       returned twice; UPSERT absorbs the duplicate.
              //   inv.getLong("returnInventoryId")
              //   inv.getString("handlingCode")
              //   inv.getString("handlingStatusCode")
              //   inv.getInt("warehouseId")
            }
          }

          offset += PAGE_SIZE;
          Thread.sleep(200); // light throttle
        }

        windowEnd = windowStart;
      }
    }
  }
  ```

  ```js Node.js theme={null}
  // Requires Node.js 18+ for built-in fetch.

  const BASE_URL  = 'https://api.returnhelpercentre.com/v1/user'; // production
  // sandbox: 'https://api.returnshelper.com/uat/user'
  const API_KEY   = '<your api key>';
  const API_TOKEN = '<your api token>';

  const PAGE_SIZE   = 50;
  const WINDOW_DAYS = 62; // server cap: createTo.Date - createFrom.Date <= 62

  const MS_PER_DAY = 24 * 60 * 60 * 1000;

  async function main() {
    const historyStart = new Date('2024-01-01T00:00:00Z'); // backfill anchor
    let windowEnd      = new Date();                       // walk backwards from now

    while (windowEnd > historyStart) {
      let windowStart = new Date(windowEnd.getTime() - WINDOW_DAYS * MS_PER_DAY);
      if (windowStart < historyStart) {
        windowStart = historyStart;
      }

      let offset = 0;
      let total  = Infinity;

      while (offset < total) {
        const params = new URLSearchParams({
          pageSize:   String(PAGE_SIZE),
          offset:     String(offset),
          createFrom: windowStart.toISOString(),
          createTo:   windowEnd.toISOString(),
        });

        const resp = await fetch(`${BASE_URL}/api/ReturnInventory/list?${params}`, {
          headers: {
            'x-rr-apikey':   API_KEY,
            'x-rr-apitoken': API_TOKEN,
            'Accept':        'application/json',
          },
        });
        const body = await resp.json();

        // Standard envelope: business status is in meta.status, not HTTP status.
        if (body?.meta?.status !== 200) {
          console.error('list call failed:', body?.meta);
          return;
        }

        total      = body.totalNumberOfRecords ?? 0;
        const rows = body.data ?? [];

        for (const inv of rows) {
          // TODO: UPSERT into your DB with returnInventoryId as primary key.
          //       Adjacent windows share a seam day, so the same row may be
          //       returned twice; UPSERT absorbs the duplicate.
          //   inv.returnInventoryId
          //   inv.handlingCode
          //   inv.handlingStatusCode
          //   inv.warehouseId
        }

        offset += PAGE_SIZE;
        await new Promise((r) => setTimeout(r, 200)); // light throttle
      }

      windowEnd = windowStart;
    }
  }

  main().catch(console.error);
  ```

  ```ts TypeScript theme={null}
  // Requires Node.js 18+ for built-in fetch (or a fetch polyfill in older runtimes).

  const BASE_URL  = 'https://api.returnhelpercentre.com/v1/user'; // production
  // sandbox: 'https://api.returnshelper.com/uat/user'
  const API_KEY   = '<your api key>';
  const API_TOKEN = '<your api token>';

  const PAGE_SIZE   = 50;
  const WINDOW_DAYS = 62; // server cap: createTo.Date - createFrom.Date <= 62

  const MS_PER_DAY = 24 * 60 * 60 * 1000;

  interface ApiEnvelope<T> {
    correlationId: string;
    meta: {
      status: number;
      errorCode?: string | null;
      error?: Record<string, unknown>;
    };
    data?: T[];
    totalNumberOfRecords?: number;
  }

  interface ReturnInventoryRow {
    returnInventoryId: number;
    handlingCode: string;
    handlingStatusCode: string;
    warehouseId: number;
    // ...other fields documented in the API reference
  }

  async function main(): Promise<void> {
    const historyStart = new Date('2024-01-01T00:00:00Z'); // backfill anchor
    let windowEnd      = new Date();                       // walk backwards from now

    while (windowEnd > historyStart) {
      let windowStart = new Date(windowEnd.getTime() - WINDOW_DAYS * MS_PER_DAY);
      if (windowStart < historyStart) {
        windowStart = historyStart;
      }

      let offset = 0;
      let total  = Infinity;

      while (offset < total) {
        const params = new URLSearchParams({
          pageSize:   String(PAGE_SIZE),
          offset:     String(offset),
          createFrom: windowStart.toISOString(),
          createTo:   windowEnd.toISOString(),
        });

        const resp = await fetch(`${BASE_URL}/api/ReturnInventory/list?${params}`, {
          headers: {
            'x-rr-apikey':   API_KEY,
            'x-rr-apitoken': API_TOKEN,
            'Accept':        'application/json',
          },
        });
        const body = (await resp.json()) as ApiEnvelope<ReturnInventoryRow>;

        // Standard envelope: business status is in meta.status, not HTTP status.
        if (body.meta?.status !== 200) {
          console.error('list call failed:', body.meta);
          return;
        }

        total      = body.totalNumberOfRecords ?? 0;
        const rows = body.data ?? [];

        for (const inv of rows) {
          // TODO: UPSERT into your DB with returnInventoryId as primary key.
          //       Adjacent windows share a seam day, so the same row may be
          //       returned twice; UPSERT absorbs the duplicate.
          //   inv.returnInventoryId
          //   inv.handlingCode
          //   inv.handlingStatusCode
          //   inv.warehouseId
        }

        offset += PAGE_SIZE;
        await new Promise((r) => setTimeout(r, 200)); // light throttle
      }

      windowEnd = windowStart;
    }
  }

  main().catch(console.error);
  ```

  ```apex Apex theme={null}
  // Salesforce Apex — callable from an execute-anonymous window or wrapped in a
  // Queueable for large backfills (single-transaction callout limit is 100).
  //
  // Add the API host to "Remote Site Settings" before running.

  public class Main {
      private static final String BASE_URL  = 'https://api.returnhelpercentre.com/v1/user'; // production
      // sandbox: 'https://api.returnshelper.com/uat/user'
      private static final String API_KEY   = '<your api key>';
      private static final String API_TOKEN = '<your api token>';

      private static final Integer PAGE_SIZE   = 50;
      private static final Integer WINDOW_DAYS = 62; // server cap: createTo.Date - createFrom.Date <= 62

      public static void main() {
          Datetime historyStart = Datetime.newInstanceGmt(2024, 1, 1, 0, 0, 0); // backfill anchor
          Datetime windowEnd    = Datetime.now();                               // walk backwards from now

          Http http = new Http();

          while (windowEnd > historyStart) {
              Datetime windowStart = windowEnd.addDays(-WINDOW_DAYS);
              if (windowStart < historyStart) {
                  windowStart = historyStart;
              }

              Integer offset = 0;
              Integer total  = Integer.MAX_VALUE;

              while (offset < total) {
                  String url = BASE_URL + '/api/ReturnInventory/list'
                      + '?pageSize='   + PAGE_SIZE
                      + '&offset='     + offset
                      + '&createFrom=' + EncodingUtil.urlEncode(formatGmt(windowStart), 'UTF-8')
                      + '&createTo='   + EncodingUtil.urlEncode(formatGmt(windowEnd),   'UTF-8');

                  HttpRequest req = new HttpRequest();
                  req.setMethod('GET');
                  req.setEndpoint(url);
                  req.setHeader('x-rr-apikey',   API_KEY);
                  req.setHeader('x-rr-apitoken', API_TOKEN);
                  req.setHeader('Accept',        'application/json');

                  HttpResponse resp = http.send(req);

                  Map<String, Object> body = (Map<String, Object>) JSON.deserializeUntyped(resp.getBody());
                  Map<String, Object> meta = (Map<String, Object>) body.get('meta');

                  // Standard envelope: business status is in meta.status, not HTTP status.
                  if (meta == null || (Integer) meta.get('status') != 200) {
                      System.debug('list call failed: ' + meta);
                      return;
                  }

                  Object totalObj = body.get('totalNumberOfRecords');
                  total = (totalObj == null) ? 0 : (Integer) totalObj;

                  List<Object> rows = (List<Object>) body.get('data');
                  if (rows != null) {
                      for (Object row : rows) {
                          Map<String, Object> inv = (Map<String, Object>) row;
                          // TODO: UPSERT into your custom object with returnInventoryId__c
                          //       as External Id. Adjacent windows share a seam day, so the
                          //       same row may be returned twice; UPSERT absorbs the duplicate.
                          //   inv.get('returnInventoryId')
                          //   inv.get('handlingCode')
                          //   inv.get('handlingStatusCode')
                          //   inv.get('warehouseId')
                      }
                  }

                  offset += PAGE_SIZE;
              }

              windowEnd = windowStart;
          }
      }

      private static String formatGmt(Datetime dt) {
          return dt.formatGmt('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'');
      }
  }
  ```
</CodeGroup>

<h2 id="related">
  関連
</h2>

* [返品在庫の詳細を取得](/ja/api-reference/returninventory/get-return-inventory-details) — webhook がキャッシュされていない `returnInventoryId` を参照した場合に、ID で 1 件取得。
* [ラインアイテム ID で返品在庫を取得](/ja/api-reference/returninventory/get-return-inventory-by-line-item-id) — `returnRequestLineItemId` で検索。
* [返品在庫ハンドリングを更新](/ja/api-reference/returninventory/update-return-inventory-handling) — 書き込み側エンドポイント。
* [すべてのハンドリングステータスを取得](/ja/api-reference/handlingstatus/get-all-handling-statuses) と [すべてのハンドリングタイプを取得](/ja/api-reference/handling/get-all-handling-types) — コード → ラベルのマッピング。
* [Webhooks](/ja/webhooks) — 在庫ライフサイクル イベントの正規チャネル。本エンドポイントを利用する前に必ず webhook を設定してください。

API のエラーレスポンスの解釈と処理については [Error codes](/ja/reference/error-codes) を参照してください。


## OpenAPI

````yaml get /api/ReturnInventory/list
openapi: 3.1.0
info:
  title: Return Helper API
  description: API documentation for Return Helper — covering User and Public endpoints.
  version: 1.0.0
servers:
  - url: https://api.returnshelper.com/uat/user
    description: Sandbox — User API
  - url: https://api.returnshelper.com/uat/public
    description: Sandbox — Public API
  - url: https://api.returnhelpercentre.com/v1/user
    description: Production — User API
  - url: https://api.returnhelpercentre.com/v1/public
    description: Production — Public API
  - url: https://api.returnhelperchina.com/user
    description: Production — User API (China)
security:
  - ApiKey: []
    ApiToken: []
paths:
  /api/ReturnInventory/list:
    get:
      tags:
        - ReturnInventory
      summary: List return inventories with pagination
      operationId: ReturnUserApi_ReturnInventory_List
      parameters:
        - name: pageSize
          in: query
          required: true
          schema:
            type: integer
            maximum: 50
            minimum: 1
          description: Number of records per page (1–50)
        - name: offset
          in: query
          required: true
          schema:
            type: integer
        - name: createFrom
          in: query
          required: true
          schema:
            type: string
            format: date-time
        - name: createTo
          in: query
          required: true
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/PaginationResponse_List_UserListReturnInventoryReply
        '401':
          description: >-
            Authentication failed. Returned when the `x-rr-apikey` or
            `x-rr-apitoken` header is missing or invalid. The body uses the
            standard `ApiResponse` envelope with `meta.error.message` describing
            the auth failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
      security:
        - ApiKey: []
          ApiToken: []
      servers:
        - url: https://api.returnshelper.com/uat/user
          description: Sandbox — User API
components:
  schemas:
    PaginationResponse_List_UserListReturnInventoryReply:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/UserListReturnInventoryReply'
          description: List of return inventories
        totalNumberOfRecords:
          type: integer
          format: int32
          description: Total count of return inventories
    ApiResponse:
      type: object
      description: >-
        Universal response envelope. Successful responses include the business
        payload as additional top-level fields alongside `correlationId` and
        `meta`. Failed responses (auth errors, validation errors) only populate
        `correlationId` and `meta`, with `meta.errorCode` and `meta.error`
        describing the failure.
      properties:
        correlationId:
          type:
            - string
            - 'null'
          description: >-
            Unique correlation ID for tracing the request through Return Helper
            systems.
        meta:
          $ref: '#/components/schemas/ApiResponseMeta'
    UserListReturnInventoryReply:
      type: object
      properties:
        returnInventoryId:
          type: integer
          format: int32
        returnRequestId:
          type: integer
          format: int32
        returnRequestLineItemId:
          type:
            - string
            - 'null'
        rma:
          type:
            - string
            - 'null'
        itemRma:
          type:
            - string
            - 'null'
        sku:
          type:
            - string
            - 'null'
        handlingCode:
          type:
            - string
            - 'null'
        handlingStatusCode:
          type:
            - string
            - 'null'
        warehouseId:
          type: integer
          format: int32
        createOn:
          type: string
          format: date-time
    ApiResponseMeta:
      type: object
      description: >-
        Application-level metadata for every API response. Inspect `status` and
        `errorCode` to detect soft-error responses (validation failures arrive
        as HTTP 200 with `meta.status: 400`).
      properties:
        status:
          type: integer
          description: >-
            Application-level status code. For successful operations this
            mirrors the HTTP status (e.g. 200). For validation failures it
            reports the logical status (e.g. 400) even though the wire HTTP
            status is 200.
        data:
          type: object
          additionalProperties:
            type: string
          description: Reserved free-form metadata key/value pairs. Usually empty.
        errorCode:
          type:
            - string
            - 'null'
          description: >-
            Machine-readable error code (e.g. `VALIDATION_FAILED`). Non-null
            only when the operation failed.
        error:
          type: object
          additionalProperties: true
          description: >-
            Field-level or message-level error detail keyed by request property
            name. Empty object on success.
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: x-rr-apikey
      description: Your API key
    ApiToken:
      type: apiKey
      in: header
      name: x-rr-apitoken
      description: Your API token — keep this private

````