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

# Grok Imagine 2.0 Ext レイヤー・範囲編集

> segment でオブジェクトレイヤーと高精度マスクを取得し、region_edit でポリゴン、矩形、検出オブジェクトを編集します。

<Info>
  `segment` と `region_edit` は既存の非同期画像エンドポイントを使用します。返された `task_id` を保存し、[タスクステータスを取得](/ja/api-reference/tasks/status) をポーリングしてください。作成リクエストは最終レイヤーや画像を直接返しません。
</Info>

<Warning>
  API Key をブラウザバンドル、LocalStorage、URL、フロントエンドログに置かないでください。バックエンドまたは BFF から APIMart を呼び出します。
</Warning>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.apimart.ai/v1/images/generations \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'Idempotency-Key: 6baf0940-25d6-4ec2-9131-925250840fa7' \
    --data '{
      "model": "grok-imagine-2.0-ext",
      "operation": "segment",
      "source_task_id": "<COMPLETED_SINGLE_IMAGE_TASK_ID>",
      "include_mask_rle": true,
      "cached_only": false
    }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "code": 200,
    "data": [{ "status": "submitted", "task_id": "task_..." }]
  }
  ```
</ResponseExample>

## 操作の概要

| 用途                                        | 主な入力                     | 完了結果                               | 課金         |
| ----------------------------------------- | ------------------------ | ---------------------------------- | ---------- |
| `segment`: オブジェクトを検出し、レイヤー、ボックス、高精度マスクを取得 | `source_task_id`         | `image_id`, `image_url`, `objects` | 無料         |
| `region_edit`: ポリゴン、矩形、検出オブジェクトを編集        | `image_id`、`prompt`、選択範囲 | 新しい URL と `image_id`               | 完了タスクごとに課金 |

```text theme={null}
task_id → segment(source_task_id) → image_id + mask_rle
        → selection_regions → region_edit → new task_id + image_id
