Train and use LoRA Styles
POST /loras/train prepares the training images, creates a saved Style, and starts
the same durable training workflow as the web Train dialog. It uses the same
captioning defaults, model parameters, permissions and run lifecycle. Training consumes
workspace usage even when you do not poll its result. Canvas-only promotions do not
apply to API or MCP training.
Start with client.loras.listTrainers({ workspace_id: workspaceId }) or MCP
flora_list_lora_trainers. Discovery returns each available family, training
parameters with effective defaults, image-count and format limits, and compatible
inference model IDs with their strength defaults and ranges. Use these fields
instead of guessing a trainer endpoint or inference parameter name.
Upload source images through the assets API first. Pass the
resulting Flora image URLs, an existing project and its workspace, and the LoRA
family key, such as flux-2 or krea-2. The selected trainer enforces its image
count and parameter limits. Do not supply an image ZIP or a provider training URL.
// Save this token with the dataset before the first request.const clientToken = crypto.randomUUID()const training = await client.loras.train( { workspace_id: workspaceId, project_id: projectId, name: "Ink study", base_model: "krea-2", image_urls: uploadedImageUrls, client_token: clientToken, }, { maxRetries: 0, timeoutInSeconds: 300 },)
const run = await client.generations.retrieve({ runId: training.run_id })Training is asynchronous. Poll the returned run_id until the run completes or
fails, then read the saved Style with client.loras.retrieve({ styleId: training.style_id, workspace_id: workspaceId }). A ready Style has usable weights
or a provider Style identifier. Failed training can remove its pending Style;
the run remains the place to inspect the failure and final charged cost.
If a response is lost, repeat the same request with the same client_token and
inputs. A new token means a new paid training attempt. A replay can return a
null style_id if someone subsequently deleted the Style. Do not treat that as
permission to retrain automatically. The optional HTTP Idempotency-Key is a
separate short-lived duplicate-request guard; it does not replace client_token.
ZIP-based trainers retain the original dataset archive and resolved settings for recovery. URL-list trainers such as Recraft retain the source URLs, so keep those images available and unchanged until training finishes.
Omit trainer_params to retain the web Train defaults. To make a deliberate
change, pass supported parameters such as steps, learning_rate,
the trigger field listed for that trainer, or its captioning mode. captions contains one entry
per image in the same order; null and blank entries use the shared fallback.
Automatic captioning and manual caption handling are model-specific, just as in
the web dialog. On Krea, omitting the mode and labels uses automatic Style
captions; supplying nonblank labels selects manual "Off" mode. You can also
select that mode explicitly with trainer_params.auto_captioning: "Off".
Combining manual labels with an explicit automatic mode is rejected.
The shared flow composes the trigger with each label once, so send the label
itself instead of prepending the trigger. Keep the effective settings with your
dataset when comparing runs.
Once the Style is ready, select a compatible inference model from the model
catalog. Put the returned sty_… ID in params.lora_id:
if (!training.style_id) throw new Error("The trained Style was deleted")const style = await client.loras.retrieve({ styleId: training.style_id, workspace_id: workspaceId,})if (style.status !== "ready") throw new Error("The Style is not ready")
const image = await client.generations.create({ workspace_id: workspaceId, project_id: projectId, type: "image", model: compatibleModelId, prompt: "A lighthouse above a calm sea", params: { lora_id: style.style_id },})style_id is the response field; lora_id is the inference parameter. Passing
params.style_id does not attach the adapter. Saved trigger metadata is resolved
by the shared generation path, and weights remain subject to workspace and owner
authorization.
In MCP, use flora_train_lora, flora_list_generations with run_ids: [run_id] and flora_get_lora, then pass the
ready Style to flora_create_generations. Calling flora_create_generations with a trainer model
does not perform the saved Style preparation lifecycle. The explicit LoRA tool
is the supported training entry point. The execute sandbox needs a published
SDK version containing client.loras; updating the curated tools alone does not
update an existing sandbox snapshot.
These endpoint tools belong to the remote Flora MCP server. Browser WebMCP tools attached to an open project are a separate surface and do not add this training tool automatically.