> ## 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 이미지 생성

>  - 비동기 텍스트 투 이미지. task_id 로 폴링
- 요청당 1–12장. 성공적으로 전달된 이미지당 과금 ($0.08/장)
- URL 출력만 지원. 이미지 투 이미지 / 스트리밍 미지원
- 이미지 URL 유효기간 72시간 

<Info>
  **텍스트 투 이미지 · 비동기 작업.** `POST /v1/images/generations` 를 제출한 뒤 [작업 상태 조회](/ko/api-reference/tasks/status) 로 폴링하세요.\
  모델명은 고정 `grok-imagine-2.0-ext`. **미지원**: 참조 이미지, `stream`, `url` 이외의 `response_format`.
</Info>

<Warning>
  API 키를 브라우저 번들(`VITE_*` / `NEXT_PUBLIC_*`, LocalStorage 등)에 넣지 마세요. 브라우저는 자체 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: 8eacb46d-ef4e-4f4e-82de-830bd8bc67e2' \
    --header 'X-APIMart-Response-Version: 2026-07-27' \
    --data '{
      "model": "grok-imagine-2.0-ext",
      "prompt": "A red apple on a white ceramic plate, clean studio product photo",
      "n": 1,
      "size": "1:1",
      "resolution": "quality",
      "response_format": "url"
    }'
  ```

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

  url = "https://api.apimart.ai/v1/images/generations"

  payload = {
      "model": "grok-imagine-2.0-ext",
      "prompt": "A red apple on a white ceramic plate, clean studio product photo",
      "n": 1,
      "size": "1:1",
      "resolution": "quality",
      "response_format": "url",
  }

  headers = {
      "Authorization": "Bearer <token>",
      "Content-Type": "application/json",
      "Accept": "application/json",
      "Idempotency-Key": str(uuid.uuid4()),
      "X-APIMart-Response-Version": "2026-07-27",
  }

  response = requests.post(url, json=payload, headers=headers)

  print(response.status_code, response.json())
  ```

  ```javascript JavaScript theme={null}
  const url = "https://api.apimart.ai/v1/images/generations";

  const payload = {
    model: "grok-imagine-2.0-ext",
    prompt: "A red apple on a white ceramic plate, clean studio product photo",
    n: 1,
    size: "1:1",
    resolution: "quality",
    response_format: "url",
  };

  const headers = {
    Authorization: "Bearer <token>",
    "Content-Type": "application/json",
    Accept: "application/json",
    "Idempotency-Key": crypto.randomUUID(),
    "X-APIMart-Response-Version": "2026-07-27",
  };

  fetch(url, {
    method: "POST",
    headers: headers,
    body: JSON.stringify(payload),
  })
    .then(async (response) => {
      console.log(response.status, await response.json());
    })
    .catch((error) => console.error("Error:", error));
  ```
</RequestExample>

<ResponseExample>
  ```json 202 theme={null}
  {
    "code": 202,
    "request_id": "2026081111342261665927mpb4IPDb",
    "data": {
      "id": "task_01KZQE5CM0Y3KZ6M1N1BK619MX",
      "object": "generation.task",
      "type": "image",
      "status": "pending",
      "progress": 0,
      "poll_url": "/v1/tasks/task_01KZQE5CM0Y3KZ6M1N1BK619MX"
    }
  }
  ```

  ```json 400 theme={null}
  {
    "request_id": "20260811...",
    "error": {
      "message": "`response_format` for grok-imagine-2.0-ext only supports `url` (got: b64_json)",
      "type": "invalid_response_format",
      "param": "",
      "code": "invalid_response_format"
    }
  }
  ```

  ```json 401 theme={null}
  {
    "error": {
      "code": 401,
      "message": "인증에 실패했습니다. API 키를 확인해 주세요",
      "type": "authentication_error"
    }
  }
  ```

  ```json 402 theme={null}
  {
    "error": {
      "code": 402,
      "message": "잔액이 부족합니다. 충전 후 다시 시도해 주세요",
      "type": "payment_required"
    }
  }
  ```

  ```json 429 theme={null}
  {
    "error": {
      "code": 429,
      "message": "요청이 너무 많습니다. 잠시 후 다시 시도해 주세요",
      "type": "rate_limit_error"
    }
  }
  ```
</ResponseExample>

## 기능 및 제한

