python vlatest

Ionq-sdk

IonQ's native Python SDK for direct access to trapped-ion quantum hardware

Quick install

pip install ionq

Background and History

IonQ was founded in 2015 by Christopher Monroe and Jungsang Kim, two leading trapped-ion physicists from the University of Maryland and Duke University, respectively. The company was established to commercialize decades of academic research on trapped-ion quantum computing, a technology that uses individual charged atoms (ions) suspended in electromagnetic traps as qubits. Trapped-ion qubits offer long coherence times, high-fidelity gates, and all-to-all connectivity (any qubit can interact with any other qubit without routing constraints), which distinguishes them from superconducting approaches.

IonQ launched its first cloud-accessible quantum computer in 2019, making trapped-ion hardware available through Amazon Braket, Microsoft Azure Quantum, and Google Cloud. The company went public via a SPAC merger in October 2021, becoming one of the first pure-play quantum computing companies listed on a public stock exchange. IonQ’s hardware generations include systems built on ytterbium ions, with the Aria processor (25 algorithmic qubits, launched 2022) and the Forte processor (36 algorithmic qubits, launched 2023) representing successive improvements in qubit count and gate fidelity.

IonQ’s native SDK provides direct access to the company’s hardware and simulators through a REST API with Python client bindings. The SDK uses a JSON-based circuit format and exposes IonQ’s native gate set: GPi, GPi2, and MS (Molmer-Sorensen), which are the physical operations natively implemented on the trapped-ion hardware. Submitting circuits in native gates avoids the overhead of decomposition from abstract gates, which can improve fidelity for performance-sensitive applications.

However, many users access IonQ hardware through third-party platforms rather than the native SDK. IonQ processors are available through Amazon Braket, Azure Quantum, Google Cloud, and via plugins for Qiskit (qiskit-ionq), Cirq (cirq-ionq), and PennyLane. This broad availability means the native SDK is primarily used by developers who want direct API access, need native gate control, or prefer to avoid the overhead of an intermediary platform.

As of 2025, IonQ is actively developing its hardware roadmap, which targets increasing qubit counts and the introduction of quantum error correction. The company has announced plans for systems with hundreds of qubits using reconfigurable multicore architectures. The native SDK continues to be maintained alongside IonQ’s cloud platform at cloud.ionq.com.

Installation

pip install ionq

Alternative access paths (when you already use one of these platforms):

pip install cirq-ionq           # Cirq integration
pip install qiskit-ionq         # Qiskit provider plugin
pip install amazon-braket-sdk   # IonQ available via Amazon Braket

Azure Quantum and Google Cloud Quantum also provide IonQ backend access without additional packages beyond those platforms’ own SDKs.

Authentication

An API key is required. Get one at cloud.ionq.com.

import ionq

client = ionq.Client(api_key="your-api-key-here")

# Or set the environment variable and omit the argument
# export IONQ_API_KEY="your-api-key-here"
client = ionq.Client()

Native Gate Set

IonQ hardware operates on three native gates. Compiling abstract gates (H, CX, etc.) to these natives reduces errors. Using them directly gives the best fidelity.

GateDescriptionParameters
GPi(phi)Single-qubit rotation: full pi rotation around an axis in the XY planephi: axis angle in turns (0 to 1)
GPi2(phi)Single-qubit rotation: pi/2 rotation around an axis in the XY planephi: axis angle in turns (0 to 1)
MS(phi0, phi1)Molmer-Sorensen two-qubit entangling gatephi0, phi1: per-qubit axis angles in turns

Angles in the IonQ native gate set are measured in turns (full rotations), not radians. One turn = 2*pi radians. So phi=0.5 means a rotation of pi radians.

Circuit Construction

IonQ circuits are expressed as a JSON-like dictionary structure, then submitted via the client.

import ionq

client = ionq.Client()

circuit = {
    "qubits": 2,
    "circuit": [
        {"gate": "gpi2", "target": 0, "phase": 0.0},       # GPi2 on qubit 0
        {"gate": "ms",   "targets": [0, 1], "phases": {"control": 0.0, "target": 0.0}},
    ]
}

Bell State in Native Gates

A Bell state using IonQ’s native gate set:

# Bell state: GPi2(0) on q0, then MS(0,0) on (q0, q1)
bell_circuit = {
    "qubits": 2,
    "circuit": [
        {"gate": "gpi2", "target": 0, "phase": 0.0},
        {"gate": "ms",   "targets": [0, 1], "phases": {"control": 0.0, "target": 0.0}},
    ]
}

Running on the Simulator

client = ionq.Client()

job = client.create_job(
    circuit=bell_circuit,
    target="simulator",    # "simulator" or a QPU name
    shots=1024,
)

print(job["id"])

# Fetch results (poll until done)
result = client.get_job(job["id"])
print(result["data"]["histogram"])
# {'0': 0.5, '3': 0.5}  -- keys are integer state indices

Simulator histogram values are exact probabilities, not counts. State 0 = |00>, state 3 = |11> for a 2-qubit system (binary: 00=0, 11=3).

Converting Histogram to Counts

shots = 1024
histogram = result["data"]["histogram"]
counts = {k: round(v * shots) for k, v in histogram.items()}
print(counts)
# {'0': 512, '3': 512}

Submitting to Real Hardware

# IonQ Aria: 25 qubits
job = client.create_job(
    circuit=bell_circuit,
    target="qpu.aria-1",
    shots=100,
)

# IonQ Forte: 36 qubits
job = client.create_job(
    circuit=bell_circuit,
    target="qpu.forte-1",
    shots=100,
)

Hardware jobs queue behind other users. Poll for completion:

import time

job_id = job["id"]
while True:
    status = client.get_job(job_id)["status"]
    print(status)
    if status in ("completed", "failed", "canceled"):
        break
    time.sleep(10)

result = client.get_job(job_id)

Available Targets

Target stringTypeQubits
simulatorIdeal simulatorup to 29
simulator.noise-model-aria-1Noise model simulator25
qpu.aria-1IonQ Aria hardware25
qpu.aria-2IonQ Aria hardware25
qpu.forte-1IonQ Forte hardware36

Use client.get_targets() for the current list.

Noise Model Simulator

job = client.create_job(
    circuit=bell_circuit,
    target="simulator.noise-model-aria-1",
    shots=1024,
)

The noise model simulator models the error characteristics of the named QPU. Results are sampled (not exact probabilities) and include realistic gate errors.

Access via cirq-ionq

If you prefer Cirq’s circuit API:

import cirq
from cirq_ionq import IonQService

service = IonQService(api_key="your-key")

q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit([
    cirq.H(q0),
    cirq.CNOT(q0, q1),
    cirq.measure(q0, q1, key='m'),
])

result = service.run(circuit, target="simulator", repetitions=1024)
print(result.histogram(key='m'))