```

<Note>
  `source_task_id` と `image_id` は交換できません。`segment` は元タスク ID、`region_edit` は画像アセット ID を使用します。編集後の画像を再分割する場合は、完了した `region_edit` のタスク ID を次の `source_task_id` にします。
</Note>

## リクエストヘッダー

`Authorization: Bearer <APIMART_API_KEY>`、`Content-Type: application/json`、`Accept: application/json` を使用します。

`Idempotency-Key` は任意ですが、有料の `region_edit` では強く推奨します。1～191 文字の可視 ASCII を使用でき、UUID を推奨します。新しい論理操作ごとに新しい Key を使い、同じリクエストのネットワーク再試行では元の Key と同一の body を再利用してください。結果が不確定な場合、新しい Key で自動再送しないでください。

## 非同期タスクフロー

作成成功時は HTTP `200` と `data[0].task_id` が返ります。`GET /v1/tasks/{task_id}?language=ja` を 2 秒間隔から最大 5 秒までバックオフし、全体を 10 分で打ち切ります。元画像の切り替え時は古いポーリングを停止します。

<Warning>
  タスク照会が HTTP `200` でも `data.status` が `failed` の場合があります。必ず `data.status` で成否を判断し、`data.error` を表示してください。
</Warning>

## `segment`

### リクエストパラメータ

| フィールド              | 型       |  必須 | デフォルト   | 説明                                     |
| ------------------ | ------- | :-: | ------- | -------------------------------------- |
| `model`            | string  |  ✅  | —       | `grok-imagine-2.0-ext` 固定              |
| `operation`        | string  |  ✅  | —       | `segment` 固定                           |
| `source_task_id`   | string  |  ✅  | —       | 現在のユーザーが所有する完了済み Grok 単一画像タスク          |
| `include_mask_rle` | boolean |  —  | `true`  | COCO compressed RLE を返す。高精度編集では `true` |
| `cache_only`       | boolean |  —  | `false` | 分割キャッシュのみ確認し、ミス時は上流を呼ばない               |
| `cached_only`      | boolean |  —  | `false` | 上流へのキャッシュヒント。ローカル命中の保証ではない             |
| `refresh`          | boolean |  —  | `false` | キャッシュを回避。通常フローでは使用しない                  |

`segment` に `prompt` は不要です。`image_id`、`image_index`、`billing_model_name`、`n`、`size`、`response_format` を送信しないでください。`cache_only=true` と `refresh=true` は同時に使えません。

### リクエスト例

<Tabs>
  <Tab title="レイヤーを取得">
    ```json theme={null}
    {
      "model": "grok-imagine-2.0-ext",
      "operation": "segment",
      "source_task_id": "<COMPLETED_SINGLE_IMAGE_TASK_ID>",
      "include_mask_rle": true,
      "cached_only": false
    }
    ```
  </Tab>

  <Tab title="キャッシュ確認">
    ```json theme={null}
    {
      "model": "grok-imagine-2.0-ext",
      "operation": "segment",
      "source_task_id": "<COMPLETED_SINGLE_IMAGE_TASK_ID>",
      "include_mask_rle": true,
      "cache_only": true
    }
    ```
  </Tab>
</Tabs>

キャッシュミスも成功タスクです。`cache_status` または `from_cache` を使用し、`cached` から命中を推測しないでください。

### 完了レスポンス

`segment` の `data.result` は分割結果そのものであり、`images` には包まれません。

```json theme={null}
{
  "code": 200,
  "data": {
    "id": "task_...",
    "status": "completed",
    "progress": 100,
    "cost": 0,
    "credits_cost": 0,
    "result": {
      "source_task_id": "task_...",
      "image_id": "6b78a7c3-5f9e-4a3d-a928-9e9b42113a3f",
      "image_url": "https://.../source.jpg",
      "from_cache": true,
      "cache_status": "hit",
      "objects": [{
        "index": 0,
        "name": "red sports car",
        "box_xyxy": [38.1, 689.8, 945.8, 1065.4],
        "score": 0.9765625,
        "mask_size": [1792, 1008],
        "mask_url": "",
        "mask_rle": { "size": [1792, 1008], "counts": "..." }
      }]
    }
  }
}
```

| フィールド                 | 説明                                 |
| --------------------- | ---------------------------------- |
| `result.image_id`     | `region_edit` が使用するアセット ID         |
| `result.image_url`    | `image_id` と対応する HTTP(S) URL       |
| `objects[].index`     | サーバーの元インデックス。`object_indices` では維持 |
| `objects[].box_xyxy`  | マスクのピクセルボックス `[x1,y1,x2,y2]`       |
| `objects[].score`     | 検出信頼度。`null` の場合あり                 |
| `objects[].mask_size` | 常に `[height,width]`。寸法を固定しない       |
| `objects[].mask_rle`  | 高精度輪郭用 COCO compressed RLE         |
| `objects[].mask_url`  | 任意のマスク URL。空の場合あり                  |

有効な `mask_rle` または `mask_url` がないオブジェクトは、矩形近似編集のみ使用できます。

## `mask_rle` のデコード

`mask_rle.counts` は COCO 圧縮カウント文字列で、Base64 や zlib ではありません。列優先で展開され、最初が背景、その後は前景と背景が交互になります。

次の TypeScript でブラウザ向けの行優先バイナリマスクへ変換できます。

```ts theme={null}
export interface CocoRLE {
  size: [height: number, width: number];
  counts: string;
}

export interface BinaryMask {
  width: number;
  height: number;
  data: Uint8Array; // data[y * width + x]
}

