Latent API
Resolve public, safe-for-work artwork by prompt tags, or upload and generate artwork through the same pipeline as the designer dashboard.
Authentication
Everything except the image resolver needs a designer API key. Create one in the key dashboard and send it as a bearer token. A key acts as its owner, so the same allowance and limits apply as when you use the site in a browser.
Authorization: Bearer lat_sk_...Keys are shown once at creation and stored only as a hash, so a lost key is replaced rather than recovered. Revoking one takes effect immediately. Latent uses manually provisioned keys — it is not an OAuth authorization server and does not support autonomous agent registration.
Resolve an image
Find one public image by prompt tags. The only endpoint that needs no credential.
/api/v1/images/resolvePublicHighest-ranked public, active, safe-for-work artwork matching every tag.
Parameters
tagstringrequired- Repeat for AND matching. Spaces and underscores are equivalent.
sourceenum- novelai · sd-webui · comfyui · invokeai — Restrict to one generator.
modelstring- 3–120 characters — Case-insensitive literal checkpoint substring.
rankintegerdefault1- 1–1000 — Result position.
sizeenumdefaultoriginal- thumb · preview · original
formatenum- json — Omit to redirect straight to the image; json returns metadata and stable links.
Example
curl "https://latent.moe/api/v1/images/resolve\
?tag=1girl&tag=nahida_(genshin_impact)&source=novelai&format=json"Focused images with fewer total tags rank first; views, likes, recency and id break ties.
Upload artwork
The same metadata extraction, duplicate check, moderation and quota policy as the browser uploader.
/api/uploadAPI keymultipart/form-data. One or more files, URLs, or a mix.
Parameters
filesfile[]- Repeat for a batch. Required unless urls is given.
urlsstring[]- Fetched server-side. Required unless files is given.
visibilityenumdefaultpublic- public · private
nsfwbooleandefaultfalse
Example
curl -X POST https://latent.moe/api/upload \
-H "Authorization: Bearer $LATENT_KEY" \
-F "[email protected]" \
-F "visibility=public" \
-F "nsfw=false"Responses
- 200One result per submitted file or URL, in request order.
- 400Malformed multipart input, or no images supplied.
- 401Missing, invalid, or revoked API key.
Only images carrying embedded generation metadata are accepted — this is a gallery for AI-generated work, not a general image host.
Generate an image
Asynchronous: queue a render, then poll until it finishes. Results land private.
/api/generateAPI keyapplication/json. Returns 202 immediately with a job id.
Parameters
promptstringrequired- 1–2000 characters
negativePromptstring- 0–2000 characters — No site default is applied on the API.
seedintegerdefaultrandom- 0 to 2^53-1
resolutionenumdefaultportrait- square (1024×1024) · portrait (920×1536) · landscape (1536×920)
stepsintegerdefault8- 8–12
samplerenumdefaulteuler- euler · res_multistep · er_sde
schedulerenumdefaultsgm_uniform- sgm_uniform · beta · beta57 · linear_quadratic
Example
# 1. Queue it — 202 with the job id.
JOB=$(curl -s https://latent.moe/api/generate \
-H "Authorization: Bearer $LATENT_KEY" \
-H 'content-type: application/json' \
-d '{"prompt":"1girl, solo, watercolor pencil (medium)","resolution":"portrait","steps":12}' \
| jq -r .id)
# 2. Poll until status leaves queued/leased/running.
curl -s "https://latent.moe/api/generate/$JOB" \
-H "Authorization: Bearer $LATENT_KEY"
# 3. The result is a PRIVATE artwork. The same key reads its bytes.
curl -s "https://latent.moe/api/media/$ARTWORK_ID?size=preview" \
-H "Authorization: Bearer $LATENT_KEY" -o render.webpResponses
- 202Queued. The body carries the job id and its queue position.
- 401Missing, invalid, or revoked API key.
- 409
too_many_active— one job in flight per account. - 422A parameter is outside the bounds above.
- 429
quota_exhausted— this week's allowance is spent. - 503
queue_full— honourRetry-After.
Related
- GET
/api/generate/{id}Poll one job - GET
/api/generateRecent jobs - POST
/api/generate/{id}/cancelCancel - GET
/api/generate/statusWorkers online, queue depth
Generation has its own weekly allowance, separate from uploads — a render does not spend an upload slot, and only a successful one counts. Read /api/generate/status before submitting: with no worker connected a job is accepted, queues, and never starts.
NovelAI compatibility
Point a NovelAI client at /api/novelai and put a Latent key where its persistent token goes.
/api/novelai/ai/generate-imageAPI keySynchronous. The response body is a ZIP containing image_0.png.
Example
curl -X POST https://latent.moe/api/novelai/ai/generate-image \
-H "Authorization: Bearer $LATENT_KEY" \
-H 'content-type: application/json' \
-d '{
"input": "1girl, cute",
"model": "nai-diffusion-4-5-full",
"parameters": {
"width": 832, "height": 1216,
"steps": 30, "sampler": "k_euler_ancestral"
}
}' \
-o image.zipWhat is preserved
This is protocol compatibility, not fidelity. Latent runs one checkpoint at three sizes with a narrow step range, so anything outside that is clamped to the nearest thing it can do — silently, because 832×1216 and 28–30 steps are NovelAI defaults and rejecting them would fail almost every real request.
width / heightclamped- nearest offered aspect — The three standard NovelAI sizes map cleanly, but portrait returns 920×1536, not 832×1216.
stepsclamped- 8–12 — A request for 30 renders at 16, which is visibly different.
samplermapped- euler · res_multistep · er_sde — k_euler, k_euler_ancestral, k_dpmpp_2s_ancestral, k_dpmpp_2m, k_dpmpp_sde, k_dpmpp_2m_sde and ddim all carry through. Anything else falls back to euler.
noise_schedulemapped- sgm_uniform · beta · beta57 · linear_quadratic — karras and exponential carry through; native maps to normal, polyexponential to exponential.
scale, cfg_rescaledropped- CFG is fixed inside the workflow, not a request parameter.
n_samplesdropped- One image per call — one job in flight per account.
characterPromptsdropped- V4 multi-character positioning has no equivalent. The largest loss: such a prompt renders as its base caption alone.
modeldropped- One checkpoint throughout.
Responses
Errors use NovelAI's { statusCode, message } shape.
- 200A ZIP archive containing image_0.png.
- 400Body is not JSON, or the prompt is empty.
- 401Missing, invalid, or revoked API key.
- 402This week's allowance is spent.
- 429A job is already running, or the queue is full.
- 504The render outlived the request deadline. It still finishes and appears in your inventory.
Browser clients
This endpoint sends Access-Control-Allow-Origin: * and answers the preflight, so a page on any origin can call it — SillyTavern and similar clients work without launching the browser with --disable-web-security. It is bearer-only and never reads a cookie, so there are no ambient credentials for a hostile page to ride; that is what makes the wildcard safe here. The native /api/generate flow above sends no CORS headers and is for server-side callers.
The stream field is ignored; the response is always a ZIP. Disconnecting does not cancel a job, so an abandoned request still spends allowance.