QVM v0.4.0
[GitHub]
Docs/REST API Reference

REST API Reference: /run Endpoint

The primary computational interface of the Quantum Virtual Machine (QVM) backend is the POST /run endpoint, implemented in api/app.py.

This document serves as the complete, authoritative specification for /run, derived directly from the application's Pydantic schemas and FastAPI route handlers.


📌 Endpoint Overview

  • URL: http://localhost:8000/run (or the deployed service domain)
  • Method: POST
  • Request Headers:
    • Content-Type: application/json
    • Accept: application/json
  • Authentication: None required for /run (open local/service endpoint).
  • Interactive OpenAPI Specs:
    • Swagger UI: GET /docs (FastAPI native interactive docs)
    • ReDoc: GET /redoc
    • OpenAPI JSON schema: GET /openapi.json

📥 Request Body Schema (RunRequest)

The request body must be a JSON object conforming to RunRequest:

FieldTypeDefaultRequired?Description & Validation Rules
source_typestring"json"NoInput format. Accepted values: "json" or "qasm".
circuitarray[object]nullYes if source_type="json"List of quantum gate operations (see Gate Dictionary).
nqubitsintegernullYes if source_type="json"Number of qubits in the circuit. Must be ≥1\ge 1.
qasmstringnullYes if source_type="qasm"Raw OpenQASM 2.0 or OpenQASM 3.0 circuit text.
transpilebooleanfalseNoIf true, runs the transpilation pass onto a physical linear architecture.
routingstring"greedy"NoPathfinding algorithm for routing two-qubit gates. Accepted: "greedy" or "sabre".
restore_mappingbooleantrueNoIf true, applies uncomputation SWAPs to restore initial qubit labeling after SABRE routing.
enginestring"statevector"NoSimulation engine. Accepted: "statevector" (dense amplitudes) or "mps" (Matrix Product States).
seedintegernullNoPseudo-random number generator seed for deterministic simulation and sampling.
shotsinteger0NoNumber of measurement samples. If 0, only analytical probabilities are computed; if >0> 0, returns measurement outcome counts.
noise_depolfloat0.0NoGlobal single-qubit depolarizing error probability (0.0≤p≤1.00.0 \le p \le 1.0).
noise_readoutfloat0.0NoGlobal bit-flip measurement readout error probability (0.0≤p≤1.00.0 \le p \le 1.0).
noise_amp_dampfloat0.0NoAmplitude damping (T1T_1 decay) parameter γ∈[0.0,1.0]\gamma \in [0.0, 1.0].
noise_phase_dampfloat0.0NoPhase damping (T2T_2 dephasing) parameter γ∈[0.0,1.0]\gamma \in [0.0, 1.0].
device_backendstringnullNoPredefined hardware noise profile. Accepted: "fake_5q", "fake_7q", or "ideal".
expectation_pauliobjectnullNoMapping of Pauli strings to scalar coefficients for expectation value calculation (e.g., {"ZZ": -1.0, "XI": 0.5}). Requires engine="statevector".

Gate Dictionary Format (JSON Circuits)

When source_type="json", each element in circuit is a dictionary:

json
{
  "name": "rx",
  "qubits": [0],
  "params": [1.5707963],
  "register": "c",
  "cbit": 0
}
  • name: Gate identifier (h, x, y, z, s, t, rx, ry, rz, p, cx, cz, swap, ccx, measure, etc.).
  • qubits: List of target qubit indices.
  • params: Optional list of float rotation angles in radians.
  • register / cbit: Required only for "name": "measure".

📤 Response Body Schema (RunResponse)

Upon successful execution, the endpoint returns HTTP 200 OK with a RunResponse JSON payload:

FieldTypeNullable?Description
probabilitiesarray[float]NoAnalytical state probabilities $P(i) =
countsobjectYesFrequency dictionary of measurement outcomes (e.g. {"00": 508, "11": 492}). Present only when shots > 0.
classical_memoryobjectYesFinal state of named classical bit registers (e.g. {"c": [0, 1]}).
transpiled_operationsarray[object]NoSequence of operations after transpilation, basis decomposition, and routing.
nqubitsintegerNoNumber of physical qubits allocated for the simulation.
circuit_plotstringYesBase64-encoded PNG image of the routed circuit diagram.
histogram_plotstringYesBase64-encoded PNG image of the state probability histogram.
openqasm2stringYesEquivalent circuit exported to OpenQASM 2.0 text format.
expectation_valuefloatYesEvaluated Hamiltonian expectation value ⟨H⟩\langle H \rangle if expectation_pauli was specified.
noise_summarystringYesText summary of active noise channels and damping parameters applied.

🚀 Examples

Example 1: Minimal Valid Request (OpenQASM)

A minimal request creating and measuring a Bell state with 1,000 shots:

Request (curl)

