> ## 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 进行文生视频、参考图生成视频和视频编辑。

<Info>
  本页适用于官方模型 `grok-imagine-video` 和 `grok-imagine-video-1.5`。它们与 [Grok Imagine 1.5 视频生成](/cn/api-reference/videos/grok-imagine/generation) 页面中的 `grok-imagine-1.5-video-ext` 不是同一组模型，请勿混用模型名和参数。
</Info>

<Warning>
  不要把 API Key 写入浏览器包、公开环境变量、LocalStorage、URL 或前端日志。浏览器应调用业务 BFF，由服务端持有 Key 并请求 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": "清晨海岸城市的电影感航拍镜头",
      "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: "增强动作连贯性，并应用电影级调色",
      nsfw_check: true,
      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` |
| -------- | :------------------: | :----------------------: |
| 文生视频     |           ✅          |             ✅            |
| 单张或多张参考图 |           ✅          |             ✅            |
| 视频编辑     |           ✅          |             ❌            |
| `480p`   |           ✅          |             ✅            |
| `720p`   |           ✅          |             ✅            |
| `1080p`  |           ❌          |             ✅            |
| 生成时长     |        1–15 秒        |          1–15 秒          |
| 默认生成时长   |          8 秒         |            8 秒           |
| 提示词长度    |       1–8000 字符      |         1–8000 字符        |

生成模式默认值：

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

参考图数量目前没有写入公开接口契约的固定上限。不要套用 Grok 图片模型的参考图上限；前端应保证数组非空、每项 URL 合法，并保留原始顺序。

## 请求头

<ParamField header="Authorization" type="string" required>
  Bearer Token：`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">
  可选，付费的视频生成和编辑请求强烈建议使用。支持 1–191 个可见 ASCII 字符，推荐 UUID。

  每次新的逻辑操作使用一个新 Key。网络失败重试同一次请求时，必须复用原 Key 和完全相同的请求体。结果不确定时，不要换新 Key 自动重提，否则可能重复生成并重复计费。
</ParamField>

## 请求参数

### 公共字段

<ParamField body="model" type="string" required>
  官方视频模型名称：

  * `grok-imagine-video`
  * `grok-imagine-video-1.5`

  视频编辑只支持 `grok-imagine-video`。
</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` 秒。仅用于文生视频和参考图生成视频。
</ParamField>

<ParamField body="resolution" type="string" default="480p">
  输出分辨率：

  * `grok-imagine-video`：`480p`、`720p`
  * `grok-imagine-video-1.5`：`480p`、`720p`、`1080p`

  从 1.5 的 `1080p` 切换到 Base 模型时，前端应自动回退到 `480p`。
</ParamField>

<ParamField body="aspect_ratio" type="string" default="auto">
  输出宽高比。支持：

  * `auto`
  * `1:1`
  * `16:9`
  * `9:16`
  * `4:3`
  * `3:4`
  * `3:2`
  * `2:3`

  前端应使用固定枚举选择器，不要提供任意文本输入。
</ParamField>

<ParamField body="image_urls" type="string[]">
  参考图片 URL 数组；省略时为文生视频。

  * 每项必须是公网可访问的 HTTPS URL；不支持相对 URL、Data URL 或裸 Base64。
  * 没有参考图时省略整个字段，不要发送空数组。
  * 数组顺序会保留；重复 URL 仍会占用多个输入槽位，并可能重复计费。
  * 不要同时发送 `image`、`images` 或 `input_reference` 等同义字段。
</ParamField>

### 视频编辑字段

<ParamField body="video" type="object">
  源视频对象，仅 `grok-imagine-video` 支持。

  <Expandable title="属性">
    <ParamField body="url" type="string" required>
      公网可访问的 HTTPS 视频 URL。
    </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": "清晨海岸城市的电影感航拍镜头",
      "duration": 5,
      "resolution": "720p",
      "aspect_ratio": "16:9"
    }
    ```
  </Tab>

  <Tab title="1.5 · 1080p">
    ```json theme={null}
    {
      "model": "grok-imagine-video-1.5",
      "prompt": "流畅棚拍运镜的产品广告",
      "duration": 5,
      "resolution": "1080p",
      "aspect_ratio": "16:9"
    }
    ```
  </Tab>

  <Tab title="单张参考图">
    ```json theme={null}
    {
      "model": "grok-imagine-video",
      "prompt": "让主体产生细微、自然的动作",
      "duration": 5,
      "resolution": "480p",
      "aspect_ratio": "16:9",
      "image_urls": [
        "https://cdn.example.com/reference.jpg"
      ]
    }
    ```
  </Tab>

  <Tab title="多张参考图">
    ```json theme={null}
    {
      "model": "grok-imagine-video-1.5",
      "prompt": "以第一张图为主体，第二张图作为视觉风格参考",
      "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": "增强动作连贯性，并应用电影级调色",
      "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
```

建议每 3–5 秒轮询一次，不要进行无间隔循环。页面刷新后可使用已保存的 `task_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` 是字符串数组，不是单个字符串。建议进行运行时校验：

