Chuyển đến nội dung chính

🎯 Hiểu khái niệm cốt lõi

MidJourney API mô phỏng các tương tác nút trên Discord. Không giống các REST API điển hình, nó hoạt động như một state machine, trong đó mỗi thao tác sẽ trả về các nút mới cho bước tiếp theo.

4 API cốt lõi

APIMục đíchKhi nào dùng
POST /mj/submit/imagineTạo ảnh từ văn bảnĐiểm khởi đầu cho mọi workflow
GET /mj/task/\{id\}/fetchTruy vấn trạng thái task và lấy các nútSau mỗi lần submit (poll cho đến khi xong)
POST /mj/submit/actionNhấn một nút (upscale, vary, zoom, v.v.)Khi bạn muốn thao tác trên một hình ảnh
POST /mj/submit/modalGửi thêm dữ liệu đầu vàoChỉ khi trạng thái là MODAL

📊 Sơ đồ workflow hoàn chỉnh

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

  ┌──────────────────┐
  │  POST /submit/   │  ← Bước 1: Gửi prompt, nhận task_id
  │     imagine      │
  └────────┬─────────┘
           │ Trả về: { "result": "task_id_1" }

  ┌──────────────────┐
  │ GET /task/{id}/  │  ← Bước 2: Poll cho đến khi status = "SUCCESS"
  │      fetch       │
  └────────┬─────────┘
           │ Trả về: imageUrl + buttons[] (U1,U2,U3,U4,V1,V2,V3,V4,🔄)

  ┌──────────────────┐
  │  POST /submit/   │  ← Bước 3: Nhấn một nút bằng customId
  │     action       │
  └────────┬─────────┘
           │ Trả về: { "result": "task_id_2" }

  ┌──────────────────┐
  │ GET /task/{id}/  │  ← Bước 4: Poll task mới
  │      fetch       │
  └────────┬─────────┘

           ├─── status = "SUCCESS" → Xong! Lấy imageUrl

           └─── status = "MODAL" → Cần thêm dữ liệu đầu vào (xem Bước 5)


           ┌──────────────────┐
           │  POST /submit/   │  ← Bước 5: Gửi mask/prompt cho các thao tác đặc biệt
           │      modal       │
           └────────┬─────────┘
                    │ Trả về: { "result": "task_id_3" }

           ┌──────────────────┐
           │ GET /task/{id}/  │  ← Bước 6: Poll cho đến khi SUCCESS
           │      fetch       │
           └──────────────────┘

🔑 Khái niệm chính: Buttons và customId

Mỗi task thành công sẽ trả về một mảng buttons. Mỗi nút có một customId mà bạn sẽ dùng để kích hoạt hành động tiếp theo. Ví dụ response từ /mj/task/\{id\}/fetch:
{
  "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": "🔄" }
  ]
}
⚠️ Quan trọng: customId KHÔNG phải là giá trị cố định. Nó thay đổi theo từng task. Luôn lấy nó từ mảng buttons.

📋 Tham chiếu Button theo từng giai đoạn

Sau IMAGINE (ảnh lưới 4 ô)

Các button này được trả về khi quá trình tạo ảnh ban đầu hoàn tất:
ButtoncustomId PatternHành độngKết quả
U1-U4MJ::JOB::upsample::1::xxxNâng cấp một ảnh đơnẢnh đơn độ phân giải cao
V1-V4MJ::JOB::variation::1::xxxTạo biến thểLưới 4 ô mới
🔄MJ::JOB::reroll::0::xxx::SOLOTạo lại toàn bộLưới 4 ô mới

Sau UPSCALE (ảnh đơn)

Sau khi upscale, bạn sẽ có quyền truy cập vào các công cụ chỉnh sửa:
NhãnCần Modal?
Upscale (Subtle) / Upscale (2x)❌ Không
Upscale (Creative) / Upscale (4x)❌ Không
Vary (Subtle) 🪄❌ Không
Vary (Strong) 🪄❌ Không
Vary (Region) 🖌️✅ Có (mask)
Zoom Out 2x / 1.5x 🔍❌ Không
Custom Zoom 🔍✅ Có (prompt)
⬅️➡️⬆️⬇️ Pan❌ Không
Animate 🎞️❌ Không
🔄 Reroll❌ Không
Lưu ý: Nhãn button và định dạng customId có thể khác nhau tùy theo phiên bản MJ được chỉ định trong prompt của bạn (ví dụ: --v 6.1 so với --v 5.2). Luôn đọc các button từ phản hồi API.
⚠️ Button Inpaint (Vary Region) chỉ xuất hiện sau khi Upscale!