function decodeCompressedCounts(counts: string): number[] {
  const runs: number[] = [];
  let cursor = 0;
  while (cursor < counts.length) {
    let value = 0;
    let shift = 0;
    let more = true;
    while (more) {
      if (cursor >= counts.length) throw new Error("Truncated COCO RLE counts");
      const current = counts.charCodeAt(cursor++) - 48;
      value |= (current & 0x1f) << shift;
      more = (current & 0x20) !== 0;
      shift += 5;
      if (!more && (current & 0x10) !== 0) value |= -1 << shift;
    }
    if (runs.length > 2) value += runs[runs.length - 2] ?? 0;
    if (value < 0) throw new Error(\`Invalid COCO RLE run: \${value}\`);
    runs.push(value);
  }
  return runs;
}

export function decodeCocoRLE(rle: CocoRLE): BinaryMask {
  const [height, width] = rle.size;
  if (!Number.isInteger(height) || !Number.isInteger(width) || height <= 0 || width <= 0) {
    throw new Error(\`Invalid mask size: \${JSON.stringify(rle.size)}\`);
  }
  const pixelCount = width * height;
  if (!Number.isSafeInteger(pixelCount) || pixelCount > 32_000_000) {
    throw new Error(\`Mask exceeds the frontend safety limit: \${pixelCount}\`);
  }
  if (!rle.counts) throw new Error("Missing COCO RLE counts");

  const data = new Uint8Array(pixelCount);
  const runs = decodeCompressedCounts(rle.counts);
  let position = 0;
  let foreground = false;
  for (const run of runs) {
    if (position + run > data.length) throw new Error("COCO RLE exceeds mask_size");
    if (foreground) {
      for (let offset = 0; offset < run; offset++) {
        const index = position + offset;
        const y = index % height;
        const x = (index - y) / height;
        data[y * width + x] = 1;
      }
    }
    position += run;
    foreground = !foreground;
  }
  if (position !== data.length) throw new Error("COCO RLE does not cover the mask");
  return { width, height, data };
}
```

大きなマスクは Web Worker でデコードしてください。完全な `mask_rle.counts` をログ、分析、URL、エラー報告へ送らないでください。

### マスクを高精度選択範囲へ変換

```ts theme={null}
interface SelectionBoundary { points: number[] }
interface SelectionRegion { outer: SelectionBoundary; holes?: SelectionBoundary[] }
```

連結領域と穴の輪郭を抽出して簡略化し、各点を `0–1` に正規化します。各リングは 3 個以上の異なる点、非ゼロ面積、自己交差なしが必要です。1 レイヤー最大 16 領域、1 リング最大 400 点にします。

<Warning>
  `mask_size` は `[height,width]` で、CSS 表示座標ではなく元マスク座標です。`object-fit: contain` では余白を差し引き、実描画領域で変換して `0–1` に収めます。
</Warning>

元画像や `mask_url` のピクセル読取には CORS が必要です。`src` より先に `crossOrigin = "anonymous"` を設定するか Blob を取得します。`mask_rle` の直接デコードなら不要です。

## 範囲編集：`region_edit`

### リクエストパラメータ

| フィールド               | 型            |  必須 | 説明                                             |
| ------------------- | ------------ | :-: | ---------------------------------------------- |
| `model`             | string       |  ✅  | `grok-imagine-2.0-ext` 固定                      |
| `operation`         | string       |  ✅  | `region_edit`                                  |
| `image_id`          | string       |  ✅  | 元アセット ID。初回は `segment` の `image_id`、以降は最新の編集結果 |
| `prompt`            | string       |  ✅  | 変更内容を示す空でない指示                                  |
| `selection_regions` | array        |  \* | `outer` と任意の `holes` を持つ `0–1` 正規化ポリゴン。推奨      |
| `boxes`             | number\[]\[] |  \* | 矩形 `[x1,y1,x2,y2]`。ピクセル座標では `mask_size` が必要    |
| `object_indices`    | integer\[]   |  \* | 元の `objects[].index`。矩形近似編集のみ                  |
| `mask_size`         | integer\[]   |  \* | ピクセルボックスで必須。正の整数の `[height,width]`             |

`selection_regions`、`boxes`、`object_indices` の少なくとも 1 つを空でない値にします。API は併用可能ですが、フロントエンドでは 1 リクエスト 1 方式を推奨します。

<Warning>
  `billing_model_name`、`size`、`aspect_ratio`、`source_aspect_ratio`、`source_size`、`image_urls` を送信しないでください。`n` は省略または `1`、`claim_asset` は省略または `false`、`response_format` は省略または `url`。Base64 と `stream=true` は非対応です。
</Warning>

### 選択方式

| 方式                  | 選択元               | 精度      | 推奨用途          |
| ------------------- | ----------------- | ------- | ------------- |
| `selection_regions` | フロントエンドのポリゴン      | 穴を含む高精度 | 本番のレイヤー・ブラシ編集 |
| `boxes`             | フロントエンドの矩形        | 矩形近似    | 矩形ツールまたは MVP  |
| `object_indices`    | 元の segment インデックス | 矩形近似    | 迅速な結合テスト      |

<Tabs>
  <Tab title="高精度ポリゴン">
    ```json theme={null}
    {
      "model": "grok-imagine-2.0-ext",
      "operation": "region_edit",
      "image_id": "<SOURCE_IMAGE_ID>",
      "prompt": "Change the selected car to bright red and preserve the rest",
      "selection_regions": [{
        "outer": { "points": [0.12, 0.20, 0.48, 0.20, 0.48, 0.61, 0.12, 0.61] },
        "holes": [{ "points": [0.30, 0.35, 0.38, 0.35, 0.38, 0.45, 0.30, 0.45] }]
      }]
    }
    ```

    `points` は平坦配列または座標ペアで指定できます。全値は有限な `0–1` で、各リングに 3 ペア以上必要です。
  </Tab>

  <Tab title="正規化ボックス">
    ```json theme={null}
    {
      "model": "grok-imagine-2.0-ext",
      "operation": "region_edit",
      "image_id": "<SOURCE_IMAGE_ID>",
      "prompt": "Change the car inside the box to bright red",
      "boxes": [[0.04, 0.385, 0.938, 0.594]]
    }
    ```
  </Tab>

  <Tab title="ピクセルボックス">
    ```json theme={null}
    {
      "model": "grok-imagine-2.0-ext",
      "operation": "region_edit",
      "image_id": "<SOURCE_IMAGE_ID>",
      "prompt": "Change the car inside the box to bright red",
      "boxes": [[40, 689.6, 945.9, 1064.4]],
      "mask_size": [1792, 1008]
    }
    ```
  </Tab>

  <Tab title="オブジェクトインデックス">
    ```json theme={null}
    {
      "model": "grok-imagine-2.0-ext",
      "operation": "region_edit",
      "image_id": "<SOURCE_IMAGE_ID>",
      "prompt": "Change the selected car to bright red",
      "object_indices": [0]
    }
    ```

    インデックスは同じ `image_id` の segment 応答から取得します。フロントエンドで絞込・並替・分類した配列の添字へ置換しないでください。
  </Tab>
</Tabs>

### 完了レスポンス

```json theme={null}
{
  "code": 200,
  "data": {
    "id": "task_...",
    "status": "completed",
    "progress": 100,
    "cost": 0.016,
    "credits_cost": 0.16,
    "result": {
      "images": [{
        "url": ["https://.../result.jpg"],
        "image_ids": ["<NEW_IMAGE_ID>"],
        "items": [{
          "url": "https://.../result.jpg",
          "image_id": "<NEW_IMAGE_ID>",
          "source_image_id": "<SOURCE_IMAGE_ID>",
          "role": "region_edit"
        }],
        "expires_at": 1787040000
      }]
    }
  }
}
```

`result.images[0].items[0]` を優先します。旧応答は配列長が一致するときだけ `url[0]` と `image_ids[0]` を対応付けます。HTTP(S) URL と新しい `image_id` の両方を得てから続行してください。

URL 期限は `expires_at` を基準にし、固定時間を実装しないでください。長期利用するアセットは保存します。

## 連続編集

編集完了後、表示 URL、現在のアセット ID、元タスク ID を同時に更新し、古いレイヤーとポーリング状態を消去します。

* 再分割：今回の `region_edit` タスク ID を `source_task_id` に使用
* 再編集：新しく返された `image_id` を使用
* `image_id` を `segment` に渡さず、以前の画像 ID の編集も続けないでください。

## エラー処理

| HTTP / 状態             | 主な原因                                                     | 対応                                  |
| --------------------- | -------------------------------------------------------- | ----------------------------------- |
| 400 元データまたは操作が不正      | 操作が違う、元タスクが利用不可、または segment に `image_id/image_index` を送信 | 操作を検証し、現在ユーザーの完了済み単一画像タスクを使用        |
| 400 選択範囲が不正           | 空のプロンプト、選択なし、またはポリゴン・ボックス・インデックスが不正                      | 送信前にプロンプトと選択範囲を検証                   |
| 400 非対応オプション          | `claim_asset`、`n`、出力形式、サイズ、ストリームが不正                      | 非対応フィールドを削除し URL 出力を使用              |
| 401 / 403             | Key が無効またはモデル権限なし                                        | サーバー側 Key とアカウント権限を確認               |
| 402                   | 残高不足                                                     | チャージ後に再試行                           |
| 409                   | 冪等リクエストが処理中、変更済み、または結果不確定                                | 応答に従い Key を自動変更しない                  |
| 429 / 5xx             | レート制限または一時障害                                             | `Retry-After` に従って制限付きバックオフ         |
| failed / task\_failed | 非同期実行に失敗                                                 | ポーリングを停止して `data.error.message` を表示 |

## 課金

* `segment` は無料で `cost=0`、`credits_cost=0` ですが、認証と有効な元タスクが必要です。
* `region_edit` は有料です。完了タスクの `cost` と `credits_cost` を使い、価格をフロントエンドへ固定しないでください。
* 内部フィールド `billing_model_name` は送信しません。

## フロントエンド確認事項

* API Key はバックエンドまたは BFF のみに保存する。
* `segment` には `source_task_id` だけを送り、`image_id` と `image_index` は送らない。
* `region_edit` には segment の `image_id` と少なくとも 1 つの選択方式を使う。
* 高精度編集には `selection_regions` を使い、`object_indices` は矩形近似とする。
* `mask_size` は常に `[height,width]` として表示倍率と余白を補正する。
* 同じネットワーク再試行では元の冪等 Key を再利用し、URL と新しい `image_id` の両方を検証する。
