curl --request POST \
--url 'https://api.example.com/ai/backpropagate_observables?HAIQU_API_KEY=' \
--header 'Content-Type: application/json' \
--data '
{
"circuit_id": "circ-123",
"max_error_total": 0.01,
"observables": [
[
[
"ZZ",
1,
0
]
]
]
}
'import requests
url = "https://api.example.com/ai/backpropagate_observables?HAIQU_API_KEY="
payload = {
"circuit_id": "circ-123",
"max_error_total": 0.01,
"observables": [[["ZZ", 1, 0]]]
}
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', max_error_total: 0.01, observables: [[['ZZ', 1, 0]]]})
};
fetch('https://api.example.com/ai/backpropagate_observables?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/backpropagate_observables?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',
'max_error_total' => 0.01,
'observables' => [
[
[
'ZZ',
1,
0
]
]
]
]),
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/backpropagate_observables?HAIQU_API_KEY="
payload := strings.NewReader("{\n \"circuit_id\": \"circ-123\",\n \"max_error_total\": 0.01,\n \"observables\": [\n [\n [\n \"ZZ\",\n 1,\n 0\n ]\n ]\n ]\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/backpropagate_observables?HAIQU_API_KEY=")
.header("Content-Type", "application/json")
.body("{\n \"circuit_id\": \"circ-123\",\n \"max_error_total\": 0.01,\n \"observables\": [\n [\n [\n \"ZZ\",\n 1,\n 0\n ]\n ]\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/ai/backpropagate_observables?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 \"max_error_total\": 0.01,\n \"observables\": [\n [\n [\n \"ZZ\",\n 1,\n 0\n ]\n ]\n ]\n}"
response = http.request(request)
puts response.read_body{
"optimized_circuit_ids": [
"<string>"
],
"backpropagated_observables": [
[
[
"<string>",
123,
123
]
]
],
"context": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Backpropagate Observables Mcp
Backpropagate observables through a circuit to shorten what must be run.
Use this tool to move part of the computation from the circuit into the observable: Haiqu rewrites each observable through the tail of the circuit and stores a correspondingly shortened circuit. Running the shorter circuit with the rewritten observable estimates the same expectation value with less hardware noise.
When to Use:
- Call this when the user wants expectation values from a circuit that is too deep to run faithfully on hardware.
- Call this before
run_circuits_on_qpu_or_simulatorfor expectation-value workloads, and pass the returned circuit and observable together.
Constraints:
- Backpropagation is synchronous and runs no quantum job.
- Each input observable yields one output circuit, so
optimized_circuit_idsandbackpropagated_observablesare aligned by index and must be used as pairs. - Truncation budgets trade accuracy for depth. Without
max_error_totalormax_error_per_slicethe rewritten observable can grow large.
Notes:
- Pauli coefficients are given and returned as
(pauli, real, imaginary)triples. - Compare the returned circuits against the input with
get_circuit_by_idto show how much depth was removed.
Args: user: Authenticated user resolved from the API key. data: Circuit identifier, observables, and optional truncation budgets. db: Active database session.
Returns: The generated circuit IDs with their rewritten observables.
Raises:
HTTPException: Raised with 404 when the circuit is not available to
the caller, 422 when an observable cannot be parsed, or 501
when the backpropagation dependency is unavailable.
curl --request POST \
--url 'https://api.example.com/ai/backpropagate_observables?HAIQU_API_KEY=' \
--header 'Content-Type: application/json' \
--data '
{
"circuit_id": "circ-123",
"max_error_total": 0.01,
"observables": [
[
[
"ZZ",
1,
0
]
]
]
}
'import requests
url = "https://api.example.com/ai/backpropagate_observables?HAIQU_API_KEY="
payload = {
"circuit_id": "circ-123",
"max_error_total": 0.01,
"observables": [[["ZZ", 1, 0]]]
}
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', max_error_total: 0.01, observables: [[['ZZ', 1, 0]]]})
};
fetch('https://api.example.com/ai/backpropagate_observables?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/backpropagate_observables?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',
'max_error_total' => 0.01,
'observables' => [
[
[
'ZZ',
1,
0
]
]
]
]),
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/backpropagate_observables?HAIQU_API_KEY="
payload := strings.NewReader("{\n \"circuit_id\": \"circ-123\",\n \"max_error_total\": 0.01,\n \"observables\": [\n [\n [\n \"ZZ\",\n 1,\n 0\n ]\n ]\n ]\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/backpropagate_observables?HAIQU_API_KEY=")
.header("Content-Type", "application/json")
.body("{\n \"circuit_id\": \"circ-123\",\n \"max_error_total\": 0.01,\n \"observables\": [\n [\n [\n \"ZZ\",\n 1,\n 0\n ]\n ]\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/ai/backpropagate_observables?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 \"max_error_total\": 0.01,\n \"observables\": [\n [\n [\n \"ZZ\",\n 1,\n 0\n ]\n ]\n ]\n}"
response = http.request(request)
puts response.read_body{
"optimized_circuit_ids": [
"<string>"
],
"backpropagated_observables": [
[
[
"<string>",
123,
123
]
]
],
"context": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Authorizations
Body
Define payload for backpropagating observables through a circuit.
Attributes:
circuit_id: Circuit to backpropagate through.
observables: Observables as lists of (pauli, real, imaginary) terms.
max_qwc_groups: Optional cap on qubit-wise-commuting groups.
max_error_total: Optional total truncation error budget.
max_error_per_slice: Optional per-slice truncation error budget.
Observables to backpropagate. Each observable is a list of Pauli terms given as [pauli_string, real_coefficient, imaginary_coefficient], for example [["ZZ", 1.0, 0.0], ["XX", 0.5, 0.0]].
Show child attributes
Show child attributes
Optional cap on the number of qubit-wise-commuting groups retained.
Optional total truncation error budget across the backpropagation.
Optional truncation error budget per circuit slice.
Response
Successful Response
Represent the outcome of an observable backpropagation.
Attributes:
optimized_circuit_ids: Circuits produced by the backpropagation, one per
input observable.
backpropagated_observables: Rewritten observables as
(pauli, real, imaginary) term lists.
context: Summary of what was produced and the next step.