Character training
Train a high-fidelity model on a character over REST, poll the training, remove the model, and learn when Generate Image uses the trained model.
Available on Nodaro Cloud
Character training creates a dedicated model of one character from its images, for the closest likeness in Generate Image. You start a training with one call, poll it until it finishes, and remove the model when you no longer need it. After training, Generate Image uses the trained model automatically whenever a prompt mentions that character.
Character training runs on Nodaro Cloud only; on self-hosted installs the routes do not exist and answer 404. On a self-hosted install, keep a character consistent with its approved portrait and reference images, as described in Characters. The routes take a bearer token and act only on your own characters. See Authentication.
Endpoints
| Method | Path | What it does |
|---|---|---|
POST | /v1/characters/:id/train | Start a training. Reserves 1,500 credits. |
GET | /v1/characters/:id/training | Get the training status. |
DELETE | /v1/characters/:id/lora | Cancel a training in progress, or remove the trained model. |
Before you train
The character needs at least 4 different images. Nodaro collects them from the character, in this order, removes duplicates, and trains on up to 20:
- The approved portrait.
- The reference photos.
- The expressions, the poses, the head angles and the body angles.
- The lighting variants.
Character sheets do not count, because their views repeat the angles. When a character has fewer than 4 images, generate a few angles and expressions first with POST /v1/generate-character-asset; see Characters.
Start a training
POST /v1/characters/:id/train reserves 1,500 credits and starts the training. It answers 202 with the training's job id, its id and the character's trigger word. You never need to type the trigger word: Nodaro adds it to prompts for you.
curl -X POST https://app.nodaro.ai/v1/characters/3f6c2a9e-8d41-4b7a-9c35-1e2f7a6b0d94/train \
-H "Authorization: Bearer $NODARO_API_KEY"import { createClient, StaticTokenAuth } from '@nodaro/sdk'
const client = createClient({
baseUrl: 'https://app.nodaro.ai',
auth: new StaticTokenAuth(process.env.NODARO_API_KEY!),
})
// The SDK has no training methods yet; its generic request method calls the route.
const training = await client.request('POST', `/v1/characters/${characterId}/train`){
"jobId": "7a9c1e3b-5d2f-4b8a-9c6e-1f3d5b7a9c2e",
"trainingId": "q4m8x2k6p1",
"triggerWord": "TOK_kira_a1b2c3"
}A double click is safe: while a training is queued or running, another start answers 409 already_training_or_not_found and reserves nothing. Each token may start 3 trainings per minute.
Follow the training
GET /v1/characters/:id/training returns the training's state. A training takes about 15 minutes. Poll every few seconds; the editor polls every 8 seconds.
curl https://app.nodaro.ai/v1/characters/3f6c2a9e-8d41-4b7a-9c35-1e2f7a6b0d94/training \
-H "Authorization: Bearer $NODARO_API_KEY"type Training = { status: string; error: string | null; triggerWord: string | null }
const path = `/v1/characters/${characterId}/training`
let state = await client.request<Training>('GET', path)
while (state.status === 'queued' || state.status === 'training') {
await new Promise((resolve) => setTimeout(resolve, 8000))
state = await client.request<Training>('GET', path)
}{
"status": "succeeded",
"trainingId": "q4m8x2k6p1",
"error": null,
"trainedAt": "2026-09-20T11:42:08Z",
"version": "b81f4c0e9d27",
"triggerWord": "TOK_kira_a1b2c3",
"imageCount": 12
}| Field | What it holds |
|---|---|
status | untrained, queued, training, succeeded, failed or cancelled. |
trainingId | The current or last training, or null. |
error | Why the training failed, or null. |
trainedAt | When the model finished training, or null. |
version | The trained model's version, or null. |
triggerWord | The word that calls up the character in the trained model, or null. |
imageCount | How many images the model was trained on, or null. |
Generate images with the trained model
Once the status is succeeded, run Generate Image with a prompt that mentions exactly one trained character with @, and with that character wired into the node. Nodaro then uses the trained model instead of the selected model and the reference images:
- Automatic. The trigger word is put at the start of the prompt for you, and your
@mentions are removed from the text. - 20 credits per image. The trained model's price replaces the selected model's price.
- One trained character at a time. When the prompt mentions two or more trained characters, Generate Image falls back to the selected model with reference images.
- Generate Image only. Other nodes, such as Modify Image and the video nodes, keep using the character's reference images.
See Run a single node for the Generate Image request, and Character training for the same feature in the editor.
Re-train or remove the model
- Re-train. Start a training again at any time after one has succeeded, failed or been cancelled. It costs 1,500 credits every time and replaces the previous model.
- Remove.
DELETE /v1/characters/:id/loracancels a training in progress and refunds its credits, deletes the trained model, and clears the character's training fields. It returns{ ok: true }. Generations go back to reference images. - Archive the character. Archiving the character also cancels a training in progress, refunds its credits and deletes the trained model.
curl -X DELETE https://app.nodaro.ai/v1/characters/3f6c2a9e-8d41-4b7a-9c35-1e2f7a6b0d94/lora \
-H "Authorization: Bearer $NODARO_API_KEY"Credits
| Action | Credits |
|---|---|
| A training | 1,500, refunded when the training fails or is cancelled. |
| A re-training | 1,500 every time. |
| An image from the trained model | 20 per image, instead of the selected model's price. |
See Credits for balances and transactions.
Errors
| Status | Code | Meaning |
|---|---|---|
400 | insufficient_training_images | The character has fewer than 4 different images. Add angles or expressions and try again. |
401 | unauthorized | The token is missing, invalid or revoked. |
402 | insufficient_credits | The account cannot cover the 1,500 credits. |
404 | not_found | No such character belongs to you, or the instance is not Nodaro Cloud. |
409 | already_training_or_not_found | A training is already queued or running for this character, or the character is not yours. |
429 | — | More than 3 training starts in a minute from this token. |
502 | training_dispatch_failed | The training service refused the request. The credits are refunded. |
503 | public_url_not_configured, webhook_not_configured | Training is not configured on this instance. |
Frequently asked questions
Related
Character training
Characters
Generate Image
Consistent characters
Credits
Last updated on
Voice and media
Voices, voice changing, multi-speaker recast, dubbing, video import, captions, trimming, audio tools and social publishing, all as REST endpoints on Nodaro.
3D scenes
Generate, edit and render editable 3D clay scenes over REST, quote and run 3D Render Pro, and read scene revisions, assets and deliveries.