curl --request POST \
--url 'https://api.example.com/ai/run_variational_workload?HAIQU_API_KEY=' \
--header 'Content-Type: application/json' \
--data '
{
"circuit_id": "circ-123",
"device_id": "fake_kyiv",
"experiment_id": "exp-123",
"loss_expression": "energy",
"mode": "optimization",
"observables": {
"energy": [
[
"ZZ",
"XX"
],
[
1,
0.5
]
]
},
"optimizer_options": {
"maxiter": 50,
"type": "nft"
},
"shots": 4096
}
'import requests
url = "https://api.example.com/ai/run_variational_workload?HAIQU_API_KEY="
payload = {
"circuit_id": "circ-123",
"device_id": "fake_kyiv",
"experiment_id": "exp-123",
"loss_expression": "energy",
"mode": "optimization",
"observables": { "energy": [["ZZ", "XX"], [1, 0.5]] },
"optimizer_options": {
"maxiter": 50,
"type": "nft"
},
"shots": 4096
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
circuit_id: 'circ-123',
device_id: 'fake_kyiv',
experiment_id: 'exp-123',
loss_expression: 'energy',
mode: 'optimization',
observables: {energy: [['ZZ', 'XX'], [1, 0.5]]},
optimizer_options: {maxiter: 50, type: 'nft'},
shots: 4096
})
};
fetch('https://api.example.com/ai/run_variational_workload?HAIQU_API_KEY=', 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.example.com/ai/run_variational_workload?HAIQU_API_KEY=",
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([
'circuit_id' => 'circ-123',
'device_id' => 'fake_kyiv',
'experiment_id' => 'exp-123',
'loss_expression' => 'energy',
'mode' => 'optimization',
'observables' => [
'energy' => [
[
'ZZ',
'XX'
],
[
1,
0.5
]
]
],
'optimizer_options' => [
'maxiter' => 50,
'type' => 'nft'
],
'shots' => 4096
]),
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.example.com/ai/run_variational_workload?HAIQU_API_KEY="
payload := strings.NewReader("{\n \"circuit_id\": \"circ-123\",\n \"device_id\": \"fake_kyiv\",\n \"experiment_id\": \"exp-123\",\n \"loss_expression\": \"energy\",\n \"mode\": \"optimization\",\n \"observables\": {\n \"energy\": [\n [\n \"ZZ\",\n \"XX\"\n ],\n [\n 1,\n 0.5\n ]\n ]\n },\n \"optimizer_options\": {\n \"maxiter\": 50,\n \"type\": \"nft\"\n },\n \"shots\": 4096\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.example.com/ai/run_variational_workload?HAIQU_API_KEY=")
.header("Content-Type", "application/json")
.body("{\n \"circuit_id\": \"circ-123\",\n \"device_id\": \"fake_kyiv\",\n \"experiment_id\": \"exp-123\",\n \"loss_expression\": \"energy\",\n \"mode\": \"optimization\",\n \"observables\": {\n \"energy\": [\n [\n \"ZZ\",\n \"XX\"\n ],\n [\n 1,\n 0.5\n ]\n ]\n },\n \"optimizer_options\": {\n \"maxiter\": 50,\n \"type\": \"nft\"\n },\n \"shots\": 4096\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/ai/run_variational_workload?HAIQU_API_KEY=")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"circuit_id\": \"circ-123\",\n \"device_id\": \"fake_kyiv\",\n \"experiment_id\": \"exp-123\",\n \"loss_expression\": \"energy\",\n \"mode\": \"optimization\",\n \"observables\": {\n \"energy\": [\n [\n \"ZZ\",\n \"XX\"\n ],\n [\n 1,\n 0.5\n ]\n ]\n },\n \"optimizer_options\": {\n \"maxiter\": 50,\n \"type\": \"nft\"\n },\n \"shots\": 4096\n}"
response = http.request(request)
puts response.read_body{
"job_id": "<string>",
"mode": "<string>",
"context": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Run Variational Workload
Train the parameters of a variational circuit, on a device or classically.
Use this tool for VQE-style workloads on a stored parameterized circuit. Set
mode to optimization to minimize an observable by running the circuit
on a backend, or to pretraining to fit the parameters classically before
spending any quantum time.
When to Use:
- Call this with
mode='optimization'when the user wants a ground-state energy, a minimized cost observable, or a VQE run. - Call this with
mode='pretraining'first when the circuit has many parameters, then feed the resulting parameters into an optimization run asinitial_parameters.
Constraints:
- Both modes require
loss_expressionand at least one entry inobservables;mode='optimization'additionally requiresdevice_idandoptimizer_options. Fields belonging to the other mode are rejected with422rather than silently ignored. optimizer_optionshas no default, because the valid choice depends on the loss. Use{'type': 'nft', ...}only whenloss_expressionis affine in the observables ('energy','2*a - b'): NFT models the loss as a sinusoid in each parameter, which a nonlinear expression ('a*b','a/b','(a - b)**2') violates, so an NFT run on one converges to a confident-looking wrong answer instead of failing. Use{'type': 'scipy', 'method': 'cobyla'}for a nonlinear loss, and whenever unsure: COBYLA assumes no structure in the loss, so it is valid for every objective.mode='pretraining'takes no optimizer at all.circuit_idmust reference a stored circuit with free parameters.- Both modes are asynchronous and billable. Poll with
get_job_results_and_status; stop a run withcancel_job. - Optimization runs many circuit evaluations, so wall-clock time and cost scale with the optimizer’s iteration budget, not with a single shot count.
Notes:
- Confirm the iteration budget with the user before submitting an optimization run against real hardware.
- Backend credentials go in
options, in the same formrun_circuits_on_qpu_or_simulatordocuments.
Args: user: Authenticated user resolved from the API key. data: Mode selector plus the fields required by that mode. db: Active database session.
Returns: The created job identifier, the mode, and the next polling step.
Raises:
HTTPException: Raised with 402 when the caller cannot submit billable
jobs, 404 when the experiment or circuit is unavailable, or 422
when the payload does not match the selected mode.
curl --request POST \
--url 'https://api.example.com/ai/run_variational_workload?HAIQU_API_KEY=' \
--header 'Content-Type: application/json' \
--data '
{
"circuit_id": "circ-123",
"device_id": "fake_kyiv",
"experiment_id": "exp-123",
"loss_expression": "energy",
"mode": "optimization",
"observables": {
"energy": [
[
"ZZ",
"XX"
],
[
1,
0.5
]
]
},
"optimizer_options": {
"maxiter": 50,
"type": "nft"
},
"shots": 4096
}
'import requests
url = "https://api.example.com/ai/run_variational_workload?HAIQU_API_KEY="
payload = {
"circuit_id": "circ-123",
"device_id": "fake_kyiv",
"experiment_id": "exp-123",
"loss_expression": "energy",
"mode": "optimization",
"observables": { "energy": [["ZZ", "XX"], [1, 0.5]] },
"optimizer_options": {
"maxiter": 50,
"type": "nft"
},
"shots": 4096
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
circuit_id: 'circ-123',
device_id: 'fake_kyiv',
experiment_id: 'exp-123',
loss_expression: 'energy',
mode: 'optimization',
observables: {energy: [['ZZ', 'XX'], [1, 0.5]]},
optimizer_options: {maxiter: 50, type: 'nft'},
shots: 4096
})
};
fetch('https://api.example.com/ai/run_variational_workload?HAIQU_API_KEY=', 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.example.com/ai/run_variational_workload?HAIQU_API_KEY=",
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([
'circuit_id' => 'circ-123',
'device_id' => 'fake_kyiv',
'experiment_id' => 'exp-123',
'loss_expression' => 'energy',
'mode' => 'optimization',
'observables' => [
'energy' => [
[
'ZZ',
'XX'
],
[
1,
0.5
]
]
],
'optimizer_options' => [
'maxiter' => 50,
'type' => 'nft'
],
'shots' => 4096
]),
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.example.com/ai/run_variational_workload?HAIQU_API_KEY="
payload := strings.NewReader("{\n \"circuit_id\": \"circ-123\",\n \"device_id\": \"fake_kyiv\",\n \"experiment_id\": \"exp-123\",\n \"loss_expression\": \"energy\",\n \"mode\": \"optimization\",\n \"observables\": {\n \"energy\": [\n [\n \"ZZ\",\n \"XX\"\n ],\n [\n 1,\n 0.5\n ]\n ]\n },\n \"optimizer_options\": {\n \"maxiter\": 50,\n \"type\": \"nft\"\n },\n \"shots\": 4096\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.example.com/ai/run_variational_workload?HAIQU_API_KEY=")
.header("Content-Type", "application/json")
.body("{\n \"circuit_id\": \"circ-123\",\n \"device_id\": \"fake_kyiv\",\n \"experiment_id\": \"exp-123\",\n \"loss_expression\": \"energy\",\n \"mode\": \"optimization\",\n \"observables\": {\n \"energy\": [\n [\n \"ZZ\",\n \"XX\"\n ],\n [\n 1,\n 0.5\n ]\n ]\n },\n \"optimizer_options\": {\n \"maxiter\": 50,\n \"type\": \"nft\"\n },\n \"shots\": 4096\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/ai/run_variational_workload?HAIQU_API_KEY=")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"circuit_id\": \"circ-123\",\n \"device_id\": \"fake_kyiv\",\n \"experiment_id\": \"exp-123\",\n \"loss_expression\": \"energy\",\n \"mode\": \"optimization\",\n \"observables\": {\n \"energy\": [\n [\n \"ZZ\",\n \"XX\"\n ],\n [\n 1,\n 0.5\n ]\n ]\n },\n \"optimizer_options\": {\n \"maxiter\": 50,\n \"type\": \"nft\"\n },\n \"shots\": 4096\n}"
response = http.request(request)
puts response.read_body{
"job_id": "<string>",
"mode": "<string>",
"context": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Authorizations
Body
Define payload for variational optimization and pretraining jobs.
One model covers both modes of the variational family. mode selects the
behavior and determines which of the remaining fields are required; the
unused fields for a mode are rejected with 422 rather than ignored.
Attributes:
mode: Which variational workload to run.
experiment_id: Parent experiment identifier.
circuit_id: Parameterized circuit to train.
name: Optional job name.
description: Optional job description.
initial_parameters: Optional starting parameter values.
device_id: Execution backend, required for optimization.
shots: Shots per circuit evaluation, optimization only.
optimizer_options: Classical optimizer configuration, optimization
only and required there; NFT is valid only for a loss that is affine
in the observables.
options: Backend or run options, forwarded as given.
use_mitigation: Whether to apply error mitigation, optimization only.
use_compression: Whether to apply state compression, optimization
only.
compression_options: Compression parameters, optimization only.
loss_expression: Loss formula, required for pretraining and optimization.
observables: Named observables referenced by loss_expression, required for
both modes and never empty.
max_time: Optional pretraining wall-clock budget in seconds.
seed: Optional pretraining random seed.
Use optimization to minimize a loss expression on a device or simulator (requires loss_expression, observables, device_id and optimizer_options), or pretraining to fit circuit parameters classically before any quantum execution (requires loss_expression and observables).
optimization, pretraining Parameterized circuit to train, from a prior MCP response.
Optional starting parameter values. Length must match the circuit's parameter count.
Backend for optimization mode, from list_qpus_and_simulators.
Shots per circuit evaluation in optimization mode.
Classical optimizer for optimization mode, required there and not accepted in pretraining mode; there is no default, and type must be stated. Either {'type': 'nft', 'maxiter': 100, 'maxfev': 200, 'reset_interval': 32} or {'type': 'scipy', 'method': 'cobyla', 'maxfev': 200, 'options': {}}. Choose nft only when loss_expression is affine in the observables ("energy", "2*a - b"): NFT models the loss as a sinusoid in each parameter, which a nonlinear loss ("a*b", "a/b", "(a - b)**2") violates, so an NFT run on one converges to a confident-looking wrong result instead of failing. Choose scipy for a nonlinear loss, and whenever unsure: COBYLA assumes no structure in the loss, so it is valid for every objective, at the cost of more circuit evaluations than NFT needs on an affine one.
Backend options, including device credentials where the backend requires them.
Apply error mitigation in optimization mode.
Apply state compression in optimization mode.
State-compression parameters used when use_compression is true.
Show child attributes
Show child attributes
Loss formula minimized in both modes, written over the keys of observables, for example "(energy - target) ** 2", or just "energy" for a plain expectation-value objective. An expression that is not affine in the observables rules out the NFT optimizer in optimization mode; see optimizer_options.
1 - 1024Named observables referenced by loss_expression, each as [[pauli_strings], [coefficients]], for example {"energy": [["ZZ"], [1.0]]}. At least one entry is required in both modes.
Show child attributes
Show child attributes
Pretraining wall-clock budget in seconds.
Pretraining random seed.