docs/src/content/docs/development/Guides/recall-api.mdx
The Recall Parameters API is a REST endpoint on the InvokeAI backend that lets external processes set recallable generation parameters on the frontend. Supported parameters include:
When parameters are updated via the API, the backend stores them in client
state persistence for the target queue and broadcasts a recall_parameters_updated
WebSocket event. Any frontend client subscribed to that queue applies the
new values immediately — no manual reload required.
Typical use cases:
/api/v1/recall/{queue_id}.recall_* keys in the client state persistence service, scoped to the
given queue_id.{INVOKEAI_ROOT}/outputs/images.recall_parameters_updated event is emitted on the
websocket room for queue_id.Base URL: http://localhost:9090/api/v1/recall/{queue_id}
The queue id is usually default.
Updates recallable parameters for the given queue_id.
POST /api/v1/recall/{queue_id}
Content-Type: application/json
{
"positive_prompt": "a beautiful landscape",
"negative_prompt": "blurry, low quality",
"model": "sd-1.5",
"steps": 20,
"cfg_scale": 7.5,
"width": 512,
"height": 512,
"seed": 12345
}
All parameters are optional — only send the fields you want to update.
The POST endpoint accepts two optional boolean query parameters that control how reference images are merged into the frontend state:
| Parameter | Default | Description |
|---|---|---|
strict | false | When true, parameters not included in the request body are reset to their defaults (cleared on the frontend). When false, only the parameters you send are updated and everything else is left as-is. |
append | false | When true, recalled reference images (ip_adapters and reference_images) are appended to the frontend's existing reference-image list instead of replacing it. When false (or omitted), the recalled reference images replace the existing list. |
strict and append are mutually exclusive — strict clears omitted
parameters while append preserves and extends the existing list, so the two
cannot be combined. Sending ?strict=true&append=true returns
400 Bad Request:
{
"detail": "The 'strict' and 'append' query parameters are mutually exclusive"
}
append only affects the reference-image collections (ip_adapters and
reference_images). All other parameters (prompts, model, LoRAs, control
layers, etc.) are updated the same way regardless of the flag.
GET /api/v1/recall/{queue_id}
{
"status": "success",
"queue_id": "queue_123",
"note": "Use the frontend to access stored recall parameters, or set specific parameters using POST"
}
| Parameter | Type | Description |
|---|---|---|
positive_prompt | string | Positive prompt text |
negative_prompt | string | Negative prompt text |
model | string | Main model name/identifier |
refiner_model | string | Refiner model name/identifier |
vae_model | string | VAE model name/identifier |
scheduler | string | Scheduler name |
steps | integer | Number of generation steps (≥1) |
refiner_steps | integer | Number of refiner steps (≥0) |
cfg_scale | number | CFG scale for guidance |
cfg_rescale_multiplier | number | CFG rescale multiplier |
refiner_cfg_scale | number | Refiner CFG scale |
guidance | number | Guidance scale |
width | integer | Image width in pixels (≥64) |
height | integer | Image height in pixels (≥64) |
seed | integer | Random seed (≥0) |
denoise_strength | number | Denoising strength (0–1) |
refiner_denoise_start | number | Refiner denoising start (0–1) |
clip_skip | integer | CLIP skip layers (≥0) |
seamless_x | boolean | Enable seamless X tiling |
seamless_y | boolean | Enable seamless Y tiling |
refiner_positive_aesthetic_score | number | Refiner positive aesthetic score |
refiner_negative_aesthetic_score | number | Refiner negative aesthetic score |
{
// LoRAs
loras?: Array<{
model_name: string; // LoRA model name
weight?: number; // Default: 0.75, Range: -10 to 10
is_enabled?: boolean; // Default: true
}>;
// Control Layers (ControlNet, T2I Adapter, Control LoRA)
control_layers?: Array<{
model_name: string; // Control adapter model name
image_name?: string; // Optional image filename from outputs/images
weight?: number; // Default: 1.0, Range: -1 to 2
begin_step_percent?: number; // Default: 0.0, Range: 0 to 1
end_step_percent?: number; // Default: 1.0, Range: 0 to 1
control_mode?: "balanced" | "more_prompt" | "more_control"; // ControlNet only
}>;
// IP Adapters (includes FLUX Redux)
ip_adapters?: Array<{
model_name: string; // IP Adapter / FLUX Redux model name
image_name?: string; // Optional reference image filename from outputs/images
weight?: number; // Default: 1.0, Range: -1 to 2
begin_step_percent?: number; // Default: 0.0, Range: 0 to 1
end_step_percent?: number; // Default: 1.0, Range: 0 to 1
method?: "full" | "style" | "composition"; // Default: "full"
image_influence?: "lowest" | "low" | "medium" | "high" | "highest"; // FLUX Redux only
}>;
// Model-free reference images (FLUX.2 Klein, FLUX Kontext, Qwen Image Edit)
reference_images?: Array<{
image_name: string; // Reference image filename from outputs/images
}>;
}
The backend resolves model names to their internal keys:
Models that cannot be resolved are skipped with a warning in the logs — the rest of the parameters are still applied.
When an image_name is supplied, the backend:
{INVOKEAI_ROOT}/outputs/images/{image_name} via the image
files service (which also validates the path).Images must be referenced by their filename as it appears in the outputs/images directory:
"image_name": "example.png""image_name": "my_control_image_20240110.jpg""image_name": "outputs/images/example.png" (no prefix)"image_name": "/full/path/to/example.png" (no absolute paths)Missing images are logged as warnings but do not fail the request — remaining parameters are still applied.
outputs/images.outputs/images are validated and passed
through.image_influence instead of a numeric weight.Used by architectures that consume a reference image directly, with no separate adapter model:
Because there is no adapter model to resolve, these entries carry only
image_name. When the frontend receives them, it picks the appropriate
config flavor (flux2_reference_image, flux_kontext_reference_image,
or qwen_image_reference_image) based on the currently-selected main
model, matching the behavior of a manual drag-and-drop.
# Core parameters
curl -X POST http://localhost:9090/api/v1/recall/default \
-H "Content-Type: application/json" \
-d '{
"positive_prompt": "a cyberpunk city at night",
"negative_prompt": "dark, unclear",
"model": "sd-1.5",
"steps": 30
}'
# Just the seed
curl -X POST http://localhost:9090/api/v1/recall/default \
-H "Content-Type: application/json" \
-d '{"seed": 99999}'
curl -X POST http://localhost:9090/api/v1/recall/default \
-H "Content-Type: application/json" \
-d '{
"loras": [
{"model_name": "add-detail-xl", "weight": 0.8, "is_enabled": true},
{"model_name": "sd_xl_offset_example-lora_1.0", "weight": 0.5}
]
}'
curl -X POST http://localhost:9090/api/v1/recall/default \
-H "Content-Type: application/json" \
-d '{
"control_layers": [
{
"model_name": "controlnet-canny-sdxl-1.0",
"image_name": "my_control_image.png",
"weight": 0.75,
"begin_step_percent": 0.0,
"end_step_percent": 0.8,
"control_mode": "balanced"
}
]
}'
curl -X POST http://localhost:9090/api/v1/recall/default \
-H "Content-Type: application/json" \
-d '{
"ip_adapters": [
{
"model_name": "ip-adapter-plus-face_sd15",
"image_name": "reference_face.png",
"weight": 0.7,
"method": "composition"
}
]
}'
By default, recalled reference images replace whatever the frontend
already has. Pass ?append=true to add the recalled ip_adapters and
reference_images to the existing list instead:
# Add a reference image without clearing the ones already on the frontend
curl -X POST 'http://localhost:9090/api/v1/recall/default?append=true' \
-H "Content-Type: application/json" \
-d '{
"reference_images": [
{"image_name": "extra_reference.png"}
]
}'
Combining append=true with strict=true is invalid and returns
400 Bad Request (see Query parameters).
curl -X POST http://localhost:9090/api/v1/recall/default \
-H "Content-Type: application/json" \
-d '{
"model": "FLUX.2 Klein",
"reference_images": [
{"image_name": "style_reference.png"}
]
}'
curl -X POST http://localhost:9090/api/v1/recall/default \
-H "Content-Type: application/json" \
-d '{
"positive_prompt": "masterpiece, detailed photo with specific style",
"negative_prompt": "blurry, low quality",
"model": "FLUX Schnell",
"steps": 25,
"cfg_scale": 8.0,
"width": 1024,
"height": 768,
"seed": 42,
"loras": [
{"model_name": "add-detail-xl", "weight": 0.6}
],
"control_layers": [
{
"model_name": "controlnet-depth-sdxl-1.0",
"image_name": "depth_map.png",
"weight": 1.0,
"end_step_percent": 0.7
}
],
"ip_adapters": [
{
"model_name": "ip-adapter-plus-face_sd15",
"image_name": "style_reference.png",
"weight": 0.5,
"method": "style"
}
]
}'
import requests
API_URL = "http://localhost:9090/api/v1/recall/default"
params = {
"positive_prompt": "a serene forest",
"negative_prompt": "people, buildings",
"steps": 25,
"cfg_scale": 7.0,
"seed": 42,
}
response = requests.post(API_URL, json=params)
result = response.json()
print(f"Status: {result['status']}")
print(f"Updated {result['updated_count']} parameters")
const API_URL = 'http://localhost:9090/api/v1/recall/default';
fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
positive_prompt: 'a beautiful sunset',
steps: 20,
width: 768,
height: 768,
seed: 12345,
}),
})
.then((res) => res.json())
.then((data) => console.log(data));
{
"status": "success",
"queue_id": "default",
"updated_count": 15,
"parameters": {
"positive_prompt": "...",
"steps": 25,
"loras": [
{"model_key": "abc123...", "weight": 0.6, "is_enabled": true}
],
"control_layers": [
{
"model_key": "controlnet-xyz...",
"weight": 1.0,
"image": {"image_name": "depth_map.png", "width": 1024, "height": 768}
}
],
"ip_adapters": [
{
"model_key": "ip-adapter-xyz...",
"weight": 0.5,
"image": {"image_name": "style_reference.png", "width": 1024, "height": 1024}
}
],
"reference_images": [
{"image": {"image_name": "style_reference.png", "width": 1024, "height": 1024}}
]
}
}
Parameter updates emit a recall_parameters_updated event to the queue
room. Connected frontend clients automatically:
append=true it is
added to whatever is already there (see
Query parameters).strict=true&append=true combination (see
Query parameters).Errors include detailed messages. Missing images and unresolved model names are not errors — they are logged and the remaining parameters are still applied.
INFO: Resolved ControlNet model name 'controlnet-canny-sdxl-1.0' to key 'controlnet-xyz...'
INFO: Found image file: depth_map.png (1024x768)
INFO: Updated 12 recall parameters for queue default
INFO: Resolved 1 LoRA(s)
INFO: Resolved 1 control layer(s)
INFO: Resolved 1 IP adapter(s)
INFO: Resolved 1 reference image(s)
Set localStorage.ROARR_FILTER = 'debug' in the browser to see all debug
messages under the events namespace.
INFO: Applied 5 recall parameters to store
INFO: Applied 2 reference image(s) (IP adapters + model-free), replacing existing list
DEBUG: Built IP adapter ref image state: ip-adapter-xyz... (weight: 0.7)
DEBUG: IP adapter image: outputs/images/depth_map.png (1024x768)
recall_* keys, scoped to the queue_id.steps ≥ 1, width ≥ 64).If you see "Image file not found" in the logs:
{INVOKEAI_ROOT}/outputs/images/.outputs/images/ prefix.If you see "Could not find model":
queue_id matches the frontend's queue (usually default).outputs/images; remote
URLs are not supported.Potential improvements not yet implemented:
outputs/images filenames.queue_ids in a single request.