Tasks
Task Specs — a customer claim formalized as a declarative, versioned protocol with instrument-bound success predicates. Lifecycle: draft → piloting → frozen@vN. Frozen specs are immutable; changes create the next revision.
POST /v1/tasks
Create a Task Spec
Formalize a claim as a declarative, versioned Task Spec. Every success predicate is validated at creation against the instruments available in the target environment class; a predicate that binds to no instrument fails with `contract_validation_failed`. The new spec starts in `draft`.
| Parameter | In | Type | Description |
|---|---|---|---|
name * | body | string | |
visibility | body | private | published | Private tasks stay the customer's method; published tasks join the public catalogue and become cross-customer comparable. |
initial_conditions * | body | object | Named objects with poses, tolerances, and randomization zones. Kit hardware is referenced as `kit/<name>`. |
success_predicates * | body | array<object> | Each predicate must bind to an available instrument in the target environment class; validated at creation. |
instructions | body | object | Instruction distribution for language-conditioned policies. Held-out paraphrases are never sampled during iteration and are reported separately. |
stages | body | array<object> | Ordered stage predicates; per-stage rates ship in results. |
envelope | body | object | The claim's declared boundaries. Out-of-scope declarations appear verbatim on reports. |
baseline | body | object | Customer's internal trials — used to sanity-check the pilot and set expectations, never published. |
Example request
{
"name": "espresso",
"visibility": "private",
"initial_conditions": {
"machine": {
"object": "kit/acme-breville",
"pose": "P1",
"tol_mm": 20
},
"cup": {
"object": "catalogue/cup-std-08",
"randomize": "zone-A"
}
},
"success_predicates": [
{
"cup_on_tray": "gt.pose(cup) within tray_zone"
},
{
"liquid_mass": "scale.delta between 25 and 40 g"
},
{
"no_spill": "vision.spill_area < 2 cm2"
},
{
"t_complete": "episode.duration < 180 s"
}
],
"instructions": {
"sampled_per_episode": [
"make an espresso",
"brew me a coffee",
"fais un espresso"
],
"held_out": [
"prepare a single shot"
]
},
"stages": [
{
"grasp_cup": "gt.pose(cup) in gripper"
},
{
"cup_placed": "gt.pose(cup) within drip_zone"
},
{
"extraction": "scale.delta > 0 within 60s"
},
{
"served": "all success_predicates"
}
],
"envelope": {
"lighting": [
"3000K",
"5600K"
],
"distractors": "set-B",
"out_of_scope": [
"oat_milk"
]
},
"baseline": {
"internal_trials": 30,
"internal_rate": 0.87
}
}Example response (201)
{
"id": "task_espresso_01",
"object": "task",
"name": "espresso",
"rev": null,
"status": "draft",
"visibility": "private",
"created": "2026-08-20T09:14:02Z",
"frozen": null,
"signatures": []
}GET /v1/tasks
List Task Specs
All Task Specs visible to the key's account, drafts and frozen revisions alike.
Example response (200)
{
"object": "list",
"url": "/v1/tasks",
"data": [
{
"id": "task_espresso_01",
"object": "task",
"name": "espresso",
"rev": "espresso@v1",
"status": "frozen",
"visibility": "private",
"created": "2026-08-20T09:14:02Z",
"frozen": "2026-08-24T16:40:11Z",
"signatures": [
"acct_acme",
"roborama"
],
"initial_conditions": {
"machine": {
"object": "kit/acme-breville",
"pose": "P1",
"tol_mm": 20
},
"cup": {
"object": "catalogue/cup-std-08",
"randomize": "zone-A"
}
},
"success_predicates": [
{
"cup_on_tray": "gt.pose(cup) within tray_zone"
},
{
"liquid_mass": "scale.delta between 22 and 42 g"
},
{
"no_spill": "vision.spill_area < 2 cm2"
},
{
"t_complete": "episode.duration < 180 s"
}
],
"instructions": {
"sampled_per_episode": [
"make an espresso",
"brew me a coffee",
"fais un espresso"
],
"held_out": [
"prepare a single shot"
]
},
"stages": [
{
"grasp_cup": "gt.pose(cup) in gripper"
},
{
"cup_placed": "gt.pose(cup) within drip_zone"
},
{
"extraction": "scale.delta > 0 within 60s"
},
{
"served": "all success_predicates"
}
],
"envelope": {
"lighting": [
"3000K",
"5600K"
],
"distractors": "set-B",
"out_of_scope": [
"oat_milk"
]
},
"pilot": {
"run_id": "run_9088",
"robot": "g1-edu-pro@fw2.3",
"episodes": 25,
"amendments": 1
}
}
],
"has_more": false
}GET /v1/tasks/{task_id}
Get a Task Spec
Fetch a Task Spec by id or by frozen revision (`espresso@v1`).
| Parameter | In | Type | Description |
|---|---|---|---|
task_id * | path | string | Task id (`task_espresso_01`) or frozen revision (`espresso@v1`). |
Example response (200)
{
"id": "task_espresso_01",
"object": "task",
"name": "espresso",
"rev": "espresso@v1",
"status": "frozen",
"visibility": "private",
"created": "2026-08-20T09:14:02Z",
"frozen": "2026-08-24T16:40:11Z",
"signatures": [
"acct_acme",
"roborama"
],
"initial_conditions": {
"machine": {
"object": "kit/acme-breville",
"pose": "P1",
"tol_mm": 20
},
"cup": {
"object": "catalogue/cup-std-08",
"randomize": "zone-A"
}
},
"success_predicates": [
{
"cup_on_tray": "gt.pose(cup) within tray_zone"
},
{
"liquid_mass": "scale.delta between 22 and 42 g"
},
{
"no_spill": "vision.spill_area < 2 cm2"
},
{
"t_complete": "episode.duration < 180 s"
}
],
"instructions": {
"sampled_per_episode": [
"make an espresso",
"brew me a coffee",
"fais un espresso"
],
"held_out": [
"prepare a single shot"
]
},
"stages": [
{
"grasp_cup": "gt.pose(cup) in gripper"
},
{
"cup_placed": "gt.pose(cup) within drip_zone"
},
{
"extraction": "scale.delta > 0 within 60s"
},
{
"served": "all success_predicates"
}
],
"envelope": {
"lighting": [
"3000K",
"5600K"
],
"distractors": "set-B",
"out_of_scope": [
"oat_milk"
]
},
"pilot": {
"run_id": "run_9088",
"robot": "g1-edu-pro@fw2.3",
"episodes": 25,
"amendments": 1
}
}POST /v1/tasks/{task_id}/pilot
Run a pilot (calibration session)
A small calibration session on the named robot. The customer watches live via `stream_url`; the session moves the spec from `draft` to `piloting`. Pilot episodes calibrate the method — they are not evidence and never appear in verification reports.
| Parameter | In | Type | Description |
|---|---|---|---|
task_id * | path | string | |
robot * | body | string | |
episodes | body | integer |
Example request
{
"robot": "g1-edu-pro@fw2.3",
"episodes": 25
}Example response (200)
{
"run_id": "run_9088",
"robot": "g1-edu-pro@fw2.3",
"episodes": 25,
"stream_url": "wss://streams.roborama.com/cells/cell-g1-02/webrtc"
}POST /v1/tasks/{task_id}/amend
Amend a draft or piloting Task Spec
Iterate on the method while piloting. Any TaskCreate field may be amended; amendments are rejected with `task_frozen` semantics once the spec is frozen (a frozen spec is immutable — create the next revision instead).
| Parameter | In | Type | Description |
|---|---|---|---|
task_id * | path | string | |
name | body | string | |
visibility | body | private | published | Private tasks stay the customer's method; published tasks join the public catalogue and become cross-customer comparable. |
initial_conditions | body | object | Named objects with poses, tolerances, and randomization zones. Kit hardware is referenced as `kit/<name>`. |
success_predicates | body | array<object> | Each predicate must bind to an available instrument in the target environment class; validated at creation. |
instructions | body | object | Instruction distribution for language-conditioned policies. Held-out paraphrases are never sampled during iteration and are reported separately. |
stages | body | array<object> | Ordered stage predicates; per-stage rates ship in results. |
envelope | body | object | The claim's declared boundaries. Out-of-scope declarations appear verbatim on reports. |
baseline | body | object | Customer's internal trials — used to sanity-check the pilot and set expectations, never published. |
Example request
{
"success_predicates": [
{
"cup_on_tray": "gt.pose(cup) within tray_zone"
},
{
"liquid_mass": "scale.delta between 22 and 42 g"
},
{
"no_spill": "vision.spill_area < 2 cm2"
},
{
"t_complete": "episode.duration < 180 s"
}
]
}Example response (200)
{
"id": "task_espresso_01",
"object": "task",
"name": "espresso",
"rev": null,
"status": "piloting",
"visibility": "private",
"created": "2026-08-20T09:14:02Z",
"frozen": null,
"signatures": [],
"pilot": {
"run_id": "run_9088",
"robot": "g1-edu-pro@fw2.3",
"episodes": 25,
"amendments": 1
},
"success_predicates": [
{
"cup_on_tray": "gt.pose(cup) within tray_zone"
},
{
"liquid_mass": "scale.delta between 22 and 42 g"
},
{
"no_spill": "vision.spill_area < 2 cm2"
},
{
"t_complete": "episode.duration < 180 s"
}
]
}POST /v1/tasks/{task_id}/freeze
Freeze the Task Spec
Freezes the current method as the next immutable revision (`espresso@v1`), mutually signed. Every verification report cites the frozen revision. Changes after a freeze create `@v2`; results across revisions are not silently comparable.
| Parameter | In | Type | Description |
|---|---|---|---|
task_id * | path | string |
Example response (200)
{
"id": "task_espresso_01",
"object": "task",
"name": "espresso",
"rev": "espresso@v1",
"status": "frozen",
"visibility": "private",
"created": "2026-08-20T09:14:02Z",
"frozen": "2026-08-24T16:40:11Z",
"signatures": [
"acct_acme",
"roborama"
]
}