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

# QuantinuumProvider

> Runtime integration for access to Quantinuum trapped-ion quantum processors via Quantinuum Nexus.

<Info>
  API Reference:
  [qbraid.runtime.quantinuum](https://qbraid.github.io/qBraid/stubs/qbraid.runtime.quantinuum.html)
</Info>

## Overview

The `qbraid.runtime.QuantinuumProvider` provides support for Quantinuum's trapped-ion quantum systems
through the [Quantinuum Nexus](https://nexus.quantinuum.com/) platform. This means you can write quantum circuits using
[pytket](https://tket.quantinuum.com/), compile and execute them on Quantinuum's H-series processors and emulators,
all from within the [qBraid Runtime framework](/v2/sdk/user-guide/runtime/components).

## Getting started

Before you begin, make sure you have:

1. A **Quantinuum Nexus** account with valid credentials.
2. The **qnexus** CLI tool installed and authenticated (see [Authentication](#authentication) below).
3. Python >= 3.10

### Set up the qBraid-SDK

Install qBraid with the `quantinuum` extra from [PyPI](https://pypi.org/project/qbraid/) using pip:

```bash theme={null}
pip install 'qbraid[quantinuum]'
```

This installs the required dependencies: `pytket`, `pytket-quantinuum`, and `qnexus`.

<Info>
  *Note*: The qBraid-SDK requires Python 3.10 or greater. You can check your
  Python version by running `python --version` from the command line.
</Info>

## Authentication

The `QuantinuumProvider` authenticates through the `qnexus` library. Before using the provider, you must
log in using the `qnexus` CLI:

```bash theme={null}
qnx login
```

This opens a browser-based authentication flow and stores your credentials locally. Once authenticated,
the provider will automatically use your stored credentials — no API keys or environment variables are needed.

Then initialize the provider:

```python theme={null}
from qbraid.runtime.quantinuum import QuantinuumProvider

provider = QuantinuumProvider()
```

## List available devices

Use the `QuantinuumProvider` to list all devices to which you have access:

```python theme={null}
from qbraid.runtime.quantinuum import QuantinuumProvider

provider = QuantinuumProvider()

devices = provider.get_devices()
print(devices)
```

Get a specific device by its ID:

```python theme={null}
device = provider.get_device("H1-1")

print(device.status())
# <DeviceStatus.ONLINE>
```

<Note>
  Devices with an "E" suffix (e.g., `H1-1E`) are emulators (simulators) that
  model the behavior of the corresponding hardware device.
</Note>

## Submitting jobs

The `QuantinuumProvider` accepts quantum programs written as pytket `Circuit` objects.

### Create a circuit

```python theme={null}
from pytket.circuit import Circuit

# Bell state circuit
circuit = Circuit(2)
circuit.H(0)
circuit.CX(0, 1)
circuit.measure_all()
```

### Run a job

Use `device.run()` to compile and submit a circuit:

```python theme={null}
from pytket.circuit import Circuit
from qbraid.runtime.quantinuum import QuantinuumProvider

provider = QuantinuumProvider()
device = provider.get_device("H1-1E")

circuit = Circuit(2)
circuit.H(0)
circuit.CX(0, 1)
circuit.measure_all()

job = device.run(circuit, shots=1000)
print(f"Job ID: {job.id}")
```

### Batch submission

Submit multiple circuits in a single call. All circuits are bundled into one Nexus job:

```python theme={null}
from pytket.circuit import Circuit
from qbraid.runtime.quantinuum import QuantinuumProvider

provider = QuantinuumProvider()
device = provider.get_device("H1-1E")

circuits = [
    Circuit(1).H(0).measure_all(),
    Circuit(1).X(0).measure_all(),
    Circuit(2).H(0).CX(0, 1).measure_all(),
]

job = device.run(circuits, shots=500)
print(f"Job ID: {job.id}")
```

<Note>
  When submitting a list of circuits, all circuits are compiled and executed as
  a single batch job on Quantinuum Nexus. The returned `measurement_counts` will
  be a list of dictionaries, one per circuit.
</Note>

## Retrieving results

```python theme={null}
result = job.result()

# Measurement counts
print(result.data.measurement_counts)
# {'00': 512, '11': 488}

# Job metadata
print(f"Device: {result.device_id}")
print(f"Job ID: {result.job_id}")
print(f"Success: {result.success}")
```

### Check job status

```python theme={null}
from qbraid.runtime.enums import JobStatus

status = job.status()
print(status)
# <JobStatus.COMPLETED>
```

### Cancel a job

```python theme={null}
job.cancel()
```

<Note>
  Cancellation is best-effort. Jobs already in a terminal state (`COMPLETED`,
  `FAILED`, `CANCELLED`) cannot be cancelled.
</Note>

### Execution time

You can retrieve the wall-clock execution time (in seconds) for a completed job:

```python theme={null}
print(f"Execution time: {job.execution_time_s()} seconds")
```

## Configuration options

The `device.run()` method accepts additional keyword arguments to control compilation and project scoping:

| Parameter            | Type  | Default    | Description                                       |
| -------------------- | ----- | ---------- | ------------------------------------------------- |
| `shots`              | `int` | `1000`     | Number of measurement shots per circuit.          |
| `project_name`       | `str` | `"qbraid"` | Nexus project name to scope compile/execute jobs. |
| `optimisation_level` | `int` | `1`        | pytket optimization level (0-2).                  |

The `project_name` and `optimisation_level` parameters can also be set via environment variables:

| Variable                        | Description                        |
| ------------------------------- | ---------------------------------- |
| `QUANTINUUM_NEXUS_PROJECT_NAME` | Default Nexus project name.        |
| `QUANTINUUM_NEXUS_OPT_LEVEL`    | Default pytket optimization level. |

## Full example

A complete end-to-end workflow targeting a Quantinuum emulator:

```python theme={null}
from pytket.circuit import Circuit
from qbraid.runtime.quantinuum import QuantinuumProvider

# 1. Initialize provider (assumes qnx login was run)
provider = QuantinuumProvider()

# 2. Get an emulator device
device = provider.get_device("H1-1E")
print(f"Device status: {device.status()}")

# 3. Define a GHZ state circuit
circuit = Circuit(3)
circuit.H(0)
circuit.CX(0, 1)
circuit.CX(1, 2)
circuit.measure_all()

# 4. Submit the job
job = device.run(circuit, shots=1000, optimisation_level=2)
print(f"Submitted job: {job.id}")

# 5. Retrieve results
result = job.result()
print(f"Counts: {result.data.measurement_counts}")
# Expected output (approximate): {'000': ~500, '111': ~500}
```

## Related links

* [Quantinuum Nexus](https://nexus.quantinuum.com/)
* [pytket Documentation](https://tket.quantinuum.com/)
* [pytket-quantinuum Extension](https://tket.quantinuum.com/extensions/pytket-quantinuum/)
