npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

midjourney-enhanced

v1.1.8

Published

Enhanced fork of the unofficial MidJourney API Node.js client with human verification monitoring, regional painting, and video creation features.

Downloads

68

Readme

midjourney-api

Unofficial MidJourney API Node.js client.

English / 中文文档

Notice: This project is an enhanced fork of erictik/midjourney-api. Built upon the original project, we've added human verification monitoring, regional painting, and video creation features. Thanks to the original author for the excellent work!

Recent Updates

  • New: Human verification monitoring humanVerify callback function
  • New: Regional painting (first VaryRegion, then WaitVaryRegion after confirmation)
  • New: Video creation (AnimateUpscale/Animate)
  • Face swap
  • Niji bot support
  • Custom zoom
  • Remix mode

Quick Start

This project requires Node.js. Run the following commands in the project root directory:

  1. Download the project code

    git clone https://github.com/erictik/midjourney-api.git
    cd midjourney-api
  2. Install dependencies

    yarn
    # or npm
    npm install
  3. Set environment variables

  • Get Discord TOKEN Login to Discord Press F12 or [Ctrl + Shift + I] or [Command + Option + I] to open developer tools, then enter the following code in the Console:

    window.webpackChunkdiscord_app.push([
        [Math.random()],
        {},
        (req) => {
            for (const m of Object.keys(req.c)
                .map((x) => req.c[x].exports)
                .filter((x) => x)) {
                if (m.default && m.default.getToken !== undefined) {
                    return copy(m.default.getToken());
                }
                if (m.getToken !== undefined) {
                    return copy(m.getToken());
                }
            }
        },
    ]);
    console.log("%cWorked!", "font-size: 50px");
    console.log(`%cYour token is in the clipboard!`, "font-size: 16px");

    You can also get the discord token by viewing the network Get Discord Token

  • Join my Discord server

    export SERVER_ID="1262639350852882442"
    export CHANNEL_ID="1262639350852882445"
  • Or create a Discord server and invite the Midjourney Bot

    # Copy your server URL in the browser
    # `https://discord.com/channels/$SERVER_ID/$CHANNEL_ID`
    export SERVER_ID="your-server-id"
    export CHANNEL_ID="your-channel-id"
  • Write environment variables to .env file or set them in the console

    #example variables, please set up yours
    
    export SERVER_ID="1262639350852882442"
    export CHANNEL_ID="1262639350852882445"
    export SALAI_TOKEN="your-discord-token"
  1. Now you can run the examples

    npx tsx example/imagine-ws.ts

    or

    yarn example:imagine
    # or npm
    npm run example:imagine
  2. More usage examples

Usage in Your Project

  1. Installation

    npm i midjourney
    # or
    yarn add midjourney
  2. Using Imagine, Variation and Upscale

    import { Midjourney } from "midjourney";
    const client = new Midjourney({
        ServerId: <string>process.env.SERVER_ID,
        ChannelId: <string>process.env.CHANNEL_ID,
        SalaiToken: <string>process.env.SALAI_TOKEN,
        Debug: true,
        Ws: true, //enable ws is required for remix mode (and custom zoom)
    });
    await client.init();
    const prompt = "Christmas dinner with spaghetti with family in a cozy house, we see interior details , simple blue&white illustration";
    //imagine
    const Imagine = await client.Imagine(prompt, (uri: string, progress: string) => {
        console.log("loading", uri, "progress", progress);
    });
    console.log(Imagine);
    if (!Imagine) {
        console.log("no message");
        return;
    }
    // U1 U2 U3 U4 V1 V2 V3 V4  "Vary (Strong)" ...
    const V1CustomID = Imagine.options?.find((o) => o.label === "V1")?.custom;
    if (!V1CustomID) {
        console.log("no V1");
        return;
    }
    // Varition V1
    const Varition = await client.Custom({
        msgId: <string>Imagine.id,
        flags: Imagine.flags,
        customId: V1CustomID,
        content: prompt, //remix mode require content
        loading: (uri: string, progress: string) => {
            console.log("loading", uri, "progress", progress);
        },
    });
    console.log(Varition);
    const U1CustomID = Imagine.options?.find((o) => o.label === "U1")?.custom;
    if (!U1CustomID) {
        console.log("no U1");
        return;
    }
    // Upscale U1
    const Upscale = await client.Custom({
        msgId: <string>Imagine.id,
        flags: Imagine.flags,
        customId: U1CustomID,
        loading: (uri: string, progress: string) => {
            console.log("loading", uri, "progress", progress);
        },
    });
    if (!Upscale) {
        console.log("no Upscale");
        return;
    }
    console.log(Upscale);
    const zoomout = Upscale?.options?.find((o) => o.label === "Custom Zoom");
    if (!zoomout) {
        console.log("no zoomout");
        return;
    }
    // Custom Zoom
    const CustomZoomout = await client.Custom({
        msgId: <string>Upscale.id,
        flags: Upscale.flags,
        content: `${prompt} --zoom 2`, // Custom Zoom  require content
        customId: zoomout.custom,
        loading: (uri: string, progress: string) => {
            console.log("loading", uri, "progress", progress);
        },
    });
    console.log(CustomZoomout);