⚡ Ví dụ hoàn chỉnh: Generate & Upscale

Bước 1: Gửi yêu cầu Imagine

curl -X POST 'https://api.cometapi.com/mj/submit/imagine' \
  -H 'Authorization: Bearer <YOUR_COMETAPI_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "botType": "MID_JOURNEY",
    "prompt": "a cute cat --v 6.1",
    "accountFilter": { "modes": ["FAST"] }
  }'
Phản hồi:
{ "code": 1, "result": "1768464763141701" }

Bước 2: Poll trạng thái tác vụ

curl -X GET 'https://api.cometapi.com/mj/task/1768464763141701/fetch' \
  -H 'Authorization: Bearer <YOUR_COMETAPI_KEY>'
Phản hồi (khi hoàn tất):
{
  "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" },
    ...
  ]
}

Bước 3: Nhấn U1 để Upscale

curl -X POST 'https://api.cometapi.com/mj/submit/action' \
  -H 'Authorization: Bearer <YOUR_COMETAPI_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "taskId": "1768464763141701",
    "customId": "MJ::JOB::upsample::1::5f20922e-xxx"
  }'
Phản hồi:
{ "code": 1, "result": "1768464800000000" }

Bước 4: Poll tác vụ mới & lấy kết quả

curl -X GET 'https://api.cometapi.com/mj/task/1768464800000000/fetch' \
  -H 'Authorization: Bearer <YOUR_COMETAPI_KEY>'

⚠️ Khi nào cần Modal?

Khi bạn gọi /mj/submit/action và trạng thái tác vụ trở thành MODAL thay vì SUCCESS, bạn phải gọi /mj/submit/modal để cung cấp thêm đầu vào.

Các thao tác Modal đã được xác nhận

Thao tácButtonCần gửi gì
InpaintVary (Region)maskBase64 (mask PNG) + prompt
Custom Zoom🔍 Custom Zoomprompt (ví dụ: “your prompt —zoom 2”)
Ví dụ: Luồng Inpaint
# 1. Click Vary (Region) button via Action API
curl -X POST 'https://api.cometapi.com/mj/submit/action' \
  -H 'Authorization: Bearer <YOUR_COMETAPI_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{"taskId": "xxx", "customId": "MJ::Inpaint::xxx", "enableRemix": true}'

# 2. Poll and see status = "MODAL"
curl -X GET 'https://api.cometapi.com/mj/task/new_task_id/fetch'
# Response: { "status": "MODAL" }

# 3. Submit mask and prompt via Modal API
curl -X POST 'https://api.cometapi.com/mj/submit/modal' \
  -H 'Authorization: Bearer <YOUR_COMETAPI_KEY>' \
  -H 'Content-Type: application/json' \
  -d '{
    "taskId": "new_task_id",
    "prompt": "replace with golden crown",
    "maskBase64": "data:image/png;base64,..."
  }'

🚀 Chọn Chế Độ Tốc Độ

Thêm tiền tố tốc độ vào đường dẫn:
Chế độTiền tố đường dẫnVí dụ
Nhanh/mj-fast/mj-fast/mj/submit/imagine
Turbo/mj-turbo/mj-turbo/mj/submit/imagine
Relax(mặc định)/mj/submit/imagine

🔗 Các Điểm Vào Khác

Các API này là điểm vào độc lập và không tuân theo luồng imagine → action:
APIMục đích
POST /mj/submit/blendTrộn 2-5 hình ảnh thành một
POST /mj/submit/describeTạo prompt từ hình ảnh
POST /mj/submit/videoChuyển đổi hình ảnh thành video
POST /mj/submit/editsChỉnh sửa hình ảnh bằng mask

❓ Mẹo Khắc Phục Sự Cố

Dựa trên thiết kế API và quy trình hoạt động, đây là các vấn đề phổ biến bạn có thể gặp phải:
Vấn đềNguyên nhân có thểCách khắc phục
Không tìm thấy nút Vary (Region)Đang xem ảnh lưới 4 ôHãy Upscale trước (nhấn U1-U4), sau đó kiểm tra các nút
Trạng thái task bị kẹt ở MODALThao tác yêu cầu thêm đầu vàoGọi /mj/submit/modal với dữ liệu cần thiết
customId không hoạt độngĐang dùng giá trị đã cũ hoặc hardcodedLuôn lấy customId mới từ phản hồi của /mj/task/\{id\}/fetch
Mảng buttons trốngTask vẫn đang được xử lýChờ status: "SUCCESS" trước khi truy cập buttons