```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` 为准展示到期时间，并提醒用户及时下载或转存，不要硬编码固定有效期。

### 失败响应

任务失败时，查询接口仍可能返回 HTTP `200`：

```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>
  必须根据 `data.status` 判断任务成败，不能仅根据查询请求的 HTTP 状态。失败任务费用为 `0`。
</Warning>

## 价格目录

前端展示价格时，请动态读取：

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

在 `data.models.video` 中按 `id` 查找当前模型。价格展示仅用于预估，任务查询响应中的 `data.cost` 才是最终金额。

### 输出视频价格

从 `fixed_prices.items` 按分辨率读取折后每秒价格：

```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`，请求参数使用小写 `480p/720p/1080p`；查价时统一大小写。
* `default` 只是兼容项，不应作为用户可选分辨率。
* 展示折后价时直接使用 `after_discount`，不要再次应用折扣。

### 输入素材价格

参考图片按张计费，读取 `input_material_prices.image`：

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

Base 模型的视频编辑按源视频秒数计费，读取 `input_material_prices.video`：

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

视频输入价是标量结构。不要强制要求其他模型可能使用的 `items`、`billing_mode` 或 `max_billable_seconds` 字段。`grok-imagine-video-1.5` 不支持视频编辑，因此没有视频输入价格。

### 预估公式

生成模式：

```text theme={null}
预估金额 = 输出分辨率每秒折后价 × duration
         + 输入图片每张折后价 × image_urls.length
```

视频编辑模式：

```text theme={null}
预估金额 = 720P 输出每秒折后价 × 源视频秒数
         + 输入视频每秒折后价 × 源视频秒数
```

用户专属价格和服务端整单取整可能使预估与结算不同，最终金额始终以任务查询的 `data.cost` 为准。

## 前端表单联动

### 模型切换

* 切换到 `grok-imagine-video`：只显示 `480p` 和 `720p`。
* 切换到 `grok-imagine-video-1.5`：允许选择 `1080p`，但隐藏视频编辑模式。
* 从 1.5 的 `1080p` 切换到 Base：自动回退到 `480p`。
* 正在视频编辑时：模型固定为 `grok-imagine-video`。

### 模式切换

| 模式    | 展示控件               | 提交字段                                      | 必须清除                                                |
| ----- | ------------------ | ----------------------------------------- | --------------------------------------------------- |
| 文生视频  | 提示词、时长、分辨率、比例、内容审核 | 生成字段、`nsfw_check`（可选）                     | `image_urls`、`video`                                |
| 参考图生成 | 生成字段、参考图上传、内容审核    | 生成字段、`image_urls`、`nsfw_check`（可选）        | `video`                                             |
| 视频编辑  | 提示词、源视频上传、内容审核     | `model`、`prompt`、`video`、`nsfw_check`（可选） | `duration`、`resolution`、`aspect_ratio`、`image_urls` |

以下任一条件成立时，应禁用运行按钮：

* 提示词为空或超过 8000 字符；
* `duration` 不是 `1–15` 的整数；
* Base 模型选择了 `1080p`；
* 参考图模式没有有效的 HTTPS 图片 URL；
* 视频编辑没有有效的 HTTPS 视频 URL；
* 1.5 模型处于视频编辑模式；
* 素材正在上传；
* 相同逻辑请求正在提交。

## 常见错误

| HTTP / 状态     | 常见原因              | 前端处理                   |
| ------------- | ----------------- | ---------------------- |
| `400`         | 参数非法、提示词超限或枚举不支持  | 展示服务端消息并定位字段           |
| `401`         | API Key 缺失或无效     | 不重试，检查服务端密钥            |
| `402`         | 余额不足              | 引导充值，不自动重试             |
| `403`         | 模型权限或分组不可用        | 不自动重试，联系管理员            |
| `409`         | 幂等 Key 冲突或原请求仍在处理 | 保留原 Key；相同请求稍后重试       |
| `429`         | 请求过快              | 遵循 `Retry-After` 或指数退避 |
| `500/502/503` | 服务暂时不可用           | 复用原幂等 Key 进行有限重试       |
| `failed`      | 异步任务失败            | 停止轮询并展示错误；费用为 `0`      |

## 前端接入检查

* API Key 仅保存在后端或 BFF。
* 使用官方模型名，不与 `grok-imagine-1.5-video-ext` 混用。
* 提示词长度不超过 8000 个 Unicode 字符。
* `duration` 是 `1–15` 的整数，默认 `8`。
* Base 只允许 `480p/720p`，1.5 额外允许 `1080p`。
* 没有参考图时省略 `image_urls`，不发送空数组或同义图片字段。
* 视频编辑只发送 `model`、`prompt`、`video` 和可选的 `nsfw_check`，且只使用 Base 模型。
* 创建成功读取 `data[0].task_id`，根据 `data.status` 判断终态。
* 完成后从 `result.videos[].url[]` 读取视频，并按 `expires_at` 提示下载。
* 价格来自价格目录，最终金额以任务查询的 `data.cost` 为准。
