Skip to content

Images

APX turns a prompt into a file with apx image. It does not run a model itself: it talks to a diffusion server you point it at — one on this machine, one on your network, or a cloud API — and routes between them the same way voice routes between TTS engines.

apx
$ apx image "a green origami fox on a white background"
/Users/you/.apx/images/2026-08-28/a1111-6f0c….png
a1111 · z_image_turbo · 512x512 · seed 1608784042 · 476 KB · 24.9s

Without --out the file lands in ~/.apx/images/<date>/ and the path is printed. Nothing is written into a project checkout unless you ask for it:

Terminal window
apx image "portrait of a fox" --size 768x512 --steps 8 --cfg 1.0 --out fox.png

An engine is a server plus the dialect it speaks. Four are built in:

idAPIWhat it covers
a1111POST /sdapi/v1/txt2img (synchronous)The universal dialect: AUTOMATIC1111, Forge, SD.Next, Draw Things on macOS, stable-diffusion.cpp. Carries every sampling knob.
sdcppPOST /sdcpp/v1/img_gen + job pollingstable-diffusion.cpp’s native queue. The request returns immediately and the job is polled, so a queued render never looks like a hung connection.
openaiPOST /v1/images/generationsOpenAI itself (gpt-image-1, dall-e-3), or any OpenAI-compatible server when you set a base URL.
mockAn offline test engine. Always last in the chain, and used only when no real engine was tried — never to paper over one that failed.

You can add any number of your own endpoints; each one declares which of the three dialects it speaks, so a single screen covers a local server, a LAN box and a cloud key.

Everything lives under images.* in ~/.apx/config.json, and has a screen at Settings → Images in the web panel.

Terminal window
apx config set --global images.a1111.base_url http://127.0.0.1:7860
apx config set --global images.a1111.defaults '{"steps":8,"cfg_scale":1}'
KeyWhat it does
images.<engine>.base_urlWhere the server is. The origin only — no API path.
images.<engine>.api_keyOptional. Most local and LAN servers need none.
images.<engine>.modelCheckpoint or model id, where the server can switch.
images.<engine>.defaultsSize, steps, guidance, sampler, scheduler for this server.
images.<engine>.timeout_sHow long to wait for one image.
images.defaultsThe shared bottom layer: size, format, negative prompt, count.
images.orderThe chain order. The first engine that draws wins.
images.modechain (router, the default) or single (only images.provider).
images.custom.<slug>Your own endpoint. Needs label, kind and base_url.

Engines are tried in order until one draws. The chain covers both ways an engine can let a call down: a configured but unreachable server is skipped, and one that answers a probe but fails the render hands the prompt to the next engine — a diffusion box whose GPU has fallen over still answers probes perfectly. --provider overrides the routing for one call, and apx image providers shows what is reachable right now.

A named engine — --provider, or single mode — fails without a retry, so the settings tester reports on the engine you pointed it at rather than quietly rendering somewhere else. mock closes the chain for a machine with nothing configured, but never stands in for a failed render: a placeholder handed back as success cannot be told apart from a real picture.

When every engine fails, the error names each one it tried, where that server lives and what the server itself said, so a broken box is identifiable from the message alone:

apx
$ apx image "a fox"
apx image: image generation failed — all 3 engines tried:
· custom:zimage (http://box.example:8189): 500: server_error: vk::Queue::submit: ErrorDeviceLost
· custom:sdxl (http://box.example:8192): 500: server_error: vk::Queue::submit: ErrorDeviceLost
· custom:flux (http://box.example:8191): 500: server_error: vk::Queue::submit: ErrorDeviceLost

Three servers, one message: that is the GPU they share, not three broken models.

apx
$ apx image providers
Routing  chain (a1111 → sdcpp → openai → mock)

● a1111  reachable, configured
    http://127.0.0.1:7860
○ openai  unreachable, not configured
● mock  reachable, not configured

Options resolve in three layers — images.defaults, then images.<engine>.defaults, then the call. Steps and guidance belong to the engine, because the right value depends on the checkpoint that server loaded: a turbo checkpoint wants about 8 steps at guidance 1, a standard one 20 at guidance 7. Putting them in the engine’s own block means no caller has to remember which server they are talking to.

The OpenAI dialect has no steps, guidance, sampler, scheduler, seed or negative prompt. stable-diffusion.cpp hosts one checkpoint and cannot switch models. Rather than accepting an option and quietly ignoring it, APX reports it:

sdcpp ignored: model

apx image capabilities asks a server what it actually offers — models, samplers, schedulers, output formats — so you are not guessing at names.

FlagMeaning
--out <file>Copy the result here. A directory works too.
--provider <id>a1111 | sdcpp | openai | mock | custom:<slug>
--size <WxH>e.g. 768x512. Or --width / --height.
--steps NSampling steps.
--cfg NGuidance scale.
--seed NFix the seed for a reproducible image. -1 is random.
--negative "…"What to keep out of the picture.
--count NHow many images in one run.
--model <id>Checkpoint, where the server can switch.
--format <ext>png | jpeg | webp, where supported.
--sampler / --schedulerNames from apx image capabilities.
--jsonEngine, resolved request, ignored options and file paths.
--openOpen the result in the OS viewer.