Documentation
¶
Overview ¶
Package mjclient is the Midjourney web client: it drives a Camoufox browser (via github.com/ehmo/gomoufox) to make authenticated, Cloudflare-passing calls to www.midjourney.com/api/*, and uses plain Go HTTP for the non-gated securetoken exchange and CDN downloads.
Index ¶
- Variables
- func DaemonAvailable(socket string) bool
- func DaemonSocketPath() string
- func Redact(s string) string
- func ServeDaemon(ctx context.Context, socket string, c *Client, idle time.Duration) error
- func StopDaemon(socket string) error
- func ValidFeed(f ExploreFeed) bool
- type APIError
- type AssetSel
- type AuthError
- type Client
- func (c *Client) Account(ctx context.Context) (mjapi.Account, error)
- func (c *Client) Assets(j mjapi.Job) []mjapi.AssetURL
- func (c *Client) CDNHead(ctx context.Context, j mjapi.Job) bool
- func (c *Client) Close() error
- func (c *Client) CurrentRefreshToken() string
- func (c *Client) Describe(ctx context.Context, imageURL string) ([]string, error)
- func (c *Client) DescribeImage(ctx context.Context, pathOrURL string) ([]string, error)
- func (c *Client) Download(ctx context.Context, j mjapi.Job, destDir string, which AssetSel) ([]string, error)
- func (c *Client) DownloadOpts(ctx context.Context, j mjapi.Job, destDir string, which AssetSel, ...) ([]string, error)
- func (c *Client) EnsureSession(ctx context.Context) error
- func (c *Client) Explore(ctx context.Context, feed ExploreFeed, page int) ([]mjapi.ExploreItem, error)
- func (c *Client) Folders(ctx context.Context) ([]byte, error)
- func (c *Client) Get(ctx context.Context, path string) ([]byte, error)
- func (c *Client) History(ctx context.Context, pageSize int, cursor string) ([]mjapi.Job, string, error)
- func (c *Client) ImageSize(ctx context.Context, source string) (int, int, error)
- func (c *Client) Imagine(ctx context.Context, req ImagineReq) (mjapi.Job, error)
- func (c *Client) LikedStyles(ctx context.Context) ([]byte, error)
- func (c *Client) Likes(ctx context.Context, page int) ([]mjapi.ExploreItem, error)
- func (c *Client) Moodboards(ctx context.Context) ([]mjapi.Moodboard, error)
- func (c *Client) Outpaint(ctx context.Context, source, prompt string, left, top, right, bottom int, ...) (mjapi.Job, error)
- func (c *Client) PersonalizedProfiles(ctx context.Context) ([]byte, error)
- func (c *Client) PostJSON(ctx context.Context, path string, body []byte) ([]byte, error)
- func (c *Client) ProfileFeed(ctx context.Context, username string) ([]mjapi.ExploreItem, error)
- func (c *Client) Queue(ctx context.Context) (mjapi.Queue, error)
- func (c *Client) ReadRefreshToken(ctx context.Context) (string, error)
- func (c *Client) Reroll(ctx context.Context, parent mjapi.JobID) (mjapi.Job, error)
- func (c *Client) Retexture(ctx context.Context, source, prompt, ar string, mode mjapi.Mode) (mjapi.Job, error)
- func (c *Client) SaveURL(ctx context.Context, url, destPath string) error
- func (c *Client) Search(ctx context.Context, query string, page int) ([]mjapi.ExploreItem, error)
- func (c *Client) Status(ctx context.Context, ids ...mjapi.JobID) ([]mjapi.Job, error)
- func (c *Client) Styles(ctx context.Context, page int) ([]mjapi.ExploreItem, error)
- func (c *Client) UploadBytes(ctx context.Context, data []byte, name string) (string, error)
- func (c *Client) UploadIfLocal(ctx context.Context, pathOrURL string) (string, error)
- func (c *Client) UploadImage(ctx context.Context, localPath string) (string, error)
- func (c *Client) Uploads(ctx context.Context) ([]mjapi.Upload, error)
- func (c *Client) Upscale(ctx context.Context, parent mjapi.JobID, index int, kind mjapi.UpscaleKind) (mjapi.Job, error)
- func (c *Client) Vary(ctx context.Context, parent mjapi.JobID, index int, strong bool) (mjapi.Job, error)
- func (c *Client) VaryRegion(ctx context.Context, source, prompt string, x, y, rw, rh int, mode mjapi.Mode) (mjapi.Job, error)
- func (c *Client) Video(ctx context.Context, req VideoReq) (mjapi.Job, error)
- func (c *Client) Wait(ctx context.Context, id mjapi.JobID, opts WaitOpts) (mjapi.Job, error)
- func (c *Client) WatchConnect(ctx context.Context) bool
- func (c *Client) WatchJob(ctx context.Context, id mjapi.JobID, wsOpen bool, timeout time.Duration, ...) (mjapi.Job, error)
- func (c *Client) WatchProgress(ctx context.Context, id mjapi.JobID, timeout time.Duration, ...) (mjapi.Job, error)
- type Config
- type CredStore
- type ExploreFeed
- type FetchReq
- type FetchRes
- type ImagineReq
- type VideoReq
- type WaitOpts
Constants ¶
This section is empty.
Variables ¶
var ErrJobFailed = errors.New("job failed or was moderated")
ErrJobFailed is returned by Wait when a job reaches a failed/moderated state.
var ErrWaitTimeout = errors.New("timed out waiting for job")
ErrWaitTimeout is returned by Wait when the deadline elapses before terminal.
var ExploreFeeds = []ExploreFeed{FeedTop, FeedTopWeek, FeedTopMonth, FeedHot, FeedRandom, FeedVideos}
ExploreFeeds lists the valid feed values.
Functions ¶
func DaemonAvailable ¶
DaemonAvailable reports whether a daemon is accepting connections at socket.
func DaemonSocketPath ¶
func DaemonSocketPath() string
DaemonSocketPath returns the per-user daemon socket path, creating its dir.
func ServeDaemon ¶
ServeDaemon listens on socket and serves browser primitives from c's warm browser. Browser ops are serialized; submit-jobs are throttled across all clients by c's MinSubmitGap. If idle > 0, the daemon shuts down after that much inactivity. Returns when ctx is cancelled, a shutdown request arrives, idle expires, or the listener errors.
func StopDaemon ¶
StopDaemon asks a running daemon to shut down.
func ValidFeed ¶
func ValidFeed(f ExploreFeed) bool
ValidFeed reports whether f is a known explore feed.
Types ¶
type APIError ¶
APIError is returned for non-2xx responses from www.midjourney.com/api/*.
type AuthError ¶
type AuthError struct{ Reason string }
AuthError indicates the credential chain could not establish a session.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a connected Midjourney web client. Not safe for concurrent submits (callers serialize); read methods may interleave.
func DialDaemon ¶
DialDaemon connects to a running daemon and returns a Client whose browser primitives execute on the daemon's warm browser.
func New ¶
New launches Camoufox, opens a page, and parks it on the midjourney.com origin so in-browser fetches send same-origin session cookies. It does not authenticate; call EnsureSession (or any API method, which auto-auths on 401).
func NewWithConn ¶
NewWithConn builds a Client over an existing transport (used by the daemon client to route browser primitives to a warm remote browser).
func Open ¶
Open returns a Client routed through a running daemon when one is available (headless commands), otherwise a fresh local browser. Headful configs always get a local browser (the interactive login flow). This is the single entry point both the CLI and the MCP server use, so they share one warm browser + session when a daemon is running.
func (*Client) Account ¶
Account returns the cached authUser, authenticating first if needed. When the transport is a daemon, it serves the daemon's warm account (no handshake). A locally-authed account older than accountTTL is refreshed proactively; if that refresh fails, the still-cached account is served (the next API call's 401 retry is the backstop).
func (*Client) CDNHead ¶
CDNHead reports whether a job's first asset is available on the CDN yet (propagation check), fetched through the browser.
func (*Client) CurrentRefreshToken ¶
CurrentRefreshToken returns the refresh token most recently validated by EnsureSession (post-rotation). Empty until a session is established.
func (*Client) Describe ¶
Describe returns ~4 suggested prompts for an image. imageURL must be a public URL Midjourney can fetch (e.g. a cdn.midjourney.com image or any web image). /api/describe is synchronous — no job polling. Confirmed live 2026-06-05.
func (*Client) DescribeImage ¶
DescribeImage describes a local file or a URL. URLs are described directly; local files are uploaded first.
func (*Client) Download ¶
func (c *Client) Download(ctx context.Context, j mjapi.Job, destDir string, which AssetSel) ([]string, error)
Download fetches selected full-res PNG CDN assets (back-compat wrapper).
func (*Client) DownloadOpts ¶
func (c *Client) DownloadOpts(ctx context.Context, j mjapi.Job, destDir string, which AssetSel, opts mjapi.AssetOpts) ([]string, error)
DownloadOpts fetches selected CDN assets for a completed job through the browser in the requested format/size and writes them to destDir. Returns the written file paths. Missing assets are retried briefly to absorb CDN propagation lag.
func (*Client) EnsureSession ¶
EnsureSession (re)establishes the MJ session: fetch refresh token → securetoken → firebase-login → cache authUser. Persists a rotated refresh token to the CredStore when one is configured.
It is serialized by authMu so concurrent 401 retries don't run the token exchange twice (which can invalidate a rotated refresh token mid-flight). A caller that arrives just after another goroutine refreshed returns immediately rather than re-exchanging.
func (*Client) Explore ¶
func (c *Client) Explore(ctx context.Context, feed ExploreFeed, page int) ([]mjapi.ExploreItem, error)
Explore browses the public explore gallery (page is 0-based, matching the web app's explore feed).
func (*Client) Folders ¶
Folders returns the raw `/api/folders` JSON (collection structure varies; the shape is surfaced verbatim for now).
func (*Client) Get ¶
Get performs an authenticated GET on a midjourney.com/api path (e.g. "/api/folders") and returns the raw body. Exposes the in-browser transport for read endpoints beyond the typed methods.
func (*Client) History ¶
func (c *Client) History(ctx context.Context, pageSize int, cursor string) ([]mjapi.Job, string, error)
History returns the user's recent jobs (metadata only) and the next cursor.
func (*Client) ImageSize ¶
ImageSize returns the width and height of a source image (local file or URL).
func (*Client) LikedStyles ¶
LikedStyles returns the raw `/api/explore-styles-likes` JSON (style objects; shape surfaced verbatim).
func (*Client) Likes ¶
Likes returns the images the account has liked. page is 1-based, matching the web app (explore-likes rejects page=0 with 422).
func (*Client) Moodboards ¶
Moodboards lists the account's personalization moodboards.
func (*Client) Outpaint ¶
func (c *Client) Outpaint(ctx context.Context, source, prompt string, left, top, right, bottom int, mode mjapi.Mode) (mjapi.Job, error)
Outpaint extends the canvas around a source image by the given pixel margins and regenerates the new (transparent) area from prompt. Pan = margin on one side; zoom-out = margins on all sides. source is a local file or a URL.
func (*Client) PersonalizedProfiles ¶
PersonalizedProfiles returns the raw `/api/personalized-profiles` JSON.
func (*Client) PostJSON ¶
PostJSON performs an authenticated POST with a JSON body on a midjourney.com /api path and returns the raw body.
func (*Client) ProfileFeed ¶
ProfileFeed returns a user's published spotlight gallery by username.
func (*Client) ReadRefreshToken ¶
ReadRefreshToken returns the Firebase refresh token from the parked page's IndexedDB (populated after an interactive login). Empty string if not logged in.
func (*Client) Retexture ¶
func (c *Client) Retexture(ctx context.Context, source, prompt, ar string, mode mjapi.Mode) (mjapi.Job, error)
Retexture re-renders an image's texture/style from a text instruction while keeping its structure, using the source as a depth reference (--dref). Confirmed live: t:"retexture" with the source uploaded and referenced as --dref in the prompt. source may be a local file or a URL.
func (*Client) SaveURL ¶
SaveURL fetches an arbitrary CDN URL through the browser and writes it to destPath (creating parent dirs). Used for assets without a job (uploads).
func (*Client) Search ¶
Search runs a semantic vector search over the public explore gallery. page is 1-based (matching the web app). Returns published community images.
func (*Client) Styles ¶
Styles browses the public style-reference gallery (explore-srefs). Each result carries an sref code usable as `--sref <code>`. page is 0-based.
func (*Client) UploadBytes ¶
UploadBytes uploads raw image bytes to Midjourney storage and returns a hosted URL (the short s.mj.run URL when available, else the cdn/u/ form).
func (*Client) UploadIfLocal ¶
UploadIfLocal returns pathOrURL unchanged if it is a URL, otherwise uploads the local file and returns its hosted URL.
func (*Client) UploadImage ¶
UploadImage uploads a local image to Midjourney's user storage and returns a public URL usable as an image_url / image prompt. Uses an in-browser multipart POST to /api/storage-upload-file.
func (*Client) Upscale ¶
func (c *Client) Upscale(ctx context.Context, parent mjapi.JobID, index int, kind mjapi.UpscaleKind) (mjapi.Job, error)
Upscale upscales a grid cell.
func (*Client) Vary ¶
func (c *Client) Vary(ctx context.Context, parent mjapi.JobID, index int, strong bool) (mjapi.Job, error)
Vary requests a variation of a grid cell.
func (*Client) VaryRegion ¶
func (c *Client) VaryRegion(ctx context.Context, source, prompt string, x, y, rw, rh int, mode mjapi.Mode) (mjapi.Job, error)
VaryRegion erases a rectangular region of the source (making it transparent) and regenerates just that region from prompt, keeping the rest. source is a local file or a URL; the rect is in source pixels.
func (*Client) Wait ¶
Wait polls job-status until the job reaches a terminal state or the timeout elapses. Returns ErrJobFailed for failed/moderated, ErrWaitTimeout on deadline.
func (*Client) WatchConnect ¶
WatchConnect opens the realtime WebSocket and subscribes to the user BEFORE a job is submitted (the server only streams a job's frames to clients that were subscribed when it started). Returns true if the socket is open; false means callers should fall back to status polling. Requires a session-local websocketToken (local client only).
func (*Client) WatchJob ¶
func (c *Client) WatchJob(ctx context.Context, id mjapi.JobID, wsOpen bool, timeout time.Duration, cb func(mjapi.Progress)) (mjapi.Job, error)
WatchJob streams progress for a job, calling cb on each percent/status change, until terminal or timeout. It drains WS frames for live percent and polls job-status as a backstop for reliable terminal detection. Returns the final job. If the WS isn't open (wsOpen=false) it polls only.
type Config ¶
type Config struct {
ProfileDir string // persistent Camoufox profile (session reuse); required for login persistence
Headless bool // false = headful (login flow)
RefreshToken string // optional explicit refresh token (overrides CredStore/IndexedDB)
Proxy string // optional "http://host:port"
ConnectTimeout time.Duration // browser connect timeout (default 60s)
MinSubmitGap time.Duration // throttle between submit-jobs (default 12s)
Creds CredStore // optional credential store (hasp)
}
Config configures a Client.
type CredStore ¶
type CredStore interface {
Get(ctx context.Context) (string, error)
Set(ctx context.Context, refreshToken string) error
}
CredStore persists the durable Firebase refresh token (e.g. hasp-backed).
type ExploreFeed ¶
type ExploreFeed string
ExploreFeed selects the explore browse feed. Values confirmed live from the web app's feed selector.
const ( FeedTop ExploreFeed = "top" // top all-time FeedTopWeek ExploreFeed = "top_week" // top this week FeedTopMonth ExploreFeed = "top_month" // top this month FeedHot ExploreFeed = "hot" // trending FeedRandom ExploreFeed = "random" FeedVideos ExploreFeed = "videos" // community videos )
type FetchReq ¶
type FetchReq struct {
URL string `json:"url"`
Method string `json:"method"`
Headers map[string]string `json:"headers"`
Body []byte `json:"body"`
MaxBytes int `json:"max_bytes"`
}
FetchReq is an in-browser fetch request (to www.midjourney.com/api/* or CDN).
type FetchRes ¶
type FetchRes struct {
StatusCode int `json:"status_code"`
Body []byte `json:"body"`
Truncated bool `json:"truncated"`
}
FetchRes is the result of an in-browser fetch.
type ImagineReq ¶
type ImagineReq struct {
Prompt string
Params mjapi.Params
Mode mjapi.Mode // default fast
Private bool // stealth (requires can_private)
}
ImagineReq is an imagine request.