Midjourney /describe Command

October 27, 2025

Table of contents

  1. Request Headers
  2. Request Body
  3. Parameters
  4. Responses
  5. Model
  6. Examples
  7. Try It

Generate text prompts from an image using Midjourney’s /describe command. Returns 4 prompt suggestions.

https://api.useapi.net/v3/midjourney/jobs/describe

Request Headers
Authorization: Bearer {API token}
Content-Type: application/json
# Alternatively you can use multipart/form-data (required for Blob content uploads).
# Content-Type: multipart/form-data
Request Body
{
  "imageUrl": "https://example.com/image.jpg",
  "stream": true,
  "replyUrl": "https://your-server.com/webhook"
}
Parameters
  • channel is optional. Discord channel ID to use. See GET /accounts for configured channels. If not provided, API automatically selects available channel with capacity. Specify when you want to use a specific configured channel.

  • imageUrl OR imageBlob is required (mutually exclusive).
    • imageUrl - URL to image
    • imageBlob - Image file upload, use Content-Type: multipart/form-data.
  • stream is optional (default: true).
    • true - Returns Content-Type: text/event-stream with live progress events. See SSE Streaming Guide
    • false - Returns Content-Type: application/json with initial job state. Use GET /jobs/jobid to retrieve updates and results
  • replyUrl is optional. Webhook URL for real-time job event callbacks. If channel has default replyUrl configured, it will be used when job-specific one is not provided. All job events POST-ed to this URL as they occur.
    Overrides channel-level replyUrl if specified.
    Maximum length 1024 characters.

  • replyRef is optional. Your reference ID stored with job.
    Returned in all responses and callbacks as response.replyRef.
    Maximum length 1024 characters.
Responses
  • 200 OK

    Use returned jobid to retrieve job status and results. content contains message generated by Midjourney reflecting current generation parameters and progress.

    {
        "jobid": "<jobid>",
        "verb": "describe",
        "status": "started",
        "created": "2023-10-06T18:36:37.963Z",
        "updated": "2023-10-06T18:36:50.401Z",
        "describeUrl": "https://...1.png",
        "discord": "<ABC…secured…xyz>",
        "channel": "<Discord channel id>",
        "maxJobs": 3,
        "messageId": "<Discord message id>",
        "content": "",
        "timestamp": "2023-10-06T18:36:48.875000+00:00",
        "code": 200
    }
    
  • 400 Bad Request

    {
      "error": "Either imageUrl or imageBlob is required"
    }
    
  • 401 Unauthorized

    {
      "error": "Unauthorized"
    }
    
  • 402 Payment Required

    {
      "error": "Account has no subscription or subscription expired"
    }
    
  • 422 Unprocessable Content

    Moderated image link, see Midjourney moderation system.

    {
        "error": "Invalid link",
        "errorDetails": "Request cancelled due to image filters.",
        "jobid": "<jobid>",
        "status": "moderated",
        "code": 422
    }
    
  • 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. API query is full and can not accept new jobs/describe requests. Size of query defined by maxJobs optional parameter. Wait in a loop for at least 10..30 seconds and retry again.
      {
       "error": "Maximum of <maxJobs> jobs executing in parallel supported",
       "executingJobs": [
         "<jobid>",
         "<jobid>",
         "<jobid>"
       ],
       "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.
    {
        "error": "Discord /interactions failed with HTTP status 429",
        "errorDetails": "{\"global\":true,\"message\":\"You are being rate limited.\",\"retry_after\":10}",
        "code": 429
    }
    
  • 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 or the Midjourney Discord bot is having issues.
    You can check Discord status and Midjourney Discord server status channel.
    Keep in mind that both links above most often will not reflect an event that has just started.

  • 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.

    {
        "error": "Job queued",
        "jobid": "<jobid>",
        "status": "failed",
        "code": 504
    }
    
  • 596 Pending Moderation

    Channel has pending moderation/CAPTCHA. Email notification sent. Log into Discord and address moderation message/CAPTCHA. Execute POST /accounts/channel/reset.

    {
      "error": "All configured Midjourney channels (2) have errors (pending moderation, CAPTCHA, etc.). Please resolve channel issues before making new requests."
    }
    
  • Real-time SSE streaming (stream: true)

    Returns Content-Type: text/event-stream with live events. See SSE Event Format for details.

  • 201 Created

    Job created successfully.

    {
      "jobid": "j1023...",
      "verb": "describe",
      "status": "created",
      "request": {
        "imageUrl": "https://example.com/image.jpg",
        "stream": false
      }
    }
    
Model

See Job Response Model for complete response structure.

Examples
  • # With URL
    curl -H "Authorization: Bearer YOUR_API_TOKEN" \
         -H "Content-Type: application/json" \
         -X POST "https://api.useapi.net/v3/midjourney/jobs/describe" \
         -d '{"imageUrl":"https://example.com/image.jpg","stream":true}'
    
    # With file upload
    curl -H "Authorization: Bearer YOUR_API_TOKEN" \
         -F "[email protected]" \
         -F "stream=true" \
         "https://api.useapi.net/v3/midjourney/jobs/describe"
    
  • // With URL
    const response = await fetch('https://api.useapi.net/v3/midjourney/jobs/describe', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        imageUrl: 'https://example.com/image.jpg',
        stream: true
      })
    });
    
    // With file upload
    const formData = new FormData();
    formData.append('imageBlob', fileInput.files[0]);
    formData.append('stream', 'true');
    
    const response2 = await fetch('https://api.useapi.net/v3/midjourney/jobs/describe', {
      method: 'POST',
      headers: {'Authorization': 'Bearer YOUR_API_TOKEN'},
      body: formData
    });
    
  • import requests
    
    # With URL
    response = requests.post(
        'https://api.useapi.net/v3/midjourney/jobs/describe',
        headers={'Authorization': 'Bearer YOUR_API_TOKEN'},
        json={'imageUrl': 'https://example.com/image.jpg', 'stream': True}
    )
    
    # With file upload
    files = {'imageBlob': open('image.jpg', 'rb')}
    data = {'stream': 'true'}
    response2 = requests.post(
        'https://api.useapi.net/v3/midjourney/jobs/describe',
        headers={'Authorization': 'Bearer YOUR_API_TOKEN'},
        files=files,
        data=data
    )
    
Try It