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

# 快速开始

> 了解 imini 开放平台的接入流程，完成首次 API 调用

本文将指导你完成从账号准备到发起首次 API 调用的完整流程。预计耗时 5 分钟。

## 前置条件

在开始之前，请确认已完成以下事项：

<Steps>
  <Step title="注册 imini 账号">
    访问 [imini.ai](https://imini.ai) 注册账号并完成邮箱验证。
  </Step>

  <Step title="充值积分">
    所有 API 调用以积分（credits）为计费单位，各模型的消耗规则详见 [模型价格](/zh/guide/pricing)。请在 [积分总览](https://imini.ai/zh/credits) 完成充值后再发起调用。
  </Step>

  <Step title="创建 API Key">
    前往 [**API Keys 管理页**](https://imini.ai/zh/api-keys)，创建一个用于服务端调用的 API Key 并妥善保存。
  </Step>
</Steps>

## 接入地址

imini 开放平台所有接口共用同一基础地址：

```
https://openapi.imini.ai/imini/router
```

下文示例中的相对路径（如 `/v1/images/generate`）均需拼接在此基础地址之后使用。

## 鉴权方式

所有请求均通过 HTTP Header 传递 API Key，采用 Bearer Token 标准：

```http theme={null}
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
```

<Warning>
  **API Key 安全**：请仅在服务端使用 API Key。切勿将其提交至代码仓库、前端代码、移动端应用或其他可能被泄露的环境。若怀疑 Key 已泄露，请立即前往 [API Keys 管理页](https://imini.ai/zh/api-keys) 轮换。
</Warning>

## 异步任务模型

imini 所有生成类接口（图像、视频）均采用异步任务模型。一次完整的生成流程包含两步：

```
┌──────────────────────────────────────────┐
│ 1. 提交生成任务                            │
│    POST /v1/images/generate              │
│    → 同步返回 { task_id }                 │
└────────────────┬─────────────────────────┘
                 │
                 ▼
┌──────────────────────────────────────────┐
│ 2. 轮询任务状态                            │
│    GET  /v1/images/tasks/{task_id}       │
│    → status: queued → processing         │
│             → succeeded（含 images[].url）│
│             → failed（含 error 对象）     │
└──────────────────────────────────────────┘
```

<Note>
  图像任务查询地址为 `/v1/images/tasks/{task_id}`；视频任务查询地址为 `/v1/videos/tasks/{task_id}`。建议轮询间隔为 **2 秒**，图像任务通常在 **10～30 秒**内完成。
</Note>

## 第一步：提交生成任务

以下示例使用 `google/nano-banana` 模型生成一张 1:1 图像：

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://openapi.imini.ai/imini/router/v1/images/generate \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "google/nano-banana",
      "prompt": "一只在樱花树下打盹的橙色猫咪，水彩风格",
      "aspect_ratio": "1:1"
    }'
  ```

  ```python Python theme={null}
  import requests

  BASE_URL = "https://openapi.imini.ai/imini/router"
  API_KEY = "YOUR_API_KEY"

  response = requests.post(
      f"{BASE_URL}/v1/images/generate",
      headers={
          "Authorization": f"Bearer {API_KEY}",
          "Content-Type": "application/json",
      },
      json={
          "model": "google/nano-banana",
          "prompt": "一只在樱花树下打盹的橙色猫咪，水彩风格",
          "aspect_ratio": "1:1",
      },
      timeout=30,
  )
  response.raise_for_status()
  task_id = response.json()["task_id"]
  print(f"Submitted task: {task_id}")
  ```

  ```javascript Node.js theme={null}
  const BASE_URL = 'https://openapi.imini.ai/imini/router';
  const API_KEY = 'YOUR_API_KEY';

  const response = await fetch(`${BASE_URL}/v1/images/generate`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'google/nano-banana',
      prompt: '一只在樱花树下打盹的橙色猫咪，水彩风格',
      aspect_ratio: '1:1',
    }),
  });

  if (!response.ok) {
    throw new Error(`Submit failed: ${response.status}`);
  }
  const { task_id } = await response.json();
  console.log(`Submitted task: ${task_id}`);
  ```
</CodeGroup>

**成功响应示例**（HTTP 200）：

```json theme={null}
{
  "task_id": "task_2041350318103396352",
  "model": "google/nano-banana",
  "created_at": "2026-04-07T03:00:17.062Z",
  "request_id": "285f20ce-8158-401b-945c-7bc6a7ef6ead"
}
```

## 第二步：轮询任务结果

使用上一步返回的 `task_id` 轮询任务状态，直至 `status` 变为 `succeeded` 或 `failed`：

<CodeGroup>
  ```bash cURL theme={null}
  curl https://openapi.imini.ai/imini/router/v1/images/tasks/TASK_ID \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```python Python theme={null}
  import time

  def wait_for_result(task_id: str, interval: int = 2, timeout: int = 120):
      """轮询任务结果，最长等待 timeout 秒。"""
      deadline = time.time() + timeout
      while time.time() < deadline:
          result = requests.get(
              f"{BASE_URL}/v1/images/tasks/{task_id}",
              headers={"Authorization": f"Bearer {API_KEY}"},
              timeout=10,
          ).json()

          status = result["status"]
          if status == "succeeded":
              return result["images"]
          if status == "failed":
              raise RuntimeError(f"Task failed: {result['error']}")

          time.sleep(interval)

      raise TimeoutError(f"Task {task_id} timed out after {timeout}s")

  images = wait_for_result(task_id)
  print(images[0]["url"])
  ```

  ```javascript Node.js theme={null}
  async function waitForResult(taskId, { intervalMs = 2000, timeoutMs = 120_000 } = {}) {
    const deadline = Date.now() + timeoutMs;
    while (Date.now() < deadline) {
      const res = await fetch(`${BASE_URL}/v1/images/tasks/${taskId}`, {
        headers: { Authorization: `Bearer ${API_KEY}` },
      });
      const data = await res.json();

      if (data.status === 'succeeded') return data.images;
      if (data.status === 'failed') throw new Error(`Task failed: ${JSON.stringify(data.error)}`);

      await new Promise(r => setTimeout(r, intervalMs));
    }
    throw new Error(`Task ${taskId} timed out`);
  }

  const images = await waitForResult(task_id);
  console.log(images[0].url);
  ```
</CodeGroup>

**任务状态说明**：

| 状态           | 含义                     |
| ------------ | ---------------------- |
| `queued`     | 任务已提交，等待进入处理队列         |
| `processing` | 模型正在生成中                |
| `succeeded`  | 生成成功，结果见 `images[]` 字段 |
| `failed`     | 生成失败，详情见 `error` 对象    |

**成功响应示例**（`status: succeeded`）：

```json theme={null}
{
  "task_id": "task_2041350318103396352",
  "status": "succeeded",
  "model": "google/nano-banana",
  "created_at": "2026-04-07T03:00:17.062Z",
  "completed_at": "2026-04-07T03:00:29.418Z",
  "images": [
    {
      "url": "https://file.iminicdn.com/file/2026/04/07/xxxx.png",
      "width": 1024,
      "height": 1024
    }
  ],
  "error": null,
  "request_id": "285f20ce-8158-401b-945c-7bc6a7ef6ead"
}
```

## 错误处理

所有错误响应共享统一结构：

```json theme={null}
{
  "error": {
    "code": "INVALID_PARAMETER",
    "message": "aspect_ratio must be one of: 1:1, 2:3, ...",
    "status": 400,
    "request_id": "req_abc123"
  }
}
```

**常见 HTTP 状态码**：

| 状态码   | 含义     | 典型原因                    |
| ----- | ------ | ----------------------- |
| `400` | 请求参数错误 | 缺少必填字段、枚举值不合法、提示词触发内容安全 |
| `401` | 鉴权失败   | API Key 缺失、无效或已被吊销      |
| `402` | 积分不足   | 账户余额无法覆盖本次调用成本          |
| `404` | 资源不存在  | 指定的 `task_id` 不存在或已过期   |
| `429` | 频率超限   | 超过账户速率配额，建议退避重试         |
| `500` | 平台内部错误 | 平台侧异常，请稍后重试             |
| `502` | 上游模型异常 | 底层模型服务不可用，通常可直接重试       |

<Tip>
  每个响应都包含 `request_id`。在提交工单或联系技术支持时请一并提供，以便我们快速定位问题。
</Tip>

## 生产接入建议

在将 imini 集成到生产环境前，请参考以下实践：

* **合理设置轮询间隔**：推荐首次查询间隔 2 秒，随后可按指数退避（2s / 3s / 5s）降低请求频率，避免对查询接口造成不必要压力。
* **配置合理的超时**：提交接口建议 30 秒超时；轮询整体超时建议按模型调整（图像 2 分钟、视频 10 分钟）。
* **错误重试策略**：对 `429`、`500`、`502` 建议重试 2～3 次并加入随机抖动（jitter）；对 `400`、`401`、`402` 不应重试。
* **API Key 轮换**：建议将 API Key 存入密钥管理系统（KMS / Secrets Manager），定期轮换，并对不同业务场景使用独立的 Key 便于观测与隔离。
* **幂等与请求追踪**：在你的侧记录提交返回的 `task_id` 与 `request_id`，便于与平台日志对账。
* **内容安全**：业务侧建议对用户输入的提示词与参考图做预审，以降低触发 `400` 内容违规错误的概率。

## 下一步

<CardGroup cols={2}>
  <Card title="API 手册" icon="book" href="/zh/api-reference/images/nano-banana">
    查阅各模型的完整参数定义与交互式 Playground
  </Card>

  <Card title="模型价格" icon="coins" href="/zh/guide/pricing">
    按模型、分辨率、场景查看积分消耗规则
  </Card>

  <Card title="更新公告" icon="bell" href="/zh/changelog/index">
    关注新模型上线、参数变更与服务调整
  </Card>

  <Card title="条款与协议" icon="file-contract" href="/zh/legal/terms">
    接入前请阅读用户协议与隐私政策
  </Card>
</CardGroup>
