Estimate Run
Minutes and tokens for the create body, from throughput measured on this robot’s own runs. Tokens are reserved at create and whatever training does not use is refunded.
curl --request POST \
--url https://api.kiteml.com/v1/rl_runs/estimate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"budget": {
"iterations": 500,
"max_tokens": 400
},
"description": "Walk forward at a steady pace with a level body and alternating feet.",
"from": {
"policy": "4d574ce4c547"
},
"hardware_tier": "gcp_gpu_l4",
"metadata": {
"example": "rl_runs/walk.json"
},
"outputs": {
"formats": [
"onnx",
"pt",
"torchscript"
],
"videos": [
{
"command": {
"vx": 0.3
},
"seconds": 8
}
]
},
"robot": "open_duck_mini_v2",
"seeds": 1,
"task": {
"commands": {
"vx": [
0.2,
0.4
],
"vy": [
-0.05,
0.05
],
"yaw": [
-0.2,
0.2
]
},
"objective": "velocity"
},
"title": "Open Duck: steady walk (fine-tuned)"
}
'import requests
url = "https://api.kiteml.com/v1/rl_runs/estimate"
payload = {
"budget": {
"iterations": 500,
"max_tokens": 400
},
"description": "Walk forward at a steady pace with a level body and alternating feet.",
"from": { "policy": "4d574ce4c547" },
"hardware_tier": "gcp_gpu_l4",
"metadata": { "example": "rl_runs/walk.json" },
"outputs": {
"formats": ["onnx", "pt", "torchscript"],
"videos": [
{
"command": { "vx": 0.3 },
"seconds": 8
}
]
},
"robot": "open_duck_mini_v2",
"seeds": 1,
"task": {
"commands": {
"vx": [0.2, 0.4],
"vy": [-0.05, 0.05],
"yaw": [-0.2, 0.2]
},
"objective": "velocity"
},
"title": "Open Duck: steady walk (fine-tuned)"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
budget: {iterations: 500, max_tokens: 400},
description: 'Walk forward at a steady pace with a level body and alternating feet.',
from: {policy: '4d574ce4c547'},
hardware_tier: 'gcp_gpu_l4',
metadata: {example: 'rl_runs/walk.json'},
outputs: {
formats: ['onnx', 'pt', 'torchscript'],
videos: [{command: {vx: 0.3}, seconds: 8}]
},
robot: 'open_duck_mini_v2',
seeds: 1,
task: {
commands: {vx: [0.2, 0.4], vy: [-0.05, 0.05], yaw: [-0.2, 0.2]},
objective: 'velocity'
},
title: 'Open Duck: steady walk (fine-tuned)'
})
};
fetch('https://api.kiteml.com/v1/rl_runs/estimate', 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/rl_runs/estimate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'budget' => [
'iterations' => 500,
'max_tokens' => 400
],
'description' => 'Walk forward at a steady pace with a level body and alternating feet.',
'from' => [
'policy' => '4d574ce4c547'
],
'hardware_tier' => 'gcp_gpu_l4',
'metadata' => [
'example' => 'rl_runs/walk.json'
],
'outputs' => [
'formats' => [
'onnx',
'pt',
'torchscript'
],
'videos' => [
[
'command' => [
'vx' => 0.3
],
'seconds' => 8
]
]
],
'robot' => 'open_duck_mini_v2',
'seeds' => 1,
'task' => [
'commands' => [
'vx' => [
0.2,
0.4
],
'vy' => [
-0.05,
0.05
],
'yaw' => [
-0.2,
0.2
]
],
'objective' => 'velocity'
],
'title' => 'Open Duck: steady walk (fine-tuned)'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.kiteml.com/v1/rl_runs/estimate"
payload := strings.NewReader("{\n \"budget\": {\n \"iterations\": 500,\n \"max_tokens\": 400\n },\n \"description\": \"Walk forward at a steady pace with a level body and alternating feet.\",\n \"from\": {\n \"policy\": \"4d574ce4c547\"\n },\n \"hardware_tier\": \"gcp_gpu_l4\",\n \"metadata\": {\n \"example\": \"rl_runs/walk.json\"\n },\n \"outputs\": {\n \"formats\": [\n \"onnx\",\n \"pt\",\n \"torchscript\"\n ],\n \"videos\": [\n {\n \"command\": {\n \"vx\": 0.3\n },\n \"seconds\": 8\n }\n ]\n },\n \"robot\": \"open_duck_mini_v2\",\n \"seeds\": 1,\n \"task\": {\n \"commands\": {\n \"vx\": [\n 0.2,\n 0.4\n ],\n \"vy\": [\n -0.05,\n 0.05\n ],\n \"yaw\": [\n -0.2,\n 0.2\n ]\n },\n \"objective\": \"velocity\"\n },\n \"title\": \"Open Duck: steady walk (fine-tuned)\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.kiteml.com/v1/rl_runs/estimate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"budget\": {\n \"iterations\": 500,\n \"max_tokens\": 400\n },\n \"description\": \"Walk forward at a steady pace with a level body and alternating feet.\",\n \"from\": {\n \"policy\": \"4d574ce4c547\"\n },\n \"hardware_tier\": \"gcp_gpu_l4\",\n \"metadata\": {\n \"example\": \"rl_runs/walk.json\"\n },\n \"outputs\": {\n \"formats\": [\n \"onnx\",\n \"pt\",\n \"torchscript\"\n ],\n \"videos\": [\n {\n \"command\": {\n \"vx\": 0.3\n },\n \"seconds\": 8\n }\n ]\n },\n \"robot\": \"open_duck_mini_v2\",\n \"seeds\": 1,\n \"task\": {\n \"commands\": {\n \"vx\": [\n 0.2,\n 0.4\n ],\n \"vy\": [\n -0.05,\n 0.05\n ],\n \"yaw\": [\n -0.2,\n 0.2\n ]\n },\n \"objective\": \"velocity\"\n },\n \"title\": \"Open Duck: steady walk (fine-tuned)\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.kiteml.com/v1/rl_runs/estimate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"budget\": {\n \"iterations\": 500,\n \"max_tokens\": 400\n },\n \"description\": \"Walk forward at a steady pace with a level body and alternating feet.\",\n \"from\": {\n \"policy\": \"4d574ce4c547\"\n },\n \"hardware_tier\": \"gcp_gpu_l4\",\n \"metadata\": {\n \"example\": \"rl_runs/walk.json\"\n },\n \"outputs\": {\n \"formats\": [\n \"onnx\",\n \"pt\",\n \"torchscript\"\n ],\n \"videos\": [\n {\n \"command\": {\n \"vx\": 0.3\n },\n \"seconds\": 8\n }\n ]\n },\n \"robot\": \"open_duck_mini_v2\",\n \"seeds\": 1,\n \"task\": {\n \"commands\": {\n \"vx\": [\n 0.2,\n 0.4\n ],\n \"vy\": [\n -0.05,\n 0.05\n ],\n \"yaw\": [\n -0.2,\n 0.2\n ]\n },\n \"objective\": \"velocity\"\n },\n \"title\": \"Open Duck: steady walk (fine-tuned)\"\n}"
response = http.request(request)
puts response.read_body{
"capped": false,
"minutes_per_run": 9.1,
"object": "rl_estimate",
"runs": 1,
"startup_minutes": 5,
"tokens": 167,
"tokens_per_run": 167
}{
"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 Body
Train a policy. Only robot and task.objective are required.
See GET /v1/rl_runs/catalog
What to learn.
Show child attributes
Show child attributes
The dated trainer to use (default: the latest, or the parent's for a fork or continue of your run). A run keeps its engine
Show child attributes
Show child attributes
A count (1-5) or explicit seeds: one run per seed, sharing a group_id
Start from another policy instead of from scratch.
Show child attributes
Show child attributes
Extras beyond what every run produces (ONNX, the checkpoint, the scene, one clip, the report).
Show child attributes
Show child attributes
See GET /v1/rl_runs/catalog (default gcp_gpu_l4)
public lists the run in the policy catalog once it finishes with a pass verdict
private, public 120What the behavior should look like; the report's judge compares the clip against it
2000Your labels, echoed on the run
Show child attributes
Show child attributes
Echoed on the run and its events
Response
Successful Response
Training minutes, from throughput measured on this robot
Reserved at create; unused tokens are refunded
budget.max_tokens will stop the run before iterations
Getting a machine and compiling; not billed
rl_estimate "rl_estimate"curl --request POST \
--url https://api.kiteml.com/v1/rl_runs/estimate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"budget": {
"iterations": 500,
"max_tokens": 400
},
"description": "Walk forward at a steady pace with a level body and alternating feet.",
"from": {
"policy": "4d574ce4c547"
},
"hardware_tier": "gcp_gpu_l4",
"metadata": {
"example": "rl_runs/walk.json"
},
"outputs": {
"formats": [
"onnx",
"pt",
"torchscript"
],
"videos": [
{
"command": {
"vx": 0.3
},
"seconds": 8
}
]
},
"robot": "open_duck_mini_v2",
"seeds": 1,
"task": {
"commands": {
"vx": [
0.2,
0.4
],
"vy": [
-0.05,
0.05
],
"yaw": [
-0.2,
0.2
]
},
"objective": "velocity"
},
"title": "Open Duck: steady walk (fine-tuned)"
}
'import requests
url = "https://api.kiteml.com/v1/rl_runs/estimate"
payload = {
"budget": {
"iterations": 500,
"max_tokens": 400
},
"description": "Walk forward at a steady pace with a level body and alternating feet.",
"from": { "policy": "4d574ce4c547" },
"hardware_tier": "gcp_gpu_l4",
"metadata": { "example": "rl_runs/walk.json" },
"outputs": {
"formats": ["onnx", "pt", "torchscript"],
"videos": [
{
"command": { "vx": 0.3 },
"seconds": 8
}
]
},
"robot": "open_duck_mini_v2",
"seeds": 1,
"task": {
"commands": {
"vx": [0.2, 0.4],
"vy": [-0.05, 0.05],
"yaw": [-0.2, 0.2]
},
"objective": "velocity"
},
"title": "Open Duck: steady walk (fine-tuned)"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
budget: {iterations: 500, max_tokens: 400},
description: 'Walk forward at a steady pace with a level body and alternating feet.',
from: {policy: '4d574ce4c547'},
hardware_tier: 'gcp_gpu_l4',
metadata: {example: 'rl_runs/walk.json'},
outputs: {
formats: ['onnx', 'pt', 'torchscript'],
videos: [{command: {vx: 0.3}, seconds: 8}]
},
robot: 'open_duck_mini_v2',
seeds: 1,
task: {
commands: {vx: [0.2, 0.4], vy: [-0.05, 0.05], yaw: [-0.2, 0.2]},
objective: 'velocity'
},
title: 'Open Duck: steady walk (fine-tuned)'
})
};
fetch('https://api.kiteml.com/v1/rl_runs/estimate', 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/rl_runs/estimate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'budget' => [
'iterations' => 500,
'max_tokens' => 400
],
'description' => 'Walk forward at a steady pace with a level body and alternating feet.',
'from' => [
'policy' => '4d574ce4c547'
],
'hardware_tier' => 'gcp_gpu_l4',
'metadata' => [
'example' => 'rl_runs/walk.json'
],
'outputs' => [
'formats' => [
'onnx',
'pt',
'torchscript'
],
'videos' => [
[
'command' => [
'vx' => 0.3
],
'seconds' => 8
]
]
],
'robot' => 'open_duck_mini_v2',
'seeds' => 1,
'task' => [
'commands' => [
'vx' => [
0.2,
0.4
],
'vy' => [
-0.05,
0.05
],
'yaw' => [
-0.2,
0.2
]
],
'objective' => 'velocity'
],
'title' => 'Open Duck: steady walk (fine-tuned)'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.kiteml.com/v1/rl_runs/estimate"
payload := strings.NewReader("{\n \"budget\": {\n \"iterations\": 500,\n \"max_tokens\": 400\n },\n \"description\": \"Walk forward at a steady pace with a level body and alternating feet.\",\n \"from\": {\n \"policy\": \"4d574ce4c547\"\n },\n \"hardware_tier\": \"gcp_gpu_l4\",\n \"metadata\": {\n \"example\": \"rl_runs/walk.json\"\n },\n \"outputs\": {\n \"formats\": [\n \"onnx\",\n \"pt\",\n \"torchscript\"\n ],\n \"videos\": [\n {\n \"command\": {\n \"vx\": 0.3\n },\n \"seconds\": 8\n }\n ]\n },\n \"robot\": \"open_duck_mini_v2\",\n \"seeds\": 1,\n \"task\": {\n \"commands\": {\n \"vx\": [\n 0.2,\n 0.4\n ],\n \"vy\": [\n -0.05,\n 0.05\n ],\n \"yaw\": [\n -0.2,\n 0.2\n ]\n },\n \"objective\": \"velocity\"\n },\n \"title\": \"Open Duck: steady walk (fine-tuned)\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.kiteml.com/v1/rl_runs/estimate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"budget\": {\n \"iterations\": 500,\n \"max_tokens\": 400\n },\n \"description\": \"Walk forward at a steady pace with a level body and alternating feet.\",\n \"from\": {\n \"policy\": \"4d574ce4c547\"\n },\n \"hardware_tier\": \"gcp_gpu_l4\",\n \"metadata\": {\n \"example\": \"rl_runs/walk.json\"\n },\n \"outputs\": {\n \"formats\": [\n \"onnx\",\n \"pt\",\n \"torchscript\"\n ],\n \"videos\": [\n {\n \"command\": {\n \"vx\": 0.3\n },\n \"seconds\": 8\n }\n ]\n },\n \"robot\": \"open_duck_mini_v2\",\n \"seeds\": 1,\n \"task\": {\n \"commands\": {\n \"vx\": [\n 0.2,\n 0.4\n ],\n \"vy\": [\n -0.05,\n 0.05\n ],\n \"yaw\": [\n -0.2,\n 0.2\n ]\n },\n \"objective\": \"velocity\"\n },\n \"title\": \"Open Duck: steady walk (fine-tuned)\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.kiteml.com/v1/rl_runs/estimate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"budget\": {\n \"iterations\": 500,\n \"max_tokens\": 400\n },\n \"description\": \"Walk forward at a steady pace with a level body and alternating feet.\",\n \"from\": {\n \"policy\": \"4d574ce4c547\"\n },\n \"hardware_tier\": \"gcp_gpu_l4\",\n \"metadata\": {\n \"example\": \"rl_runs/walk.json\"\n },\n \"outputs\": {\n \"formats\": [\n \"onnx\",\n \"pt\",\n \"torchscript\"\n ],\n \"videos\": [\n {\n \"command\": {\n \"vx\": 0.3\n },\n \"seconds\": 8\n }\n ]\n },\n \"robot\": \"open_duck_mini_v2\",\n \"seeds\": 1,\n \"task\": {\n \"commands\": {\n \"vx\": [\n 0.2,\n 0.4\n ],\n \"vy\": [\n -0.05,\n 0.05\n ],\n \"yaw\": [\n -0.2,\n 0.2\n ]\n },\n \"objective\": \"velocity\"\n },\n \"title\": \"Open Duck: steady walk (fine-tuned)\"\n}"
response = http.request(request)
puts response.read_body{
"capped": false,
"minutes_per_run": 9.1,
"object": "rl_estimate",
"runs": 1,
"startup_minutes": 5,
"tokens": 167,
"tokens_per_run": 167
}{
"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": {}
}
}