Human Verification Callback humanVerify (New)

When Discord human verification is triggered (such as requiring CAPTCHA), the SDK will provide the verification page URL through the humanVerify(url) callback. You can display this URL to users for verification completion.

import { Midjourney } from "midjourney";

const client = new Midjourney({
    ServerId: <string>process.env.SERVER_ID,
    ChannelId: <string>process.env.CHANNEL_ID,
    SalaiToken: <string>process.env.SALAI_TOKEN,
    Debug: true,
    Ws: true,
    humanVerify: (url?: string) => {
        // Display the URL to frontend or log it, prompting users to complete verification
        console.log("Human verification required, please visit:", url);
    },
});
await client.init();

Regional Painting (VaryRegion → WaitVaryRegion) (New)

Regional painting workflow:

  • First call VaryRegion to trigger regional repainting, the returned URI is Midjourney's regional painting canvas link;
  • Embed this URI into your webpage (e.g., iframe), users can select regions to repaint on the canvas;
  • After users complete region selection and click submit on the canvas;
  • Call WaitVaryRegion to wait for the regional painting results.

Dependency note: Requires Ws: true to receive real-time events and results.

import { Midjourney } from "midjourney";

const client = new Midjourney({
    ServerId: <string>process.env.SERVER_ID,
    ChannelId: <string>process.env.CHANNEL_ID,
    SalaiToken: <string>process.env.SALAI_TOKEN,
    Debug: true,
    Ws: true,
});
await client.init();

const prompt = "a cozy living room, watercolor, soft light";
const imagine = await client.Imagine(prompt, (uri, progress) => {
    console.log("loading", uri, progress);
});
if (!imagine) throw new Error("imagine failed");

// Step 1: Trigger regional painting, get canvas link
const varyRegionResult = await client.VaryRegion({
    msgId: <string>imagine.id,
    hash: <string>imagine.hash!,
    flags: imagine.flags,
    // Optional: provide prompt here for regional repainting
    content: `${prompt}, add a red pillow on the sofa`,
    loading: (uri, progress) => console.log("varyRegion", uri, progress),
});

if (varyRegionResult?.uri) {
    // Important: Embed this URI into your webpage for user region selection
    console.log("Regional painting canvas link:", varyRegionResult.uri);
    // Example: <iframe src={varyRegionResult.uri} width="100%" height="600px"></iframe>
    
    // Step 2: After user completes region selection and submits on canvas, wait for results
    const varyResult = await client.WaitVaryRegion({
        msgId: <string>imagine.id,
        // Optional: provide/override prompt again
        content: `${prompt}, add a red pillow on the sofa`,
        loading: (uri, progress) => console.log("waitVaryRegion", uri, progress),
    });
    console.log("Regional painting result:", varyResult);
}

Video Creation (New)

Two methods available:

  • AnimateUpscale: Create video based on single sub-image (U1~U4) (virtual upscale track).
  • Animate: Directly trigger low/high quality video on grid image (low/high).

Dependency note: Recommend enabling Ws: true for progress and results.

import { Midjourney } from "midjourney";

const client = new Midjourney({
    ServerId: <string>process.env.SERVER_ID,
    ChannelId: <string>process.env.CHANNEL_ID,
    SalaiToken: <string>process.env.SALAI_TOKEN,
    Debug: true,
    Ws: true,
});
await client.init();

const prompt = "futuristic city skyline at sunset, ultra detailed";
const imagine = await client.Imagine(prompt);
if (!imagine) throw new Error("imagine failed");

// First upscale a sub-image (e.g., U1), then create video based on upscaled result
const u1 = imagine.options?.find((o) => o.label === "U1")?.custom;
if (!u1) throw new Error("no U1 option");

const upscale = await client.Custom({
    msgId: <string>imagine.id,
    flags: imagine.flags,
    customId: u1,
});
if (!upscale) throw new Error("upscale failed");

// Method 1: Create video based on upscaled image (virtual upscale track)
const video1 = await client.AnimateUpscale({
    index: 1, // Corresponds to U1
    msgId: <string>upscale.id,
    hash: <string>upscale.hash!,
    flags: upscale.flags,
    loading: (uri, progress) => console.log("video_upscale", uri, progress),
});
console.log("video1", video1);

// Method 2: Directly create video on grid image (low/high)
const video2 = await client.Animate({
    msgId: <string>imagine.id,
    hash: <string>imagine.hash!,
    animate_type: "low", // or "high"
    loading: (uri, progress) => console.log("animate", uri, progress),
});
console.log("video2", video2);

Route Map

  • [x] /imagine variation upscale reroll blend zoomout vary
  • [x] /info
  • [x] /fast and /relax
  • [x] /prefer remix
  • [x] variation (remix mode)
  • [x] /describe
  • [x] /shorten
  • [x] /settings reset
  • [x] verify human
  • [x] varyRegion & waitVaryRegion (regional painting)
  • [x] animate / video virtual upscale (video creation)
  • [x] proxy
  • [x] niji bot
  • [x] custom zoom
  • [x] autoload command payload