bash
curl -X POST "http://127.0.0.1:8000/run" \
  -H "Content-Type: application/json" \
  -d '{
    "source_type": "qasm",
    "qasm": "OPENQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[2];\ncreg c[2];\nh q[0];\ncx q[0], q[1];\nmeasure q[0] -> c[0];\nmeasure q[1] -> c[1];",
    "shots": 1000,
    "seed": 42
  }'

Response (200 OK)

json
{
  "probabilities": [0.5, 0.0, 0.0, 0.5],
  "classical_memory": {
    "c": [1, 1]
  },
  "transpiled_operations": [
    {"name": "h", "qubits": [0]},
    {"name": "cx", "qubits": [0, 1]},
    {"name": "measure", "qubits": [0], "register": "c", "cbit": 0},
    {"name": "measure", "qubits": [1], "register": "c", "cbit": 1}
  ],
  "nqubits": 2,
  "circuit_plot": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAEACA...",
  "histogram_plot": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAEACA...",
  "counts": {
    "00": 498,
    "11": 502
  },
  "openqasm2": "OPENQASM 2.0;\ninclude \"qelib1.inc\";\nqreg q[2];\ncreg c[2];\nh q[0];\ncx q[0], q[1];\nmeasure q[0] -> c[0];\nmeasure q[1] -> c[1];\n",
  "expectation_value": null,
  "noise_summary": null
}

Example 2: Full-Featured Request (Python requests)

This example demonstrates hardware SABRE routing, depolarizing & readout noise, shot sampling, and Pauli expectation value calculation:

python
import requests

payload = {
    "source_type": "json",
    "nqubits": 2,
    "circuit": [
        {"name": "h", "qubits": [0]},
        {"name": "cx", "qubits": [0, 1]},
        {"name": "measure", "qubits": [0], "register": "c", "cbit": 0},
        {"name": "measure", "qubits": [1], "register": "c", "cbit": 1}
    ],
    "transpile": True,
    "routing": "sabre",
    "restore_mapping": True,
    "engine": "statevector",
    "shots": 2000,
    "seed": 1337,
    "noise_depol": 0.02,
    "noise_readout": 0.01,
    "expectation_pauli": {
        "ZZ": 1.0,
        "XX": 1.0
    }
}

response = requests.post("http://127.0.0.1:8000/run", json=payload)
data = response.json()

print("Status Code:", response.status_code)
print("Physical Qubits:", data["nqubits"])
print("Sampled Counts:", data["counts"])
print("Expectation Value <ZZ + XX>:", data["expectation_value"])
print("Noise Summary:", data["noise_summary"])

⚠️ Error Responses and Status Codes

The API returns standard HTTP status codes along with descriptive error payloads in the format {"detail": "Error description"}:

1. 400 Bad Request — Parse Error

Occurs when QASM syntax is invalid or required fields for the chosen source_type are missing:

  • Example Trigger: source_type="json" without supplying circuit or nqubits.
    json
    {
      "detail": "Parse error: circuit and nqubits are required for source_type=json"
    }
  • Example Trigger: Syntax error in OpenQASM text:
    json
    {
      "detail": "Parse error: Syntax error in QASM: Unexpected token 'foo' at line 3"
    }

2. 400 Bad Request — Transpilation Error

Occurs if SABRE or Greedy routing encounters an unsupported multi-qubit topology or invalid qubit index:

json
{
  "detail": "Transpilation error: Qubit index 5 out of range for 2-qubit architecture"
}

3. 422 Unprocessable Entity — Schema Validation Failure

FastAPI and Pydantic automatically validate types, non-null requirements, and enum values before execution starts:

  • Example Trigger: Passing engine="quantum_supremacy" (valid values: "statevector", "mps"):
    json
    {
      "detail": [
        {
          "type": "literal_error",
          "loc": ["body", "engine"],
          "msg": "Input should be 'statevector' or 'mps'",
          "input": "quantum_supremacy"
        }
      ]
    }

4. 500 Internal Server Error — Simulation Failure

Raised if an unhandled runtime error occurs during numerical statevector contraction:

json
{
  "detail": "Simulation error: Memory allocation failure during state evolution"
}

🔒 Limitations & Best Practices

  1. Qubit Scaling Limit:
    • engine="statevector" allocates 2N2^N complex amplitudes (2N+42^{N+4} bytes for complex128). While N≤14N \le 14 executes in milliseconds, N>16N > 16 requires gigabytes of memory and can cause process timeouts.
    • For N≥16N \ge 16 with 1D nearest-neighbor topologies, use engine="mps".
  2. Deterministic Reproducibility:
    • Always pass the seed parameter when benchmarking or testing shot distributions to ensure exact reproducibility across multiple runs.
  3. Pauli Expectation Support:
    • expectation_pauli currently evaluates against the statevector engine (engine="statevector"). It returns null if used with engine="mps".

Next: Web API and Dashboard Architecture.