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

# Midjourney API 시작하기

> CometAPI에서 Midjourney API를 빠르게 시작하는 방법: /mj/submit/imagine 제출, /mj/task/{id}/fetch 폴링, 이후 /mj/submit/action 및 modal 버튼 사용.

## 핵심 개념 이해하기

MidJourney API는 **Discord 버튼 상호작용을 시뮬레이션**합니다. 일반적인 REST API와 달리, 각 작업이 다음 단계에 사용할 새로운 버튼을 반환하는 **상태 머신**처럼 동작합니다.

### 4가지 핵심 API

| API                                                                                      | 목적                             | 사용 시점                   |
| ---------------------------------------------------------------------------------------- | ------------------------------ | ----------------------- |
| [`POST /mj/submit/imagine`](/api/image/midjourney/imagine)                               | 텍스트-이미지 생성                     | 모든 워크플로우의 시작점           |
| [`GET /mj/task/\{id\}/fetch`](/api/image/midjourney/task-fetching-api/fetch-single-task) | 작업 상태 조회 및 버튼 가져오기             | 각 submit 이후(완료될 때까지 폴링) |
| [`POST /mj/submit/action`](/api/image/midjourney/action)                                 | 버튼 클릭(업스케일, variation, zoom 등) | 이미지에 작업을 수행하고 싶을 때      |
| [`POST /mj/submit/modal`](/api/image/midjourney/modal)                                   | 추가 입력 제출                       | status가 `MODAL`일 때만     |

***

## 전체 워크플로우 다이어그램

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                         MIDJOURNEY API WORKFLOW                             │
└─────────────────────────────────────────────────────────────────────────────┘

  ┌──────────────────┐
  │  POST /submit/   │  ← Step 1: Submit prompt, get task_id
  │     imagine      │
  └────────┬─────────┘
           │ Returns: { "result": "task_id_1" }
           ▼
  ┌──────────────────┐
  │ GET /task/{id}/  │  ← Step 2: Poll until status = "SUCCESS"
  │      fetch       │
  └────────┬─────────┘
           │ Returns: imageUrl + buttons[] (U1,U2,U3,U4,V1,V2,V3,V4,🔄)
           ▼
  ┌──────────────────┐
  │  POST /submit/   │  ← Step 3: Click a button using customId
  │     action       │
  └────────┬─────────┘
           │ Returns: { "result": "task_id_2" }
           ▼
  ┌──────────────────┐
  │ GET /task/{id}/  │  ← Step 4: Poll the new task
  │      fetch       │
  └────────┬─────────┘
           │
           ├─── status = "SUCCESS" → Done! Get imageUrl
           │
           └─── status = "MODAL" → Need additional input (see Step 5)
                      │
                      ▼
           ┌──────────────────┐
           │  POST /submit/   │  ← Step 5: Submit mask/prompt for special operations
           │      modal       │
           └────────┬─────────┘
                    │ Returns: { "result": "task_id_3" }
                    ▼
           ┌──────────────────┐
           │ GET /task/{id}/  │  ← Step 6: Poll until SUCCESS
           │      fetch       │
           └──────────────────┘
