> ## Documentation Index
> Fetch the complete documentation index at: https://docs.haiqu.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with Haiqu Circuits

> Compose, transpile, execute, and measure opaque Haiqu-generated circuits — and why local Qiskit tooling fails on them

Data-loading job results return a `HaiquCircuitGate`: an **opaque handle to a circuit stored in the
Haiqu cloud**. The gate carries only a `circuit_id` and qubit count — its `definition` is `None`,
and it is expanded server-side when you transpile or run it.

[State compression](/core_features/compression) job results return a `CircuitModel` instead. Pass
it directly to `haiqu.transpile` or `haiqu.run`, call `.to_gate()` to embed it in a larger Qiskit
circuit, and persist `result.id` if you need to retrieve it later with `haiqu.get_circuit`.

You can also obtain a `HaiquCircuitGate` from any cloud-stored circuit via
`haiqu.get_circuit(circuit_id).to_gate()`.

This page explains what works on these circuits, what fails, and how to read depth and gate counts
from cloud-computed analytics.

## What works and what doesn't

| Task                      | Use                                                                                                         | Doesn't work                                                     |
| :------------------------ | :---------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------- |
| Embed in a larger circuit | `circuit.append(gate, ...)`, `circuit.compose(...)`                                                         | —                                                                |
| Invert                    | `gate.inverse()` (returns the dagger gate)                                                                  | —                                                                |
| Transpile                 | `haiqu.transpile(circuit, device)`                                                                          | local `qiskit.transpile` / `circuit.decompose()` on opaque gates |
| Depth / gate counts       | `haiqu.transpile(...).analytics` (e.g. `.depth`, `.depth_2q`, `.gates_2q`) or `.core_metrics(widget=False)` | `qc.depth()` / local counts on opaque gates                      |
| Execute                   | `haiqu.run(...)`, `haiqu.statevector_run(...)`                                                              | local Aer, `Statevector`                                         |
| Persist a cloud circuit   | store `circuit.id`; retrieve with `haiqu.get_circuit(circuit_id)`                                           | pickling `CircuitModel` objects                                  |

Composition works because `HaiquCircuitGate` is a regular `qiskit.circuit.Instruction` — you can
freely build hybrid algorithms around it. Only operations that need the gate's *contents* fail
locally, because the contents live in the cloud.

## Local pitfalls

Local expansion does not work on circuits containing opaque gates:

```python theme={null}
from qiskit import transpile

transpile(circuit_with_haiqu_gate, basis_gates=["u", "cx"])
# cannot expand the server-side circuit definition

circuit_with_haiqu_gate.decompose()
# same — use haiqu.transpile instead

circuit_with_haiqu_gate.depth()
# misleading: the opaque gate counts as one instruction
```

## Cloud analytics

Structure metrics are computed cloud-side on the `CircuitModel` returned by `haiqu.transpile` and
exposed through [Circuit Analytics](/core_features/circ_analytics):

```python theme={null}
device = haiqu.get_device("fake_torino")

transpiled = haiqu.transpile(circuit, device)
depth = transpiled.analytics.depth
depth_2q = transpiled.analytics.depth_2q
gates_2q = transpiled.analytics.gates_2q

# or as a dict of core metrics:
metrics = transpiled.core_metrics(widget=False)
```

If `analytics` is not yet populated, call `core_metrics(widget=False)` or
`wait_for_analytics(widget=False)` — both block until metrics are ready.

## Executing and validating

Circuits containing Haiqu gates execute through [`haiqu.run`](/reference/run/run) like any other
circuit — the cloud expands the gate at submission time. For small circuits (up to 20 qubits,
non-parameterized) `statevector_run` returns exact amplitudes, which is useful for validating a
loaded state against its classical target.
