curl --request PATCH \
--url https://api.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration \
--header 'Content-Type: application/json' \
--data '
{
"buffer_pct": 50
}
'import requests
url = "https://api.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration"
payload = { "buffer_pct": 50 }
headers = {"Content-Type": "application/json"}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({buffer_pct: 50})
};
fetch('https://api.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration', 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.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'buffer_pct' => 50
]),
CURLOPT_HTTPHEADER => [
"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.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration"
payload := strings.NewReader("{\n \"buffer_pct\": 50\n}")
req, _ := http.NewRequest("PATCH", url, payload)
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.patch("https://api.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration")
.header("Content-Type", "application/json")
.body("{\n \"buffer_pct\": 50\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"buffer_pct\": 50\n}"
response = http.request(request)
puts response.read_body{
"name": "<string>",
"id": "<string>",
"organization_id": "<string>",
"project_id": "<string>",
"status": "requested",
"requested_by": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"cell_specification_id": "<string>",
"cell_instance_id": "<string>",
"channel_id": "<string>",
"set_temperature_c": 123,
"thermal_chamber_id": "<string>",
"protocol_id": "<string>",
"program_id": "<string>",
"test_setup": {},
"planned_start_time": "2023-11-07T05:31:56Z",
"planned_end_time": "2023-11-07T05:31:56Z",
"estimated_duration_seconds": 2,
"setup_duration_seconds": 0,
"teardown_duration_seconds": 0,
"notes": "<string>",
"scheduled_by": "<string>",
"scheduled_at": "2023-11-07T05:31:56Z",
"started_measurement_id": "<string>",
"cancelled_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"requested_by_email": "<string>",
"scheduled_by_email": "<string>",
"channel_name": "<string>",
"cycler_id": "<string>",
"cycler_name": "<string>",
"program_name": "<string>",
"estimated_duration_status": "estimating",
"estimated_duration_job_id": "<string>",
"estimated_duration_simulation_id": "<string>",
"simulated_duration_seconds": 123,
"estimated_duration_is_exact": true,
"estimated_duration_margin_pct": 123,
"actual_duration_seconds": 123,
"estimated_duration_note": "<string>",
"estimated_duration_calculated_at": "2023-11-07T05:31:56Z"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Estimate a planned measurement's duration from its protocol
Work out how long this planned test will take, before it runs.
Simulates the whole protocol with the cell specification’s default model and
writes the total into estimated_duration_seconds — the value scheduling
books channel windows off, which until now was always typed in by hand.
buffer_pct pads the simulated figure by that percentage before booking it,
defaulting to DEFAULT_BUFFER_PCT. A protocol whose duration is fixed by the
protocol alone is never padded.
Returns immediately with estimated_duration_status set to estimating;
the job worker fills the duration in when the simulation finishes. Poll the
plan, or watch the status. When the simulation was already run for an
identical protocol and model, the estimate comes back ready instead.
For a test that has already started, use the cell measurement’s
estimate_end_time endpoint instead: that one replays the measured steps
and forecasts only what remains.
curl --request PATCH \
--url https://api.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration \
--header 'Content-Type: application/json' \
--data '
{
"buffer_pct": 50
}
'import requests
url = "https://api.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration"
payload = { "buffer_pct": 50 }
headers = {"Content-Type": "application/json"}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({buffer_pct: 50})
};
fetch('https://api.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration', 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.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'buffer_pct' => 50
]),
CURLOPT_HTTPHEADER => [
"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.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration"
payload := strings.NewReader("{\n \"buffer_pct\": 50\n}")
req, _ := http.NewRequest("PATCH", url, payload)
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.patch("https://api.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration")
.header("Content-Type", "application/json")
.body("{\n \"buffer_pct\": 50\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ionworks.com/projects/{project_id}/planned_measurements/{planned_measurement_id}/estimate_duration")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"buffer_pct\": 50\n}"
response = http.request(request)
puts response.read_body{
"name": "<string>",
"id": "<string>",
"organization_id": "<string>",
"project_id": "<string>",
"status": "requested",
"requested_by": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"cell_specification_id": "<string>",
"cell_instance_id": "<string>",
"channel_id": "<string>",
"set_temperature_c": 123,
"thermal_chamber_id": "<string>",
"protocol_id": "<string>",
"program_id": "<string>",
"test_setup": {},
"planned_start_time": "2023-11-07T05:31:56Z",
"planned_end_time": "2023-11-07T05:31:56Z",
"estimated_duration_seconds": 2,
"setup_duration_seconds": 0,
"teardown_duration_seconds": 0,
"notes": "<string>",
"scheduled_by": "<string>",
"scheduled_at": "2023-11-07T05:31:56Z",
"started_measurement_id": "<string>",
"cancelled_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"requested_by_email": "<string>",
"scheduled_by_email": "<string>",
"channel_name": "<string>",
"cycler_id": "<string>",
"cycler_name": "<string>",
"program_name": "<string>",
"estimated_duration_status": "estimating",
"estimated_duration_job_id": "<string>",
"estimated_duration_simulation_id": "<string>",
"simulated_duration_seconds": 123,
"estimated_duration_is_exact": true,
"estimated_duration_margin_pct": 123,
"actual_duration_seconds": 123,
"estimated_duration_note": "<string>",
"estimated_duration_calculated_at": "2023-11-07T05:31:56Z"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Body
Options for a planned test's duration estimate.
The body is optional on the endpoint; omitting it takes the default margin.
0 <= x <= 100Response
Successful Response
A planned measurement row returned by the API.
1 - 255Lifecycle state for a planned measurement.
requested, scheduled, in_progress, completed, cancelled Cell specification the requester wants tested (set at request time).
Cell instance this future measurement will run on.
Channel reserved for this measurement, once scheduled.
Temperature this test must run at, in degrees Celsius, held fixed for the whole test. None means ambient: the test runs outside a thermal chamber.
Chamber this test's channel sits in for the reservation. Recorded per reservation rather than per channel, because channels move between chambers.
Named protocol (experiment_template) this measurement will run. Required on create; a planned measurement must name a protocol.
Optional catalog program (Formation, Cycling, …) for this test request.
Planned physical setup.
When setup/run is planned to start.
When this planned measurement is expected to release the channel.
Expected run duration before scheduled times exist.
x >= 1Operator setup duration before the test starts.
x >= 0Operator teardown duration after the test finishes.
x >= 0Free-text planning notes.
Lifecycle of a duration estimate computed by a background simulation.
Used by both estimates: a planned test's total duration
(planned_measurements.estimated_duration_*) and a running test's
remaining duration (cell_measurements.estimated_end_time_*). One enum
because the lifecycle is identical -- only what is being estimated differs.
estimating while the job is in flight, ready once a value came from
it, failed with the reason in the accompanying note. None means no
estimate was ever requested.
estimating, ready, failed Was this page helpful?