```

***

## 핵심 개념: Buttons와 customId

성공한 각 작업은 `buttons` 배열을 반환합니다. 각 버튼에는 다음 작업을 실행할 때 사용하는 `customId`가 있습니다.

**`/mj/task/\{id\}/fetch`의 응답 예시:**

```json theme={null}
{
  "status": "SUCCESS",
  "imageUrl": "https://api.cometapi.com/mj/image/xxx",
  "buttons": [
    { "customId": "MJ::JOB::upsample::1::abc123", "label": "U1" },
    { "customId": "MJ::JOB::upsample::2::abc123", "label": "U2" },
    { "customId": "MJ::JOB::variation::1::abc123", "label": "V1" },
    { "customId": "MJ::JOB::reroll::0::abc123", "emoji": "🔄" }
  ]
}
```

<Warning>
  `customId`는 고정된 값이 아닙니다. 작업마다 달라집니다. 항상 `buttons` 배열에서 가져오세요.
</Warning>

***

## 단계별 버튼 참조

### IMAGINE 이후 (4분할 그리드 이미지)

초기 이미지 생성이 완료되면 다음 버튼이 반환됩니다:

| Button | customId Pattern                | Action      | Result      |
| ------ | ------------------------------- | ----------- | ----------- |
| U1-U4  | `MJ::JOB::upsample::1::xxx`     | 단일 이미지 업스케일 | 고해상도 단일 이미지 |
| V1-V4  | `MJ::JOB::variation::1::xxx`    | 변형 생성       | 새로운 4분할 그리드 |
| 🔄     | `MJ::JOB::reroll::0::xxx::SOLO` | 전체 다시 생성    | 새로운 4분할 그리드 |

### UPSCALE 이후 (단일 이미지)

업스케일 후에는 편집 도구를 사용할 수 있습니다:

| Label                             | Needs Modal? |
| --------------------------------- | ------------ |
| Upscale (Subtle) / Upscale (2x)   | ❌ 아니요        |
| Upscale (Creative) / Upscale (4x) | ❌ 아니요        |
| Vary (Subtle) 🪄                  | ❌ 아니요        |
| Vary (Strong) 🪄                  | ❌ 아니요        |
| Vary (Region) 🖌️                 | ✅ 예 (mask)   |
| Zoom Out 2x / 1.5x 🔍             | ❌ 아니요        |
| Custom Zoom 🔍                    | ✅ 예 (prompt) |
| ⬅️➡️⬆️⬇️ Pan                      | ❌ 아니요        |
| Animate 🎞️                       | ❌ 아니요        |
| 🔄 Reroll                         | ❌ 아니요        |

> **참고:** 버튼 라벨과 `customId` 형식은 프롬프트에 지정한 MJ 버전(예: `--v 6.1` 대 `--v 5.2`)에 따라 달라질 수 있습니다. 항상 API 응답에서 버튼을 읽으세요.

<Warning>
  Inpaint (Vary Region) 버튼은 Upscale 이후에만 표시됩니다.
</Warning>

***

## 전체 예시: 생성 및 업스케일

### 1단계: imagine 요청 제출

```bash theme={null}
curl -X POST 'https://api.cometapi.com/mj/submit/imagine' \
  -H "Authorization: Bearer $COMETAPI_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "botType": "MID_JOURNEY",
    "prompt": "a cute cat --v 6.1",
    "accountFilter": { "modes": ["FAST"] }
  }'
```

**응답:**

```json theme={null}
{ "code": 1, "result": "1768464763141701" }
```

### 2단계: 작업 상태 폴링

```bash theme={null}
curl -X GET 'https://api.cometapi.com/mj/task/1768464763141701/fetch' \
  -H "Authorization: Bearer $COMETAPI_KEY"
```

**응답(완료 시):**

```json theme={null}
{
  "status": "SUCCESS",
  "imageUrl": "https://api.cometapi.com/mj/image/1768464763141701",
  "buttons": [
    { "customId": "MJ::JOB::upsample::1::5f20922e-xxx", "label": "U1" },
    { "customId": "MJ::JOB::upsample::2::5f20922e-xxx", "label": "U2" },
    ...
  ]
}
```

### 3단계: U1을 클릭해 업스케일

```bash theme={null}
curl -X POST 'https://api.cometapi.com/mj/submit/action' \
  -H "Authorization: Bearer $COMETAPI_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "taskId": "1768464763141701",
    "customId": "MJ::JOB::upsample::1::5f20922e-xxx"
  }'
```

**응답:**

```json theme={null}
{ "code": 1, "result": "1768464800000000" }
```

### 4단계: 새 작업을 폴링하고 결과 받기

```bash theme={null}
curl -X GET 'https://api.cometapi.com/mj/task/1768464800000000/fetch' \
  -H "Authorization: Bearer $COMETAPI_KEY"
