> ## 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 公式動画モデル

> grok-imagine-video と grok-imagine-video-1.5 でテキストや参照画像から動画を生成し、Base モデルで元動画を編集します。

<Info>
  本ページは公式モデル `grok-imagine-video` と `grok-imagine-video-1.5` が対象です。既存ページの `grok-imagine-1.5-video-ext` とは別モデルのため、名前やパラメータを混在させないでください。
</Info>

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

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.apimart.ai/v1/videos/generations \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'Idempotency-Key: 7d0141e4-a19a-4650-a717-dab777b3a330' \
    --data '{
      "model": "grok-imagine-video",
      "prompt": "A cinematic aerial shot of a coastal city at sunrise",
      "duration": 5,
      "resolution": "720p",
      "aspect_ratio": "16:9",
      "nsfw_check": true
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.apimart.ai/v1/videos/generations", {
    method: "POST",
    headers: {
      Authorization: "Bearer <token>",
      "Content-Type": "application/json",
      Accept: "application/json",
      "Idempotency-Key": crypto.randomUUID(),
    },
    body: JSON.stringify({
      model: "grok-imagine-video",
      prompt: "Improve motion consistency and apply cinematic color grading",
      video: { url: "https://cdn.example.com/source-video.mp4" },
    }),
  });

  console.log(response.status, await response.json());
  ```
</RequestExample>

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

  ```json 400 theme={null}
  {
    "error": {
      "message": "Invalid request parameters",
      "type": "invalid_request_error",
      "param": "resolution",
      "code": "invalid_request_error"
    }
  }
  ```
</ResponseExample>

## 連携概要

すべてのモードは同じ非同期エンドポイントを使用します。

```http theme={null}
POST https://api.apimart.ai/v1/videos/generations
```

| リクエスト項目                   | モード      | モデル                     |
| ------------------------- | -------- | ----------------------- |
| `image_urls` と `video` なし | テキストから動画 | 両モデル                    |
| `image_urls`              | 参照画像から動画 | 両モデル                    |
| `video`                   | 動画編集     | `grok-imagine-video` のみ |

送信後に `data[0].task_id` を保存し、次をポーリングします。

```http theme={null}
GET https://api.apimart.ai/v1/tasks/{task_id}
```

<Warning>
  `X-APIMart-Response-Version` は送信しないでください。HTTP `202` 形式に切り替わるため、本ページの旧 HTTP `200` 非同期形式とは互換性がありません。
</Warning>

## モデル機能

| 機能                      | `grok-imagine-video` | `grok-imagine-video-1.5` |
| ----------------------- | :------------------: | :----------------------: |
| テキストから動画                |           ✅          |             ✅            |
| 1 枚または複数の参照画像           |           ✅          |             ✅            |
| 動画編集                    |           ✅          |             ❌            |
| `480p`                  |           ✅          |             ✅            |
| `720p`                  |           ✅          |             ✅            |
| `1080p`                 |           ❌          |             ✅            |
| 長さ：1～15 秒、既定 8 秒        |         1–15         |           1–15           |
| プロンプト：1～8000 Unicode 文字 |        1–8000        |          1–8000          |

```text theme={null}
duration     = 8
resolution   = 480p
aspect_ratio = auto
```

公開契約に参照画像数の固定上限はありません。有効 URL の空でない配列を元の順序で保持し、画像モデルの上限を流用しないでください。

## リクエストヘッダー

<ParamField header="Authorization" type="string" required>
  `Bearer <APIMART_API_KEY>`
</ParamField>

<ParamField header="Content-Type" type="string" required>
  常に `application/json` を使用します。
</ParamField>

<ParamField header="Accept" type="string">
  `application/json`
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  `Idempotency-Key` は任意ですが、有料リクエストでは強く推奨します。1～191 文字の可視 ASCII が使用でき、UUID 推奨です。ネットワーク再試行は元の Key と同一 body を再利用し、結果不明時に Key を変更しないでください。

  新しい論理操作ごとに新しい Key を使います。同じ操作の再試行では元の Key と同じ body を再利用します。
</ParamField>

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

### 共通フィールド

<ParamField body="model" type="string" required>
  公式モデル名。動画編集は Base のみ

  * `grok-imagine-video`
  * `grok-imagine-video-1.5`
</ParamField>

<ParamField body="prompt" type="string" required>
  空でない指示、最大 8000 Unicode 文字

  `Array.from(prompt).length`
</ParamField>

<ParamField body="nsfw_check" type="boolean" default={false}>
  動画タスクの送信前にコンテンツ審査を実行するかどうかを指定します。

  * `true`: `omni-moderation-latest` でプロンプトと入力画像を審査します
  * `false` または省略: 審査リクエストを行わず、審査コストと遅延を追加しません（デフォルト）
</ParamField>

### 生成フィールド

<ParamField body="duration" type="integer" default={8}>
  生成のみ。1～15 の整数、既定 8
</ParamField>

<ParamField body="resolution" type="string" default="480p">
  Base：`480p/720p`、1.5：`480p/720p/1080p`、既定 `480p`

  * `grok-imagine-video`: `480p`, `720p`
  * `grok-imagine-video-1.5`: `480p`, `720p`, `1080p`
</ParamField>

<ParamField body="aspect_ratio" type="string" default="auto">
  生成のみ。`auto`、`1:1`、`16:9`、`9:16`、`4:3`、`3:4`、`3:2`、`2:3`

  * `auto`
  * `1:1`, `16:9`, `9:16`
  * `4:3`, `3:4`, `3:2`, `2:3`
</ParamField>

<ParamField body="image_urls" type="string[]">
  任意の参照画像配列。各項目は公開 HTTPS URL。空なら省略

  * 各項目は公開 HTTPS URL に限ります。相対 URL、Data URL、裸の Base64 は非対応です。
  * `image`、`images`、`input_reference` などの別名フィールドを送信しないでください。
  * 配列順は保持されます。重複 URL は複数スロットを占有し、重複課金される場合があります。
</ParamField>

### 動画編集フィールド

<ParamField body="video" type="object">
  元動画 `{url}` は公開 HTTPS URL。Base のみ

  <Expandable title="URL">
    <ParamField body="url" type="string" required>
      HTTPS
    </ParamField>
  </Expandable>
</ParamField>

動画編集では `model`、`prompt`、`video` が必須で、`nsfw_check` は任意です。`duration`、`resolution`、`aspect_ratio`、`image_urls` は送信しません。元動画の長さはプラットフォームが検出します。

## TypeScript リクエスト型

判別可能なユニオン型を使い、生成専用フィールドが動画編集に送信されないようにします。

```ts theme={null}
type GrokVideoModel =
  | "grok-imagine-video"
  | "grok-imagine-video-1.5";