| 항목     | 계약                                                                     |
| ------ | ---------------------------------------------------------------------- |
| 모델     | 고정 `grok-imagine-2.0-ext`                                              |
| 기능     | **텍스트 투 이미지만**                                                         |
| 모드     | 비동기 작업                                                                 |
| 장수 `n` | `1`–`12`, 기본값 `1`                                                      |
| `size` | 비율 7종 + 픽셀 별칭 5종 (아래)                                                  |
| 출력     | `response_format=url` 만 (기본값도 동일)                                      |
| 품질     | 공개 필드 `resolution`. 검증된 값 `quality`                                    |
| 미지원    | 이미지 투 이미지, `stream=true`, 공개 `quality`, `style`, `b64_json` / `base64` |
| 과금     | 고정 단가. **성공적으로 전달된** 이미지에 과금                                           |

## 인증 및 권장 헤더

<ParamField header="Authorization" type="string" required>
  Bearer 토큰. [API Key 페이지](https://apimart.ai/keys) 에서 키를 발급받으세요.

  ```
  Authorization: Bearer YOUR_API_KEY
  ```
</ParamField>

| Header                       | 설명                                                                     |
| ---------------------------- | ---------------------------------------------------------------------- |
| `Content-Type`               | `application/json` (제출 시)                                              |
| `Accept`                     | `application/json`                                                     |
| `Idempotency-Key`            | 강력 권장. 사용자가 확정한 논리 생성마다 새 UUID. 네트워크 재시도 시 **동일 key 와 body 를 재사용**해야 함 |
| `X-APIMart-Response-Version` | 안정적인 제출 응답 형태(`data.id`)를 위해 `2026-07-27` 권장                           |

## 요청 파라미터

<ParamField body="model" type="string" required>
  고정 값: `grok-imagine-2.0-ext`
</ParamField>

<ParamField body="prompt" type="string" required>
  프롬프트. trim 후 비어 있으면 안 됩니다. 제출 전에 trim 하세요.
</ParamField>

<ParamField body="n" type="integer" default="1">
  이미지 장수: `1`–`12`. 명시적 `0` 은 오류. 생략 시 `1`.
</ParamField>

<ParamField body="size" type="string">
  화면 비율. **비율 문자열 권장** (UI 에는 비율만 표시):

  | `size` | 방향  | 전형적 용도      |
  | ------ | --- | ----------- |
  | `1:1`  | 정사각 | 상품, 아바타     |
  | `2:3`  | 세로  | 포스터, 전신     |
  | `3:2`  | 가로  | 사진, 넓은 장면   |
  | `3:4`  | 세로  | 이커머스, 인물    |
  | `4:3`  | 가로  | 디스플레이 아트    |
  | `9:16` | 세로형 | 스토리 / 숏폼 커버 |
  | `16:9` | 와이드 | 배너, 영상 커버   |

  픽셀 별칭: `1024x1024` (1:1), `1024x1792` (2:3), `1792x1024` (3:2), `720x1280` (9:16), `1280x720` (16:9).

  화이트리스트 밖 값은 `400 invalid_size` 를 반환합니다 (예: `1:2`, `2:1`, `4:5`, `auto`).

  <Note>
    동일 비율이라도 실제 픽셀은 별칭 표와 다를 수 있습니다 (예: `1:1` 이 1408×1408 반환). 반환 이미지를 기준으로 하고, 측정 픽셀로 `size` 를 다시 쓰지 마세요.
  </Note>
</ParamField>

<ParamField body="resolution" type="string">
  품질 모드 필드. 검증된 값: `quality`.

  * 생략 가능 (모델은 기본적으로 품질 모드), 또는
  * 명시적으로 `resolution: "quality"` 전달

  **`1K` / `2K` / `4K` 픽셀 단계가 아닙니다.** 구도는 `size` 로 제어합니다.

  <Warning>
    공개 `quality` 필드를 보내지 마세요 — `400 invalid_quality` 가 됩니다. `resolution` 을 사용하세요.
  </Warning>
</ParamField>

<ParamField body="response_format" type="string" default="url">
  `url` 만 허용. 생략 가능. `b64_json` / `base64` → `400 invalid_response_format`.
</ParamField>

<ParamField body="webhook" type="string">
  선택적 공개 HTTPS **베이스 URL**. 종료 상태 시 플랫폼이 `{webhook}/callback` 으로 POST 합니다. 서버 측 전용 — [Webhook](#webhook-선택) 참고.
</ParamField>

### 미지원 파라미터

| 파라미터                                       | 동작                                      |
| ------------------------------------------ | --------------------------------------- |
| `quality`                                  | `400 invalid_quality` → `resolution` 사용 |
| `style`                                    | `400 invalid_style`                     |
| `image_urls` / `image_with_roles`          | `400 invalid_image_input`               |
| `stream: true`                             | `400 invalid_stream`                    |
| `response_format: "b64_json"` / `"base64"` | `400 invalid_response_format`           |

화이트리스트로 요청을 구성하세요. 다른 이미지 모델의 일반 폼 객체를 그대로 전달하지 마세요.

## 요청 예제

### 최소

```json theme={null}
{
  "model": "grok-imagine-2.0-ext",
  "prompt": "A red apple on a white ceramic plate, clean studio product photo"
}
```

### 권장

```json theme={null}
{
  "model": "grok-imagine-2.0-ext",
  "prompt": "A red apple on a white ceramic plate, clean studio product photo",
  "n": 1,
  "size": "1:1",
  "resolution": "quality",
  "response_format": "url"
}
```

## 제출 응답

`X-APIMart-Response-Version: 2026-07-27` 권장. 성공 시 HTTP **`202`**. 작업 ID 는 **`data.id`** (레거시 `data[0].task_id` 에 의존하지 마세요).

저장할 항목:

* 폴링용 `data.id`
* 게이트웨이 디버깅용 `request_id`
* 결과 불명 시 안전 재시도를 위한 `Idempotency-Key`
* UI / 지원용 원본 요청 파라미터

## 멱등성 및 안전 재시도

이미지 생성은 과금 대상입니다 — **강력 권장** `Idempotency-Key` (1–191 인쇄 가능 ASCII. UUID 가 가장 간편. 약 24시간 유지).

| 시나리오                 | 동작                                            | 조치                           |
| -------------------- | --------------------------------------------- | ---------------------------- |
| 동일 key + 동일 body 완료됨 | 재생. 헤더 `Idempotency-Replayed: true`           | 동일 작업 ID 사용                  |
| 동일 key 처리 중          | `409 idempotency_in_progress` + `Retry-After` | 대기 후 **동일 key 와 body** 로 재시도 |
| 동일 key, 다른 body      | `409 idempotency_key_reused`                  | 새 논리 작업에는 새 key 필요           |
| 결과 불확정               | `409 idempotency_result_indeterminate`        | 새 key 를 만들지 말고 기존 key 로 조사   |

POST 네트워크 타임아웃으로 서버 수락 여부를 알 수 없으면 **즉시 새 key 를 만들지 마세요** — 동일 key / body / 응답 버전으로 재시도하세요.

## 작업 폴링

```http theme={null}
GET /v1/tasks/{task_id}?language=ko
Authorization: Bearer YOUR_API_KEY
Accept: application/json
```

선택 `language`: `zh` / `en` / `ko` / `ja` (실패 메시지 로컬라이즈만). [작업 상태 조회](/ko/api-reference/tasks/status) 참고.

### 상태

| `status`                 |  종료 | 처리                                        |
| ------------------------ | :-: | ----------------------------------------- |
| `pending` / `processing` | 아니오 | 폴링 계속 (`result` 부재는 실패가 아님)               |
| `completed`              |  예  | `result.images` 파싱                        |
| `failed`                 |  예  | `error.message` 표시. `cost` 는 `0` (선과금 환불) |
| `unknown`                | 아니오 | 짧게 재시도. 지속 시 작업 ID 와 함께 지원 문의             |

약 **2초**마다 폴링. 상한 약 **10분** 또는 **120** 회. `429` 시 `Retry-After` 준수. 작업은 기본 약 3일 보관 — 클라이언트 타임아웃 후에도 작업 ID 를 유지하세요.

### 완료 예제

```json theme={null}
{
  "code": 200,
  "data": {
    "id": "task_01KZQE5CM0Y3KZ6M1N1BK619MX",
    "status": "completed",
    "progress": 100,
    "created": 1786419262,
    "completed": 1786419275,
    "actual_time": 13,
    "estimated_time": 100,
    "cost": 0.08,
    "credits_cost": 0.8,
    "result": {
      "images": [
        {
          "expires_at": 1786505675,
          "url": [
            "https://example.com/image/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.jpg"
          ],
          "image_ids": [
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
          ]
        }
      ]
    }
  }
}
```

### `url` 과 `image_ids` 파싱

```text theme={null}
result.images[]
  ├─ url[]          ← 표시/다운로드 권위 필드 (배열)
  ├─ image_ids[]    ← 선택적 불투명 ID
  └─ expires_at     ← Unix 초. JS Date 는 ×1000
```

1. 표시에는 `url[]` 사용. `n>1` 이면 모든 항목 순회
2. `image_ids.length === url.length` 일 때만 인덱스로 매칭
3. `image_ids` 가 없어도 표시 가능
4. 링크 유효기간 **72시간** — 빠르게 다운로드. `expires_at` 도 신뢰

## 과금

기본 가격 **\$0.08 / 장** (성공 전달분):

| `n` | 예상 기본 금액 |
| --: | -------: |
|   1 |   \$0.08 |
|   4 |   \$0.32 |
|   8 |   \$0.64 |
|  12 |   \$0.96 |

* 제출 전 UI 는 “예상”으로 표기. 최종 USD 는 **`data.cost`**
* **`data.credits_cost`** 는 크레딧 뷰 (현재 약 USD × 10)
* 요청 장수로 선과금. 성공 장수로 정산 (부분 실패 시 차액 환불)
* 전체 실패: `cost=0`, 선과금 환불
* `resolution` 으로 가격 키를 만들지 마세요. 이 모델은 장당 고정가

## Webhook (선택)

```json theme={null}
{
  "webhook": "https://your-service.example.com/apimart"
}
```

* **베이스 URL** 을 제공. 플랫폼이 `{base}/callback` 호출
* 공개 접근 가능하고 SSRF 검사를 통과해야 함
* `webhook_secret` 설정 시 서명은 원본 바이트에 대한 `hex(HMAC-SHA256(secret, raw_body))`
* 콜백 본문은 작업 조회의 `data` 와 동일 (추가 `{code,data}` 래퍼 없음)
* 폴백으로 저빈도 폴링도 유지

## 자주 발생하는 오류

| HTTP | `error.code`              | 원인                  | 조치                            |
| ---: | ------------------------- | ------------------- | ----------------------------- |
|  400 | `invalid_request`         | 빈 prompt / 잘못된 JSON | 입력 검증                         |
|  400 | `invalid_n`               | `n` 이 1–12 밖        | 장수 제한                         |
|  400 | `invalid_size`            | size 화이트리스트 밖       | 고정 선택 옵션                      |
|  400 | `invalid_response_format` | `url` 아님            | 수정 또는 생략                      |
|  400 | `invalid_quality`         | 공개 `quality` 전송     | `resolution` 사용               |
|  400 | `invalid_style`           | `style` 전송          | 제거                            |
|  400 | `invalid_image_input`     | 참조 이미지              | 모델 전환                         |
|  400 | `invalid_stream`          | `stream=true`       | 제거                            |
|  400 | `invalid_idempotency_key` | 잘못된 key             | UUID 사용                       |
|  401 | 인증 실패                     | 잘못된 key             | 서버 자격 증명 수정                   |
|  402 | 결제 필요                     | 잔액 부족               | 충전                            |
|  409 | `idempotency_*`           | 멱등성 충돌              | 위 표 참고                        |
|  429 | 속도 제한                     | 너무 빠름               | `Retry-After` 준수              |
|  5xx | 서버 오류                     | —                   | Idempotency-Key 유지. 무분별 교체 금지 |

UI 에는 `error.message` 를 우선 사용. 원시 인증 내부 정보를 최종 사용자에게 노출하지 마세요.

## 1.5 와의 차이 (요약)

| 항목        | Grok Imagine 1.5             | 2.0 Ext                                   |
| --------- | ---------------------------- | ----------------------------------------- |
| 모델        | `grok-imagine-1.5-apimart` 등 | `grok-imagine-2.0-ext`                    |
| 이미지 투 이미지 | 지원 (1.5 문서 참고)               | **미지원**                                   |
| 장수        | 1.5 문서 참고                    | **1–12**                                  |
| 품질 필드     | 1.5 문서 참고                    | `resolution` (`quality`). 공개 `quality` 불가 |
| 출력        | 1.5 문서 참고                    | **URL 만**                                 |
| URL 유효기간  | 1.5 문서 참고 (종종 24h)           | **72시간**                                  |
| 단가        | 1.5 문서 참고                    | **\$0.08 / 장**                            |
