API docs
API reference

Fine-tuning jobs

Submit managed fine-tuning jobs and follow them from queue to trained model.

A fine-tuning job takes an uploaded dataset and a base model and produces a trained model, with the training loop, scheduling and checkpointing managed for you. Upload your data as a file, submit a job, poll until it finishes, then serve the result. Teams that need step-level control over the loop, for custom losses or reinforcement learning, use training runs instead.

A job moves through queued and running to succeeded, failed or cancelled. While it runs, Stream job events carries the loss curve and any warnings. Once it succeeds, Retrieve a fine-tuning job returns the result_model path you hand to Create a sampler to start serving.

Create a fine-tuning job

POST/v1/fine-tuning/jobsscope: train

Submits a fine-tuning job. The training file must have finished validating and reached ready before you submit; see Retrieve a dataset.

Body parameters

base_modelstringrequired

The base model to fine-tune, for example Qwen/Qwen3-8B.

training_filestringrequired

ID of an uploaded fine-tune file to train on.

validation_filestring

ID of a held-out file used to compute validation loss during training.

methodstringdefault: sft

Training method: sft (supervised fine-tuning) or dpo (direct preference optimisation).

hyperparametersobject

An object of epochs, learning_rate, batch_size and lora_rank, all optional. Anything you omit is chosen automatically; the job response shows the resolved values.

suffixstring

Names the output model, so you can tell your fine-tunes apart later.

Submitting is not idempotent: retrying a timed-out request can start a duplicate job. Send an Idempotency-Key header if your client retries automatically. See Errors and retries.

curl https://api.nucleus-ai.io/v1/fine-tuning/jobs \
  -H "Authorization: Bearer $NUCLEUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "base_model": "Qwen/Qwen3-8B",
    "training_file": "file_9fQ2x",
    "hyperparameters": { "epochs": 3, "lora_rank": 32 },
    "suffix": "support-assistant"
  }'
201 Created
{
  "id": "ftjob_7Kd1p",
  "status": "queued",
  "base_model": "Qwen/Qwen3-8B",
  "training_file": "file_9fQ2x",
  "hyperparameters": {
    "epochs": 3,
    "lora_rank": 32,
    "learning_rate": "auto"
  },
  "result_model": null
}

List fine-tuning jobs

GET/v1/fine-tuning/jobsscope: read

Returns your fine-tuning jobs, so you can see what is queued, running and finished across the account. See Pagination for how limit, offset and the cursor object behave across list endpoints.

Query parameters

statusstring

Filter to one status: queued, running, succeeded, failed or cancelled.

project_idstring

Only jobs in this project.

limitinteger

Maximum number of jobs to return.

offsetinteger

Number of jobs to skip from the start of the list.

curl "https://api.nucleus-ai.io/v1/fine-tuning/jobs?status=running" \
  -H "Authorization: Bearer $NUCLEUS_API_KEY"
200 OK
{
  "data": [
    {
      "id": "ftjob_7Kd1p",
      "status": "running",
      "progress": 0.42
    }
  ],
  "cursor": { "offset": 0, "total_count": 3 }
}

Retrieve a fine-tuning job

GET/v1/fine-tuning/jobs/{job_id}scope: read

Returns one job, including progress, trained_tokens and, on success, the trained model. This is the endpoint to poll after submitting.

result_model is a nucleus:// path: pass it straight to Create a sampler to serve the model. It is the handoff point from training to serving. training_run_id identifies the underlying training run, and metrics reports the final training and validation loss.

Path parameters

job_idstringrequired

ID of the job, from the create response.

curl https://api.nucleus-ai.io/v1/fine-tuning/jobs/ftjob_7Kd1p \
  -H "Authorization: Bearer $NUCLEUS_API_KEY"
200 OK
{
  "id": "ftjob_7Kd1p",
  "status": "succeeded",
  "progress": 1.0,
  "trained_tokens": 8420117,
  "training_run_id": "run_3Bz",
  "result_model": "nucleus://run_3Bz:train:0/sampler_weights/000240",
  "metrics": {
    "final_loss": 0.72,
    "val_loss": 0.81
  }
}

Cancel a fine-tuning job

POST/v1/fine-tuning/jobs/{job_id}/cancelscope: train

Cancels a queued or running job. Cancelling stops the run and stops the meter: billed_tokens_so_far is the total you are charged for. The job reports cancelling while it shuts down, then settles at cancelled.

Path parameters

job_idstringrequired

ID of the job to cancel.

curl -X POST https://api.nucleus-ai.io/v1/fine-tuning/jobs/ftjob_7Kd1p/cancel \
  -H "Authorization: Bearer $NUCLEUS_API_KEY"
200 OK
{
  "id": "ftjob_7Kd1p",
  "status": "cancelling",
  "billed_tokens_so_far": 3910442
}

Stream job events

GET/v1/fine-tuning/jobs/{job_id}/eventsscope: read

Returns the job's event log: step-by-step loss values, epoch boundaries and warnings such as validation loss rising. This is how you watch the loss curve and judge whether a run is going well while it is still spending tokens.

With stream=true the response is Server-Sent Events (text/event-stream) and events arrive as the trainer emits them; use curl -N to disable buffering. Without it you get the events accumulated so far in one response. Each event carries an id; if a stream disconnects, pass the last ID you saw as after to resume without replaying old events.

Query parameters

afterstring

Event ID to resume from. Only events after this ID are returned.

streamboolean

When true, stream events over SSE as they happen.

curl -N "https://api.nucleus-ai.io/v1/fine-tuning/jobs/ftjob_7Kd1p/events?stream=true" \
  -H "Authorization: Bearer $NUCLEUS_API_KEY"
200 OK
{ "id": "evt_04", "level": "info",
  "step": 120, "loss": 0.94,
  "message": "epoch 2/3" }
{ "id": "evt_05", "level": "warn",
  "message": "val loss rising, possible overfit" }
Fine-tuning jobs | Nucleus AI API