curl --request GET \
--url https://api.kiteml.com/v1/training_runs/{run_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.kiteml.com/v1/training_runs/{run_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.kiteml.com/v1/training_runs/{run_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.kiteml.com/v1/training_runs/{run_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.kiteml.com/v1/training_runs/{run_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.kiteml.com/v1/training_runs/{run_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.kiteml.com/v1/training_runs/{run_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"cameras": {},
"completed_at": "2026-09-27T15:41:52.664301+00:00",
"config": {
"batch_size": 8,
"eval_enabled": false,
"save_freq": 1000,
"steps": 30000
},
"created_at": "2026-09-27T14:02:11.482913+00:00",
"dataset": {
"uri": "lerobot/svla_so101_pickplace"
},
"eval": {},
"group_id": "5f0c2e9a7b1d4c3e8f6a2b9d0c1e7f35",
"hardware_tier": "gcp_gpu_t4",
"id": "trn_01K65Z3N8Q4W2H7R9T6Y1B3C5D",
"metrics": {
"loss": 0.043,
"max_steps": 30000,
"step": 30000
},
"object": "training_run",
"output": {
"checkpoint_count": 30,
"hf_push_status": "ok",
"hf_repo_id": "your-hf-user/act-pickplace",
"hf_url": "https://huggingface.co/your-hf-user/act-pickplace",
"latest_checkpoint": {
"artifact_uri": "gs://example-bucket/jobs/7c1e9f0a2b3d4e5f8a9b0c1d2e3f4a5b/artifacts/lerobot/checkpoints/030000/pretrained_model/",
"created_at": "2026-09-27T15:38:40.120394+00:00",
"download_url": "/v1/training_runs/trn_01K65Z3N8Q4W2H7R9T6Y1B3C5D/checkpoints/30000/download",
"object": "training_checkpoint",
"step": 30000
}
},
"phase": "completed",
"policy": "act",
"progress": 1,
"robot": "so101_follower",
"started_at": "2026-09-27T14:02:13.107554+00:00",
"status": "succeeded",
"status_message": "Completed",
"tokens": {
"charged": 500,
"refunded": 0
},
"webhook_metadata": {
"ref": "nightly-42"
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"request_id": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"request_id": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"request_id": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"request_id": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"request_id": "<string>",
"details": {}
}
}Get Training Run
Status, live progress, metrics, and output for one run.
curl --request GET \
--url https://api.kiteml.com/v1/training_runs/{run_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.kiteml.com/v1/training_runs/{run_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.kiteml.com/v1/training_runs/{run_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.kiteml.com/v1/training_runs/{run_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.kiteml.com/v1/training_runs/{run_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.kiteml.com/v1/training_runs/{run_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.kiteml.com/v1/training_runs/{run_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"cameras": {},
"completed_at": "2026-09-27T15:41:52.664301+00:00",
"config": {
"batch_size": 8,
"eval_enabled": false,
"save_freq": 1000,
"steps": 30000
},
"created_at": "2026-09-27T14:02:11.482913+00:00",
"dataset": {
"uri": "lerobot/svla_so101_pickplace"
},
"eval": {},
"group_id": "5f0c2e9a7b1d4c3e8f6a2b9d0c1e7f35",
"hardware_tier": "gcp_gpu_t4",
"id": "trn_01K65Z3N8Q4W2H7R9T6Y1B3C5D",
"metrics": {
"loss": 0.043,
"max_steps": 30000,
"step": 30000
},
"object": "training_run",
"output": {
"checkpoint_count": 30,
"hf_push_status": "ok",
"hf_repo_id": "your-hf-user/act-pickplace",
"hf_url": "https://huggingface.co/your-hf-user/act-pickplace",
"latest_checkpoint": {
"artifact_uri": "gs://example-bucket/jobs/7c1e9f0a2b3d4e5f8a9b0c1d2e3f4a5b/artifacts/lerobot/checkpoints/030000/pretrained_model/",
"created_at": "2026-09-27T15:38:40.120394+00:00",
"download_url": "/v1/training_runs/trn_01K65Z3N8Q4W2H7R9T6Y1B3C5D/checkpoints/30000/download",
"object": "training_checkpoint",
"step": 30000
}
},
"phase": "completed",
"policy": "act",
"progress": 1,
"robot": "so101_follower",
"started_at": "2026-09-27T14:02:13.107554+00:00",
"status": "succeeded",
"status_message": "Completed",
"tokens": {
"charged": 500,
"refunded": 0
},
"webhook_metadata": {
"ref": "nightly-42"
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"request_id": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"request_id": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"request_id": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"request_id": "<string>",
"details": {}
}
}{
"error": {
"type": "<string>",
"code": "<string>",
"message": "<string>",
"param": "<string>",
"request_id": "<string>",
"details": {}
}
}Authorizations
A Kite API key (kite_...), from Platform API → Keys in the dashboard.
Headers
The dated contract your code was written against. Without it you get 2026-09-27; every response says which version served it.
2026-09-27 Path Parameters
Response
The run, read live
One policy trained on one GPU.
trn_ + a time-ordered ULID
training_run "training_run"processing, succeeded, failed, canceled; an open set
Finer than status, e.g. provisioning, preparing, downloading_dataset, training, completed, failed, cancelled. Only GET /v1/training_runs/{id} reads it: null in list, create and cancel responses
phase in words, e.g. Provisioning GPU…
0 <= x <= 1Why, when failed
Show child attributes
Show child attributes
The LeRobot policy type (see GET /v1/training_policies)
The robot tag from create (a label only)
See GET /v1/hardware_tiers
Shared by the runs one create started, one per policy
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Live from the trainer on GET /v1/training_runs/{id}; elsewhere, the last values stored
Show child attributes
Show child attributes
Once the trainer has reported on evaluation (a finished run has); null in list, create and cancel responses
Show child attributes
Show child attributes
What the run has produced
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Echoed from create
When the GPU job was submitted
When it became succeeded, failed or canceled