=== URL: https://useapi.net/docs/api-v2 === Document URL: https://useapi.net/docs/api-v2 --- layout: default title: Midjourney API v2 nav_order: 12000 has_children: true permalink: /docs/api-v2 --- # Midjourney API v2 December 2023 (December 8, 2025) This is an [experimental](../../docs/legal) API for the [Midjourney Discord Bot](https://discord.com/invite/midjourney) by [Midjourney](https://www.midjourney.com). Since its initial release in early 2023, our experimental API has provided pure and unrestricted access to the Midjourney Discord Bot, allowing you to utilize its full potential. The **entire** Midjourney Discord Bot functionality, including **video generation**, is supported, as well as retrieval of [seed](https://docs.midjourney.com/docs/seeds), support for [variations mode](https://docs.midjourney.com/docs/variations), [remix mode](https://docs.midjourney.com/docs/remix), and everything else the Midjourney Discord Bot offers. Think of our experimental API as a smart proxy for your Midjourney Discord bot. Our experimental API uses intelligent logic to prevent potential issues with Discord and Midjourney, such as bans, CAPTCHA challenges, or excessive requests. API comes with an automated [CAPTCHA solver](https://useapi.net/docs/api-v2/captcha-solver) at no additional cost. We fully support the ability to use [multiple Midjourney accounts](../../docs/api-v2/setup-multiple-midjourney-accounts), complete with automated load balancing. [Setup Midjourney](../../docs/start-here/setup-midjourney) [Postman collection](https://www.postman.com/useapinet/useapi-net/collection) (January 20, 2026) [Q&A](../../docs/questions-and-answers) [GitHub repo with code examples](https://github.com/useapi/examples) Articles: * [Interact with Midjourney using Discord API • Part I](../../docs/articles/discord-api-part-1) * [Interact with Midjourney using Discord API • Part II](../../docs/articles/discord-api-part-2) * [Discord CDN Proxy](../../docs/articles/discord-cdn-proxy) * [Automating Asset Generation with the Midjourney API • Part I](../../docs/articles/asset-generation-part-1) Examples: * [Midjourney Video](../../blog/250728) Developer Community: * Discord Server * Telegram Channel * r/midjourney_api === URL: https://useapi.net/docs/api-v2/captcha-solver === Document URL: https://useapi.net/docs/api-v2/captcha-solver --- layout: default title: 🔓 CAPTCHA Solver parent: Midjourney API v2 nav_order: 5000 --- # CAPTCHA Solver {: .no_toc } December 8, 2025 ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Our API includes an **automated CAPTCHA solver** at no additional cost with your subscription. ## What Triggers CAPTCHA Challenges Midjourney Discord bot may present CAPTCHA challenges when it detects unusual activity patterns: - Too many generations in a short period of time - Recently created Discord accounts are more likely to be challenged - Active connections from different geographical locations for the same account ## How It Works When a CAPTCHA is detected: 1. The generation that triggered the CAPTCHA fails with a `596` error. The Midjourney account is locked and updated with an error message explaining that a CAPTCHA was detected. All subsequent API calls for this account will return `596` until the CAPTCHA solver unlocks the account or you manually resolve it via [POST /account/channel/reset](https://useapi.net/docs/api-v2/post-account-midjourney-channel-reset) 2. You receive a notification email immediately 3. The CAPTCHA solver is triggered automatically 4. A second email is sent either: - Confirming the solver successfully cleared the CAPTCHA and unlocked the account, or - Asking you to solve it manually (rare cases) The entire process takes 60-90 seconds. Based on our in-house testing, we expect the success rate to be close to 100%. 👉 We strongly recommend setting your Discord account language to **English**. Our CAPTCHA solver is primarily tested with English and may not work as reliably with other languages. ## Important: Preventing Excessive CAPTCHAs While our CAPTCHA solver will handle challenges automatically, **frequent CAPTCHAs indicate you are pushing the account too hard**. Continued aggressive usage patterns may lead to **permanent account bans** by Discord/Midjourney. To avoid problems: ### Add More Accounts If you're hitting CAPTCHAs frequently, consider adding more Midjourney accounts to spread the load. Our API supports [multiple accounts](https://useapi.net/docs/api-v2/setup-multiple-midjourney-accounts) with automatic load balancing. ### Handle 596 Errors Gracefully When you receive a `596` error response, it indicates account issues (often CAPTCHA-related). Consider a 10-15 minute cooloff period before retrying. If you have multiple accounts configured, our load balancer will automatically switch to a different one. ### Recommended Practices - Spread load across multiple accounts - Add random delays between generations - If you run mostly `--relax` generations, execute `--fast` once in a while ## No Additional Cost The CAPTCHA solver is **included free** with your useapi.net subscription. There are no per-solve charges or hidden fees. === URL: https://useapi.net/docs/api-v2/del-account-midjourney-channel === Document URL: https://useapi.net/docs/api-v2/del-account-midjourney-channel --- layout: default title: DEL …/midjourney/channel parent: Midjourney API v2 nav_order: 600 --- ## Delete Midjourney account {: .no_toc } December 2023 ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- {: .delete } > **https://api.useapi.net/v2/account/midjourney/`channel`** The `channel` value should correspond to an account configured previously via a [POST account/midjourney](post-account-midjourney) request. ##### Request Headers ``` yaml Authorization: Bearer {API token} ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Responses {% tabs del_account_midjourney_response %} {% tab del_account_midjourney_response 204 %} 204 No Content {% endtab %} {% tab del_account_midjourney_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% tab del_account_midjourney_response 404 %} 404 Not Found {% endtab %} {% endtabs %} ##### Model ```typescript { // TypeScript, all fields are optional error: string, errorDetails: string, code: number } ``` ##### Examples {% tabs del_account_midjourney_example %} {% tab del_account_midjourney_example Curl %} ``` bash curl -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer …" \ -X DELETE https://api.useapi.net/v2/account/midjourney/ ``` {% endtab %} {% tab del_account_midjourney_example JavaScript %} ``` javascript const channel = "Previously configured channel id"; const apiUrl = `https://api.useapi.net/v2/account/midjourney/${channnel}`; const token = "API token"; const data = { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }; const response = await fetch(apiUrl, data); const result = await response.json(); console.log("response", {response, result}); ``` {% endtab %} {% tab del_account_midjourney_example Python %} ``` python import requests channel = "Previously configured channel id" apiUrl = f"https://api.useapi.net/v2/account/midjourney/{channel}" token = "API token" headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } response = requests.delete(apiUrl, headers=headers) print(response, response.json()) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/get-account-midjourney-channel === Document URL: https://useapi.net/docs/api-v2/get-account-midjourney-channel --- layout: default title: GET …/midjourney/channel parent: Midjourney API v2 nav_order: 400 --- ## Retrieve Midjourney configuration for `channel` {: .no_toc } December 2023 (May 5, 2025) ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- {: .get } > **https://api.useapi.net/v2/account/midjourney/`channel`** The `channel` value should correspond to an account configured previously via a [POST account/midjourney](post-account-midjourney) request. ##### Request Headers ``` yaml Authorization: Bearer {API token} ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Responses {% tabs get_account_midjourney_channel_response %} {% tab get_account_midjourney_channel_response 200 %} 200 OK ```json { "channel": "Discord channel id", "discord": "Discord token", "maxJobs": 1-15 } ``` {% endtab %} {% tab get_account_midjourney_channel_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% tab get_account_midjourney_channel_response 404 %} 404 Not Found {% endtab %} {% endtabs %} ##### Model ```typescript { // TypeScript, all fields are optional discord: string, channel: string, maxJobs: number, pendingModMessage: string } ``` ##### Examples {% tabs get_account_midjourney_channel_example %} {% tab get_account_midjourney_channel_example Curl %} ``` bash curl https://api.useapi.net/v2/account/midjourney/ \ -H "Accept: application/json" \ -H "Authorization: Bearer …" ``` {% endtab %} {% tab get_account_midjourney_channel_example JavaScript %} ``` javascript const token = "API token"; const channel = "Previously configured channel id"; const apiUrl = `https://api.useapi.net/v2/account/midjourney/${channel}`; const response = await fetch(apiUrl, { headers: { "Authorization": `Bearer ${token}`, }, }); const result = await response.json(); console.log("response", {response, result}); ``` {% endtab %} {% tab get_account_midjourney_channel_example Python %} ``` python import requests token = "API token" channel = "Previously configured channel id" apiUrl = f"https://api.useapi.net/v2/account/midjourney/{channel}" headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } response = requests.get(apiUrl, headers=headers) print(response, response.json()) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/get-account-midjourney === Document URL: https://useapi.net/docs/api-v2/get-account-midjourney --- layout: default title: GET account/midjourney parent: Midjourney API v2 nav_order: 300 --- ## Retrieve Midjourney accounts information {: .no_toc } December 2023 (May 5, 2025) ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- For your convenience, you can specify your Midjourney configuration values under your account so that you no longer need to provide them with every API call. If you specify multiple Midjourney accounts, the API will automatically perform load balancing by randomly selecting an account with available capacity before making calls to Discord / Midjourney. This endpoint retrieves the complete list of configured accounts for Midjourney. {: .get } > **https://api.useapi.net/v2/account/midjourney** ##### Request Headers ``` yaml Authorization: Bearer {API token} ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Responses {% tabs account_midjourney_response %} {% tab account_midjourney_response 200 %} 200 OK ```json { "Discord channel A": { "channel": "Discord channel A", "discord": "Discord token A", "maxJobs": 1-15 }, "Discord channel B": { "channel": "Discord channel B", "discord": "Discord token B", "maxJobs": 1-15 }, "Discord channel N": { "channel": "Discord channel N", "discord": "Discord token N", "maxJobs": 1-15 } } ``` {% endtab %} {% tab account_midjourney_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% tab account_midjourney_response 404 %} 404 Not Found Configuration not found. To create configuration use [POST account/midjourney](post-account-midjourney). {% endtab %} {% endtabs %} ##### Model ```typescript { // TypeScript, all fields are optional [channel: string]: { discord: string, channel: string, maxJobs: number, pendingModMessage: string } } ``` ##### Examples {% tabs account_midjourney_example %} {% tab account_midjourney_example Curl %} ``` bash curl https://api.useapi.net/v2/account/midjourney \ -H "Accept: application/json" \ -H "Authorization: Bearer …" ``` {% endtab %} {% tab account_midjourney_example JavaScript %} ``` javascript const token = "API token"; const apiUrl = "https://api.useapi.net/v2/account/midjourney"; const response = await fetch(apiUrl, { headers: { "Authorization": `Bearer ${token}`, }, }); const result = await response.json(); console.log("response", {response, result}); ``` {% endtab %} {% tab account_midjourney_example Python %} ``` python import requests token = "API token" apiUrl = "https://api.useapi.net/v2/account/midjourney" headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } response = requests.get(apiUrl, headers=headers) print(response, response.json()) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/get-jobs-cancel === Document URL: https://useapi.net/docs/api-v2/get-jobs-cancel --- layout: default title: GET jobs/cancel/?jobid=jobid parent: Midjourney API v2 nav_order: 2100 --- ## Cancel Midjourney job {: .no_toc } December 2023 (October 7, 2024) ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Cancel execution of job created by - [jobs/imagine](../api-v2/post-jobs-imagine) - [jobs/button](../api-v2/post-jobs-button) - [jobs/blend](../api-v2/post-jobs-blend) - [jobs/describe](../api-v2/post-jobs-describe) - [jobs/seed_async](../api-v2/post-jobs-seed_async) {: .get } > **https://api.useapi.net/v2/jobs/cancel/?jobid=`jobid`** ##### Request Headers ``` yaml Authorization: Bearer {API token} ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Query Parameter `jobid` is **required**, use value returned by - [jobs/imagine](../api-v2/post-jobs-imagine) - [jobs/button](../api-v2/post-jobs-button) - [jobs/blend](../api-v2/post-jobs-blend) - [jobs/describe](../api-v2/post-jobs-describe) - [jobs/seed_async](../api-v2/post-jobs-seed_async) ##### Responses {:toc} {% tabs post_cancel_response %} {% tab post_cancel_response 200 %} ```json { "jobid": "", "status": "cancelled" } "code": 200 ``` {% endtab %} {% tab post_cancel_response 400 %} 400 Bad Request ```json { "error": "Query param jobid not provided", "code": 400 } ``` {% endtab %} {% tab post_cancel_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% tab post_cancel_response 402 %} 402 Payment Required ```json { "error": "Account has no subscription or subscription expired", "code": 402 } ``` {% endtab %} {% tab post_cancel_response 404 %} 404 Not Found ```json { "error": "Unable to locate job ", "code": 404 } ``` {% endtab %} {% endtabs %} ##### Model ```typescript { // TypeScript, all fields are optional jobid: string, status: 'created' | 'started' | 'moderated' | 'progress' | 'completed' | 'failed' | 'cancelled', error: string, errorDetails: string, code: number } ``` ##### Examples {% tabs cancel_example %} {% tab cancel_example Curl %} ``` bash curl https://api.useapi.net/v2/jobs/cancel/?jobid=… \ -H "Accept: application/json" \ -H "Authorization: Bearer …" ``` {% endtab %} {% tab cancel_example JavaScript %} ``` javascript const token = "API token"; const jobid = "jobid returned by jobs/imagine or jobs/button"; const apiUrl = `https://api.useapi.net/v2/jobs/cancel/?jobid=${jobid}`; const response = await fetch(apiUrl, { headers: { "Authorization": `Bearer ${token}`, }, }); const result = await response.json(); console.log("response", {response, result}); ``` {% endtab %} {% tab cancel_example Python %} ``` python import requests token = "API token" jobid = "jobid returned by jobs/imagine or jobs/button" apiUrl = f"https://api.useapi.net/v2/jobs/cancel/?jobid={jobid}" headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } response = requests.get(apiUrl, headers=headers) print(response, response.json()) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/get-jobs-jobid === Document URL: https://useapi.net/docs/api-v2/get-jobs-jobid --- layout: default title: GET jobs/?jobid=jobid parent: Midjourney API v2 nav_order: 1900 --- ## Retrieve job status and results {: .no_toc } December 2023 (September 1, 2025) ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Use this endpoint to retrieve status and results of - [jobs/imagine](post-jobs-imagine) - [jobs/button](post-jobs-button) - [jobs/blend](post-jobs-blend) - [jobs/describe](post-jobs-describe) - [jobs/info](post-jobs-info) - [jobs/relax](post-jobs-relax) - [jobs/fast](post-jobs-fast) - [jobs/turbo](post-jobs-turbo) - [jobs/variability](post-jobs-variability) - [jobs/remix](post-jobs-remix) - [jobs/seed_async](post-jobs-seed_async) If you specified optional parameter [`replyUrl`](post-jobs-imagine#request-body) you technically do not need to use this endpoint to retrieve results since API will call provided `replyUrl` once job generation completed. **Important** The API checks Discord periodically - every 15 seconds (and up to 60 seconds in rare cold start cases) - to update the statuses and results of all currently running jobs. This polling interval is set for safety reasons to help prevent issues with Discord and Midjourney, such as bans or excessive request rates. Jobs lifespan guaranteed to be at least 31 days, after that they will be expired and may be recycled. {: .get } > **https://api.useapi.net/v2/jobs/?jobid=`jobid`** ##### Request Headers ``` yaml Authorization: Bearer {API token} ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Query Parameter `jobid` is **required**, use the value returned by the following jobs: - [jobs/imagine](post-jobs-imagine) - [jobs/button](post-jobs-button) - [jobs/blend](post-jobs-blend) - [jobs/describe](post-jobs-describe) - [jobs/seed_async](post-jobs-seed_async) You can also retrieve results for the jobs listed below, even though they will return the final result with the original call: - [jobs/info](post-jobs-info) - [jobs/relax](post-jobs-relax) - [jobs/fast](post-jobs-fast) - [jobs/turbo](post-jobs-turbo) - [jobs/variability](post-jobs-variability) - [jobs/remix](post-jobs-remix) ##### Responses {:toc} {% tabs post_job_response %} {% tab post_job_response 200 %} 200 OK If field `status` value is *created*, *started* or *progress* wait in a loop for **at least** 10..30 seconds and retry again. When completed retrieve generated image from `attachments` field. If you're planning to take advantage of Discord CDN to host attachments, take a look at our [Discord CDN Proxy](../articles/discord-cdn-proxy) article. Field `content` contains message generated by Midjourney reflecting current generation parameters and progress. Optional array `embeds` contains additional information. Optional array `imageUx` contains separate image URLs to the upscaled images where available. Optional array `imageUx` contains separate video URLs to the upscaled videos where available. To retrieve `imageUx` and `videoUx` URLs, use [GET proxy/cdn-midjourney](get-proxy-cdn-midjourney). Both URLs are behind CloudFlare, and unless you plan to display them as part of an HTML page served via a standard browser context, you will need to use the provided proxy above to download those images and videos. >⚠️ Security consideration when using `videoUx` and `imageUx` URLs: URLs in both arrays follow this format: `https://cdn.midjourney.com//…`. They contain a job GUID which can be traced back to your account and will expose your account details such as your Discord account name and email. Exercise caution when posting these URLs publicly. You may want to save the URL content locally and serve it from your own origin, or proxy the links to obfuscate the original URLs. ```json { "jobid": "job:20250822143812123-user:12345-channel:1122334455667788990-bot:midjourney", "verb": "imagine", "status": "completed", "created": "2025-08-22T14:38:12.123Z", "updated": "2025-08-22T14:40:05.889Z", "prompt": "https://modern.art/abcdef/bird.webp Tweety Bird spins kettlebell with one hand around once and hurls the kettlebell directly at the camera in a slow motion --iw 2 --ar 3:2 --motion low --video", "replyRef": "2025-08-22T14:38:10.456Z", "replyUrl": "https://webhook.site/b4d8e1a0-5c6f-4a3b-9e1d-f8c7b6a5d4e3", "channel": "1122334455667788990", "maxJobs": 3, "discord": "NDE...secured...ABC", "messageId": "1522889900112233445", "content": "** https://fluxpro.ai/abcdef/bird.webp Tweety Bird spins kettlebell with one hand around once and hurls the kettlebell directly at the camera in a slow motion --iw 2 --ar 3:2 --motion low --video 1** - <@987654321098765432> [(Open on website for full quality)]() (fast)", "timestamp": "2025-08-22T14:39:55.777000+00:00", "attachments": [ { "proxy_url": "https://media.discordapp.net/attachments/….webp?ex=…&is=…&hm=…&", "height": 768, "content_type": "image/webp", "placeholder": "…", "placeholder_version": 1, "filename": "….webp", "size": 3105492, "url": "https://cdn.discordapp.com/attachments/….webp?ex=…&is=…&hm=…&", "width": 512, "flags": 32, "content_scan_version": 2, "id": "1522889900112233445" } ], "buttons": [ "U1", "U2", "U3", "U4", "🔄" ], "videoUx": [ { "id": 1, "url": "https://cdn.midjourney.com/video/b4d8e1a0-5c6f-4a3b-9e1d-f8c7b6a5d4e3/0.mp4" }, { "id": 2, "url": "https://cdn.midjourney.com/video/b4d8e1a0-5c6f-4a3b-9e1d-f8c7b6a5d4e3/1.mp4" }, { "id": 3, "url": "https://cdn.midjourney.com/video/b4d8e1a0-5c6f-4a3b-9e1d-f8c7b6a5d4e3/2.mp4" }, { "id": 4, "url": "https://cdn.midjourney.com/video/b4d8e1a0-5c6f-4a3b-9e1d-f8c7b6a5d4e3/3.mp4" } ], "code": 200 } ``` {% endtab %} {% tab post_job_response 400 %} 400 Bad Request ```json { "error": "Query param jobid not provided", "code": 400 } ``` {% endtab %} {% tab post_job_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% tab post_job_response 402 %} 402 Payment Required ```json { "error": "Account has no subscription or subscription expired", "code": 402 } ``` {% endtab %} {% tab post_job_response 404 %} 404 Not Found ```json { "error": "Unable to locate job ", "code": 404 } ``` {% endtab %} {% tab post_job_response 410 %} 410 Gone ```json { "error": "Job has expired", "code": 410 } ``` {% endtab %} {% endtabs %} ##### Model To learn more about `status: moderated`, see [Midjourney moderation system](../articles/discord-api-part-2#midjourney-moderation-system). ```typescript { // TypeScript, all fields are optional jobid: string, parentJobId: string, verb: 'imagine' | 'button' | 'blend' | 'describe' | 'info' | 'relax' | 'fast' | 'turbo' | 'variability' | 'remix' | 'seed' | 'seed_async', status: 'created' | 'started' | 'moderated' | 'progress' | 'completed' | 'failed' | 'cancelled', seed: { value: number, // Parsed seed number content: string, // Original content message returned by Midjourney for a seed request attachments: { // Seed images id: string, content_type: string, filename: string, url: string, proxy_url: string, size: number, width: number, height: number }[] }, created: string, // YYYY-MM-DDTHH:mm:ss.sssZ, IS0 8601, UTC updated: string, // YYYY-MM-DDTHH:mm:ss.sssZ, IS0 8601, UTC prompt: string, blendUrls: string[], blendDimensions: 'Portrait' | 'Square' | 'Landscape', describeUrl: string, button: 'U1' | 'U2' | 'U3' | 'U4' | 'V1' | 'V2' | 'V3' | 'V4' | '⬅️' | '➡️' | '⬆️' | '⬇️' | '🔄' | 'Vary (Region)' | 'Vary (Strong)' | 'Vary (Subtle)' | 'Zoom Out 1.5x' | 'Zoom Out 2x' | 'Make Square' | 'Upscale (2x)' | 'Upscale (4x)' | 'Upscale (Subtle)' | 'Upscale (Creative)' | 'Redo Upscale (2x)' | 'Redo Upscale (4x)' | 'Redo Upscale (Subtle)' | 'Redo Upscale (Creative)' | 'Make Variations' | 'Remaster' | 'Custom Zoom' | 'Animate (Low motion)' | 'Animate (High motion)' | // Added July 28, 2025 'Extend (Low motion)' | 'Extend (High motion)', // Added July 28, 2025 children: { messageId: string, button: 'U1' | 'U2' | 'U3' | 'U4' | 'V1' | 'V2' | 'V3' | 'V4' | '⬅️' | '➡️' | '⬆️' | '⬇️' | '🔄' | 'Vary (Region)'| 'Vary (Strong)' | 'Vary (Subtle)' | 'Zoom Out 1.5x' | 'Zoom Out 2x' | 'Make Square' | 'Upscale (2x)' | 'Upscale (4x)' | 'Upscale (Subtle)' | 'Upscale (Creative)' | 'Redo Upscale (2x)' | 'Redo Upscale (4x)' | 'Redo Upscale (Subtle)' | 'Redo Upscale (Creative)' | 'Make Variations' | 'Remaster' | 'Custom Zoom' | 'Animate (Low motion)' | 'Animate (High motion)' | // Added July 28, 2025 'Extend (Low motion)' | 'Extend (High motion)', // Added July 28, 2025 jobid: string }[], buttons: [ 'U1' | 'U2' | 'U3' | 'U4' | 'V1' | 'V2' | 'V3' | 'V4' | '⬅️' | '➡️' | '⬆️' | '⬇️' | '🔄' | 'Vary (Region)'| 'Vary (Strong)' | 'Vary (Subtle)' | 'Zoom Out 1.5x' | 'Zoom Out 2x' | 'Make Square' 'Upscale (2x)' | 'Upscale (4x)' | 'Upscale (Subtle)' | 'Upscale (Creative)' | 'Redo Upscale (2x)' | 'Redo Upscale (4x)' | 'Redo Upscale (Subtle)' | 'Redo Upscale (Creative)' | 'Make Variations' | 'Remaster' | 'Custom Zoom' | 'Animate (Low motion)' | 'Animate (High motion)' | // Added July 28, 2025 'Extend (Low motion)' | 'Extend (High motion)', // Added July 28, 2025 ], imageUx: { id: number, url: string }[], // Added September 1, 2025. Upscaled image URLs for Ux buttons videoUx: { id: number, url: string }[], // Added September 1, 2025. Upscaled video URLs for Ux buttons when --video is used discord: string, // Provided for debugging purposes only, contains the first 3 and the last 3 characters of the original value channel: string, maxJobs: number, messageId: string, content: string, // Contains message generated by Midjourney reflecting current generation parameters and progress timestamp: string, attachments: { id: string, content_type: string, filename: string, url: string, proxy_url: string, size: number, width: number, height: number }[], embeds: { type: string, description: string, image: { url: string, proxy_url: string, width: number, height: number } }[], error: string, errorDetails: string, replyUrl: string, replyRef: string, code: 200 } ``` ##### Examples {% tabs job_example %} {% tab job_example Curl %} ``` bash curl https://api.useapi.net/v2/jobs/?jobid=… \ -H "Accept: application/json" \ -H "Authorization: Bearer …" ``` {% endtab %} {% tab job_example JavaScript %} ``` javascript const token = "API token"; const jobid = "jobid returned by jobs/imagine or jobs/button"; const apiUrl = `https://api.useapi.net/v2/jobs/?jobid=${jobid}`; const response = await fetch(apiUrl, { headers: { "Authorization": `Bearer ${token}`, }, }); const result = await response.json(); console.log("response", {response, result}); ``` {% endtab %} {% tab job_example Python %} ``` python import requests token = "API token" jobid = "jobid returned by jobs/imagine or jobs/button" apiUrl = f"https://api.useapi.net/v2/jobs/?jobid={jobid}" headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } response = requests.get(apiUrl, headers=headers) print(response, response.json()) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/get-jobs === Document URL: https://useapi.net/docs/api-v2/get-jobs --- layout: default title: GET jobs parent: Midjourney API v2 nav_order: 2200 --- ## Get list of currently executing Midjourney jobs {: .no_toc } December 2023 ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- {: .get } > **https://api.useapi.net/v2/jobs** ##### Request Headers ``` yaml Authorization: Bearer {API token} ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Responses {:toc} {% tabs post_jobs_response %} {% tab post_jobs_response 200 %} 200 OK ```json [ "", "", "" ] ``` {% endtab %} {% tab post_jobs_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% tab post_jobs_response 402 %} 402 Payment Required ```json { "error": "Account has no subscription or subscription expired", "code": 402 } ``` {% endtab %} {% endtabs %} ##### Model ```typescript // TypeScript string[] ``` ##### Examples {% tabs jobs_example %} {% tab jobs_example Curl %} ``` bash curl https://api.useapi.net/v2/jobs \ -H "Accept: application/json" \ -H "Authorization: Bearer …" ``` {% endtab %} {% tab jobs_example JavaScript %} ``` javascript const token = "API token"; const apiUrl = `https://api.useapi.net/v2/jobs`; const response = await fetch(apiUrl, { headers: { "Authorization": `Bearer ${token}`, }, }); const result = await response.json(); console.log("response", {response, result}); ``` {% endtab %} {% tab jobs_example Python %} ``` python import requests token = "API token" apiUrl = f"https://api.useapi.net/v2/jobs" headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } response = requests.get(apiUrl, headers=headers) print(response, response.json()) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/get-proxy-cdn-midjourney === Document URL: https://useapi.net/docs/api-v2/get-proxy-cdn-midjourney --- layout: default title: GET proxy/cdn-midjourney parent: Midjourney API v2 nav_order: 2300 --- ## Proxy asset retrieval from https://cdn.midjourney.com {: .no_toc } September 12, 2025 ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- This endpoint allows you to fetch images and videos from `https://cdn.midjourney.com/` through the useapi.net proxy. Use it to retrieve `imageUx` and `videoUx` URLs returned by [GET jobs/?jobid=`jobid`](../api-v2/get-jobs-jobid) or any other assets hosted on `https://cdn.midjourney.com/`. The Midjourney CDN requires standard browser headers—specifically the `User-Agent` header—to serve assets. Without it, Cloudflare will block the request. This proxy endpoint adds these headers automatically. ##### Alternative: Direct CDN Access You can skip the proxy and fetch assets directly from `https://cdn.midjourney.com/` by including the necessary headers: {% tabs direct_cdn_access %} {% tab direct_cdn_access Curl %} ``` bash curl "https://cdn.midjourney.com/example-image.jpg" \ -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" \ -H "Accept: */*" \ -H "Accept-Encoding: gzip, deflate, br" \ -H "Connection: keep-alive" \ --output image.jpg ``` {% endtab %} {% tab direct_cdn_access JavaScript %} ``` javascript const cdnUrl = "https://cdn.midjourney.com/example-image.jpg"; const headers = new Headers(); headers.set('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'); headers.set('Accept', '*/*'); headers.set('Accept-Encoding', 'gzip, deflate, br'); headers.set('Connection', 'keep-alive'); const response = await fetch(cdnUrl, { headers }); const blob = await response.blob(); // Save to file (Node.js) const fs = require('fs'); const buffer = await blob.arrayBuffer(); fs.writeFileSync('image.jpg', Buffer.from(buffer)); ``` {% endtab %} {% tab direct_cdn_access Python %} ``` python import requests cdnUrl = "https://cdn.midjourney.com/example-image.jpg" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36', 'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive' } response = requests.get(cdnUrl, headers=headers) # Save image/video content with open('image.jpg', 'wb') as f: f.write(response.content) ``` {% endtab %} {% endtabs %} **Note:** The `User-Agent` header is critical—without it, Cloudflare will block your request. --- {: .get } > **https://api.useapi.net/v1/proxy/cdn-midjourney/?cdnUrl=`https://cdn.midjourney.com/…`** ##### Request Headers ``` yaml Authorization: Bearer {API token} ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Query Parameter - `cdnUrl` is **required** and must be a valid asset URL starting with `https://cdn.midjourney.com/` ##### Responses {% tabs proxy_cdn_midjourney_response %} {% tab proxy_cdn_midjourney_response 200 %} 200 OK Returns the proxied content from the Midjourney CDN with appropriate headers. {% endtab %} {% tab proxy_cdn_midjourney_response 400 %} 400 Bad Request ```json { "error": "", "code": 400 } ``` {% endtab %} {% tab proxy_cdn_midjourney_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% tab proxy_cdn_midjourney_response 403 %} 403 Forbidden Cloudflare may occasionally block requests even with proper headers. This is typically temporary and can be resolved with retry logic. **Recommendation:** Implement retry logic with exponential backoff when encountering 403 errors, or better yet, implement your own direct CDN access using the headers shown in the "Alternative: Direct CDN Access" section above for greater control and reliability. {% endtab %} {% endtabs %} ##### Examples {% tabs get_proxy_cdn_midjourney_example %} {% tab get_proxy_cdn_midjourney_example Curl %} ``` bash curl -H "Authorization: Bearer …" \ "https://api.useapi.net/v1/proxy/cdn-midjourney/?cdnUrl=https://cdn.midjourney.com/example-image.jpg" ``` {% endtab %} {% tab get_proxy_cdn_midjourney_example JavaScript %} ``` javascript const cdnUrl = "https://cdn.midjourney.com/example-image.jpg"; const apiUrl = `https://api.useapi.net/v1/proxy/cdn-midjourney/`; const api_token = "API token"; const response = await fetch(`${apiUrl}?cdnUrl=${encodeURIComponent(cdnUrl)}`, { method: 'GET', headers: { 'Authorization': `Bearer ${api_token}` } }); const result = await response.blob(); // For image/video content console.log("response", {response, result}); ``` {% endtab %} {% tab get_proxy_cdn_midjourney_example Python %} ``` python import requests cdnUrl = "https://cdn.midjourney.com/example-image.jpg" apiUrl = f"https://api.useapi.net/v1/proxy/cdn-midjourney/" api_token = "API token" headers = { "Authorization": f"Bearer {api_token}" } params = { "cdnUrl": cdnUrl } response = requests.get(apiUrl, headers=headers, params=params) print(response.status_code, response.headers) # Save image/video content with open('image.jpg', 'wb') as f: f.write(response.content) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/post-account-midjourney-channel-reset === Document URL: https://useapi.net/docs/api-v2/post-account-midjourney-channel-reset --- layout: default title: POST …/channel/reset parent: Midjourney API v2 nav_order: 700 --- ## Reset `pendingModMessage` field for Midjourney account `channel` {: .no_toc } December 2023 ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- If the API detects a pending moderation message or a CAPTCHA account verification request from Midjourney, it will flag the corresponding account by setting the `pendingModMessage` field to the message provided by Midjourney. This will effectively remove that account from the rotation. Any attempts to make API calls using this account will result in a 596 response code, indicating that the account is under moderation and cannot be used for API interactions. The best course of action is to log into your Discord account and address the Midjourney moderation message to avoid a potential ban on your Midjourney account. Once you have acknowledged the message, you can use this endpoint to reset the Midjourney account and return it to the rotation. If a CAPTCHA account verification request was issued by MidJourney, you may need to manually execute `/imagine` to display the dialog with verification links. Please note that the API will also send you an email notification when a Midjourney pending moderation message or CAPTCHA account verification request is detected. {: .post } > **https://api.useapi.net/v2/account/midjourney/`channel`/reset** The `channel` value should correspond to an account configured previously via a [POST](post-account-midjourney-reset-channel) request. ##### Request Headers ``` yaml Authorization: Bearer {API token} ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Responses {% tabs post_account_midjourney_reset_response %} {% tab post_account_midjourney_reset_response 204 %} 204 No Content {% endtab %} {% tab post_account_midjourney_reset_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% tab post_account_midjourney_reset_response 404 %} 404 Not Found {% endtab %} {% endtabs %} ##### Model ```typescript { // TypeScript, all fields are optional error: string, errorDetails: string, code: number } ``` ##### Examples {% tabs post_account_midjourney_reset_example %} {% tab post_account_midjourney_reset_example Curl %} ``` bash curl -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer …" \ -X POST https://api.useapi.net/v2/account/midjourney//reset ``` {% endtab %} {% tab post_account_midjourney_reset_example JavaScript %} ``` javascript const channel = "Previously configured channel id with pendingModMessage"; const apiUrl = `https://api.useapi.net/v2/account/midjourney/${channel}/reset`; const token = "API token"; const data = { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }; const response = await fetch(apiUrl, data); const result = await response.json(); console.log("response", {response, result}); ``` {% endtab %} {% tab post_account_midjourney_reset_example Python %} ``` python import requests channel = "Previously configured channel id with pendingModMessage" apiUrl = f"https://api.useapi.net/v2/account/midjourney/{channel}" token = "API token" headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } response = requests.post(apiUrl, headers=headers) print(response, response.json()) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/post-account-midjourney-channel === Document URL: https://useapi.net/docs/api-v2/post-account-midjourney-channel --- layout: default title: POST …/midjourney/channel parent: Midjourney API v2 nav_order: 500 nav_exclude: true --- ## Create or update Midjourney account information (retired) {: .no_toc } December 2023 (August 5, 2025) ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Important **We will be officially sunsetting this endpoint in January 2025. Please use [POST account/midjourney](post-account-midjourney) instead.** For your convenience, you can specify your Midjourney configuration values under your account so that you no longer need to provide them with every API call. If you specify multiple Midjourney accounts, the API will automatically perform load balancing by randomly selecting an account with available capacity before making calls to Discord / Midjourney. {: .post } > **https://api.useapi.net/v2/account/midjourney/`channel`** ##### Request Headers ``` yaml Authorization: Bearer {API token} ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Request Body ```json { "discord": "Discord token", "channel": "Discord channel id", "maxJobs": 1-15, } ``` - `discord`, `channel` are **required**. Please see [Setup Midjourney](../start-here/setup-midjourney) for details. - `channel` value specified in the request body **must match** the channel value specified in the URL path https://api.useapi.net/v2/account/midjourney/`channel`. - `maxJobs` is **required**. This value should be the same or less than your Midjourney subscription plan [Maximum Concurrent Jobs](https://docs.midjourney.com/docs/plans#plan-comparison). Currently, it should be 3 or less for Basic and Standard plans and 15 or less for Pro and Mega plans. **Important** Specifying a higher number than supported by your Midjourney subscription will prevent API from functioning properly. ##### Responses {% tabs post_account_midjourney_channel_response %} {% tab post_account_midjourney_channel_response 204 %} 204 No Content {% endtab %} {% tab post_account_midjourney_channel_response 400 %} 400 Bad Request ```json { "error": "Required param discord is missing or empty" "Required param channel is missing or empty" "Required param channel () is not valid Discord channel id" "Required param channel () not matching to /midjourney/channel (/midjourney/)" "Required param maxJobs is missing or empty" "Required param maxJobs can't be more that " "Channel configuration has same discord value" "code": 400 } ``` {% endtab %} {% tab post_account_midjourney_channel_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% endtabs %} ##### Model ```typescript { // TypeScript, all fields are optional discord: string, channel: string, maxJobs: number, error: string, errorDetails: string, code: number } ``` ##### Examples {% tabs post_account_midjourney_channel_example %} {% tab post_account_midjourney_channel_example Curl %} ``` bash curl -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer …" \ -X POST https://api.useapi.net/v2/account/midjourney/ \ -d '{"discord": "…", "channel": "…", "maxJobs": …}' ``` {% endtab %} {% tab post_account_midjourney_channel_example JavaScript %} ``` javascript const channel = "Discord channel id"; const apiUrl = `https://api.useapi.net/v2/account/midjourney/${channel}`; const token = "API token"; const discord = "Discord token"; const maxJobs = 3; const data = { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }; data.body = JSON.stringify({ discord, channel, maxJobs }); const response = await fetch(apiUrl, data); const result = await response.json(); console.log("response", {response, result}); ``` {% endtab %} {% tab post_account_midjourney_channel_example Python %} ``` python import requests channel = "Discord channel id" apiUrl = f"https://api.useapi.net/v2/account/midjourney/{channel}" token = "API token" discord = "Discord token" maxJobs = 3 headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } body = { "discord": f"{discord}", "channel": f"{channel}", "maxJobs": maxJobs } response = requests.post(apiUrl, headers=headers, json=body) print(response, response.json()) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/post-account-midjourney === Document URL: https://useapi.net/docs/api-v2/post-account-midjourney --- layout: default title: POST account/midjourney parent: Midjourney API v2 nav_order: 350 --- ## Create or update Midjourney account information {: .no_toc } December 2023 (August 5, 2025) ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- You must configure a Midjourney API account before making calls using the Midjourney API. If you specify multiple Midjourney accounts, the API will automatically perform load balancing by randomly selecting an account with available capacity before making calls to Discord / Midjourney. {: .post } > **https://api.useapi.net/v2/account/midjourney** ##### Request Headers ``` yaml Authorization: Bearer {API token} ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Request Body ```json { "discord": "Discord token", "maxJobs": 1-15, } ``` - `discord` is **required**. Please see [Setup Midjourney](../start-here/setup-midjourney) for details. - `maxJobs` is optional and will be set to 3 if not provided. This value should be equal to or less than the Maximum Concurrent Jobs allowed by your Midjourney subscription plan ([see plan comparison](https://docs.midjourney.com/docs/plans#plan-comparison)). Currently, it should be 3 or less for Basic and Standard plans, and 15 or less for Pro and Mega plans. **Important:** Specifying a higher number than supported by your Midjourney subscription will prevent the API from functioning properly. ##### Responses {% tabs post_account_midjourney_response %} {% tab post_account_midjourney_response 200 %} 200 OK Existing Midjourney API account was updated. ```json { "discord": "", "channel": "", "maxJobs": 1-15 } ``` {% endtab %} {% tab post_account_midjourney_response 201 %} 201 Created New Midjourney API account was created. ```json { "discord": "", "channel": "", "maxJobs": 1-15 } ``` {% endtab %} {% tab post_account_midjourney_response 400 %} 400 Bad Request ```json { "error": "Required param discord is missing or empty" "Required param maxJobs can't be more that " "Channel configuration has same discord value" "`Midjourney bot not configured" "code": 400 } ``` {% endtab %} {% tab post_account_midjourney_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% tab post_account_midjourney_response 402 %} 402 Payment Required ```json { "error": "Account has no subscription or subscription expired" "Subscription quantity exceeded, see https://useapi.net/docs/subscription", "code": 402 } ``` {% endtab %} {% endtabs %} ##### Model ```typescript { // TypeScript, all fields are optional discord: string, channel: string, maxJobs: number, error: string, errorDetails: string, code: number } ``` ##### Examples {% tabs post_account_midjourney_example %} {% tab post_account_midjourney_example Curl %} ``` bash curl -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer …" \ -X POST https://api.useapi.net/v2/account/midjourney \ -d '{"discord": "…", "maxJobs": …}' ``` {% endtab %} {% tab post_account_midjourney_example JavaScript %} ``` javascript const apiUrl = `https://api.useapi.net/v2/account/midjourney`; const token = "API token"; const discord = "Discord token"; const maxJobs = 3; const data = { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }; data.body = JSON.stringify({ discord, maxJobs }); const response = await fetch(apiUrl, data); const result = await response.json(); console.log("response", {response, result}); ``` {% endtab %} {% tab post_account_midjourney_example Python %} ``` python import requests apiUrl = f"https://api.useapi.net/v2/account/midjourney" token = "API token" discord = "Discord token" maxJobs = 3 headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } body = { "discord": f"{discord}", "maxJobs": maxJobs } response = requests.post(apiUrl, headers=headers, json=body) print(response, response.json()) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/post-jobs-blend === Document URL: https://useapi.net/docs/api-v2/post-jobs-blend --- layout: default title: POST jobs/blend parent: Midjourney API v2 nav_order: 1000 --- ## Midjourney [/blend](https://docs.midjourney.com/docs/blend) command {: .no_toc } December 2023 (August 15, 2025) ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Use this endpoint to submit the Midjourney [/blend](https://docs.midjourney.com/docs/blend) command to your [Discord Midjourney channel](../start-here/setup-midjourney#locate-midjourney-direct-messages-channel). Results obtained as a callback via optional parameter [`replyUrl`](#request-body) or by querying [jobs/?jobid=jobid](../api-v2/get-jobs-jobid) endpoint. Your current [Midjourney Settings and Presets](https://docs.midjourney.com/docs/settings-and-presets) will be used, log in to your Discord Midjourney account to adjust them to your liking. It is **important** not to use the Midjourney account setup for API access for any purposes other than its intended use, such as executing `/imagine` or any other Midjourney commands _manually_ or in conjunction with _any other_ automation tools. The useapi.net API internally tracks the usage of the Midjourney account, including the number of currently active executions. Using it for other activities may cause API to function incorrectly. {: .post } > **https://api.useapi.net/v2/jobs/blend** ##### Request Headers ``` yaml Authorization: Bearer {API token} Content-Type: application/json ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Request Body ```json { "blendUrls": ["URL #1", "URL #2", "URL #3", "URL #4", "URL #5"], "blendDimensions": "Portrait, Square or Landscape", "channel": "Discord channel id", "maxJobs": 3, "replyUrl": "Place your call back URL here", "replyRef": "Place your reference id here" } ``` - `blendUrls` is **required**, must contain at least 2 valid URL image links. Up to 5 URL image links supported. - `blendDimensions` is optional, can be `Portrait`, `Square` or `Landscape` - `channel` is optional, if not provided randomly selected available account from [account/midjourney](../api-v2/get-account-midjourney) will be used. See [Setup Midjourney](../start-here/setup-midjourney) for details. Specify the `channel` value when you wish to use a specific account from the configured list at [account/midjourney](../api-v2/get-account-midjourney). - `maxJobs` is optional, if not provided value for `channel` account selected above will be used, if not provided defaulted to 3. This value should be the same or less than your Midjourney subscription plan [Maximum Concurrent Jobs](https://docs.midjourney.com/docs/plans#plan-comparison). Currently, it should be 3 or less for Basic and Standard plans and 15 or less for Pro and Mega plans. **Important** Specifying a higher number than supported by your Midjourney subscription will prevent API from functioning properly. - `replyUrl` is optional, if not provided value from [useapi.net account](../account-management/get-account) will be used. Place here your callback URL. API will call the provided `replyUrl` once job completed or failed. Maximum length 1024 characters. We recommend using sites like [webhook.site](https://webhook.site) to test callback URL functionality. - `replyRef` is optional, place here your reference id which will be stored and returned along with this job response / result. Maximum length 1024 characters. ##### Responses {% tabs post_blend_response %} {% tab post_blend_response 200 %} 200 OK Use returned `jobid` to [retrieve job status and results](../api-v2/get-jobs-jobid). `content` contains message generated by Midjourney reflecting current generation parameters and progress. If you want to retrieve four separate upscaled images once job completed successfully execute [seed](https://useapi.net/docs/api-v2/post-jobs-seed). ```json { "jobid": "", "verb": "blend", "status": "started", "created": "2023-10-06T18:36:37.963Z", "updated": "2023-10-06T18:36:50.401Z", "blendUrls": [ "https://...1.png", "https://...2.jpg" ], "blendDimensions": "Landscape", "discord": "", "channel": "", "maxJobs": 3, "replyUrl": "https://webhook.site/abc", "replyRef": "", "messageId": "", "content": "** --s 750 --v 5.2** - <@Discord user id> (Waiting to start)", "timestamp": "2023-10-06T18:36:48.875000+00:00", "code": 200 } ``` {% endtab %} {% tab post_blend_response 400 %} 400 Bad Request ```json { "error": "blendUrls is missing" "blendUrls should contain at least 2 urls" "blendUrls should contain no more than 5 urls" "blendUrls # contains empty value" "blendDimensions should be one of Portrait, Square, Landscape" "GET failed with HTTP status . Response body " " unknown mime type" " is too long" "code": 412 } ``` {% endtab %} {% tab post_blend_response 401 %} 401 Unauthorized ```json { "error": "Unauthorized", "code": 401 } ``` {% endtab %} {% tab post_blend_response 402 %} 402 Payment Required ```json { "error": "Account has no subscription or subscription expired", "code": 402 } ``` {% endtab %} {% tab post_blend_response 422 %} 422 Unprocessable Content Moderated image link, see [Midjourney moderation system](../articles/discord-api-part-2#midjourney-moderation-system). ```json { "error": "Invalid link", "errorDetails": "Request cancelled due to image filters.", "jobid": "", "status": "moderated", "code": 422 } ``` {% endtab %} {% tab post_blend_response 429 %} 429 Too Many Requests Wait in a loop for **at least** 10..30 seconds and retry again. There are two possible cases for API response 429. 1. The API query is full and can not accept new [jobs/blend](#midjourney-blend-command) requests. Size of query defined by [`maxJobs` optional parameter](#request-body). ```json { "error": "Maximum of jobs executing in parallel supported", "executingJobs": [ "", "", "" ], "code": 429 } ``` 2. The API received an HTTP status 429 from the Discord API when it attempted to POST to the `/interactions` endpoint. Under normal circumstances, this should be a rare occurrence because the API is designed to strictly adhere to Discord rate limits. However, in certain scenarios, Discord may still issue a 429 response. ```json { "error": "Discord /interactions failed with HTTP status 429", "errorDetails": "{\"global\":true,\"message\":\"You are being rate limited.\",\"retry_after\":10}", "code": 429 } ``` {% endtab %} {% tab post_blend_response 502 %} 502 Bad Gateway Response code `502` means the Midjourney Discord bot did not reply within the allotted time limit. This usually happens when the [Discord Gateway API](https://discord.com/developers/docs/events/gateway) or the [Midjourney Discord bot](https://discord.com/discovery/applications/936929561302675456) is having issues. You can check Discord [status](https://discordstatus.com) and Midjourney Discord server status [channel](https://discord.com/channels/662267976984297473/942231458918064148). Keep in mind that both links above most often will not reflect an event that has just started. {% endtab %} {% tab post_blend_response 504 %} 504 Job queued Job queued. The API will not be able to track the progress of this job, although it will still be processed by Midjourney. You may want to adjust the `maxJobs` number to a lower value for the next several minutes. You should not receive this error under normal circumstances unless you have specified a `maxJobs` parameter higher than your Midjourney subscription supports, or if you are using the Midjourney bot outside of API interactions. On occasions when Midjourney is releasing new updates or experiencing technical issues, jobs may be paused for an extended period of time. Our API will mark all jobs running over 30 minutes as `failed`. When Midjourney comes back online, it will attempt to complete previously paused jobs, and you may encounter a conflict if you try to submit a new job at the same time. Although this happens very rarely, we have decided to add an extra layer to ensure such cases are detected. ```json { "error": "Job queued", "jobid": "", "status": "failed", "code": 504 } ``` {% endtab %} {% tab post_blend_response 596 %} 596 Pending mod message API detected Midjourney pending moderation message and CAPTCHA account verification requests. All API calls will be halted and returned 569 response status code until you clear this field by posting to [account/midjourney/`channel`/reset](../api-v2/post-account-midjourney-channel-reset). We will also send you an email when this error ocurred. The best course of action is to log into your Discord account and acknowledge the Midjourney moderation message to prevent a potential ban on your Midjourney account. ```json { "jobid": "", "verb": "blend", "status": "failed", "created": "2023-09-09T02:04:49.667Z", "updated": "2023-09-09T02:04:53.490Z", "blendUrls": [ "https://...1.png", "https://...2.jpg" ], "discord": "", "channel": "", "maxJobs": 3, "replyUrl": "https://webhook.site/abc", "replyRef": "", "messageId": "", "timestamp": "2023-09-09T02:04:51.926000+00:00", "error": "Pending mod message", "errorDetails": "You have a pending moderation message. Please acknowledge it before using the bot further.", "code": 596 } ``` ```json { "error": "Your Discord account has received a pending moderation message from Midjourney. Please address this issue and POST account/midjourney//reset before making any new API calls.", "code": 596 } ``` {% endtab %} {% endtabs %} ##### Model ```typescript { // TypeScript, all fields are optional jobid: string, // Use returned jobid value to retrieve job status and results verb: 'blend', status: 'started' | 'moderated' | 'failed', created: string, // YYYY-MM-DDTHH:mm:ss.sssZ, IS0 8601, UTC updated: string, // YYYY-MM-DDTHH:mm:ss.sssZ, IS0 8601, UTC blendUrls: string[], blendDimensions: 'Portrait' | 'Square' | 'Landscape', discord: string, // Provided for debugging purposes only, contains the first 3 and the last 3 characters of the original value channel: string, maxJobs: number, replyUrl: string, replyRef: string, messageId: string, content: string, // Contains message generated by Midjourney reflecting current generation parameters and progress timestamp: string, error: string, errorDetails: string, executingJobs: string[], code: number } ``` ##### Examples {% tabs blend_example %} {% tab blend_example Curl %} ``` bash curl -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer …" \ -X POST https://api.useapi.net/v2/jobs/blend \ -d '{"blendUrls": ["…", "…"], "channel": "…"}' ``` {% endtab %} {% tab blend_example JavaScript %} ``` javascript const apiUrl = "https://api.useapi.net/v2/jobs/blend"; const token = "API token"; const channel = "Discord channel id"; const data = { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }; const blendUrls = ["https://url.1", "https://url.2"]; data.body = JSON.stringify({ blendUrls, channel }); const response = await fetch(apiUrl, data); const result = await response.json(); console.log("response", {response, result}); ``` {% endtab %} {% tab blend_example Python %} ``` python import requests apiUrl = "https://api.useapi.net/v2/jobs/blend" token = "API token" channel = "Discord channel id" blendUrls = ["https://url.1", "https://url.2"] headers = { "Content-Type": "application/json", "Authorization" : f"Bearer {token}" } body = { "blendUrls": blendUrls, "channel": f"{channel}" } response = requests.post(apiUrl, headers=headers, json=body) print(response, response.json()) ``` {% endtab %} {% endtabs %} === URL: https://useapi.net/docs/api-v2/post-jobs-button === Document URL: https://useapi.net/docs/api-v2/post-jobs-button --- layout: default title: POST jobs/button parent: Midjourney API v2 nav_order: 900 --- ## Midjourney [upscale or create variations](https://docs.midjourney.com/docs/quick-start#8-upscale-or-create-variations) and [enhance or modify](https://docs.midjourney.com/docs/quick-start#9-enhance-or-modify-your-image) buttons {: .no_toc } December 2023 (August 15, 2025) ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- Use this endpoint to execute Midjourney [upscale or create variations](https://docs.midjourney.com/docs/quick-start#8-upscale-or-create-variations) and [enhance or modify](https://docs.midjourney.com/docs/quick-start#9-enhance-or-modify-your-image) button commands. Results obtained as a callback via optional parameter [`replyUrl`](#request-body) or by querying [jobs/?jobid=jobid](../api-v2/get-jobs-jobid) endpoint. We provide full support for **video generation**, including the buttons `Animate (High motion)`, `Animate (Low motion)`, `Extend (High motion)`, and `Extend (Low motion)`. Please refer to the [official documentation](https://docs.midjourney.com/hc/en-us/articles/37460773864589-Video) for details. Your current [Midjourney Settings and Presets](https://docs.midjourney.com/docs/settings-and-presets) will be used, log in to your Discord Midjourney account to adjust them to your liking. It is **important** not to use the Midjourney account setup for API access for any purposes other than its intended use, such as executing `/imagine` or any other Midjourney commands _manually_ or in conjunction with _any other_ automation tools. The useapi.net API internally tracks the usage of the Midjourney account, including the number of currently active executions. Using it for other activities may cause API to function incorrectly. {: .post } > **https://api.useapi.net/v2/jobs/button** ##### Request Headers ``` yaml Authorization: Bearer {API token} Content-Type: application/json ``` - `API token` is **required**, see [Setup useapi.net](../start-here/setup-useapi) for details. ##### Request Body ```json { "jobid": "jobid", "button": "button", "prompt": "required for button Custom Zoom", "maxJobs": 3, "replyUrl": "Place your call back URL here", "replyRef": "Place your reference id here" } ``` - `jobid` is **required**, `jobid` of successfully completed (`status` set to [*completed*](../api-v2/get-jobs-jobid#model)) [jobs/imagine](../api-v2/post-jobs-imagine), [jobs/button](#midjourney-upscale-or-create-variations-and-enhance-or-modify-buttons) or [jobs/blend](../api-v2/post-jobs-blend) job. - `button` is **required**, button from buttons array of job referenced via `jobid` above, see [*button*](#model). - `prompt` is optional, it is required for `Custom Zoom` button, see [Custom Zoom](https://docs.midjourney.com/docs/zoom-out#custom-zoom). When [Remix Mode](https://docs.midjourney.com/docs/remix) is active, the buttons `V1`, `V2`, `V3`, `V4`, `Vary (Region)`, `Vary (Strong)`, `Vary (Subtle)`, ⬅️, ➡️, ⬆️, ⬇️ and 🔄 also accept a prompt. - `mask` is required for `Vary (Region)` button, see [Vary Region mask editor](https://useapi.net/docs/api-v2/vary-region-mask-editor). - `maxJobs` is optional, if provided will override `maxJobs` value of referenced above `jobid`, if not provided defaulted to 3. This value should be the same or less than your Midjourney subscription plan [Maximum Concurrent Jobs](https://docs.midjourney.com/docs/plans#plan-comparison). Currently, it should be 3 or less for Basic and Standard plans and 15 or less for Pro and Mega plans. **Important** Specifying a higher number than supported by your Midjourney subscription will prevent API from functioning properly. - `replyUrl` is optional, if not provided value from [useapi.net account](../account-management/get-account) will be used. Place here your callback URL. API will call the provided `replyUrl` once job completed or failed. Maximum length 1024 characters. We recommend using sites like [webhook.site](https://webhook.site) to test callback URL functionality. - `replyRef` is optional, place here your reference id which will be stored and returned along with this job response / result. Maximum length 1024 characters. ##### Responses {% tabs post_button_response %} {% tab post_button_response 200 %} 200 OK Use returned `jobid` to [retrieve job status and results](../api-v2/get-jobs-jobid). If you want to retrieve four separate upscaled images once job completed successfully execute [seed_async](https://useapi.net/docs/api-v2/post-jobs-seed_async). ```json { "jobid": "", "verb": "button", "status": "started", "created": "2023-09-09T20:19:57.073Z", "updated": "2023-09-09T20:19:58.536Z", "button": "V1", "parentJobId": "", "discord": "", "channel": "", "maxJobs": 3, "replyUrl": "https://webhook.site/abc", "replyRef": "", "content": "", "messageId": "", "timestamp": "2023-09-09T20:19:57.926000+00:00", "code": 200 } ``` {% endtab %} {% tab post_button_response 400 %} 400 Bad Request ```json { "error": "button {% endraw %}
Source code Copy the code provided below into a `
```
=== URL: https://useapi.net/docs/questions-and-answers === Document URL: https://useapi.net/docs/questions-and-answers --- title: Q&A nav_order: 110000 layout: home --- # Questions and Answers {: .no_toc } 4 min read • September 2023 (January 14, 2026) ## Table of contents {: .no_toc .text-delta } 1. TOC {:toc} --- ### How to avoid Midjourney bans? Using automation is against Discord and Midjourney's Terms of Service, so you need to plan accordingly and have backup account(s) ready. * The best practice is to create several new Discord accounts and join the Midjourney Discord server. These accounts should be used exclusively for API work and nothing else. We strongly recommend using a VPN to prevent your personal data/IP addresses from being leaked. You can use the [Opera](https://www.opera.com/download) browser with built-in VPN or the [Brave](https://brave.com/download) browser with [Tor support](https://support.brave.com/hc/en-us/articles/360018121491-What-is-a-Private-Window-with-Tor-Connectivity). * Brand new/fresh Discord accounts have a significantly higher chance of being banned when running high Midjourney generation loads. Consider purchasing aged Discord accounts (2-3 years old) from marketplaces like [z2u.com](https://www.z2u.com/) for around $1-3 each. Aged accounts appear more legitimate and are less likely to trigger automated bans. * When creating accounts in bulk, make sure to restart Opera/Brave so that your IP is different every time, since Discord tracks and records the IP addresses used to create new accounts. Make sure to log in to the Discord accounts designated for API use through a VPN. When creating new email and Discord accounts, use names closely resembling real names - something that does not look suspicious. * Once a Discord account is created, join the Midjourney Discord [server](https://discord.com/invite/midjourney) and follow the [instructions](https://useapi.net/docs/start-here/setup-midjourney) to create your own server and invite the Midjourney bot. If you're planning to use this account, you can proceed with a Midjourney subscription. It's a good idea to create several Discord accounts with the Midjourney setup, as described above early on, this will *"age"* them and make them less suspicious later on when you need to subscribe to Midjourney. * When paying for a Midjourney subscription use a virtual credit card number (provided by most major credit card companies) or services like [Privacy.com](https://privacy.com). Make sure to use a credit card name and address that resemble an actual address and name. Use a *different name and address* for every new Midjourney subscription. Midjourney has access to all payment details and will cross-check banned accounts' payment information to ban newly created accounts if a match is found. * If your account gets banned, file a charge dispute with your credit card company. Since Midjourney cannot produce any evidence of you violating the ToS, the bank will fully refund your payment. Our customers have reported a 100% success rate of getting their money back, though it may take some time. * When using the API, try to simulate real users. Avoid running generations 24/7 by establishing quiet hours (for example, you can use two or three accounts and rotate them every 12/8 hours). Midjourney seems to specifically target accounts with a large number of `--relax` usage, so try to limit those generations to a reasonable number (<300 generations/day). If you heavily rely on `--relax`, execute at least one fast generation for every NN relax generations. * Do not post public links to Discord/Midjourney CDN attachments, they contain your Discord account number and can be used to trace back to your account. * Sharing cross-account `--p` codes is not safe. You risk all accounts using the same `--p` codes being banned by Midjourney. * Do not run multiple requests with the same or similar prompts (e.g., "My test prompt 1", "My test prompt 2", and so on). Midjourney analyzes prompts and will force your Discord account token to expire when this kind of situation is detected. You will have to reset your Discord password manually before you can continue operating. * Adjust [maxJobs](../docs/api-v2/post-account-midjourney) parameter to be one less than the maximum possible. For example, for the [Pro Plan](https://docs.midjourney.com/docs/plans) with a maximum of 12 concurrent jobs, set `maxJobs` to 11 or even 10. * If you ever receive a [504](../docs/api-v2/post-jobs-imagine#responses) response code, it means your `maxJobs` is set to a value higher than your account plan supports. Adjust it accordingly. * Finally, monitor for [596](../docs/api-v2/post-jobs-imagine#responses) response codes and ensure you check your API email. The API will proactively warn you if you have pending moderation messages or if Midjourney issues a CAPTCHA request. ### How to avoid Runway account suspension? Using automation is against Runway's Terms of Service, so you need to plan accordingly and have backup account(s) ready. * The best practice is to create several stand-by Runway accounts. These accounts should be used exclusively for API work and nothing else. We strongly recommend using a VPN to prevent your personal data/IP addresses from being leaked. You can use the [Opera](https://www.opera.com/download) browser with a built-in VPN or the [Brave](https://brave.com/download) browser with [Tor support](https://support.brave.com/hc/en-us/articles/360018121491-What-is-a-Private-Window-with-Tor-Connectivity). * When creating accounts in bulk, make sure to restart Opera/Brave so that your IP is different every time. When creating new emails and Runway accounts, use names that closely resemble real names—something that does not look suspicious. * Once a new Runway account is created, you will have a few free credits with which you can test the API. After testing, log out and leave the account alone until you are ready to activate the [Unlimited plan](https://runwayml.com/pricing) (the only subscription plan that makes sense to pay for). * When paying for a Runway subscription, use a virtual credit card number (provided by most major credit card companies) or services like [Privacy.com](https://privacy.com). Make sure to use a credit card name and address that resemble an actual name and address. Use a *different name and address* for every new Runway subscription. Runway has access to all payment details and can cross-check banned accounts' payment information to ban newly created accounts if a match is found. * If your account gets suspended, file a charge dispute with your credit card company. Since Runway cannot produce any evidence of you violating the ToS, the bank will fully refund your payment. Our customers have reported a 100% success rate of getting their money back, though it may take some time. * When using the API, try to simulate real users. Avoid running generations 24/7 by establishing quiet hours (for example, you can use two or three accounts and rotate them every 12 to 8 hours). Avoid calling API endpoints too frequently, and consider using the `replyUrl` webhook to retrieve results, as this will ensure the least intrusive operation. * Finally, monitor your API email—the one you used to subscribe to useapi.net services. The API will proactively warn you if your Runway account has any issues. ### Do you validate a user's text/image prompts to ensure they are passing AI services' safety requirements? It is common practice for AI services to ban users for violating prompt guidelines (for example, see Midjourney PG13 [requirements](https://docs.midjourney.com/docs/community-guidelines)). Our API does not perform any prompt pre-validations, it will return a [422](../docs/api-v2/post-jobs-imagine#responses) status code if the job is moderated by Midjourney, and similar checks apply for the other AI APIs we offer. Generally speaking, if you're planning to use the API for a public Telegram bot (which is one of the popular use cases) or in similar scenarios where you do not control the quality of the prompt, it might be a good idea to use a combination of a ban/stop word list along with [OpenAI ChatGPT](https://openai.com/api/pricing) or [Google Gemini](https://ai.google.dev/pricing) to check if the prompts meet safety requirements. [Gemini](https://ai.google.dev/pricing) offers a free tier with some RPM (requests per minute) limitations. We also offer LLM models, specifically `MiniMax-Text-01`, a fast instructional multimodal model that is free to use and can validate both text and images for safety. Please see [POST minimax/llm](../docs/api-minimax-v1/post-minimax-llm). ### How is your experimental Runway API different from the official Runway API? Official [Runway API](https://docs.dev.runwayml.com) currently only supports Gen-3 Alpha Turbo. The cost for Gen-3 Alpha Turbo 10-second generation is [$0.50](https://docs.dev.runwayml.com/usage/billing). Our [experimental Runway API](https://useapi.net/docs/api-runwayml-v1) is a reverse-engineered version of [runwayml.com](https://runwayml.com). It fully supports **all** features of Gen-3 Alpha, Gen-3 Alpha Turbo, Act-One, Video to Video, Super-Slow Motion, Gen-2, the LipSync feature, and [more](https://useapi.net/docs/api-runwayml-v1). When used along with the Runway [Unlimited plan](https://runwayml.com/pricing), it allows you to run several hundred generations each day. On average, you can expect the following numbers for Gen-3 Alpha Turbo 10-second generation: - 1 generation is completed within 25 seconds - 10 generations take about 4 minutes to complete - 30 generations take about 12 minutes to complete - 150 generations take about one hour to complete If you generate 200+ videos, the official API will cost you $0.50 per generation, so 200 generations cost about $100. This means the $95 [Unlimited plan](https://runwayml.com/pricing), combined with our $15/month subscription, will pay for itself by the **first day**, most often within the first few hours. We provide an API for all the features available at [runwayml.com](https://runwayml.com), including Gen-3 Alpha, Act-One, video-to-video (with extend and expand), Frames, and many more. The official Runway API only supports [Gen-3 Alpha Turbo](https://docs.dev.runwayml.com/). ### How is your experimental MiniMax API different from the official MiniMax API? Official [MiniMax API](https://intl.minimaxi.com/document/video_generation) costs $0.43…$0.65 [link](https://www.minimaxi.com/en/price) per single 6-second-long generation. Our [experimental MiniMax API](https://useapi.net/docs/api-minimax-v1) is a reverse-engineered version of the MiniMax/HailuoAI websites. It does not cost you anything to generate as many videos as you wish, thanks to a flat monthly [subscription](https://useapi.net/docs/subscription) fee. You can link as many [paid](https://hailuoai.video/subscribe) or free MiniMax/HailuoAI accounts to our API as you wish. With [Unlimited](https://hailuoai.video/subscribe) Hailuo AI plan or [Standard](https://hailuoai.video/subscribe) plan for first day, you can expect the following numbers: - 1 generation completed within 2 minutes - 10 generations take about 20 minutes to complete - 30 generations take about an hour to complete If you generate 250+ videos, the official API will cost you $0.43 per generation, so 250 generations total about $107.50. This means the $95 [Unlimited](https://hailuoai.video/subscribe) plan, combined with our $15/month subscription, will pay for itself by the **first day**. When using free [hailuoai.video](https://hailuoai.video) account, it costs one credit to generate a single image, and you can generate up to four images at once. With a daily free top-up of 100 credits, a free hailuoai.video account can generate 100 images per day – up to 3K images per month. ### Do you support [n8n](https://n8n.io) workflow automation? Please consider the [n8n-nodes-useapi](https://github.com/lvalics/n8n-nodes-useapi) package by [lvalics](https://github.com/lvalics). ### How POST raw content to [runwayml/assets](https://useapi.net/docs/api-runwayml-v1/post-runwayml-assets) and [minimax/files](https://useapi.net/docs/api-minimax-v1/post-minimax-files) using Make.com and similar nocode tools? We recommend using module called [0codekit](https://www.make.com/en/integrations/onesaas) to run JavaScript and return a result.
0codekit JavaScript example ```js async function fetchFromURLandPOST(imageURL, name) { const apiToken = ""; // https://useapi.net/docs/start-here/setup-useapi // Runway https://useapi.net/docs/api-runwayml-v1/post-runwayml-assets const apiUrl = `https://api.useapi.net/v1/runwayml/assets/?name=${name}`; // MiniMax https://useapi.net/docs/api-minimax-v1/post-minimax-files // const apiUrl = `https://api.useapi.net/v1/minimax/files/`; try { // Fetch the image from the URL const responseImage = await fetch(imageURL); if (!responseImage.ok) throw new Error(`Failed to fetch ${imageURL}: ${responseImage.statusText}`); // Convert the response to a Blob const blob = await responseImage.blob(); // Prepare headers for the POST request const headers = { "Authorization": `Bearer ${apiToken}`, "Content-Type": blob.type, }; // Make the POST request with the blob as the body const response = await fetch(apiUrl, { method: "POST", headers: headers, body: blob, }); const result = await response.json(); return { data: result }; } catch (error) { return { error: error.message }; } } // Calling the function result = await fetchFromURLandPOST("https:\\website.com\image.jpeg", "my_image"); ```