type GrokVideoResolution = "480p" | "720p" | "1080p";

type GrokVideoAspectRatio =
  | "auto"
  | "1:1"
  | "16:9"
  | "9:16"
  | "4:3"
  | "3:4"
  | "3:2"
  | "2:3";

interface GrokVideoGenerateRequest {
  model: GrokVideoModel;
  prompt: string;
  nsfw_check?: boolean;
  duration?: number;
  resolution?: GrokVideoResolution;
  aspect_ratio?: GrokVideoAspectRatio;
  image_urls?: string[];
}

interface GrokVideoEditRequest {
  model: "grok-imagine-video";
  prompt: string;
  nsfw_check?: boolean;
  video: { url: string };
}

type GrokVideoRequest =
  | GrokVideoGenerateRequest
  | GrokVideoEditRequest;
```

## リクエスト例

<Tabs>
  <Tab title="テキストから動画">
    ```json theme={null}
    {"model":"grok-imagine-video","prompt":"A cinematic aerial shot at sunrise","duration":5,"resolution":"720p","aspect_ratio":"16:9"}
    ```
  </Tab>

  <Tab title="1.5 · 1080p">
    ```json theme={null}
    {"model":"grok-imagine-video-1.5","prompt":"A smooth studio product commercial","duration":5,"resolution":"1080p","aspect_ratio":"16:9"}
    ```
  </Tab>

  <Tab title="1 枚または複数の参照画像">
    ```json theme={null}
    {
      "model":"grok-imagine-video-1.5",
      "prompt":"Use the first image as subject and the second as style",
      "duration":5,
      "resolution":"720p",
      "aspect_ratio":"16:9",
      "image_urls":[
        "https://cdn.example.com/subject.jpg",
        "https://cdn.example.com/style.jpg"
      ]
    }
    ```
  </Tab>

  <Tab title="動画編集">
    ```json theme={null}
    {
      "model":"grok-imagine-video",
      "prompt":"Improve motion consistency and apply cinematic color grading",
      "video":{"url":"https://cdn.example.com/source.mp4"}
    }
    ```
  </Tab>
</Tabs>

## 非同期タスク

### 作成成功

作成成功は HTTP `200` を返します。`data[0].task_id` を保存してください。送信完了は動画完成を意味しません。 タスク ID は送信済みを示し、完了を意味しません。

```json theme={null}
{
  "code":200,
  "data":[{"status":"submitted","task_id":"task_01M09Y4Y101HTFFPV2QPW9DQ3W"}]
}
```

### タスク照会

```http theme={null}
GET https://api.apimart.ai/v1/tasks/{task_id}
Authorization: Bearer <APIMART_API_KEY>
Accept: application/json
```

`GET /v1/tasks/{task_id}` を 3～5 秒ごとに照会します。再読み込み後は保存済み ID で再開します。

| `data.status` | 意味      | 動作         |
| ------------- | ------- | ---------- |
| `pending`     | 待機中     | 照会を継続      |
| `processing`  | 生成中     | 進捗を表示      |
| `completed`   | 完了      | 結果を読み停止    |
| `failed`      | 失敗・返金済み | エラーを表示し停止  |
| `unknown`     | 一時的に不明  | 頻度を下げ後で再試行 |

### 完了レスポンス

```json theme={null}
{
  "code":200,
  "data":{
    "id":"task_xxx",
    "status":"completed",
    "progress":100,
    "created":1787040038,
    "completed":1787040081,
    "actual_time":43,
    "estimated_time":100,
    "cost":0.072,
    "credits_cost":0.72,
    "result":{"videos":[{"url":["https://cdn.example.com/result.mp4"],"expires_at":1787126481}]}
  }
}
```

`result.videos[0].url` は単一文字列ではなく文字列配列です。各値を HTTPS URL として検証してください。 実行時検証を推奨します。

```ts theme={null}
function extractVideoURLs(payload: unknown): string[] {
  const groups = (payload as any)?.data?.result?.videos;
  if (!Array.isArray(groups)) return [];

  return groups.flatMap((group: any) =>
    Array.isArray(group?.url)
      ? group.url.filter(
          (url: unknown): url is string =>
            typeof url === "string" && /^https:///i.test(url),
        )
      : [],
  );
}
```

期限は `expires_at` を使用します。固定時間を実装せず、ダウンロードまたは保存を促してください。

### 失敗レスポンス

```json theme={null}
{
  "code":200,
  "data":{
    "id":"task_xxx",
    "status":"failed",
    "progress":100,
    "cost":0,
    "credits_cost":0,
    "error":{"message":"Task failed.","type":"task_failed","param":"","code":"task_failed"}
  }
}
```

<Warning>
  照会が HTTP `200` でも `data.status=failed` の場合があります。`data.status` で判断し、失敗タスクは `cost=0` です。
</Warning>

## 価格カタログ

```http theme={null}
GET https://api.apimart.ai/api/pricing/models/all
```

`GET /api/pricing/models/all` を読み、`data.models.video` から `id` で検索します。表示は概算で、最終金額はタスクの `data.cost` です。

### 出力動画の価格

```json theme={null}
{
  "fixed_prices":{
    "unit":"usd_per_second",
    "dimension":"resolution",
    "items":[
      {"key":"480P","original_price":0.05,"after_discount":0.04},
      {"key":"720P","original_price":0.07,"after_discount":0.056}
    ]
  }
}
```

* 価格キーは大文字 `480P/720P/1080P`、リクエスト値は小文字です。検索時に正規化してください。
* `default` は互換用メタデータであり、選択可能な解像度ではありません。
* `after_discount` を直接使い、割引を再適用しないでください。

### 入力素材の価格

```json theme={null}
{"unit":"usd_per_image","original_price":0.002,"after_discount":0.0016}
```

```json theme={null}
{"unit":"usd_per_second","original_price":0.01,"after_discount":0.008}
```

動画入力価格はスカラーオブジェクトです。`items`、`billing_mode`、`max_billable_seconds` を必須にしないでください。1.5 には動画入力価格がありません。

### 見積もり式

```text theme={null}
生成概算 = 出力秒単価 × duration + 画像単価 × 枚数
編集概算 = 720P 出力秒単価 × 元動画秒数 + 動画入力秒単価 × 元動画秒数
```

ユーザー別価格とサーバー丸めで見積もりは変動します。最終金額は常に `data.cost` です。

## フロントエンド規則

### モデル切り替え

* Base は `480p/720p`、1.5 は `1080p` も表示。
* 1.5 `1080p` から Base へ切替時は `480p` に戻す。
* 動画編集では `grok-imagine-video` に固定。

### モード切り替え

| モード  | 表示コントロール                                             | 送信フィールド                         | 消去必須                                          |
| ---- | ---------------------------------------------------- | ------------------------------- | --------------------------------------------- |
| 生成   | `prompt/duration/resolution/aspect_ratio/nsfw_check` | 生成フィールド                         | `image_urls/video`                            |
| 参照画像 | 生成フィールド + `image_urls`                               | 生成フィールド + `image_urls`          | `video`                                       |
| 動画編集 | `prompt/video/nsfw_check`                            | `model/prompt/video/nsfw_check` | `duration/resolution/aspect_ratio/image_urls` |

`nsfw_check` はすべてのモードで任意です。審査を有効にする場合は `true`、無効時は省略または `false` を送信します。

次のいずれかに該当する場合は実行ボタンを無効にします。

* テキストモードは `image_urls` と `video` を省略。
* 参照モードは `image_urls` を送り `video` を省略。
* 動画編集では生成専用フィールドを消去。
* プロンプト、長さ、解像度、URL が不正、アップロード中、重複送信時は無効化。
* プロンプトは 8000 Unicode 以下、長さは整数 1～15。
* 公開 HTTPS URL のみ。空の `image_urls` は省略。

## 主なエラー

| HTTP / 状態     | 原因                 | 対応                |
| ------------- | ------------------ | ----------------- |
| `400`         | パラメータ、プロンプト、列挙値が不正 | メッセージと対象項目を表示     |
| `401`         | API Key がない・無効     | 再試行せずサーバー設定を確認    |
| `402`         | 残高不足               | チャージを案内           |
| `403`         | モデル権限なし            | 自動再試行しない          |
| `409`         | 冪等競合または処理中         | 元 Key を維持し後で再試行   |
| `429`         | レート制限              | `Retry-After` に従う |
| `500/502/503` | 一時障害               | 元 Key で回数制限付き再試行  |
| `failed`      | 非同期タスク失敗           | 照会停止、費用ゼロ         |

## フロントエンド確認

* API Key はバックエンドまたは BFF のみ。
* 公式モデルを `grok-imagine-1.5-video-ext` と混在させない。
* プロンプトは 8000 Unicode 以下、長さは整数 1～15。
* 公開 HTTPS URL のみ。空の `image_urls` は省略。
* 動画編集では Base を使い、`model/prompt/video` と任意の `nsfw_check` のみを送信します。
* 送信時 `data[0].task_id`、終端は `data.status` を読む。
* `result.videos[].url[]` と `expires_at` を使用。
* カタログを表示し最終金額は `data.cost`。