```

***

## Modal은 언제 필요한가요?

[`/mj/submit/action`](/api/image/midjourney/action)을 호출했을 때 작업 상태가 `SUCCESS`가 아니라 `MODAL`이 되면, 추가 입력을 제공하기 위해 [`/mj/submit/modal`](/api/image/midjourney/modal)을 호출해야 합니다.

### 확인된 Modal 작업

| Operation   | Button         | What to Submit                       |
| ----------- | -------------- | ------------------------------------ |
| Inpaint     | Vary (Region)  | `maskBase64` (PNG mask) + `prompt`   |
| Custom Zoom | 🔍 Custom Zoom | `prompt` (예: "your prompt --zoom 2") |

**예시: Inpaint 흐름**

```bash theme={null}
# 1. Action API를 통해 Vary (Region) 버튼 클릭
curl -X POST 'https://api.cometapi.com/mj/submit/action' \
  -H "Authorization: Bearer $COMETAPI_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"taskId": "xxx", "customId": "MJ::Inpaint::xxx", "enableRemix": true}'

# 2. 폴링 후 status = "MODAL" 확인
curl -X GET 'https://api.cometapi.com/mj/task/new_task_id/fetch'
# Response: { "status": "MODAL" }

# 3. Modal API를 통해 mask와 prompt 제출
curl -X POST 'https://api.cometapi.com/mj/submit/modal' \
  -H "Authorization: Bearer $COMETAPI_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "taskId": "new_task_id",
    "prompt": "replace with golden crown",
    "maskBase64": "data:image/png;base64,..."
  }'
```

***

## 속도 모드 선택

경로에 속도 접두사를 추가하세요:

| 모드    | 경로 접두사      | 예시                            |
| ----- | ----------- | ----------------------------- |
| Fast  | `/mj-fast`  | `/mj-fast/mj/submit/imagine`  |
| Turbo | `/mj-turbo` | `/mj-turbo/mj/submit/imagine` |
| Relax | (기본값)       | `/mj/submit/imagine`          |

***

## 기타 진입점

이 API들은 imagine → action 흐름을 따르지 않는 **독립적인 진입점**입니다:

| API                                                            | 용도                    |
| -------------------------------------------------------------- | --------------------- |
| [`POST /mj/submit/blend`](/api/image/midjourney/blend)         | 2\~5개의 이미지를 하나로 블렌드   |
| [`POST /mj/submit/describe`](/api/image/midjourney/describe)   | 이미지에서 프롬프트(Prompt) 생성 |
| [`POST /mj/submit/video`](/api/image/midjourney/submit-video)  | 이미지를 비디오로 변환          |
| [`POST /mj/submit/edits`](/api/image/midjourney/submit-editor) | 마스크를 사용해 이미지 편집       |

***

## 문제 해결 팁

API 설계와 워크플로를 기준으로, 다음은 자주 발생할 수 있는 문제들입니다:

| 문제                        | 가능한 원인                | 해결 방법                                                                                                             |
| ------------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Vary (Region) 버튼을 찾을 수 없음 | 4분할 그리드 이미지를 보고 있음    | 먼저 업스케일하세요(U1-U4 클릭), 그다음 버튼을 확인하세요                                                                               |
| 작업 상태가 `MODAL`에 멈춤        | 작업에 추가 입력이 필요함        | 필요한 데이터와 함께 [`/mj/submit/modal`](/api/image/midjourney/modal)을 호출하세요                                              |
| `customId`가 작동하지 않음       | 오래되었거나 하드코딩된 값을 사용 중임 | 항상 [`/mj/task/\{id\}/fetch`](/api/image/midjourney/task-fetching-api/fetch-single-task) 응답에서 최신 `customId`를 가져오세요 |
| `buttons` 배열이 비어 있음       | 작업이 아직 진행 중임          | 버튼에 접근하기 전에 `status: "SUCCESS"`를 기다리세요                                                                            |
