From 2a2a87b8d1598ce27b6bdd8d3e115615634a6659 Mon Sep 17 00:00:00 2001 From: Spencer Churchill <25377399+splch@users.noreply.github.com> Date: Tue, 19 May 2026 13:50:56 -0700 Subject: [PATCH 1/4] Polish hand-written layer: narrower except, design notes, drop pass-through Internal cleanups; no behavior change visible from the public API. - _transport.py: narrow JSON-decode `except Exception` to `(ValueError, UnicodeDecodeError)` and parenthesise the `message`/`error` truthy-fallback so operator precedence is obvious. - ionq_client.py: document why `IonQClient` is a PascalCase factory (so call sites read like construction) and why the async path re-injects `Authorization` and reads private `_verify_ssl` / `_follow_redirects` from the generated `AuthenticatedClient`. - polling.py: drop the `job_id` pass-through to `_check_terminal`; use `job.id` (identical here \u2014 we just fetched the job with that uuid). - tests/test_polling.py: note that `_real_sleep = asyncio.sleep` is captured at import so async tests can call the real sleep even after monkeypatch shadows it. - tests/integration/conftest.py: replace module-level `_job_ids` global with a session-scoped `_tracked_jobs` fixture consumed by `track_job` and `cleanup_jobs` via normal pytest DI. --- ionq_core/_transport.py | 6 ++++-- ionq_core/ionq_client.py | 8 ++++++++ ionq_core/polling.py | 8 ++++---- tests/integration/conftest.py | 16 ++++++++++------ tests/test_polling.py | 2 ++ 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/ionq_core/_transport.py b/ionq_core/_transport.py index ac2f917..1550635 100644 --- a/ionq_core/_transport.py +++ b/ionq_core/_transport.py @@ -28,9 +28,11 @@ def _raise_for_response(response: httpx.Response) -> None: try: body: dict | str | None = response.json() - except Exception: + except (ValueError, UnicodeDecodeError): + # json.JSONDecodeError subclasses ValueError; UnicodeDecodeError covers + # bodies that aren't decodable in the declared (or guessed) encoding. body = (response.text or "")[:500] or None - message = body.get("message") or body.get("error") if isinstance(body, dict) else None + message = (body.get("message") or body.get("error")) if isinstance(body, dict) else None try: retry_after = max(0.0, float(response.headers["retry-after"])) except (KeyError, ValueError): diff --git a/ionq_core/ionq_client.py b/ionq_core/ionq_client.py index 910f2b2..52d2286 100644 --- a/ionq_core/ionq_client.py +++ b/ionq_core/ionq_client.py @@ -34,6 +34,8 @@ _AUTH_HEADER = "Authorization" +# Factory named in PascalCase (deliberately, not a class) so call sites read +# like construction. Returns the generated `AuthenticatedClient`. def IonQClient( *, api_key: str | None = None, @@ -169,6 +171,12 @@ def IonQClient( httpx_args={"transport": sync_transport}, **kwargs, ) + # `set_async_httpx_client` bypasses `AuthenticatedClient`'s lazy auth-header + # injection (see generated `client.py::get_async_httpx_client`), so we merge + # `Authorization` in manually here. The `_verify_ssl` / `_follow_redirects` + # fields are private on the generated `AuthenticatedClient` but are the only + # way to mirror the caller's choices onto the async transport; do not add a + # public accessor in the hand-written layer — they belong to generated code. client.set_async_httpx_client( httpx.AsyncClient( base_url=base_url, diff --git a/ionq_core/polling.py b/ionq_core/polling.py index 3f299a3..13e9b52 100644 --- a/ionq_core/polling.py +++ b/ionq_core/polling.py @@ -79,12 +79,12 @@ def __init__(self, job_id: str, failure: object) -> None: super().__init__(f"Job {job_id} failed: {failure}") -def _check_terminal(job: GetJobResponse, job_id: str, raise_on_failure: bool) -> bool: +def _check_terminal(job: GetJobResponse, raise_on_failure: bool) -> bool: if job.status not in _TERMINAL: return False if raise_on_failure and job.status == "failed": failure = job.failure if not isinstance(job.failure, Unset) else None - raise JobFailedError(job_id, failure) + raise JobFailedError(job.id, failure) return True @@ -128,7 +128,7 @@ def wait_for_job( if job is None: raise IonQError(f"Failed to fetch job {job_id}") logger.debug("Job %s status: %s", job_id, job.status) - if _check_terminal(job, job_id, raise_on_failure): + if _check_terminal(job, raise_on_failure): return job if time.monotonic() >= deadline: raise JobTimeoutError(job_id, timeout, job.status) @@ -169,7 +169,7 @@ async def async_wait_for_job( if job is None: raise IonQError(f"Failed to fetch job {job_id}") logger.debug("Job %s status: %s", job_id, job.status) - if _check_terminal(job, job_id, raise_on_failure): + if _check_terminal(job, raise_on_failure): return job if time.monotonic() >= deadline: raise JobTimeoutError(job_id, timeout, job.status) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 97ba16d..96efd09 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -8,8 +8,6 @@ from ionq_core import AuthenticatedClient, IonQClient from ionq_core.api.default import delete_job -_job_ids: list[str] = [] - @pytest.fixture(scope="session") def api_key() -> str: @@ -24,21 +22,27 @@ def client(api_key: str) -> AuthenticatedClient: return IonQClient(api_key=api_key) +@pytest.fixture(scope="session") +def _tracked_jobs() -> list[str]: + """Session-scoped list of job IDs to delete in `cleanup_jobs`.""" + return [] + + @pytest.fixture -def track_job(): +def track_job(_tracked_jobs: list[str]): """Register a job ID for cleanup after the session.""" def _track(job_id: str) -> str: - _job_ids.append(job_id) + _tracked_jobs.append(job_id) return job_id return _track @pytest.fixture(scope="session", autouse=True) -def cleanup_jobs(client: AuthenticatedClient): +def cleanup_jobs(client: AuthenticatedClient, _tracked_jobs: list[str]): """Delete all jobs created during the test session.""" yield - for job_id in _job_ids: + for job_id in _tracked_jobs: with contextlib.suppress(Exception): delete_job.sync_detailed(uuid=job_id, client=client) diff --git a/tests/test_polling.py b/tests/test_polling.py index 6ca6bc2..d0c34d7 100644 --- a/tests/test_polling.py +++ b/tests/test_polling.py @@ -6,6 +6,8 @@ from ionq_core.polling import JobFailedError, JobTimeoutError, async_wait_for_job, wait_for_job from tests.conftest import make_job_json +# Captured at import time so async tests can call the real sleep even after +# `monkeypatch.setattr("ionq_core.polling.asyncio.sleep", ...)` shadows it. _real_sleep = asyncio.sleep _FAILURE = {"code": "SimulationError", "message": "boom"} From dcfe4c884fa1d907acd193ad6fc8caab2de153ed Mon Sep 17 00:00:00 2001 From: Spencer Churchill <25377399+splch@users.noreply.github.com> Date: Tue, 19 May 2026 13:58:51 -0700 Subject: [PATCH 2/4] Regenerate client against May 15 2026 upstream spec Refreshes openapi.json from https://api.ionq.co/v0.4/api-docs and regenerates ionq_core/api/ + ionq_core/models/. Tracks the upstream changes surfaced by the spec-drift workflow (issue #43); the bot's diff in #43 was truncated at 60 KB and missed cost_model + the qubits tightening on NativeCircuitInput/JsonMultiCircuitInput. User-visible changes: - New `QctrlQaoaJobCreationPayload` + `QctrlQaoaJobInput` models, plus the inline schemas the generator synthesises (`*_external_settings`, `*_settings`, `*_settings_error_mitigation`, `*_problem`, and the literal-enum modules for `type` / `problem_type`). The `create_job` body union now also accepts `QctrlQaoaJobCreationPayload`. - New optional `cost_model: CostModel | Unset` field on `BaseJob`, `GetCircuitJobResponse`, and `GetJobResponse`. `CostModel` is a string literal enum: "quantum_compute_time" or "execution_time". - `NativeCircuitInput.qubits` and `JsonMultiCircuitInput.qubits` go from `float | Unset` to `int | Unset` to match upstream's tightening to `format: int32, minimum: 1`. Callers that pass integer literals (which is everyone) are unaffected. Overlay simplification: - Dropped the `QisCircuitInput.properties.qubits` type/format action from openapi-overlay.yaml. Upstream adopted that fix in May 2026 (and extended it to NativeCircuitInput and JsonMultiCircuitInput), so the local patch is now a no-op. The two `required:` actions remain load-bearing \u2014 upstream still treats `qubits` as optional on QisCircuitInput, which fails the simulator preflight. All gates pass: ruff check, ruff format --check, ty check, pytest (242 passed, 100% branch coverage on hand-written code). --- CHANGELOG.md | 9 + ionq_core/api/default/create_job.py | 27 ++- ionq_core/models/__init__.py | 18 ++ ionq_core/models/base_job.py | 25 ++- ionq_core/models/cost_model.py | 14 ++ ionq_core/models/get_circuit_job_response.py | 25 ++- ionq_core/models/get_job_response.py | 25 ++- ionq_core/models/json_multi_circuit_input.py | 6 +- ionq_core/models/native_circuit_input.py | 7 +- .../models/qctrl_qaoa_job_creation_payload.py | 207 ++++++++++++++++++ ..._job_creation_payload_external_settings.py | 90 ++++++++ ...ctrl_qaoa_job_creation_payload_settings.py | 97 ++++++++ ...ation_payload_settings_error_mitigation.py | 82 +++++++ .../qctrl_qaoa_job_creation_payload_type.py | 14 ++ ionq_core/models/qctrl_qaoa_job_input.py | 103 +++++++++ .../models/qctrl_qaoa_job_input_problem.py | 74 +++++++ .../qctrl_qaoa_job_input_problem_type.py | 14 ++ openapi-overlay.yaml | 17 +- openapi.json | 2 +- 19 files changed, 822 insertions(+), 34 deletions(-) create mode 100644 ionq_core/models/cost_model.py create mode 100644 ionq_core/models/qctrl_qaoa_job_creation_payload.py create mode 100644 ionq_core/models/qctrl_qaoa_job_creation_payload_external_settings.py create mode 100644 ionq_core/models/qctrl_qaoa_job_creation_payload_settings.py create mode 100644 ionq_core/models/qctrl_qaoa_job_creation_payload_settings_error_mitigation.py create mode 100644 ionq_core/models/qctrl_qaoa_job_creation_payload_type.py create mode 100644 ionq_core/models/qctrl_qaoa_job_input.py create mode 100644 ionq_core/models/qctrl_qaoa_job_input_problem.py create mode 100644 ionq_core/models/qctrl_qaoa_job_input_problem_type.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eed351..c655fdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ## [Unreleased] +### Added + +- `QctrlQaoaJobCreationPayload` and `QctrlQaoaJobInput` for submitting Q-CTRL QAOA maxcut combinatorial-optimization jobs via `create_job`. The `create_job` body union now also accepts `QctrlQaoaJobCreationPayload`. +- `cost_model` optional field on `BaseJob`, `GetCircuitJobResponse`, and `GetJobResponse`, typed as `CostModel` (`"quantum_compute_time"` or `"execution_time"`). + +### Changed + +- `NativeCircuitInput.qubits` and `JsonMultiCircuitInput.qubits` are now `int | Unset` (previously `float | Unset`), matching upstream's tightening to `format: int32, minimum: 1`. `QisCircuitInput.qubits` already had this type locally via the OpenAPI overlay; that overlay action has been removed now that upstream is correct natively. + ## [0.1.1] - 2026-04-30 ### Changed diff --git a/ionq_core/api/default/create_job.py b/ionq_core/api/default/create_job.py index 7619a7b..42654d7 100644 --- a/ionq_core/api/default/create_job.py +++ b/ionq_core/api/default/create_job.py @@ -15,6 +15,7 @@ from ...models.circuit_job_creation_payload import CircuitJobCreationPayload from ...models.job_creation_response import JobCreationResponse from ...models.json_multi_circuit_job import JSONMultiCircuitJob +from ...models.qctrl_qaoa_job_creation_payload import QctrlQaoaJobCreationPayload from ...models.quantum_function_job_creation_payload import QuantumFunctionJobCreationPayload from typing import cast @@ -22,26 +23,28 @@ def _get_kwargs( *, - body: CircuitJobCreationPayload | JSONMultiCircuitJob | QuantumFunctionJobCreationPayload, + body: CircuitJobCreationPayload | JSONMultiCircuitJob | QctrlQaoaJobCreationPayload | QuantumFunctionJobCreationPayload, ) -> dict[str, Any]: headers: dict[str, Any] = {} - - + + _kwargs: dict[str, Any] = { "method": "post", "url": "/jobs", } - + if isinstance(body, CircuitJobCreationPayload): _kwargs["json"] = body.to_dict() elif isinstance(body, JSONMultiCircuitJob): _kwargs["json"] = body.to_dict() + elif isinstance(body, QuantumFunctionJobCreationPayload): + _kwargs["json"] = body.to_dict() else: _kwargs["json"] = body.to_dict() @@ -96,7 +99,7 @@ def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Res def sync_detailed( *, client: AuthenticatedClient, - body: CircuitJobCreationPayload | JSONMultiCircuitJob | QuantumFunctionJobCreationPayload, + body: CircuitJobCreationPayload | JSONMultiCircuitJob | QctrlQaoaJobCreationPayload | QuantumFunctionJobCreationPayload, ) -> Response[Any | JobCreationResponse]: """ Submit a single-circuit or multi-circuit job for simulation or execution. In `ionq.multi-circuit.v1` @@ -104,7 +107,7 @@ def sync_detailed( its own `gateset`. Args: - body (CircuitJobCreationPayload | JSONMultiCircuitJob | + body (CircuitJobCreationPayload | JSONMultiCircuitJob | QctrlQaoaJobCreationPayload | QuantumFunctionJobCreationPayload): Example: {'type': 'ionq.circuit.v1', 'input': {'qubits': 1, 'gateset': 'qis', 'circuit': [{'gate': 'h', 'target': 0}]}, 'backend': 'qpu.forte-1', 'shots': 500, 'settings': {'error_mitigation': {'debiasing': False}}}. @@ -132,7 +135,7 @@ def sync_detailed( def sync( *, client: AuthenticatedClient, - body: CircuitJobCreationPayload | JSONMultiCircuitJob | QuantumFunctionJobCreationPayload, + body: CircuitJobCreationPayload | JSONMultiCircuitJob | QctrlQaoaJobCreationPayload | QuantumFunctionJobCreationPayload, ) -> Any | JobCreationResponse | None: """ Submit a single-circuit or multi-circuit job for simulation or execution. In `ionq.multi-circuit.v1` @@ -140,7 +143,7 @@ def sync( its own `gateset`. Args: - body (CircuitJobCreationPayload | JSONMultiCircuitJob | + body (CircuitJobCreationPayload | JSONMultiCircuitJob | QctrlQaoaJobCreationPayload | QuantumFunctionJobCreationPayload): Example: {'type': 'ionq.circuit.v1', 'input': {'qubits': 1, 'gateset': 'qis', 'circuit': [{'gate': 'h', 'target': 0}]}, 'backend': 'qpu.forte-1', 'shots': 500, 'settings': {'error_mitigation': {'debiasing': False}}}. @@ -163,7 +166,7 @@ def sync( async def asyncio_detailed( *, client: AuthenticatedClient, - body: CircuitJobCreationPayload | JSONMultiCircuitJob | QuantumFunctionJobCreationPayload, + body: CircuitJobCreationPayload | JSONMultiCircuitJob | QctrlQaoaJobCreationPayload | QuantumFunctionJobCreationPayload, ) -> Response[Any | JobCreationResponse]: """ Submit a single-circuit or multi-circuit job for simulation or execution. In `ionq.multi-circuit.v1` @@ -171,7 +174,7 @@ async def asyncio_detailed( its own `gateset`. Args: - body (CircuitJobCreationPayload | JSONMultiCircuitJob | + body (CircuitJobCreationPayload | JSONMultiCircuitJob | QctrlQaoaJobCreationPayload | QuantumFunctionJobCreationPayload): Example: {'type': 'ionq.circuit.v1', 'input': {'qubits': 1, 'gateset': 'qis', 'circuit': [{'gate': 'h', 'target': 0}]}, 'backend': 'qpu.forte-1', 'shots': 500, 'settings': {'error_mitigation': {'debiasing': False}}}. @@ -199,7 +202,7 @@ async def asyncio_detailed( async def asyncio( *, client: AuthenticatedClient, - body: CircuitJobCreationPayload | JSONMultiCircuitJob | QuantumFunctionJobCreationPayload, + body: CircuitJobCreationPayload | JSONMultiCircuitJob | QctrlQaoaJobCreationPayload | QuantumFunctionJobCreationPayload, ) -> Any | JobCreationResponse | None: """ Submit a single-circuit or multi-circuit job for simulation or execution. In `ionq.multi-circuit.v1` @@ -207,7 +210,7 @@ async def asyncio( its own `gateset`. Args: - body (CircuitJobCreationPayload | JSONMultiCircuitJob | + body (CircuitJobCreationPayload | JSONMultiCircuitJob | QctrlQaoaJobCreationPayload | QuantumFunctionJobCreationPayload): Example: {'type': 'ionq.circuit.v1', 'input': {'qubits': 1, 'gateset': 'qis', 'circuit': [{'gate': 'h', 'target': 0}]}, 'backend': 'qpu.forte-1', 'shots': 500, 'settings': {'error_mitigation': {'debiasing': False}}}. diff --git a/ionq_core/models/__init__.py b/ionq_core/models/__init__.py index 3c7d117..3aea456 100644 --- a/ionq_core/models/__init__.py +++ b/ionq_core/models/__init__.py @@ -29,6 +29,7 @@ from .circuit_job_settings_error_mitigation_debiasing_type_0 import CircuitJobSettingsErrorMitigationDebiasingType0 from .circuit_job_settings_error_mitigation_debiasing_type_0_phi_chi_twirling import CircuitJobSettingsErrorMitigationDebiasingType0PhiChiTwirling from .circuit_job_stats import CircuitJobStats +from .cost_model import CostModel from .create_session_request import CreateSessionRequest from .error import Error from .failure import Failure @@ -93,6 +94,14 @@ from .noise import Noise from .noise_model import NoiseModel from .number_map import NumberMap +from .qctrl_qaoa_job_creation_payload import QctrlQaoaJobCreationPayload +from .qctrl_qaoa_job_creation_payload_external_settings import QctrlQaoaJobCreationPayloadExternalSettings +from .qctrl_qaoa_job_creation_payload_settings import QctrlQaoaJobCreationPayloadSettings +from .qctrl_qaoa_job_creation_payload_settings_error_mitigation import QctrlQaoaJobCreationPayloadSettingsErrorMitigation +from .qctrl_qaoa_job_creation_payload_type import QctrlQaoaJobCreationPayloadType +from .qctrl_qaoa_job_input import QctrlQaoaJobInput +from .qctrl_qaoa_job_input_problem import QctrlQaoaJobInputProblem +from .qctrl_qaoa_job_input_problem_type import QctrlQaoaJobInputProblemType from .qis_circuit import QISCircuit from .qis_circuit_gateset import QISCircuitGateset from .qis_circuit_input import QisCircuitInput @@ -141,6 +150,7 @@ "CircuitJobSettingsErrorMitigationDebiasingType0", "CircuitJobSettingsErrorMitigationDebiasingType0PhiChiTwirling", "CircuitJobStats", + "CostModel", "CreateSessionRequest", "Error", "Failure", @@ -205,6 +215,14 @@ "Noise", "NoiseModel", "NumberMap", + "QctrlQaoaJobCreationPayload", + "QctrlQaoaJobCreationPayloadExternalSettings", + "QctrlQaoaJobCreationPayloadSettings", + "QctrlQaoaJobCreationPayloadSettingsErrorMitigation", + "QctrlQaoaJobCreationPayloadType", + "QctrlQaoaJobInput", + "QctrlQaoaJobInputProblem", + "QctrlQaoaJobInputProblemType", "QISCircuit", "QISCircuitGateset", "QisCircuitInput", diff --git a/ionq_core/models/base_job.py b/ionq_core/models/base_job.py index 8bce548..e628549 100644 --- a/ionq_core/models/base_job.py +++ b/ionq_core/models/base_job.py @@ -12,6 +12,8 @@ from ..types import UNSET, Unset +from ..models.cost_model import check_cost_model +from ..models.cost_model import CostModel from ..models.job_status import check_job_status from ..models.job_status import JobStatus from ..types import UNSET, Unset @@ -33,7 +35,7 @@ @_attrs_define class BaseJob: - """ + """ Attributes: id (str): status (JobStatus): @@ -60,6 +62,7 @@ class BaseJob: results (JsonObject | None): shots (int | Unset): noise (Noise | Unset): + cost_model (CostModel | Unset): """ id: str @@ -86,6 +89,7 @@ class BaseJob: results: JsonObject | None shots: int | Unset = UNSET noise: Noise | Unset = UNSET + cost_model: CostModel | Unset = UNSET @@ -167,6 +171,11 @@ def to_dict(self) -> dict[str, Any]: if not isinstance(self.noise, Unset): noise = self.noise.to_dict() + cost_model: str | Unset = UNSET + if not isinstance(self.cost_model, Unset): + cost_model = self.cost_model + + field_dict: dict[str, Any] = {} @@ -198,6 +207,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["shots"] = shots if noise is not UNSET: field_dict["noise"] = noise + if cost_model is not UNSET: + field_dict["cost_model"] = cost_model return field_dict @@ -380,6 +391,16 @@ def _parse_results(data: object) -> JsonObject | None: + _cost_model = d.pop("cost_model", UNSET) + cost_model: CostModel | Unset + if isinstance(_cost_model, Unset): + cost_model = UNSET + else: + cost_model = check_cost_model(_cost_model) + + + + base_job = cls( id=id, status=status, @@ -405,7 +426,7 @@ def _parse_results(data: object) -> JsonObject | None: results=results, shots=shots, noise=noise, + cost_model=cost_model, ) return base_job - diff --git a/ionq_core/models/cost_model.py b/ionq_core/models/cost_model.py new file mode 100644 index 0000000..c464277 --- /dev/null +++ b/ionq_core/models/cost_model.py @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2026 IonQ, Inc. +# SPDX-License-Identifier: Apache-2.0 +# @generated + +from typing import Literal, cast + +CostModel = Literal['execution_time', 'quantum_compute_time'] + +COST_MODEL_VALUES: set[CostModel] = { 'execution_time', 'quantum_compute_time', } + +def check_cost_model(value: str) -> CostModel: + if value in COST_MODEL_VALUES: + return cast(CostModel, value) + raise TypeError(f"Unexpected value {value!r}. Expected one of {COST_MODEL_VALUES!r}") diff --git a/ionq_core/models/get_circuit_job_response.py b/ionq_core/models/get_circuit_job_response.py index 51603c0..6b989a0 100644 --- a/ionq_core/models/get_circuit_job_response.py +++ b/ionq_core/models/get_circuit_job_response.py @@ -12,6 +12,8 @@ from ..types import UNSET, Unset +from ..models.cost_model import check_cost_model +from ..models.cost_model import CostModel from ..models.job_status import check_job_status from ..models.job_status import JobStatus from ..types import UNSET, Unset @@ -36,7 +38,7 @@ @_attrs_define class GetCircuitJobResponse: - """ + """ Attributes: id (str): status (JobStatus): @@ -64,6 +66,7 @@ class GetCircuitJobResponse: child_job_ids (list[str] | None): shots (int | Unset): noise (Noise | Unset): + cost_model (CostModel | Unset): """ id: str @@ -91,6 +94,7 @@ class GetCircuitJobResponse: child_job_ids: list[str] | None shots: int | Unset = UNSET noise: Noise | Unset = UNSET + cost_model: CostModel | Unset = UNSET @@ -183,6 +187,11 @@ def to_dict(self) -> dict[str, Any]: if not isinstance(self.noise, Unset): noise = self.noise.to_dict() + cost_model: str | Unset = UNSET + if not isinstance(self.cost_model, Unset): + cost_model = self.cost_model + + field_dict: dict[str, Any] = {} @@ -215,6 +224,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["shots"] = shots if noise is not UNSET: field_dict["noise"] = noise + if cost_model is not UNSET: + field_dict["cost_model"] = cost_model return field_dict @@ -416,6 +427,16 @@ def _parse_child_job_ids(data: object) -> list[str] | None: + _cost_model = d.pop("cost_model", UNSET) + cost_model: CostModel | Unset + if isinstance(_cost_model, Unset): + cost_model = UNSET + else: + cost_model = check_cost_model(_cost_model) + + + + get_circuit_job_response = cls( id=id, status=status, @@ -442,7 +463,7 @@ def _parse_child_job_ids(data: object) -> list[str] | None: child_job_ids=child_job_ids, shots=shots, noise=noise, + cost_model=cost_model, ) return get_circuit_job_response - diff --git a/ionq_core/models/get_job_response.py b/ionq_core/models/get_job_response.py index 5f3dbf8..177bf64 100644 --- a/ionq_core/models/get_job_response.py +++ b/ionq_core/models/get_job_response.py @@ -12,6 +12,8 @@ from ..types import UNSET, Unset +from ..models.cost_model import check_cost_model +from ..models.cost_model import CostModel from ..models.job_status import check_job_status from ..models.job_status import JobStatus from ..types import UNSET, Unset @@ -36,7 +38,7 @@ @_attrs_define class GetJobResponse: - """ + """ Attributes: id (str): status (JobStatus): @@ -64,6 +66,7 @@ class GetJobResponse: child_job_ids (list[str] | None): shots (int | Unset): noise (Noise | Unset): + cost_model (CostModel | Unset): """ id: str @@ -91,6 +94,7 @@ class GetJobResponse: child_job_ids: list[str] | None shots: int | Unset = UNSET noise: Noise | Unset = UNSET + cost_model: CostModel | Unset = UNSET @@ -183,6 +187,11 @@ def to_dict(self) -> dict[str, Any]: if not isinstance(self.noise, Unset): noise = self.noise.to_dict() + cost_model: str | Unset = UNSET + if not isinstance(self.cost_model, Unset): + cost_model = self.cost_model + + field_dict: dict[str, Any] = {} @@ -215,6 +224,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["shots"] = shots if noise is not UNSET: field_dict["noise"] = noise + if cost_model is not UNSET: + field_dict["cost_model"] = cost_model return field_dict @@ -416,6 +427,16 @@ def _parse_child_job_ids(data: object) -> list[str] | None: + _cost_model = d.pop("cost_model", UNSET) + cost_model: CostModel | Unset + if isinstance(_cost_model, Unset): + cost_model = UNSET + else: + cost_model = check_cost_model(_cost_model) + + + + get_job_response = cls( id=id, status=status, @@ -442,7 +463,7 @@ def _parse_child_job_ids(data: object) -> list[str] | None: child_job_ids=child_job_ids, shots=shots, noise=noise, + cost_model=cost_model, ) return get_job_response - diff --git a/ionq_core/models/json_multi_circuit_input.py b/ionq_core/models/json_multi_circuit_input.py index 5b32733..888629a 100644 --- a/ionq_core/models/json_multi_circuit_input.py +++ b/ionq_core/models/json_multi_circuit_input.py @@ -31,16 +31,16 @@ @_attrs_define class JsonMultiCircuitInput: - """ + """ Attributes: gateset (JsonMultiCircuitInputGateset): circuits (list[NativeCircuit | QISCircuit]): - qubits (float | Unset): + qubits (int | Unset): """ gateset: JsonMultiCircuitInputGateset circuits: list[NativeCircuit | QISCircuit] - qubits: float | Unset = UNSET + qubits: int | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) diff --git a/ionq_core/models/native_circuit_input.py b/ionq_core/models/native_circuit_input.py index a7f8568..a0da9f6 100644 --- a/ionq_core/models/native_circuit_input.py +++ b/ionq_core/models/native_circuit_input.py @@ -30,16 +30,16 @@ @_attrs_define class NativeCircuitInput: - """ + """ Attributes: circuit (list[GateNativeGate]): gateset (NativeCircuitInputGateset): - qubits (float | Unset): + qubits (int | Unset): """ circuit: list[GateNativeGate] gateset: NativeCircuitInputGateset - qubits: float | Unset = UNSET + qubits: int | Unset = UNSET @@ -100,4 +100,3 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: ) return native_circuit_input - diff --git a/ionq_core/models/qctrl_qaoa_job_creation_payload.py b/ionq_core/models/qctrl_qaoa_job_creation_payload.py new file mode 100644 index 0000000..9a8f8b5 --- /dev/null +++ b/ionq_core/models/qctrl_qaoa_job_creation_payload.py @@ -0,0 +1,207 @@ +# SPDX-FileCopyrightText: 2026 IonQ, Inc. +# SPDX-License-Identifier: Apache-2.0 +# @generated + +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..models.qctrl_qaoa_job_creation_payload_type import check_qctrl_qaoa_job_creation_payload_type +from ..models.qctrl_qaoa_job_creation_payload_type import QctrlQaoaJobCreationPayloadType +from ..types import UNSET, Unset +from typing import cast + +if TYPE_CHECKING: + from ..models.job_metadata import JobMetadata + from ..models.qctrl_qaoa_job_creation_payload_external_settings import QctrlQaoaJobCreationPayloadExternalSettings + from ..models.qctrl_qaoa_job_creation_payload_settings import QctrlQaoaJobCreationPayloadSettings + from ..models.qctrl_qaoa_job_input import QctrlQaoaJobInput + + + + + +T = TypeVar("T", bound="QctrlQaoaJobCreationPayload") + + + +@_attrs_define +class QctrlQaoaJobCreationPayload: + """ Submit a combinatorial optimization job to solve a maxcut problem using Q-CTRL's QAOA Solver. See our QAOA Job guide + for more infromation. + + Attributes: + backend (str): Available options: `simulator`, `qpu.aria-1`, `qpu.aria-2`, `qpu.forte-1`, `qpu.forte- + enterprise-1` + type_ (QctrlQaoaJobCreationPayloadType): + input_ (QctrlQaoaJobInput): + external_settings (QctrlQaoaJobCreationPayloadExternalSettings): + name (str | Unset): + metadata (JobMetadata | Unset): + shots (int | Unset): Default: 100. + session_id (str | Unset): + settings (QctrlQaoaJobCreationPayloadSettings | Unset): + dry_run (bool | Unset): + """ + + backend: str + type_: QctrlQaoaJobCreationPayloadType + input_: QctrlQaoaJobInput + external_settings: QctrlQaoaJobCreationPayloadExternalSettings + name: str | Unset = UNSET + metadata: JobMetadata | Unset = UNSET + shots: int | Unset = 100 + session_id: str | Unset = UNSET + settings: QctrlQaoaJobCreationPayloadSettings | Unset = UNSET + dry_run: bool | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + from ..models.job_metadata import JobMetadata + from ..models.qctrl_qaoa_job_creation_payload_external_settings import QctrlQaoaJobCreationPayloadExternalSettings + from ..models.qctrl_qaoa_job_creation_payload_settings import QctrlQaoaJobCreationPayloadSettings + from ..models.qctrl_qaoa_job_input import QctrlQaoaJobInput + backend = self.backend + + type_: str = self.type_ + + input_ = self.input_.to_dict() + + external_settings = self.external_settings.to_dict() + + name = self.name + + metadata: dict[str, Any] | Unset = UNSET + if not isinstance(self.metadata, Unset): + metadata = self.metadata.to_dict() + + shots = self.shots + + session_id = self.session_id + + settings: dict[str, Any] | Unset = UNSET + if not isinstance(self.settings, Unset): + settings = self.settings.to_dict() + + dry_run = self.dry_run + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "backend": backend, + "type": type_, + "input": input_, + "external_settings": external_settings, + }) + if name is not UNSET: + field_dict["name"] = name + if metadata is not UNSET: + field_dict["metadata"] = metadata + if shots is not UNSET: + field_dict["shots"] = shots + if session_id is not UNSET: + field_dict["session_id"] = session_id + if settings is not UNSET: + field_dict["settings"] = settings + if dry_run is not UNSET: + field_dict["dry_run"] = dry_run + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.job_metadata import JobMetadata + from ..models.qctrl_qaoa_job_creation_payload_external_settings import QctrlQaoaJobCreationPayloadExternalSettings + from ..models.qctrl_qaoa_job_creation_payload_settings import QctrlQaoaJobCreationPayloadSettings + from ..models.qctrl_qaoa_job_input import QctrlQaoaJobInput + d = dict(src_dict) + backend = d.pop("backend") + + type_ = check_qctrl_qaoa_job_creation_payload_type(d.pop("type")) + + + + + input_ = QctrlQaoaJobInput.from_dict(d.pop("input")) + + + + + external_settings = QctrlQaoaJobCreationPayloadExternalSettings.from_dict(d.pop("external_settings")) + + + + + name = d.pop("name", UNSET) + + _metadata = d.pop("metadata", UNSET) + metadata: JobMetadata | Unset + if isinstance(_metadata, Unset): + metadata = UNSET + else: + metadata = JobMetadata.from_dict(_metadata) + + + + + shots = d.pop("shots", UNSET) + + session_id = d.pop("session_id", UNSET) + + _settings = d.pop("settings", UNSET) + settings: QctrlQaoaJobCreationPayloadSettings | Unset + if isinstance(_settings, Unset): + settings = UNSET + else: + settings = QctrlQaoaJobCreationPayloadSettings.from_dict(_settings) + + + + + dry_run = d.pop("dry_run", UNSET) + + qctrl_qaoa_job_creation_payload = cls( + backend=backend, + type_=type_, + input_=input_, + external_settings=external_settings, + name=name, + metadata=metadata, + shots=shots, + session_id=session_id, + settings=settings, + dry_run=dry_run, + ) + + + qctrl_qaoa_job_creation_payload.additional_properties = d + return qctrl_qaoa_job_creation_payload + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/ionq_core/models/qctrl_qaoa_job_creation_payload_external_settings.py b/ionq_core/models/qctrl_qaoa_job_creation_payload_external_settings.py new file mode 100644 index 0000000..378da90 --- /dev/null +++ b/ionq_core/models/qctrl_qaoa_job_creation_payload_external_settings.py @@ -0,0 +1,90 @@ +# SPDX-FileCopyrightText: 2026 IonQ, Inc. +# SPDX-License-Identifier: Apache-2.0 +# @generated + +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset + + + + + + +T = TypeVar("T", bound="QctrlQaoaJobCreationPayloadExternalSettings") + + + +@_attrs_define +class QctrlQaoaJobCreationPayloadExternalSettings: + """ + Attributes: + api_credentials (str): API Key for your Q-CTRL Account + external_organization (str | Unset): Optional unique slug for your target Q-CTRL organization + """ + + api_credentials: str + external_organization: str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + api_credentials = self.api_credentials + + external_organization = self.external_organization + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "api_credentials": api_credentials, + }) + if external_organization is not UNSET: + field_dict["external_organization"] = external_organization + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + api_credentials = d.pop("api_credentials") + + external_organization = d.pop("external_organization", UNSET) + + qctrl_qaoa_job_creation_payload_external_settings = cls( + api_credentials=api_credentials, + external_organization=external_organization, + ) + + + qctrl_qaoa_job_creation_payload_external_settings.additional_properties = d + return qctrl_qaoa_job_creation_payload_external_settings + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/ionq_core/models/qctrl_qaoa_job_creation_payload_settings.py b/ionq_core/models/qctrl_qaoa_job_creation_payload_settings.py new file mode 100644 index 0000000..cabe335 --- /dev/null +++ b/ionq_core/models/qctrl_qaoa_job_creation_payload_settings.py @@ -0,0 +1,97 @@ +# SPDX-FileCopyrightText: 2026 IonQ, Inc. +# SPDX-License-Identifier: Apache-2.0 +# @generated + +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset +from typing import cast + +if TYPE_CHECKING: + from ..models.qctrl_qaoa_job_creation_payload_settings_error_mitigation import QctrlQaoaJobCreationPayloadSettingsErrorMitigation + + + + + +T = TypeVar("T", bound="QctrlQaoaJobCreationPayloadSettings") + + + +@_attrs_define +class QctrlQaoaJobCreationPayloadSettings: + """ + Attributes: + error_mitigation (QctrlQaoaJobCreationPayloadSettingsErrorMitigation | Unset): + """ + + error_mitigation: QctrlQaoaJobCreationPayloadSettingsErrorMitigation | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + from ..models.qctrl_qaoa_job_creation_payload_settings_error_mitigation import QctrlQaoaJobCreationPayloadSettingsErrorMitigation + error_mitigation: dict[str, Any] | Unset = UNSET + if not isinstance(self.error_mitigation, Unset): + error_mitigation = self.error_mitigation.to_dict() + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + }) + if error_mitigation is not UNSET: + field_dict["error_mitigation"] = error_mitigation + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.qctrl_qaoa_job_creation_payload_settings_error_mitigation import QctrlQaoaJobCreationPayloadSettingsErrorMitigation + d = dict(src_dict) + _error_mitigation = d.pop("error_mitigation", UNSET) + error_mitigation: QctrlQaoaJobCreationPayloadSettingsErrorMitigation | Unset + if isinstance(_error_mitigation, Unset): + error_mitigation = UNSET + else: + error_mitigation = QctrlQaoaJobCreationPayloadSettingsErrorMitigation.from_dict(_error_mitigation) + + + + + qctrl_qaoa_job_creation_payload_settings = cls( + error_mitigation=error_mitigation, + ) + + + qctrl_qaoa_job_creation_payload_settings.additional_properties = d + return qctrl_qaoa_job_creation_payload_settings + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/ionq_core/models/qctrl_qaoa_job_creation_payload_settings_error_mitigation.py b/ionq_core/models/qctrl_qaoa_job_creation_payload_settings_error_mitigation.py new file mode 100644 index 0000000..ab48cda --- /dev/null +++ b/ionq_core/models/qctrl_qaoa_job_creation_payload_settings_error_mitigation.py @@ -0,0 +1,82 @@ +# SPDX-FileCopyrightText: 2026 IonQ, Inc. +# SPDX-License-Identifier: Apache-2.0 +# @generated + +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..types import UNSET, Unset + + + + + + +T = TypeVar("T", bound="QctrlQaoaJobCreationPayloadSettingsErrorMitigation") + + + +@_attrs_define +class QctrlQaoaJobCreationPayloadSettingsErrorMitigation: + """ + Attributes: + debiasing (bool | Unset): + """ + + debiasing: bool | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + debiasing = self.debiasing + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + }) + if debiasing is not UNSET: + field_dict["debiasing"] = debiasing + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + debiasing = d.pop("debiasing", UNSET) + + qctrl_qaoa_job_creation_payload_settings_error_mitigation = cls( + debiasing=debiasing, + ) + + + qctrl_qaoa_job_creation_payload_settings_error_mitigation.additional_properties = d + return qctrl_qaoa_job_creation_payload_settings_error_mitigation + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/ionq_core/models/qctrl_qaoa_job_creation_payload_type.py b/ionq_core/models/qctrl_qaoa_job_creation_payload_type.py new file mode 100644 index 0000000..8f8d8a8 --- /dev/null +++ b/ionq_core/models/qctrl_qaoa_job_creation_payload_type.py @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2026 IonQ, Inc. +# SPDX-License-Identifier: Apache-2.0 +# @generated + +from typing import Literal, cast + +QctrlQaoaJobCreationPayloadType = Literal['qctrl.qaoa.v1'] + +QCTRL_QAOA_JOB_CREATION_PAYLOAD_TYPE_VALUES: set[QctrlQaoaJobCreationPayloadType] = { 'qctrl.qaoa.v1', } + +def check_qctrl_qaoa_job_creation_payload_type(value: str) -> QctrlQaoaJobCreationPayloadType: + if value in QCTRL_QAOA_JOB_CREATION_PAYLOAD_TYPE_VALUES: + return cast(QctrlQaoaJobCreationPayloadType, value) + raise TypeError(f"Unexpected value {value!r}. Expected one of {QCTRL_QAOA_JOB_CREATION_PAYLOAD_TYPE_VALUES!r}") diff --git a/ionq_core/models/qctrl_qaoa_job_input.py b/ionq_core/models/qctrl_qaoa_job_input.py new file mode 100644 index 0000000..001e80e --- /dev/null +++ b/ionq_core/models/qctrl_qaoa_job_input.py @@ -0,0 +1,103 @@ +# SPDX-FileCopyrightText: 2026 IonQ, Inc. +# SPDX-License-Identifier: Apache-2.0 +# @generated + +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +from ..models.qctrl_qaoa_job_input_problem_type import check_qctrl_qaoa_job_input_problem_type +from ..models.qctrl_qaoa_job_input_problem_type import QctrlQaoaJobInputProblemType +from typing import cast + +if TYPE_CHECKING: + from ..models.qctrl_qaoa_job_input_problem import QctrlQaoaJobInputProblem + + + + + +T = TypeVar("T", bound="QctrlQaoaJobInput") + + + +@_attrs_define +class QctrlQaoaJobInput: + """ + Attributes: + problem_type (QctrlQaoaJobInputProblemType): + problem (QctrlQaoaJobInputProblem): A NetworkX adjacency_graph object Example: {'directed': False, 'multigraph': + False, 'graph': [], 'nodes': [{'id': 0}, {'id': 1}, {'id': 2}], 'adjacency': [[{'id': 1}, {'id': 2}], [{'id': + 0}, {'id': 2}], [{'id': 0}, {'id': 1}]]}. + """ + + problem_type: QctrlQaoaJobInputProblemType + problem: QctrlQaoaJobInputProblem + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + from ..models.qctrl_qaoa_job_input_problem import QctrlQaoaJobInputProblem + problem_type: str = self.problem_type + + problem = self.problem.to_dict() + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "problem_type": problem_type, + "problem": problem, + }) + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.qctrl_qaoa_job_input_problem import QctrlQaoaJobInputProblem + d = dict(src_dict) + problem_type = check_qctrl_qaoa_job_input_problem_type(d.pop("problem_type")) + + + + + problem = QctrlQaoaJobInputProblem.from_dict(d.pop("problem")) + + + + + qctrl_qaoa_job_input = cls( + problem_type=problem_type, + problem=problem, + ) + + + qctrl_qaoa_job_input.additional_properties = d + return qctrl_qaoa_job_input + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/ionq_core/models/qctrl_qaoa_job_input_problem.py b/ionq_core/models/qctrl_qaoa_job_input_problem.py new file mode 100644 index 0000000..e3a4ba2 --- /dev/null +++ b/ionq_core/models/qctrl_qaoa_job_input_problem.py @@ -0,0 +1,74 @@ +# SPDX-FileCopyrightText: 2026 IonQ, Inc. +# SPDX-License-Identifier: Apache-2.0 +# @generated + +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + + + + + + + +T = TypeVar("T", bound="QctrlQaoaJobInputProblem") + + + +@_attrs_define +class QctrlQaoaJobInputProblem: + """ A NetworkX adjacency_graph object + + Example: + {'directed': False, 'multigraph': False, 'graph': [], 'nodes': [{'id': 0}, {'id': 1}, {'id': 2}], 'adjacency': + [[{'id': 1}, {'id': 2}], [{'id': 0}, {'id': 2}], [{'id': 0}, {'id': 1}]]} + + """ + + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + + + + def to_dict(self) -> dict[str, Any]: + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + qctrl_qaoa_job_input_problem = cls( + ) + + + qctrl_qaoa_job_input_problem.additional_properties = d + return qctrl_qaoa_job_input_problem + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/ionq_core/models/qctrl_qaoa_job_input_problem_type.py b/ionq_core/models/qctrl_qaoa_job_input_problem_type.py new file mode 100644 index 0000000..ef9c929 --- /dev/null +++ b/ionq_core/models/qctrl_qaoa_job_input_problem_type.py @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2026 IonQ, Inc. +# SPDX-License-Identifier: Apache-2.0 +# @generated + +from typing import Literal, cast + +QctrlQaoaJobInputProblemType = Literal['maxcut'] + +QCTRL_QAOA_JOB_INPUT_PROBLEM_TYPE_VALUES: set[QctrlQaoaJobInputProblemType] = { 'maxcut', } + +def check_qctrl_qaoa_job_input_problem_type(value: str) -> QctrlQaoaJobInputProblemType: + if value in QCTRL_QAOA_JOB_INPUT_PROBLEM_TYPE_VALUES: + return cast(QctrlQaoaJobInputProblemType, value) + raise TypeError(f"Unexpected value {value!r}. Expected one of {QCTRL_QAOA_JOB_INPUT_PROBLEM_TYPE_VALUES!r}") diff --git a/openapi-overlay.yaml b/openapi-overlay.yaml index 00c0976..d371a15 100644 --- a/openapi-overlay.yaml +++ b/openapi-overlay.yaml @@ -1,12 +1,17 @@ overlay: 1.0.0 info: title: ionq-core-python local OpenAPI fixes - version: 0.1.0 + version: 0.2.0 description: | Patches applied to openapi.json before client generation. The upstream - spec marks QisCircuitInput.qubits as optional and floating-point, but - the simulator preflight rejects payloads without it (surfacing as - UnexpectedCompilationError) and qubit counts are non-negative integers. + spec marks QisCircuitInput.qubits as optional, but the simulator + preflight rejects payloads without it (surfacing as + UnexpectedCompilationError), so we make it required locally. + + Previously this overlay also coerced QisCircuitInput.qubits from + number/double to integer/int32; upstream adopted that fix in May 2026 + (and extended it to NativeCircuitInput and JsonMultiCircuitInput), so + that action was removed. actions: - target: $.components.schemas.QisCircuitInput.required @@ -17,7 +22,3 @@ actions: - circuit - gateset - qubits - - target: $.components.schemas.QisCircuitInput.properties.qubits - update: - type: integer - format: int32 diff --git a/openapi.json b/openapi.json index 1831fc6..a067622 100644 --- a/openapi.json +++ b/openapi.json @@ -1 +1 @@ -{"openapi":"3.0.3","info":{"contact":{"email":"support@ionq.co","name":"IonQ","url":"https://ionq.com/"},"description":"*Last updated: April 30, 2026*\nIonQ's API for accessing the IonQ Quantum Cloud platform\n\nPlease subscribe for automated updates when we perform maintenance or\nexperience an outage.\n\nIn addition, you may use the [status endpoint](#tag/status) to check the\ncurrent status of our API.\n\n## Authentication\n\n\n","title":"IonQ Cloud Platform API","version":"v0.4"},"servers":[{"url":"https://api.ionq.co/v0.4"}],"paths":{"/whoami":{"get":{"description":"Retrieves current key associated with this session.","operationId":"getWhoami","responses":{"200":{"$ref":"#/components/responses/Whoami"}},"summary":"Get current key","tags":["whoami"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/whoami\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}},"/backends":{"get":{"description":"This endpoint retrieves all backends.","operationId":"getBackends","responses":{"200":{"$ref":"#/components/responses/ListBackends"}},"security":[],"summary":"Get Backends","tags":["backends"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/backends\"\n"}]}},"/backends/{backend}":{"get":{"description":"This endpoint retrieves a backend.","operationId":"getBackend","parameters":[{"$ref":"#/components/parameters/backend"}],"responses":{"200":{"$ref":"#/components/responses/GetBackend"}},"security":[],"summary":"Get a Backend","tags":["backends"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/backends/qpu.aria-1\"\n"}]}},"/backends/{backend}/characterizations":{"get":{"description":"This endpoint retrieves an array of all available backend characterizations, with pagination.","operationId":"getCharacterizationsForBackend","parameters":[{"$ref":"#/components/parameters/backend"},{"description":"Characterizations starting at this time (e.g., `start=2025-12-31`)","in":"query","name":"start","schema":{"type":"string"}},{"description":"Characterizations before this time (e.g., `end=2025-12-31`)","in":"query","name":"end","schema":{"type":"string"}},{"description":"How many objects to return.","in":"query","name":"limit","schema":{"default":10,"maximum":10,"minimum":1,"type":"integer"}},{"$ref":"#/components/parameters/pagination-page"}],"responses":{"200":{"$ref":"#/components/responses/ListCharacterizations"}},"security":[],"summary":"Get All Backend Characterizations","tags":["characterizations"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/backends/qpu.aria-1/characterizations\"\n"}]}},"/backends/{backend}/characterizations/{UUID}":{"get":{"description":"This endpoint retrieves a characterization.","operationId":"getCharacterization","parameters":[{"$ref":"#/components/parameters/backend"},{"$ref":"#/components/parameters/uuid"}],"responses":{"200":{"$ref":"#/components/responses/GetCharacterization"}},"summary":"Get a Characterization","tags":["characterizations"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/backends/qpu.aria-1/characterizations/aa54e783-0a9b-4f73-ad2f-63983b6aa4a8\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}},"/jobs":{"post":{"operationId":"CreateJob","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobCreationResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobCreationPayload"}}}},"description":"Submit a single-circuit or multi-circuit job for simulation or execution. In `ionq.multi-circuit.v1` payloads, each entry in `input.circuits` inherits the parent `input.gateset` unless the circuit sets its own `gateset`.\n","x-codeSamples":[{"lang":"curl","label":"Single-circuit QIS job","source":"curl -X POST \"https://api.ionq.co/v0.4/jobs\" \\\n -H \"Authorization: apiKey your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"type\" : \"ionq.circuit.v1\",\n \"name\": \"Sample circuit\",\n \"metadata\": {\n \"fizz\": \"buzz\",\n \"foo\": \"bar\"\n },\n \"shots\": 500,\n \"backend\": \"qpu.forte-1\",\n \"settings\" :\n {\n \"error_mitigation\":\n {\n \"debiasing\": false\n }\n },\n \"input\": {\n \"qubits\": 2,\n \"gateset\": \"qis\",\n \"circuit\": [\n {\n \"gate\": \"h\",\n \"target\": 0\n }\n ]\n }\n }'\n"},{"lang":"curl","label":"Mixed-gateset multi-circuit job","source":"curl -X POST \"https://api.ionq.co/v0.4/jobs\" \\\n -H \"Authorization: apiKey your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"type\": \"ionq.multi-circuit.v1\",\n \"backend\": \"simulator\",\n \"shots\": 500,\n \"input\": {\n \"gateset\": \"native\",\n \"qubits\": 2,\n \"circuits\": [\n {\n \"name\": \"qis circuit override\",\n \"gateset\": \"qis\",\n \"circuit\": [\n {\n \"gate\": \"h\",\n \"target\": 0\n },\n {\n \"gate\": \"cnot\",\n \"target\": 0,\n \"control\": 1\n }\n ]\n },\n {\n \"name\": \"native circuit from parent\",\n \"circuit\": [\n {\n \"gate\": \"ms\",\n \"targets\": [0, 1],\n \"phases\": [0, 0.25]\n },\n {\n \"gate\": \"gpi2\",\n \"target\": 0,\n \"phase\": 0.75\n }\n ]\n }\n ]\n }\n }'\n"}]},"get":{"operationId":"GetJobs","responses":{"200":{"description":"Successfully retrieved a list of jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetJobsResponse"},"examples":{"Example 1":{"value":{"jobs":[{"id":"e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524","status":"completed","type":"ionq.circuit.v1","backend":"simulator","dry_run":false,"submitter_id":"64b03577072d45001c85e9c4","project_id":"1333d459-cf47-4a5e-acc1-8d4eb4f7b025","parent_job_id":null,"session_id":null,"metadata":null,"name":null,"submitted_at":"2025-05-28T20:47:05.440Z","started_at":null,"completed_at":null,"predicted_execution_duration_ms":null,"predicted_wait_time_ms":null,"execution_duration_ms":null,"shots":1000,"noise":{"model":"ideal"},"failure":null,"settings":{"compilation":{}},"stats":{"qubits":20,"circuits":1,"gate_counts":{"1q":1028,"2q":110},"predicted_quantum_compute_time_us":5000,"billed_quantum_compute_time_us":5200},"results":{"probabilities":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/results/probabilities"}},"output":{}}],"next":null}}}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"query","name":"ids","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"in":"query","name":"parent_job_id","required":false,"schema":{"type":"string"}},{"in":"query","name":"status","required":false,"schema":{"$ref":"#/components/schemas/JobStatus"}},{"description":"Filter jobs by backend target. Supports single target or comma-separated list of targets.","in":"query","name":"target","required":false,"schema":{"type":"string"},"example":"simulator"},{"in":"query","name":"session_id","required":false,"schema":{"type":"string"}},{"description":"The id of another user within a shared project to view their submitted jobs. Ignored if not a project member.","in":"query","name":"submitter_id","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"format":"int32","type":"integer"}},{"in":"query","name":"next","required":false,"schema":{"type":"string"}}],"x-codeSamples":[{"lang":"curl","source":"# Get all jobs:\ncurl \"https://api.ionq.co/v0.4/jobs\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]},"delete":{"operationId":"DeleteJobs","responses":{"200":{"description":"Successfully deleted a list of jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsDeletedResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsBulkOperationRequest"}}}},"x-codeSamples":[{"lang":"curl","source":"curl -X DELETE \"https://api.ionq.co/v0.4/jobs\" \\\n -H \"Authorization: apiKey your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"ids\": [\n \"617a1f8b-59d4-435d-aa33-695433d7155e\",\n \"2ccf2773-4c28-468e-a290-2f8554808a25\",\n \"f92df2b6-d212-4f4a-b9ea-024b58c5c3e8\"\n ]\n }'\n"}]}},"/jobs/{UUID}":{"get":{"operationId":"GetJob","responses":{"200":{"description":"Successfully retrieved a job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetJobResponse"},"examples":{"Example 1":{"value":{"id":"e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524","status":"completed","type":"ionq.circuit.v1","backend":"simulator","dry_run":false,"submitter_id":"64b03577072d45001c85e9c4","project_id":"1333d459-cf47-4a5e-acc1-8d4eb4f7b025","parent_job_id":null,"child_job_ids":null,"session_id":null,"metadata":null,"name":null,"submitted_at":"2025-05-28T20:47:05.440Z","started_at":null,"completed_at":null,"predicted_execution_duration_ms":null,"predicted_wait_time_ms":null,"execution_duration_ms":null,"shots":1000,"noise":{"model":"ideal"},"failure":null,"settings":{"compilation":{}},"stats":{"qubits":20,"circuits":1,"gate_counts":{"1q":1028,"2q":110},"predicted_quantum_compute_time_us":5000,"billed_quantum_compute_time_us":5200},"results":{"probabilities":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/results/probabilities"}},"output":{"compilation":{},"error_mitigation":{"debiasing":{"variants":[{"variant_id":"069ce8f8-f437-7d75-8000-9f5f8c3d7897","qubit_map":[4,12,7],"shots":120,"results":{"probabilities":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/variants/069ce8f8-f437-7d75-8000-9f5f8c3d7897/results/probabilities"},"histogram":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/variants/069ce8f8-f437-7d75-8000-9f5f8c3d7897/results/histogram"},"shots":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/variants/069ce8f8-f437-7d75-8000-9f5f8c3d7897/results/shots"}}}]}}}}}}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The UUID of the job — this UUID is provided in the response on job creation.","in":"path","name":"UUID","required":true,"schema":{"type":"string"}}],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/jobs/617a1f8b-59d4-435d-aa33-695433d7155e\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]},"delete":{"operationId":"DeleteJob","responses":{"200":{"description":"Successfully deleted a job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobDeletedResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The UUID of the job — this UUID is provided in the response on job creation.","in":"path","name":"UUID","required":true,"schema":{"type":"string"}}],"x-codeSamples":[{"lang":"curl","source":"curl -X DELETE \"https://api.ionq.co/v0.4/jobs/617a1f8b-59d4-435d-aa33-695433d7155e\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}},"/jobs/{UUID}/cost":{"get":{"operationId":"GetJobCost","responses":{"200":{"description":"Successfully retrieved the cost of a job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetJobCostResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"UUID","required":true,"schema":{"type":"string"}}],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/jobs/0197379a-c3b8-7548-9da4-bbb7067311c1/cost\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}},"/jobs/{UUID}/circuits/{lang}":{"get":{"operationId":"GetCompiledFile","responses":{"200":{"description":"Successfully downloaded a compiled file.","content":{"application/json":{"schema":{"type":"string"}}}},"403":{"description":"Forbidden"},"404":{"description":"Not Found"},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"UUID","required":true,"schema":{"type":"string"}},{"in":"path","name":"lang","required":true,"schema":{"type":"string","enum":["native","qasm3"]}}]}},"/jobs/{UUID}/status/cancel":{"put":{"operationId":"CancelJob","responses":{"200":{"description":"Successfully canceled a job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobCanceledResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"description":"Cancel the execution of many jobs at once by passing a list of jobs.","summary":"Cancel a job","security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The UUID of the job — this UUID is provided in the response on job creation.","in":"path","name":"UUID","required":true,"schema":{"type":"string"}}],"x-codeSamples":[{"lang":"curl","source":"curl -X PUT \"https://api.ionq.co/v0.4/jobs/617a1f8b-59d4-435d-aa33-695433d7155e/status/cancel\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}},"/jobs/status/cancel":{"put":{"operationId":"CancelJobs","responses":{"200":{"description":"Successfully canceled a list of jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsCanceledResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsBulkOperationRequest"}}}},"x-codeSamples":[{"lang":"curl","source":"curl -X PUT \"https://api.ionq.co/v0.4/jobs/status/cancel\" \\\n -H \"Authorization: apiKey your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"ids\": [\n \"617a1f8b-59d4-435d-aa33-695433d7155e\",\n \"2ccf2773-4c28-468e-a290-2f8554808a25\",\n \"f92df2b6-d212-4f4a-b9ea-024b58c5c3e8\"\n ]\n }'\n"}]}},"/jobs/estimate":{"get":{"operationId":"EstimateJobCost","responses":{"200":{"description":"Successfully retrieved the cost estimate of a job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetJobEstimateResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"query","name":"backend","required":true,"schema":{"$ref":"#/components/schemas/JobBackends"}},{"in":"query","name":"type","required":false,"schema":{"default":"ionq.circuit.v1","type":"string"}},{"in":"query","name":"qubits","required":false,"schema":{"default":25,"format":"int32","type":"integer"}},{"in":"query","name":"shots","required":false,"schema":{"default":1000,"format":"int32","type":"integer"}},{"in":"query","name":"1q_gates","required":false,"schema":{"default":0,"format":"int32","type":"integer"}},{"in":"query","name":"2q_gates","required":false,"schema":{"default":0,"format":"int32","type":"integer"}},{"in":"query","name":"error_mitigation","required":false,"schema":{"default":false,"type":"boolean"}}]}},"/jobs/{UUID}/results/probabilities":{"get":{"operationId":"GetJobProbabilities","responses":{"200":{"description":"Probability distribution keyed by decimal qubit state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetResultsResponse"}}}},"404":{"description":"Job not found or not yet completed."}},"summary":"Fetch the probability distribution for a completed job.","security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The UUID of the job.","in":"path","name":"UUID","required":true,"schema":{"type":"string"}},{"description":"Whether to apply sharpening to the probability distribution.","in":"query","name":"sharpen","required":false,"schema":{"type":"boolean"}}]}},"/jobs/{UUID}/variants/{variantId}/results/probabilities":{"get":{"operationId":"GetVariantProbabilities","responses":{"200":{"description":"Per-variant probabilities histogram","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVariantResultsResponse"}}}},"404":{"description":"Not found"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"UUID","required":true,"schema":{"type":"string"}},{"in":"path","name":"variantId","required":true,"schema":{"type":"string"}}]}},"/jobs/{UUID}/variants/{variantId}/results/histogram":{"get":{"operationId":"GetVariantHistogram","responses":{"200":{"description":"Per-variant raw histogram (counts)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVariantResultsResponse"}}}},"404":{"description":"Not found"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"UUID","required":true,"schema":{"type":"string"}},{"in":"path","name":"variantId","required":true,"schema":{"type":"string"}}]}},"/jobs/{UUID}/variants/{variantId}/results/shots":{"get":{"operationId":"GetVariantShots","responses":{"200":{"description":"Per-variant shot-wise results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVariantResultsResponse"}}}},"404":{"description":"Not found"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"UUID","required":true,"schema":{"type":"string"}},{"in":"path","name":"variantId","required":true,"schema":{"type":"string"}}]}},"/sessions":{"post":{"operationId":"CreateSession","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}}},"security":[{"apiKeyAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionRequest"}}}}},"get":{"operationId":"GetSessions","responses":{"200":{"description":"Successfully retrieved a list of sessions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionsResponse"}}}}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"query","name":"active","required":false,"schema":{"type":"boolean"}}]}},"/sessions/{session_id}/end":{"post":{"operationId":"EndSession","responses":{"200":{"description":"Successfully end a session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}}},"security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The id of the session — this id is provided in the response on session creation.","in":"path","name":"session_id","required":true,"schema":{"type":"string"}}]}},"/sessions/{session_id}":{"get":{"operationId":"GetSession","responses":{"200":{"description":"Successfully retrieved a session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}}},"security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The id of the session — this id is provided in the response on session creation.","in":"path","name":"session_id","required":true,"schema":{"type":"string"}}]}},"/sessions/{session_id}/jobs":{"get":{"operationId":"GetSessionJobs","responses":{"200":{"description":"Successfully retrieved a list of jobs from a session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetJobsResponse"},"examples":{"Example 1":{"value":{"jobs":[{"id":"e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524","status":"completed","type":"ionq.circuit.v1","backend":"simulator","dry_run":false,"submitter_id":"64b03577072d45001c85e9c4","project_id":"1333d459-cf47-4a5e-acc1-8d4eb4f7b025","parent_job_id":null,"session_id":null,"metadata":null,"name":null,"submitted_at":"2025-05-28T20:47:05.440Z","started_at":null,"completed_at":null,"predicted_execution_duration_ms":null,"predicted_wait_time_ms":null,"execution_duration_ms":null,"shots":1000,"noise":{"model":"ideal"},"failure":null,"settings":{"compilation":{}},"stats":{"qubits":20,"circuits":1,"gate_counts":{"1q":1028,"2q":110},"predicted_quantum_compute_time_us":5000,"billed_quantum_compute_time_us":5200},"results":{"probabilities":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/results/probabilities"}},"output":{}}],"next":null}}}}}}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}},{"in":"query","name":"ids","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"in":"query","name":"parent_job_id","required":false,"schema":{"type":"string"}},{"in":"query","name":"status","required":false,"schema":{"$ref":"#/components/schemas/JobStatus"}},{"description":"Filter jobs by backend target. Supports single target or comma-separated list of targets.","in":"query","name":"target","required":false,"schema":{"type":"string"},"example":"simulator"},{"in":"query","name":"session_id","required":false,"schema":{"type":"string"}},{"description":"The id of another user within a shared project to view their submitted jobs. Ignored if not a project member.","in":"query","name":"submitter_id","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"format":"int32","type":"integer"}},{"in":"query","name":"next","required":false,"schema":{"type":"string"}}]}},"/organizations/{organization_id}/usage":{"get":{"description":"Retrieves the costs of a given group type, broken down by the given date modality.","operationId":"get-usages","parameters":[{"$ref":"#/components/parameters/organization_id"},{"description":"Start date, inclusive","example":"2023-07-01","in":"query","name":"start_date","required":true,"schema":{"format":"date","type":"string"}},{"description":"End date, exclusive","example":"2023-08-01","in":"query","name":"end_date","required":true,"schema":{"format":"date","type":"string"}},{"description":"QPU Usage grouping","in":"query","name":"group_by","required":true,"schema":{"$ref":"#/components/schemas/group_by"}},{"description":"Report modality","in":"query","name":"modality","required":true,"schema":{"$ref":"#/components/schemas/modality"}}],"responses":{"200":{"$ref":"#/components/responses/UsagesResponse"}},"summary":"Get usage costs","tags":["usage"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/organizations/com.my.org/usage?group_by=project&start_date=2025-01-01&end_date=2025-03-02&modality=weekly\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}}},"components":{"schemas":{"BadRequestError":{"description":"Error when a bad client request was received.","properties":{"error":{"description":"A short error type descrption.","type":"string"},"message":{"description":"A helpful error message.","type":"string"},"statusCode":{"description":"The HTTP status code for this error.","type":"integer"},"validation":{"$ref":"#/components/schemas/RequestValidation"}},"required":["statusCode","error","message"],"type":"object"},"Error":{"description":"Basic API error response.","properties":{"error":{"description":"A short error type descrption.","type":"string"},"message":{"description":"A helpful error message.","type":"string"},"statusCode":{"description":"The HTTP status code for this error.","type":"integer"}},"required":["statusCode","error","message"],"type":"object"},"RequestValidation":{"description":"Request validation failure details.","properties":{"keys":{"description":"A list of request payload keys which have bad values.","items":{"type":"string"},"type":"array"},"source":{"description":"Location in the request of the bad value(s).","type":"string"}},"type":"object"},"Whoami":{"description":"Details of current API Key session.","properties":{"key_id":{"$ref":"#/components/schemas/key-id"},"key_name":{"$ref":"#/components/schemas/key-name"},"project_id":{"$ref":"#/components/schemas/project-id"}},"required":["key_id","key_name"],"type":"object"},"key-id":{"description":"UUID of a API key.","example":"e060759f-4348-4767-a645-8c0301265791","format":"uuid","type":"string"},"key-name":{"description":"key name.","example":"My First Key","type":"string"},"project-id":{"description":"UUID of a project.","example":"944904d6-2e30-4cfb-8bc4-04afaabcdd42","format":"uuid","type":"string"},"Backend":{"description":"A backend that you can target your program to run on.","properties":{"average_queue_time":{"description":"Current wait time on the queue for execution.","example":1181215,"format":"unix-timestamp","type":"number"},"backend":{"description":"Specifies target hardware and generation where applies: `simulator`, `qpu.aria-1`, `qpu.aria-2`, `qpu.forte-1`, `qpu.forte-enterprise-1`, `qpu.forte-enterprise-2`, `qpu.forte-enterprise-3`","example":"qpu.aria-1","type":"string"},"characterization_id":{"description":"Current characterization ID for this backend","example":"617a1f8b-59d4-435d-aa33-695433d7155e","type":"string"},"degraded":{"description":"Flag to tell if the backend is degraded or not.","type":"boolean"},"kw":{"description":"The amount of energy used by the backend in kilowatt-hours.","example":4902.81,"format":"double","type":"number"},"last_updated":{"description":"Last date time the backend status was updated.","example":"2025-06-16T00:00:00Z","type":"string"},"location":{"description":"The location of the backend.","example":"College Park, MD, USA","type":"string"},"qubits":{"description":"The number of qubits available.","example":25,"minimum":0,"type":"integer"},"status":{"description":"Current status of the backend: `available`, `unavailable`, `retired`.","type":"string"}},"required":["backend","status","qubits","average_queue_time","last_updated"],"type":"object"},"Characterization":{"description":"Quantum hardware characterization data.","properties":{"backend":{"description":"The backend calibrated hardware: `simulator`, `qpu.aria-1`, `qpu.aria-2`, `qpu.forte-1`, `qpu.forte-enterprise-1`, `qpu.forte-enterprise-2`, `qpu.forte-enterprise-3`","type":"string"},"connectivity":{"description":"An array of valid, unordered tuples of possible qubits for executing two-qubit gates (e.g., `[[0, 1], [0, 2], [1, 2]]`)","example":[[0,1],[0,2],[10,9]],"items":{"items":{"type":"integer"},"type":"array"},"type":"array"},"date":{"description":"Date time of the measurement, in ISO format.","example":"2025-06-16T00:00:00Z","type":"string"},"fidelity":{"description":"Fidelity for single-qubit (`1q`) and two-qubit (`2q`) gates, and State Preparation and Measurement (`spam`) operations.\nCurrently provides only median fidelity; additional statistical data will be added in the future.\n","properties":{"spam":{"description":"SPAM error correction information.","properties":{"median":{"example":0.9962,"type":"number"},"stderr":{"description":"SPAM error.","example":null,"minimum":0,"type":"integer"}},"required":["median"],"type":"object"}},"required":["spam"],"type":"object"},"id":{"description":"UUID of the characterization.","format":"uuid","type":"string"},"qubits":{"description":"The number of qubits available.","example":25,"minimum":1,"type":"integer"},"timing":{"description":"Time, in seconds, of various system properties: `t1` time, `t2` time, `1q` gate time, `2q` gate time, `readout` time, and qubit `reset` time.","properties":{"1q":{"type":"integer"},"2q":{"type":"integer"},"readout":{"description":"Readout time.","type":"integer"},"reset":{"description":"qubit reset time.","type":"integer"},"t1":{"example":10,"type":"integer"},"t2":{"example":1,"type":"integer"}},"required":["readout","reset"],"type":"object"}},"type":"object"},"pagination-limit":{"default":25,"description":"How many objects to return.","maximum":25,"minimum":1,"type":"integer"},"pagination-next":{"description":"ID of next batch of resources to load.","format":"uuid","type":"string"},"pagination-page":{"default":1,"description":"Specify the page of results to return.","minimum":1,"type":"integer"},"JobStatus":{"type":"string","enum":["submitted","ready","started","canceled","failed","completed"]},"JobCreationResponse":{"properties":{"id":{"type":"string","example":"617a1f8b-59d4-435d-aa33-695433d7155e"},"status":{"$ref":"#/components/schemas/JobStatus"},"session_id":{"type":"string","nullable":true,"example":null}},"required":["id","status","session_id"],"type":"object","additionalProperties":false},"QisGate":{"type":"string","enum":["x","y","z","rx","ry","rz","h","s","si","v","vi","t","ti","not","cnot","swap","xx","yy","zz","pauliexp"]},"Gate_QisGate":{"properties":{"gate":{"$ref":"#/components/schemas/QisGate"},"target":{"type":"integer","format":"int32"},"targets":{"items":{"type":"number","format":"double"},"type":"array","description":"The qubits that a quantum gate is applied to"},"controls":{"items":{"type":"number","format":"double"},"type":"array","description":"The qubits that determine whether the operation is applied to targets."},"control":{"type":"integer","format":"int32"},"rotation":{"type":"number","format":"double","description":"Rotation angle for rx/ry/rz gates"}},"required":["gate"],"type":"object","additionalProperties":false},"QisCircuitInput":{"properties":{"qubits":{"type":"number","format":"double"},"circuit":{"items":{"$ref":"#/components/schemas/Gate_QisGate"},"type":"array"},"gateset":{"type":"string","enum":["qis"],"nullable":false}},"required":["circuit","gateset"],"type":"object","additionalProperties":false},"NativeGate":{"type":"string","enum":["zz","ms","gpi","gpi2","nop"]},"Gate_NativeGate":{"properties":{"gate":{"$ref":"#/components/schemas/NativeGate"},"target":{"type":"integer","format":"int32"},"targets":{"items":{"type":"number","format":"double"},"type":"array","description":"The qubits that a quantum gate is applied to"},"controls":{"items":{"type":"number","format":"double"},"type":"array","description":"The qubits that determine whether the operation is applied to targets."},"phase":{"type":"number","format":"double","description":"Phase for gpi/gpi2 gates"},"phases":{"items":{"type":"number","format":"double"},"type":"array","description":"Phases for ms gate"},"angle":{"type":"number","format":"double","description":"Interaction angle for ms gate (in turns, default 0.25)"},"rotation":{"type":"number","format":"double","description":"Rotation angle for rx/ry/rz gates"}},"required":["gate"],"type":"object","additionalProperties":false},"NativeCircuitInput":{"properties":{"qubits":{"type":"number","format":"double"},"circuit":{"items":{"$ref":"#/components/schemas/Gate_NativeGate"},"type":"array"},"gateset":{"type":"string","enum":["native"],"nullable":false}},"required":["circuit","gateset"],"type":"object","additionalProperties":false},"JsonCircuitInput":{"anyOf":[{"$ref":"#/components/schemas/QisCircuitInput","title":"Qis Circuit"},{"$ref":"#/components/schemas/NativeCircuitInput","title":"Native Circuit"}]},"JobMetadata":{"properties":{},"type":"object","additionalProperties":{"type":"string"}},"JobBackends":{"type":"string","description":"Available options: `simulator`, `qpu.aria-1`, `qpu.aria-2`, `qpu.forte-1`, `qpu.forte-enterprise-1`"},"NoiseModel":{"type":"string","enum":["ideal","harmony","harmony-1","harmony-2","aria-1","aria-2","forte-1","forte-enterprise-1"]},"Noise":{"properties":{"model":{"$ref":"#/components/schemas/NoiseModel"},"seed":{"type":"integer","format":"int32"}},"required":["model"],"type":"object","additionalProperties":false},"CircuitJobCreationPayload":{"properties":{"name":{"type":"string"},"metadata":{"$ref":"#/components/schemas/JobMetadata","description":"User defined metadata"},"shots":{"type":"integer","format":"int32","default":100,"maximum":1000000},"backend":{"$ref":"#/components/schemas/JobBackends"},"session_id":{"type":"string"},"settings":{"properties":{"error_mitigation":{"properties":{"debiasing":{"type":"boolean"}},"type":"object","description":"To turn on debiasing, you must request at least 500 shots"},"compilation":{"properties":{"opt":{"type":"number","format":"double"},"precision":{"type":"string"}},"type":"object"}},"type":"object"},"dry_run":{"type":"boolean"},"noise":{"$ref":"#/components/schemas/Noise"},"type":{"type":"string","enum":["ionq.circuit.v1"],"nullable":false},"input":{"$ref":"#/components/schemas/JsonCircuitInput"}},"required":["backend","type","input"],"type":"object","additionalProperties":false},"Registers":{"properties":{},"type":"object","additionalProperties":{"items":{"type":"number","format":"double","nullable":true},"type":"array"}},"QISCircuit":{"properties":{"name":{"type":"string"},"circuit":{"items":{"$ref":"#/components/schemas/Gate_QisGate"},"type":"array","description":"Circuit gates. Can be either QIS gates or Native gates depending on the gateset property."},"qubits":{"type":"integer","format":"int32"},"registers":{"$ref":"#/components/schemas/Registers","description":"Registers to use in your circuit. Each register is a list of qubit indices (starting from zero)."},"gateset":{"type":"string","enum":["qis"],"nullable":false,"description":"Optional gateset override for this individual circuit. If not specified, inherits from parent.\nWhen set, the circuit must use the appropriate gate format (QIS)."}},"required":["circuit"],"type":"object","additionalProperties":false},"NativeCircuit":{"properties":{"name":{"type":"string"},"circuit":{"items":{"$ref":"#/components/schemas/Gate_NativeGate"},"type":"array","description":"Circuit gates. Can be either QIS gates or Native gates depending on the gateset property."},"qubits":{"type":"integer","format":"int32"},"registers":{"$ref":"#/components/schemas/Registers","description":"Registers to use in your circuit. Each register is a list of qubit indices (starting from zero)."},"gateset":{"type":"string","enum":["native"],"nullable":false,"description":"Optional gateset override for this individual circuit. If not specified, inherits from parent.\nWhen set, the circuit must use the appropriate gate format (Native)."}},"required":["circuit"],"type":"object","additionalProperties":false},"JsonMultiCircuitInput":{"properties":{"gateset":{"type":"string","enum":["qis","native"]},"circuits":{"items":{"anyOf":[{"$ref":"#/components/schemas/QISCircuit"},{"$ref":"#/components/schemas/NativeCircuit"}]},"type":"array"},"qubits":{"type":"number","format":"double"}},"required":["gateset","circuits"],"type":"object"},"MultiCircuitJobCreationPayload":{"properties":{"name":{"type":"string"},"metadata":{"$ref":"#/components/schemas/JobMetadata","description":"User defined metadata"},"shots":{"type":"integer","format":"int32","default":100,"maximum":1000000},"backend":{"$ref":"#/components/schemas/JobBackends"},"session_id":{"type":"string"},"settings":{"properties":{"error_mitigation":{"properties":{"debiasing":{"type":"boolean"}},"type":"object","description":"To turn on debiasing, you must request at least 500 shots"},"compilation":{"properties":{"opt":{"type":"number","format":"double"},"precision":{"type":"string"}},"type":"object"}},"type":"object"},"dry_run":{"type":"boolean"},"noise":{"$ref":"#/components/schemas/Noise"},"type":{"type":"string","enum":["ionq.multi-circuit.v1"],"nullable":false},"input":{"$ref":"#/components/schemas/JsonMultiCircuitInput","description":"Submit multiple circuits in a single job. Each circuit inherits the parent\n`input.gateset` unless overridden by `circuits[].gateset`."}},"required":["backend","type","input"],"type":"object","additionalProperties":false,"title":"JSON Multi Circuit Job","description":"Submit multiple circuits in a single job. Each circuit inherits the parent `input.gateset` unless overridden by `circuits[].gateset`.\n","example":{"type":"ionq.multi-circuit.v1","backend":"simulator","shots":500,"input":{"gateset":"native","qubits":2,"circuits":[{"name":"qis circuit override","gateset":"qis","circuit":[{"gate":"h","target":0},{"gate":"cnot","target":0,"control":1}]},{"name":"native circuit from parent","circuit":[{"gate":"ms","targets":[0,1],"phases":[0,0.25]},{"gate":"gpi2","target":0,"phase":0.75}]}]}}},"JobCreationPayload":{"anyOf":[{"$ref":"#/components/schemas/CircuitJobCreationPayload","title":"Single Circuit"},{"$ref":"#/components/schemas/MultiCircuitJobCreationPayload","title":"Multi Circuit"},{"$ref":"#/components/schemas/QuantumFunctionJobCreationPayload","title":"Quantum Function"}],"example":{"type":"ionq.circuit.v1","input":{"qubits":1,"gateset":"qis","circuit":[{"gate":"h","target":0}]},"backend":"qpu.forte-1","shots":500,"settings":{"error_mitigation":{"debiasing":false}}}},"IsoTimestamp":{"type":"string"},"Failure":{"properties":{"code":{"type":"string","enum":["InvalidInput","CompilationError","ContractExpiredError","DebiasingError","InternalError","NotEnoughQubits","OptimizationError","PreflightError","QuantumCircuitComplexityError","QuantumComputerError","QuotaExhaustedError","SimulationError","SimulationTimeout","SystemCancel","TooLongPredictedExecutionTime","TooManyControls","TooManyGates","TooManyShots","UnknownBillingError","UnsupportedGate"]},"message":{"type":"string"}},"required":["code","message"],"type":"object","additionalProperties":false},"JsonObject":{"properties":{},"type":"object","additionalProperties":{}},"BaseJob":{"properties":{"id":{"type":"string"},"status":{"$ref":"#/components/schemas/JobStatus"},"type":{"type":"string"},"backend":{"type":"string"},"dry_run":{"type":"boolean"},"submitter_id":{"type":"string","description":"The id of the user who submitted the job"},"project_id":{"type":"string","nullable":true},"parent_job_id":{"type":"string","nullable":true},"session_id":{"type":"string","nullable":true},"metadata":{"allOf":[{"$ref":"#/components/schemas/JobMetadata"}],"nullable":true},"name":{"type":"string","nullable":true},"submitted_at":{"$ref":"#/components/schemas/IsoTimestamp"},"started_at":{"allOf":[{"$ref":"#/components/schemas/IsoTimestamp"}],"nullable":true},"completed_at":{"allOf":[{"$ref":"#/components/schemas/IsoTimestamp"}],"nullable":true},"predicted_wait_time_ms":{"type":"integer","format":"int32","nullable":true},"predicted_execution_duration_ms":{"type":"integer","format":"int32","nullable":true},"execution_duration_ms":{"type":"integer","format":"int32","nullable":true,"description":"How long the job actually took to run on the QPU. Null if the job hasn't run yet."},"shots":{"type":"integer","format":"int32"},"noise":{"$ref":"#/components/schemas/Noise","description":"Only present in the response when `backend` is simulator."},"failure":{"allOf":[{"$ref":"#/components/schemas/Failure"}],"nullable":true},"output":{"$ref":"#/components/schemas/JsonObject"},"settings":{"$ref":"#/components/schemas/JsonObject"},"stats":{"$ref":"#/components/schemas/JsonObject"},"results":{"allOf":[{"$ref":"#/components/schemas/JsonObject"}],"nullable":true}},"required":["id","status","type","backend","dry_run","submitter_id","project_id","parent_job_id","session_id","metadata","name","submitted_at","started_at","completed_at","predicted_wait_time_ms","predicted_execution_duration_ms","execution_duration_ms","failure","output","settings","stats","results"],"type":"object","additionalProperties":false},"GetJobsResponse":{"properties":{"jobs":{"items":{"$ref":"#/components/schemas/BaseJob"},"type":"array"},"next":{"type":"string","nullable":true}},"required":["jobs","next"],"type":"object","additionalProperties":false},"GetJobsQueryParams":{"properties":{"ids":{"items":{"type":"string"},"type":"array"},"parent_job_id":{"type":"string"},"status":{"$ref":"#/components/schemas/JobStatus"},"target":{"type":"string","description":"Filter jobs by backend target. Supports single target or comma-separated list of targets.","example":"simulator"},"session_id":{"type":"string"},"submitter_id":{"type":"string","description":"The id of another user within a shared project to view their submitted jobs. Ignored if not a project member."},"limit":{"type":"integer","format":"int32"},"next":{"type":"string"}},"type":"object","additionalProperties":false},"CircuitJobCompilationSettings":{"properties":{"precision":{"type":"string"},"opt":{"type":"number","format":"double"},"gate_basis":{"type":"string"},"service_version":{"type":"string"}},"type":"object","additionalProperties":false},"CircuitJobSettings":{"properties":{"compilation":{"$ref":"#/components/schemas/CircuitJobCompilationSettings"},"error_mitigation":{"properties":{"debiasing":{"anyOf":[{"properties":{"phi_chi_twirling":{"properties":{"p2q":{"type":"number","format":"double"},"t2q":{"type":"number","format":"double"},"t1q":{"type":"number","format":"double"}},"type":"object"}},"type":"object"},{"type":"boolean"}]}},"type":"object"}},"type":"object","additionalProperties":false},"NumberMap":{"properties":{},"type":"object","additionalProperties":{"type":"number","format":"double"}},"CircuitJobStats":{"properties":{"qubits":{"type":"integer","format":"int32"},"circuits":{"type":"integer","format":"int32"},"gate_counts":{"$ref":"#/components/schemas/NumberMap"},"kwh":{"type":"number","format":"double"},"predicted_quantum_compute_time_us":{"type":"integer","format":"int32"},"billed_quantum_compute_time_us":{"type":"integer","format":"int32"}},"type":"object","additionalProperties":false},"CircuitJobResult":{"properties":{"probabilities":{"properties":{"url":{"type":"string"}},"required":["url"],"type":"object"},"histogram":{"properties":{"url":{"type":"string"}},"required":["url"],"type":"object"},"shots":{"properties":{"url":{"type":"string"}},"required":["url"],"type":"object"}},"type":"object","additionalProperties":false},"GetCircuitJobResponse":{"properties":{"id":{"type":"string"},"status":{"$ref":"#/components/schemas/JobStatus"},"type":{"type":"string"},"backend":{"type":"string"},"dry_run":{"type":"boolean"},"submitter_id":{"type":"string","description":"The id of the user who submitted the job"},"project_id":{"type":"string","nullable":true},"parent_job_id":{"type":"string","nullable":true},"session_id":{"type":"string","nullable":true},"metadata":{"allOf":[{"$ref":"#/components/schemas/JobMetadata"}],"nullable":true},"name":{"type":"string","nullable":true},"submitted_at":{"$ref":"#/components/schemas/IsoTimestamp"},"started_at":{"allOf":[{"$ref":"#/components/schemas/IsoTimestamp"}],"nullable":true},"completed_at":{"allOf":[{"$ref":"#/components/schemas/IsoTimestamp"}],"nullable":true},"predicted_wait_time_ms":{"type":"integer","format":"int32","nullable":true},"predicted_execution_duration_ms":{"type":"integer","format":"int32","nullable":true},"execution_duration_ms":{"type":"integer","format":"int32","nullable":true,"description":"How long the job actually took to run on the QPU. Null if the job hasn't run yet."},"shots":{"type":"integer","format":"int32"},"noise":{"$ref":"#/components/schemas/Noise","description":"Only present in the response when `backend` is simulator."},"failure":{"allOf":[{"$ref":"#/components/schemas/Failure"}],"nullable":true},"output":{"$ref":"#/components/schemas/JsonObject"},"settings":{"$ref":"#/components/schemas/CircuitJobSettings"},"stats":{"$ref":"#/components/schemas/CircuitJobStats"},"results":{"allOf":[{"$ref":"#/components/schemas/CircuitJobResult"}],"nullable":true},"child_job_ids":{"items":{"type":"string"},"type":"array","nullable":true}},"required":["id","status","type","backend","dry_run","submitter_id","project_id","parent_job_id","session_id","metadata","name","submitted_at","started_at","completed_at","predicted_wait_time_ms","predicted_execution_duration_ms","execution_duration_ms","failure","output","settings","stats","results","child_job_ids"],"type":"object","additionalProperties":false},"GetJobResponse":{"$ref":"#/components/schemas/GetCircuitJobResponse"},"GetJobCostResponse":{"properties":{"dry_run":{"type":"boolean","example":false},"estimated_cost":{"properties":{"value":{"type":"number","format":"double","example":24.83},"unit":{"type":"string","example":"usd"}},"required":["value","unit"],"type":"object"},"cost":{"properties":{"value":{"type":"number","format":"double","example":24.83},"unit":{"type":"string","example":"usd"}},"required":["value","unit"],"type":"object"}},"required":["dry_run","estimated_cost"],"type":"object","additionalProperties":false},"JobCanceledResponse":{"properties":{"id":{"type":"string","example":"617a1f8b-59d4-435d-aa33-695433d7155e"},"status":{"type":"string","enum":["canceled"],"nullable":false}},"required":["id","status"],"type":"object","additionalProperties":false},"JobsCanceledResponse":{"properties":{"ids":{"items":{"type":"string"},"type":"array","example":["617a1f8b-59d4-435d-aa33-695433d7155e","617a1f8b-59d4-435d-aa33-695433d7155f"]},"status":{"type":"string","enum":["canceled"],"nullable":false}},"required":["ids","status"],"type":"object","additionalProperties":false},"JobsBulkOperationRequest":{"properties":{"ids":{"items":{"type":"string"},"type":"array"}},"required":["ids"],"type":"object","additionalProperties":false},"JobDeletedResponse":{"properties":{"id":{"type":"string","example":"617a1f8b-59d4-435d-aa33-695433d7155e"},"status":{"type":"string","enum":["deleted"],"nullable":false}},"required":["id","status"],"type":"object","additionalProperties":false},"JobsDeletedResponse":{"properties":{"ids":{"items":{"type":"string"},"type":"array"},"status":{"type":"string","enum":["deleted"],"nullable":false}},"required":["ids","status"],"type":"object","additionalProperties":false},"GetJobEstimateQueryParams":{"properties":{"backend":{"$ref":"#/components/schemas/JobBackends"},"type":{"type":"string","default":"ionq.circuit.v1"},"qubits":{"type":"integer","format":"int32","default":25},"shots":{"type":"integer","format":"int32","default":1000},"1q_gates":{"type":"integer","format":"int32","default":0},"2q_gates":{"type":"integer","format":"int32","default":0},"error_mitigation":{"type":"boolean","default":false}},"required":["backend"],"type":"object","additionalProperties":false},"GetJobEstimateResponse":{"properties":{"input_values":{"$ref":"#/components/schemas/GetJobEstimateQueryParams"},"estimated_at":{"$ref":"#/components/schemas/IsoTimestamp"},"cost_unit":{"type":"string"},"rate_information":{"properties":{"job_cost_minimum":{"type":"number","format":"double"},"cost_2q_gate":{"type":"number","format":"double"},"cost_1q_gate":{"type":"number","format":"double"},"organization":{"type":"string"}},"required":["job_cost_minimum","cost_2q_gate","cost_1q_gate","organization"],"type":"object"},"estimated_cost":{"type":"number","format":"double"},"estimated_execution_time":{"type":"number","format":"double"},"current_predicted_queue_time":{"type":"number","format":"double"}},"required":["input_values","estimated_at","cost_unit","rate_information","estimated_cost","estimated_execution_time","current_predicted_queue_time"],"type":"object","additionalProperties":false},"AddJobResultsResponse":{"properties":{"job_id":{"type":"string"}},"required":["job_id"],"type":"object","additionalProperties":false},"JobQCtrlStatus":{"enum":["running","complete","max_iteration"],"type":"string"},"AddJobResultsPayload":{"properties":{"processing_status":{"$ref":"#/components/schemas/JobQCtrlStatus"},"optimal_cost":{"type":"number","format":"double"},"optimal_bitstring":{"type":"string"}},"required":["processing_status","optimal_cost","optimal_bitstring"],"type":"object","additionalProperties":false},"GetResultsResponse":{"properties":{},"type":"object","additionalProperties":{"type":"number","format":"double"}},"GetVariantResultsResponse":{"properties":{},"type":"object","additionalProperties":{"type":"number","format":"double"}},"SessionCostLimit":{"properties":{"unit":{"type":"string"},"value":{"type":"number","format":"double"}},"required":["unit","value"],"type":"object","additionalProperties":false},"SessionSettings":{"properties":{"job_count_limit":{"type":"integer","format":"int32"},"duration_limit_min":{"type":"integer","format":"int32"},"cost_limit":{"$ref":"#/components/schemas/SessionCostLimit"},"expires_at":{"type":"string","format":"date-time"}},"type":"object","additionalProperties":false},"SessionStatusEnum":{"enum":["created","started","ended"],"type":"string"},"Session":{"properties":{"id":{"type":"string","description":"The id of the session."},"created_at":{"type":"string","format":"date-time"},"organization_id":{"type":"string"},"backend":{"type":"string","nullable":true},"project_id":{"type":"string","nullable":true},"creator_id":{"type":"string","nullable":true},"ended_at":{"type":"string","format":"date-time","nullable":true},"ender_id":{"type":"string","nullable":true},"settings":{"$ref":"#/components/schemas/SessionSettings"},"active":{"type":"boolean"},"status":{"$ref":"#/components/schemas/SessionStatusEnum"},"started_at":{"type":"string","format":"date-time","nullable":true}},"required":["id","created_at","organization_id","backend","project_id","creator_id","ended_at","ender_id","active","status","started_at"],"type":"object","additionalProperties":false},"SessionSettingsRequest":{"properties":{"job_count_limit":{"type":"integer","format":"int32"},"duration_limit_min":{"type":"integer","format":"int32"},"cost_limit":{"$ref":"#/components/schemas/SessionCostLimit"}},"type":"object","additionalProperties":false},"CreateSessionRequest":{"properties":{"backend":{"type":"string"},"settings":{"$ref":"#/components/schemas/SessionSettingsRequest"}},"required":["backend"],"type":"object","additionalProperties":false},"SessionsResponse":{"properties":{"organization_id":{"type":"string"},"sessions":{"items":{"$ref":"#/components/schemas/Session"},"type":"array"}},"required":["organization_id","sessions"],"type":"object","additionalProperties":false},"GetSessionsQueryParams":{"properties":{"active":{"type":"boolean"}},"type":"object","additionalProperties":false},"QuantumFunctionInput":{"oneOf":[{"$ref":"#/components/schemas/HamiltonianEnergyInput"},{"$ref":"#/components/schemas/GenericQuantumFunctionInput"}],"discriminator":{"propertyName":"type","mapping":{"hamiltonian-energy":"#/components/schemas/HamiltonianEnergyInput"}}},"QuantumFunctionJobCreationPayload":{"type":"object","properties":{"name":{"type":"string"},"metadata":{"$ref":"#/components/schemas/JobMetadata"},"shots":{"type":"integer","format":"int32","default":100,"maximum":1000000},"backend":{"$ref":"#/components/schemas/JobBackends"},"session_id":{"type":"string"},"settings":{"type":"object","properties":{"error_mitigation":{"type":"object","properties":{"debiasing":{"type":"boolean"}}}}},"dry_run":{"type":"boolean"},"type":{"type":"string","enum":["quantum-function"]},"input":{"$ref":"#/components/schemas/QuantumFunctionInput"}},"required":["backend","type","input"]},"GroupUsage":{"description":"A group's single date usage","properties":{"amount":{"description":"The cost amount for the group of the given date","example":144.39,"type":"number"},"group_id":{"description":"The unique ID from the group","example":"2bfd0fd5-5854-4916-917f-a907af586755","type":"string"},"group_name":{"description":"The group's descriptive name","example":"Project Jumping Lemming","type":"string"},"job_count":{"description":"The number of jobs run for the group on the given date","example":9,"type":"integer"},"time_us":{"description":"The QPU time in microseconds","example":1566154.312523,"type":"number"}},"type":"object"},"Usage":{"description":"Single date of QPU usage","properties":{"amount":{"description":"The amount as a cost in USD","example":1614.23,"type":"number"},"from":{"description":"Date for this group's usage","example":"2023-07-01","format":"date","type":"string"},"group_usages":{"description":"The top 5 usage groups in order of cost amount descending","items":{"$ref":"#/components/schemas/GroupUsage"},"type":"array"},"job_count":{"description":"The count of jobs for this group on the given from date","example":10,"type":"integer"},"time_us":{"description":"The QPU time in microseconds","example":5143166.13413,"type":"number"}},"required":["from","job_count","amount","time_us","group_usages"],"type":"object"},"Usages":{"description":"QPU usage details for a given modality and date range.","properties":{"amount_total":{"description":"The total cost amount for the given timeframe, in units given by usage_unit","example":151.31,"type":"number"},"group_type":{"$ref":"#/components/schemas/group_by"},"job_count":{"description":"The total number of jobs run in the timeframe","example":514,"type":"integer"},"modality":{"$ref":"#/components/schemas/modality"},"organization":{"$ref":"#/components/schemas/organization_id"},"time_us_total":{"description":"The total QPU time usage for the given timeframe, in microseconds","example":1566154.312523,"type":"number"},"usage_data":{"description":"The breakdown of usage by group type in date order most to least recent","items":{"$ref":"#/components/schemas/Usage"},"type":"array"},"usage_from":{"description":"Usage beginning RFC 3339 timestamp","example":"2025-10-01T00:00:00Z","format":"date-time","type":"string"},"usage_to":{"description":"Usage end RFC 3339 timestamp","example":"2025-11-01T00:00:00Z","format":"date-time","type":"string"},"usage_unit":{"description":"The currency of the total and job cost amounts","example":"USD","type":"string"}},"required":["start_date","end_date","group_type","modality"],"type":"object"},"group_by":{"description":"QPU Usage grouping","enum":["job","project","user"],"example":"project","type":"string"},"modality":{"description":"Report modality","enum":["daily","weekly","monthly"],"example":"daily","type":"string"},"organization_id":{"description":"UUID of an organization.","example":"71d164e-6ebe-4126-8839-f1529bb01a00","format":"uuid","type":"string"},"HamiltonianEnergyData":{"properties":{"hamiltonian":{"items":{"$ref":"#/components/schemas/HamiltonianPauliTerm"},"title":"Hamiltonian","type":"array"},"ansatz":{"$ref":"#/components/schemas/Ansatz"},"linear_constraints":{"default":[],"items":{"$ref":"#/components/schemas/LinearConstraint"},"title":"Linear Constraints","type":"array"},"quadratic_constraints":{"default":[],"items":{"$ref":"#/components/schemas/QuadraticConstraint"},"title":"Quadratic Constraints","type":"array"},"penalty":{"default":0,"nullable":true,"title":"Penalty","type":"number"},"cvar_alpha":{"default":null,"nullable":true,"title":"Cvar Alpha","type":"number"}},"required":["hamiltonian","ansatz"],"type":"object"},"Ansatz":{"properties":{"data":{"title":"Data","type":"string"}},"required":["data"],"type":"object"},"HamiltonianPauliTerm":{"properties":{"pauli_string":{"title":"Pauli String","type":"string"},"coefficient":{"title":"Coefficient","type":"number"}},"required":["pauli_string","coefficient"],"type":"object"},"LinearConstraint":{"description":"A class to model linear inequality constraints of the form\n\n.. math::\n\n A x \\leq b.","properties":{"coeffs":{"items":{"type":"number"},"title":"Coeffs","type":"array"},"rhs":{"title":"Rhs","type":"number"}},"required":["coeffs","rhs"],"type":"object"},"QuadraticConstraint":{"description":"A class to model quadratic inequality constraints of the form\n\n.. math::\n\n x^T P x + r^T x \\leq c.","properties":{"quadratic_coeff":{"items":{"items":{"type":"number"},"type":"array"},"title":"Quadratic Coeff","type":"array"},"linear_coeff":{"items":{"type":"number"},"title":"Linear Coeff","type":"array"},"rhs":{"title":"Rhs","type":"number"}},"required":["quadratic_coeff","linear_coeff","rhs"],"type":"object"},"HamiltonianEnergyInput":{"type":"object","properties":{"data":{"type":"object","properties":{"type":{"type":"string","enum":["hamiltonian-energy"]},"data":{"$ref":"#/components/schemas/HamiltonianEnergyData"}},"required":["type","data"]},"params":{"type":"array","items":{"type":"number"}}},"required":["data"]},"GenericQuantumFunctionInput":{"type":"object","properties":{"type":{"type":"string"},"data":{"type":"object"},"params":{"type":"array","items":{"type":"number"}}},"required":["type","data"]}},"responses":{"BadRequest":{"content":{"application/json":{"example":{"error":"Bad Request","message":"\"some-parameter\" was invalid.","statusCode":400,"validation":{"keys":["some-parameter"],"source":"params"}},"schema":{"$ref":"#/components/schemas/BadRequestError"}}},"description":"Invalid request parameters"},"Error":{"content":{"application/json":{"example":{"error":"Internal Server Error","message":"Internal service outage. Visit https://status.ionq.co/ to track this incident.","statusCode":500},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"},"NotFound":{"content":{"application/json":{"example":{"error":"Not Found Error","message":"Resource not found. See https://docs.ionq.com/ for details, or email support@ionq.co for help.","statusCode":404},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Resource was not found."},"Unauthorized":{"content":{"application/json":{"example":{"error":"Unauthorized Error","message":"Invalid key provided. See https://docs.ionq.com/#authentication for details, or email support@ionq.co for help.","statusCode":401},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Request was not authorized."},"Whoami":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Whoami"}}},"description":"Successfully retrieved a current of key from this session."},"GetBackend":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Backend"}}},"description":"Successfully retrieved backend."},"GetCharacterization":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Characterization"}}},"description":"Successfully retrieved current characterization"},"ListBackends":{"content":{"application/json":{"schema":{"description":"The list of backends.","items":{"$ref":"#/components/schemas/Backend"},"type":"array"}}},"description":"Successfully retrieved backend."},"ListCharacterizations":{"content":{"application/json":{"schema":{"description":"Response body from requesting characterization data.","properties":{"characterizations":{"description":"A page of characterizations measurements.","items":{"$ref":"#/components/schemas/Characterization"},"type":"array"},"pages":{"description":"The number of remaining pages of characterization measurements.","type":"integer"}},"required":["characterizations"],"type":"object"}}},"description":"Successfully retrieved characterizations."},"UsagesResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usages"}}},"description":"Successfully retrieved a list of projects."}},"examples":{"Metadata":{"value":{"input":"{ \"format\": \"ionq.circuit.v0\", \"qubits\": 1, \"circuit\": [ { \"gate\": \"h\", \"target\": 0 } ] }","metadata":{"bar":2,"foo":1}}}},"securitySchemes":{"apiKeyAuth":{"description":"API keys are associated with a user and can be created on the [IonQ Quantum Cloud](https://cloud.ionq.com) application. To authenticate, prefix your API Key with `apiKey ` and place it in the `Authorization` request header. Ex: `Authorization: apiKey your-api-key`","in":"header","name":"Authorization","type":"apiKey"}},"parameters":{"backend":{"description":"A backend where jobs can run on.","in":"path","name":"backend","required":true,"schema":{"enum":["qpu.aria-1","qpu.aria-2","qpu.forte-1","qpu.forte-enterprise-1","qpu.forte-enterprise-2","qpu.forte-enterprise-3"],"type":"string"}},"pagination-limit":{"in":"query","name":"limit","schema":{"$ref":"#/components/schemas/pagination-limit"}},"pagination-next":{"in":"query","name":"next","schema":{"$ref":"#/components/schemas/pagination-next"}},"pagination-page":{"in":"query","name":"page","schema":{"$ref":"#/components/schemas/pagination-page"}},"uuid":{"description":"A UUID identifying a specific resource","example":"617a1f8b-59d4-435d-aa33-695433d7155e","in":"path","name":"UUID","required":true,"schema":{"format":"uuid","type":"string"}},"organization_id":{"description":"The UUID of the organization — this UUID is provided in the response on organization creation.","example":"71d164e-6ebe-4126-8839-f1529bb01a00","in":"path","name":"organization_id","required":true,"schema":{"format":"uuid","type":"string"}}},"requestBodies":{},"headers":{}}} \ No newline at end of file +{"openapi":"3.0.3","info":{"contact":{"email":"support@ionq.co","name":"IonQ","url":"https://ionq.com/"},"description":"*Last updated: May 15, 2026*\nIonQ's API for accessing the IonQ Quantum Cloud platform\n\nPlease subscribe for automated updates when we perform maintenance or\nexperience an outage.\n\nIn addition, you may use the [status endpoint](#tag/status) to check the\ncurrent status of our API.\n\n## Authentication\n\n\n","title":"IonQ Cloud Platform API","version":"v0.4"},"servers":[{"url":"https://api.ionq.co/v0.4"}],"paths":{"/whoami":{"get":{"description":"Retrieves current key associated with this session.","operationId":"getWhoami","responses":{"200":{"$ref":"#/components/responses/Whoami"}},"summary":"Get current key","tags":["whoami"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/whoami\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}},"/backends":{"get":{"description":"This endpoint retrieves all backends.","operationId":"getBackends","responses":{"200":{"$ref":"#/components/responses/ListBackends"}},"security":[],"summary":"Get Backends","tags":["backends"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/backends\"\n"}]}},"/backends/{backend}":{"get":{"description":"This endpoint retrieves a backend.","operationId":"getBackend","parameters":[{"$ref":"#/components/parameters/backend"}],"responses":{"200":{"$ref":"#/components/responses/GetBackend"}},"security":[],"summary":"Get a Backend","tags":["backends"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/backends/qpu.aria-1\"\n"}]}},"/backends/{backend}/characterizations":{"get":{"description":"This endpoint retrieves an array of all available backend characterizations, with pagination.","operationId":"getCharacterizationsForBackend","parameters":[{"$ref":"#/components/parameters/backend"},{"description":"Characterizations starting at this time (e.g., `start=2025-12-31`)","in":"query","name":"start","schema":{"type":"string"}},{"description":"Characterizations before this time (e.g., `end=2025-12-31`)","in":"query","name":"end","schema":{"type":"string"}},{"description":"How many objects to return.","in":"query","name":"limit","schema":{"default":10,"maximum":10,"minimum":1,"type":"integer"}},{"$ref":"#/components/parameters/pagination-page"}],"responses":{"200":{"$ref":"#/components/responses/ListCharacterizations"}},"security":[],"summary":"Get All Backend Characterizations","tags":["characterizations"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/backends/qpu.aria-1/characterizations\"\n"}]}},"/backends/{backend}/characterizations/{UUID}":{"get":{"description":"This endpoint retrieves a characterization.","operationId":"getCharacterization","parameters":[{"$ref":"#/components/parameters/backend"},{"$ref":"#/components/parameters/uuid"}],"responses":{"200":{"$ref":"#/components/responses/GetCharacterization"}},"summary":"Get a Characterization","tags":["characterizations"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/backends/qpu.aria-1/characterizations/aa54e783-0a9b-4f73-ad2f-63983b6aa4a8\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}},"/jobs":{"post":{"operationId":"CreateJob","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobCreationResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobCreationPayload"}}}},"description":"Submit a single-circuit or multi-circuit job for simulation or execution. In `ionq.multi-circuit.v1` payloads, each entry in `input.circuits` inherits the parent `input.gateset` unless the circuit sets its own `gateset`.\n","x-codeSamples":[{"lang":"curl","label":"Single-circuit QIS job","source":"curl -X POST \"https://api.ionq.co/v0.4/jobs\" \\\n -H \"Authorization: apiKey your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"type\" : \"ionq.circuit.v1\",\n \"name\": \"Sample circuit\",\n \"metadata\": {\n \"fizz\": \"buzz\",\n \"foo\": \"bar\"\n },\n \"shots\": 500,\n \"backend\": \"qpu.forte-1\",\n \"settings\" :\n {\n \"error_mitigation\":\n {\n \"debiasing\": false\n }\n },\n \"input\": {\n \"qubits\": 2,\n \"gateset\": \"qis\",\n \"circuit\": [\n {\n \"gate\": \"h\",\n \"target\": 0\n }\n ]\n }\n }'\n"},{"lang":"curl","label":"Mixed-gateset multi-circuit job","source":"curl -X POST \"https://api.ionq.co/v0.4/jobs\" \\\n -H \"Authorization: apiKey your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"type\": \"ionq.multi-circuit.v1\",\n \"backend\": \"simulator\",\n \"shots\": 500,\n \"input\": {\n \"gateset\": \"native\",\n \"qubits\": 2,\n \"circuits\": [\n {\n \"name\": \"qis circuit override\",\n \"gateset\": \"qis\",\n \"circuit\": [\n {\n \"gate\": \"h\",\n \"target\": 0\n },\n {\n \"gate\": \"cnot\",\n \"target\": 0,\n \"control\": 1\n }\n ]\n },\n {\n \"name\": \"native circuit from parent\",\n \"circuit\": [\n {\n \"gate\": \"ms\",\n \"targets\": [0, 1],\n \"phases\": [0, 0.25]\n },\n {\n \"gate\": \"gpi2\",\n \"target\": 0,\n \"phase\": 0.75\n }\n ]\n }\n ]\n }\n }'\n"}]},"get":{"operationId":"GetJobs","responses":{"200":{"description":"Successfully retrieved a list of jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetJobsResponse"},"examples":{"Example 1":{"value":{"jobs":[{"id":"e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524","status":"completed","type":"ionq.circuit.v1","backend":"simulator","dry_run":false,"cost_model":"quantum_compute_time","submitter_id":"64b03577072d45001c85e9c4","project_id":"1333d459-cf47-4a5e-acc1-8d4eb4f7b025","parent_job_id":null,"session_id":null,"metadata":null,"name":null,"submitted_at":"2025-05-28T20:47:05.440Z","started_at":null,"completed_at":null,"predicted_execution_duration_ms":null,"predicted_wait_time_ms":null,"execution_duration_ms":null,"shots":1000,"noise":{"model":"ideal"},"failure":null,"settings":{"compilation":{}},"stats":{"qubits":20,"circuits":1,"gate_counts":{"1q":1028,"2q":110},"predicted_quantum_compute_time_us":5000,"billed_quantum_compute_time_us":5200},"results":{"probabilities":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/results/probabilities"}},"output":{}}],"next":null}}}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"query","name":"ids","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"in":"query","name":"parent_job_id","required":false,"schema":{"type":"string"}},{"in":"query","name":"status","required":false,"schema":{"$ref":"#/components/schemas/JobStatus"}},{"description":"Filter jobs by backend target. Supports single target or comma-separated list of targets.","in":"query","name":"target","required":false,"schema":{"type":"string"},"example":"simulator"},{"in":"query","name":"session_id","required":false,"schema":{"type":"string"}},{"description":"The id of another user within a shared project to view their submitted jobs. Ignored if not a project member.","in":"query","name":"submitter_id","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"format":"int32","type":"integer"}},{"in":"query","name":"next","required":false,"schema":{"type":"string"}}],"x-codeSamples":[{"lang":"curl","source":"# Get all jobs:\ncurl \"https://api.ionq.co/v0.4/jobs\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]},"delete":{"operationId":"DeleteJobs","responses":{"200":{"description":"Successfully deleted a list of jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsDeletedResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsBulkOperationRequest"}}}},"x-codeSamples":[{"lang":"curl","source":"curl -X DELETE \"https://api.ionq.co/v0.4/jobs\" \\\n -H \"Authorization: apiKey your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"ids\": [\n \"617a1f8b-59d4-435d-aa33-695433d7155e\",\n \"2ccf2773-4c28-468e-a290-2f8554808a25\",\n \"f92df2b6-d212-4f4a-b9ea-024b58c5c3e8\"\n ]\n }'\n"}]}},"/jobs/{UUID}":{"get":{"operationId":"GetJob","responses":{"200":{"description":"Successfully retrieved a job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetJobResponse"},"examples":{"Example 1":{"value":{"id":"e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524","status":"completed","type":"ionq.circuit.v1","backend":"simulator","dry_run":false,"cost_model":"quantum_compute_time","submitter_id":"64b03577072d45001c85e9c4","project_id":"1333d459-cf47-4a5e-acc1-8d4eb4f7b025","parent_job_id":null,"child_job_ids":null,"session_id":null,"metadata":null,"name":null,"submitted_at":"2025-05-28T20:47:05.440Z","started_at":null,"completed_at":null,"predicted_execution_duration_ms":null,"predicted_wait_time_ms":null,"execution_duration_ms":null,"shots":1000,"noise":{"model":"ideal"},"failure":null,"settings":{"compilation":{}},"stats":{"qubits":20,"circuits":1,"gate_counts":{"1q":1028,"2q":110},"predicted_quantum_compute_time_us":5000,"billed_quantum_compute_time_us":5200},"results":{"probabilities":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/results/probabilities"}},"output":{"compilation":{},"error_mitigation":{"debiasing":{"variants":[{"variant_id":"069ce8f8-f437-7d75-8000-9f5f8c3d7897","qubit_map":[4,12,7],"shots":120,"results":{"probabilities":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/variants/069ce8f8-f437-7d75-8000-9f5f8c3d7897/results/probabilities"},"histogram":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/variants/069ce8f8-f437-7d75-8000-9f5f8c3d7897/results/histogram"},"shots":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/variants/069ce8f8-f437-7d75-8000-9f5f8c3d7897/results/shots"}}}]}}}}}}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The UUID of the job — this UUID is provided in the response on job creation.","in":"path","name":"UUID","required":true,"schema":{"type":"string"}}],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/jobs/617a1f8b-59d4-435d-aa33-695433d7155e\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]},"delete":{"operationId":"DeleteJob","responses":{"200":{"description":"Successfully deleted a job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobDeletedResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The UUID of the job — this UUID is provided in the response on job creation.","in":"path","name":"UUID","required":true,"schema":{"type":"string"}}],"x-codeSamples":[{"lang":"curl","source":"curl -X DELETE \"https://api.ionq.co/v0.4/jobs/617a1f8b-59d4-435d-aa33-695433d7155e\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}},"/jobs/{UUID}/cost":{"get":{"operationId":"GetJobCost","responses":{"200":{"description":"Successfully retrieved the cost of a job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetJobCostResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"UUID","required":true,"schema":{"type":"string"}}],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/jobs/0197379a-c3b8-7548-9da4-bbb7067311c1/cost\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}},"/jobs/{UUID}/circuits/{lang}":{"get":{"operationId":"GetCompiledFile","responses":{"200":{"description":"Successfully downloaded a compiled file.","content":{"application/json":{"schema":{"type":"string"}}}},"403":{"description":"Forbidden"},"404":{"description":"Not Found"},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"UUID","required":true,"schema":{"type":"string"}},{"in":"path","name":"lang","required":true,"schema":{"type":"string","enum":["native","qasm3"]}}]}},"/jobs/{UUID}/status/cancel":{"put":{"operationId":"CancelJob","responses":{"200":{"description":"Successfully canceled a job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobCanceledResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"description":"Cancel the execution of many jobs at once by passing a list of jobs.","summary":"Cancel a job","security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The UUID of the job — this UUID is provided in the response on job creation.","in":"path","name":"UUID","required":true,"schema":{"type":"string"}}],"x-codeSamples":[{"lang":"curl","source":"curl -X PUT \"https://api.ionq.co/v0.4/jobs/617a1f8b-59d4-435d-aa33-695433d7155e/status/cancel\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}},"/jobs/status/cancel":{"put":{"operationId":"CancelJobs","responses":{"200":{"description":"Successfully canceled a list of jobs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsCanceledResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsBulkOperationRequest"}}}},"x-codeSamples":[{"lang":"curl","source":"curl -X PUT \"https://api.ionq.co/v0.4/jobs/status/cancel\" \\\n -H \"Authorization: apiKey your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"ids\": [\n \"617a1f8b-59d4-435d-aa33-695433d7155e\",\n \"2ccf2773-4c28-468e-a290-2f8554808a25\",\n \"f92df2b6-d212-4f4a-b9ea-024b58c5c3e8\"\n ]\n }'\n"}]}},"/jobs/estimate":{"get":{"operationId":"EstimateJobCost","responses":{"200":{"description":"Successfully retrieved the cost estimate of a job.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetJobEstimateResponse"}}}},"429":{"description":"Too Many Requests. To get a higher rate limit, please reach out to support@ionq.co"},"500":{"description":"A generic server failure, please reach out to support@ionq.co for help with this error"},"502":{"description":"Bad Gateway, this can be caused by misbehaving proxies, or by service issues. These can be retried, and downtime can be found on status.ionq.co"},"503":{"description":"Service Unavailable, this is indicative of service outage, please check status.ionq.co"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"query","name":"backend","required":true,"schema":{"$ref":"#/components/schemas/JobBackends"}},{"in":"query","name":"type","required":false,"schema":{"default":"ionq.circuit.v1","type":"string"}},{"in":"query","name":"qubits","required":false,"schema":{"default":25,"format":"int32","type":"integer"}},{"in":"query","name":"shots","required":false,"schema":{"default":1000,"format":"int32","type":"integer"}},{"in":"query","name":"1q_gates","required":false,"schema":{"default":0,"format":"int32","type":"integer"}},{"in":"query","name":"2q_gates","required":false,"schema":{"default":0,"format":"int32","type":"integer"}},{"in":"query","name":"error_mitigation","required":false,"schema":{"default":false,"type":"boolean"}}]}},"/jobs/{UUID}/results/probabilities":{"get":{"operationId":"GetJobProbabilities","responses":{"200":{"description":"Probability distribution keyed by decimal qubit state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetResultsResponse"}}}},"404":{"description":"Job not found or not yet completed."}},"summary":"Fetch the probability distribution for a completed job.","security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The UUID of the job.","in":"path","name":"UUID","required":true,"schema":{"type":"string"}},{"description":"Whether to apply sharpening to the probability distribution.","in":"query","name":"sharpen","required":false,"schema":{"type":"boolean"}}]}},"/jobs/{UUID}/variants/{variantId}/results/probabilities":{"get":{"operationId":"GetVariantProbabilities","responses":{"200":{"description":"Per-variant probabilities histogram","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVariantResultsResponse"}}}},"404":{"description":"Not found"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"UUID","required":true,"schema":{"type":"string"}},{"in":"path","name":"variantId","required":true,"schema":{"type":"string"}}]}},"/jobs/{UUID}/variants/{variantId}/results/histogram":{"get":{"operationId":"GetVariantHistogram","responses":{"200":{"description":"Per-variant raw histogram (counts)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVariantResultsResponse"}}}},"404":{"description":"Not found"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"UUID","required":true,"schema":{"type":"string"}},{"in":"path","name":"variantId","required":true,"schema":{"type":"string"}}]}},"/jobs/{UUID}/variants/{variantId}/results/shots":{"get":{"operationId":"GetVariantShots","responses":{"200":{"description":"Per-variant shot-wise results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetVariantResultsResponse"}}}},"404":{"description":"Not found"}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"UUID","required":true,"schema":{"type":"string"}},{"in":"path","name":"variantId","required":true,"schema":{"type":"string"}}]}},"/sessions":{"post":{"operationId":"CreateSession","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}}},"security":[{"apiKeyAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionRequest"}}}}},"get":{"operationId":"GetSessions","responses":{"200":{"description":"Successfully retrieved a list of sessions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionsResponse"}}}}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"query","name":"active","required":false,"schema":{"type":"boolean"}}]}},"/sessions/{session_id}/end":{"post":{"operationId":"EndSession","responses":{"200":{"description":"Successfully end a session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}}},"security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The id of the session — this id is provided in the response on session creation.","in":"path","name":"session_id","required":true,"schema":{"type":"string"}}]}},"/sessions/{session_id}":{"get":{"operationId":"GetSession","responses":{"200":{"description":"Successfully retrieved a session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Session"}}}}},"security":[{"apiKeyAuth":[]}],"parameters":[{"description":"The id of the session — this id is provided in the response on session creation.","in":"path","name":"session_id","required":true,"schema":{"type":"string"}}]}},"/sessions/{session_id}/jobs":{"get":{"operationId":"GetSessionJobs","responses":{"200":{"description":"Successfully retrieved a list of jobs from a session.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetJobsResponse"},"examples":{"Example 1":{"value":{"jobs":[{"id":"e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524","status":"completed","type":"ionq.circuit.v1","backend":"simulator","dry_run":false,"cost_model":"quantum_compute_time","submitter_id":"64b03577072d45001c85e9c4","project_id":"1333d459-cf47-4a5e-acc1-8d4eb4f7b025","parent_job_id":null,"session_id":null,"metadata":null,"name":null,"submitted_at":"2025-05-28T20:47:05.440Z","started_at":null,"completed_at":null,"predicted_execution_duration_ms":null,"predicted_wait_time_ms":null,"execution_duration_ms":null,"shots":1000,"noise":{"model":"ideal"},"failure":null,"settings":{"compilation":{}},"stats":{"qubits":20,"circuits":1,"gate_counts":{"1q":1028,"2q":110},"predicted_quantum_compute_time_us":5000,"billed_quantum_compute_time_us":5200},"results":{"probabilities":{"url":"/v0.4/jobs/e1a09d90-b2ba-4ea5-9fd7-4bfc14eac524/results/probabilities"}},"output":{}}],"next":null}}}}}}},"security":[{"apiKeyAuth":[]}],"parameters":[{"in":"path","name":"session_id","required":true,"schema":{"type":"string"}},{"in":"query","name":"ids","required":false,"schema":{"type":"array","items":{"type":"string"}}},{"in":"query","name":"parent_job_id","required":false,"schema":{"type":"string"}},{"in":"query","name":"status","required":false,"schema":{"$ref":"#/components/schemas/JobStatus"}},{"description":"Filter jobs by backend target. Supports single target or comma-separated list of targets.","in":"query","name":"target","required":false,"schema":{"type":"string"},"example":"simulator"},{"in":"query","name":"session_id","required":false,"schema":{"type":"string"}},{"description":"The id of another user within a shared project to view their submitted jobs. Ignored if not a project member.","in":"query","name":"submitter_id","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"format":"int32","type":"integer"}},{"in":"query","name":"next","required":false,"schema":{"type":"string"}}]}},"/organizations/{organization_id}/usage":{"get":{"description":"Retrieves the costs of a given group type, broken down by the given date modality.","operationId":"get-usages","parameters":[{"$ref":"#/components/parameters/organization_id"},{"description":"Start date, inclusive","example":"2023-07-01","in":"query","name":"start_date","required":true,"schema":{"format":"date","type":"string"}},{"description":"End date, exclusive","example":"2023-08-01","in":"query","name":"end_date","required":true,"schema":{"format":"date","type":"string"}},{"description":"QPU Usage grouping","in":"query","name":"group_by","required":true,"schema":{"$ref":"#/components/schemas/group_by"}},{"description":"Report modality","in":"query","name":"modality","required":true,"schema":{"$ref":"#/components/schemas/modality"}}],"responses":{"200":{"$ref":"#/components/responses/UsagesResponse"}},"summary":"Get usage costs","tags":["usage"],"x-codeSamples":[{"lang":"curl","source":"curl \"https://api.ionq.co/v0.4/organizations/com.my.org/usage?group_by=project&start_date=2025-01-01&end_date=2025-03-02&modality=weekly\" \\\n -H \"Authorization: apiKey your-api-key\"\n"}]}}},"components":{"schemas":{"BadRequestError":{"description":"Error when a bad client request was received.","properties":{"error":{"description":"A short error type descrption.","type":"string"},"message":{"description":"A helpful error message.","type":"string"},"statusCode":{"description":"The HTTP status code for this error.","type":"integer"},"validation":{"$ref":"#/components/schemas/RequestValidation"}},"required":["statusCode","error","message"],"type":"object"},"Error":{"description":"Basic API error response.","properties":{"error":{"description":"A short error type descrption.","type":"string"},"message":{"description":"A helpful error message.","type":"string"},"statusCode":{"description":"The HTTP status code for this error.","type":"integer"}},"required":["statusCode","error","message"],"type":"object"},"RequestValidation":{"description":"Request validation failure details.","properties":{"keys":{"description":"A list of request payload keys which have bad values.","items":{"type":"string"},"type":"array"},"source":{"description":"Location in the request of the bad value(s).","type":"string"}},"type":"object"},"Whoami":{"description":"Details of current API Key session.","properties":{"key_id":{"$ref":"#/components/schemas/key-id"},"key_name":{"$ref":"#/components/schemas/key-name"},"project_id":{"$ref":"#/components/schemas/project-id"}},"required":["key_id","key_name"],"type":"object"},"key-id":{"description":"UUID of a API key.","example":"e060759f-4348-4767-a645-8c0301265791","format":"uuid","type":"string"},"key-name":{"description":"key name.","example":"My First Key","type":"string"},"project-id":{"description":"UUID of a project.","example":"944904d6-2e30-4cfb-8bc4-04afaabcdd42","format":"uuid","type":"string"},"Backend":{"description":"A backend that you can target your program to run on.","properties":{"average_queue_time":{"description":"Current wait time on the queue for execution.","example":1181215,"format":"unix-timestamp","type":"number"},"backend":{"description":"Specifies target hardware and generation where applies: `simulator`, `qpu.aria-1`, `qpu.aria-2`, `qpu.forte-1`, `qpu.forte-enterprise-1`, `qpu.forte-enterprise-2`, `qpu.forte-enterprise-3`","example":"qpu.aria-1","type":"string"},"characterization_id":{"description":"Current characterization ID for this backend","example":"617a1f8b-59d4-435d-aa33-695433d7155e","type":"string"},"degraded":{"description":"Flag to tell if the backend is degraded or not.","type":"boolean"},"kw":{"description":"The amount of energy used by the backend in kilowatt-hours.","example":4902.81,"format":"double","type":"number"},"last_updated":{"description":"Last date time the backend status was updated.","example":"2025-06-16T00:00:00Z","type":"string"},"location":{"description":"The location of the backend.","example":"College Park, MD, USA","type":"string"},"qubits":{"description":"The number of qubits available.","example":25,"minimum":0,"type":"integer"},"status":{"description":"Current status of the backend: `available`, `unavailable`, `retired`.","type":"string"}},"required":["backend","status","qubits","average_queue_time","last_updated"],"type":"object"},"Characterization":{"description":"Quantum hardware characterization data.","properties":{"backend":{"description":"The backend calibrated hardware: `simulator`, `qpu.aria-1`, `qpu.aria-2`, `qpu.forte-1`, `qpu.forte-enterprise-1`, `qpu.forte-enterprise-2`, `qpu.forte-enterprise-3`","type":"string"},"connectivity":{"description":"An array of valid, unordered tuples of possible qubits for executing two-qubit gates (e.g., `[[0, 1], [0, 2], [1, 2]]`)","example":[[0,1],[0,2],[10,9]],"items":{"items":{"type":"integer"},"type":"array"},"type":"array"},"date":{"description":"Date time of the measurement, in ISO format.","example":"2025-06-16T00:00:00Z","type":"string"},"fidelity":{"description":"Fidelity for single-qubit (`1q`) and two-qubit (`2q`) gates, and State Preparation and Measurement (`spam`) operations.\nCurrently provides only median fidelity; additional statistical data will be added in the future.\n","properties":{"spam":{"description":"SPAM error correction information.","properties":{"median":{"example":0.9962,"type":"number"},"stderr":{"description":"SPAM error.","example":null,"minimum":0,"type":"integer"}},"required":["median"],"type":"object"}},"required":["spam"],"type":"object"},"id":{"description":"UUID of the characterization.","format":"uuid","type":"string"},"qubits":{"description":"The number of qubits available.","example":25,"minimum":1,"type":"integer"},"timing":{"description":"Time, in seconds, of various system properties: `t1` time, `t2` time, `1q` gate time, `2q` gate time, `readout` time, and qubit `reset` time.","properties":{"1q":{"type":"integer"},"2q":{"type":"integer"},"readout":{"description":"Readout time.","type":"integer"},"reset":{"description":"qubit reset time.","type":"integer"},"t1":{"example":10,"type":"integer"},"t2":{"example":1,"type":"integer"}},"required":["readout","reset"],"type":"object"}},"type":"object"},"pagination-limit":{"default":25,"description":"How many objects to return.","maximum":25,"minimum":1,"type":"integer"},"pagination-next":{"description":"ID of next batch of resources to load.","format":"uuid","type":"string"},"pagination-page":{"default":1,"description":"Specify the page of results to return.","minimum":1,"type":"integer"},"JobStatus":{"type":"string","enum":["submitted","ready","started","canceled","failed","completed"]},"JobCreationResponse":{"properties":{"id":{"type":"string","example":"617a1f8b-59d4-435d-aa33-695433d7155e"},"status":{"$ref":"#/components/schemas/JobStatus"},"session_id":{"type":"string","nullable":true,"example":null}},"required":["id","status","session_id"],"type":"object","additionalProperties":false},"QisGate":{"type":"string","enum":["x","y","z","rx","ry","rz","h","s","si","v","vi","t","ti","not","cnot","swap","xx","yy","zz","pauliexp"]},"Gate_QisGate":{"properties":{"gate":{"$ref":"#/components/schemas/QisGate"},"target":{"type":"integer","format":"int32"},"targets":{"items":{"type":"number","format":"double"},"type":"array","description":"The qubits that a quantum gate is applied to"},"controls":{"items":{"type":"number","format":"double"},"type":"array","description":"The qubits that determine whether the operation is applied to targets."},"control":{"type":"integer","format":"int32"},"rotation":{"type":"number","format":"double","description":"Rotation angle for rx/ry/rz gates"}},"required":["gate"],"type":"object","additionalProperties":false},"QisCircuitInput":{"properties":{"qubits":{"type":"integer","format":"int32","minimum":1},"circuit":{"items":{"$ref":"#/components/schemas/Gate_QisGate"},"type":"array"},"gateset":{"type":"string","enum":["qis"],"nullable":false}},"required":["circuit","gateset"],"type":"object","additionalProperties":false},"NativeGate":{"type":"string","enum":["zz","ms","gpi","gpi2","nop"]},"Gate_NativeGate":{"properties":{"gate":{"$ref":"#/components/schemas/NativeGate"},"target":{"type":"integer","format":"int32"},"targets":{"items":{"type":"number","format":"double"},"type":"array","description":"The qubits that a quantum gate is applied to"},"controls":{"items":{"type":"number","format":"double"},"type":"array","description":"The qubits that determine whether the operation is applied to targets."},"phase":{"type":"number","format":"double","description":"Phase for gpi/gpi2 gates"},"phases":{"items":{"type":"number","format":"double"},"type":"array","description":"Phases for ms gate"},"angle":{"type":"number","format":"double","description":"Interaction angle for ms gate (in turns, default 0.25)"},"rotation":{"type":"number","format":"double","description":"Rotation angle for rx/ry/rz gates"}},"required":["gate"],"type":"object","additionalProperties":false},"NativeCircuitInput":{"properties":{"qubits":{"type":"integer","format":"int32","minimum":1},"circuit":{"items":{"$ref":"#/components/schemas/Gate_NativeGate"},"type":"array"},"gateset":{"type":"string","enum":["native"],"nullable":false}},"required":["circuit","gateset"],"type":"object","additionalProperties":false},"JsonCircuitInput":{"anyOf":[{"$ref":"#/components/schemas/QisCircuitInput","title":"Qis Circuit"},{"$ref":"#/components/schemas/NativeCircuitInput","title":"Native Circuit"}]},"JobMetadata":{"properties":{},"type":"object","additionalProperties":{"type":"string"}},"JobBackends":{"type":"string","description":"Available options: `simulator`, `qpu.aria-1`, `qpu.aria-2`, `qpu.forte-1`, `qpu.forte-enterprise-1`"},"NoiseModel":{"type":"string","enum":["ideal","harmony","harmony-1","harmony-2","aria-1","aria-2","forte-1","forte-enterprise-1"]},"Noise":{"properties":{"model":{"$ref":"#/components/schemas/NoiseModel"},"seed":{"type":"integer","format":"int32"}},"required":["model"],"type":"object","additionalProperties":false},"CircuitJobCreationPayload":{"properties":{"name":{"type":"string"},"metadata":{"$ref":"#/components/schemas/JobMetadata","description":"User defined metadata"},"shots":{"type":"integer","format":"int32","default":100,"minimum":1,"maximum":1000000},"backend":{"$ref":"#/components/schemas/JobBackends"},"session_id":{"type":"string"},"settings":{"properties":{"error_mitigation":{"properties":{"debiasing":{"type":"boolean"}},"type":"object","description":"To turn on debiasing, you must request at least 500 shots"},"compilation":{"properties":{"opt":{"type":"number","format":"double"},"precision":{"type":"string"}},"type":"object"}},"type":"object"},"dry_run":{"type":"boolean"},"noise":{"$ref":"#/components/schemas/Noise"},"type":{"type":"string","enum":["ionq.circuit.v1"],"nullable":false},"input":{"$ref":"#/components/schemas/JsonCircuitInput"}},"required":["backend","type","input"],"type":"object","additionalProperties":false},"Registers":{"properties":{},"type":"object","additionalProperties":{"items":{"type":"number","format":"double","nullable":true},"type":"array"}},"QISCircuit":{"properties":{"name":{"type":"string"},"circuit":{"items":{"$ref":"#/components/schemas/Gate_QisGate"},"type":"array","description":"Circuit gates. Can be either QIS gates or Native gates depending on the gateset property."},"qubits":{"type":"integer","format":"int32"},"registers":{"$ref":"#/components/schemas/Registers","description":"Registers to use in your circuit. Each register is a list of qubit indices (starting from zero)."},"gateset":{"type":"string","enum":["qis"],"nullable":false,"description":"Optional gateset override for this individual circuit. If not specified, inherits from parent.\nWhen set, the circuit must use the appropriate gate format (QIS)."}},"required":["circuit"],"type":"object","additionalProperties":false},"NativeCircuit":{"properties":{"name":{"type":"string"},"circuit":{"items":{"$ref":"#/components/schemas/Gate_NativeGate"},"type":"array","description":"Circuit gates. Can be either QIS gates or Native gates depending on the gateset property."},"qubits":{"type":"integer","format":"int32"},"registers":{"$ref":"#/components/schemas/Registers","description":"Registers to use in your circuit. Each register is a list of qubit indices (starting from zero)."},"gateset":{"type":"string","enum":["native"],"nullable":false,"description":"Optional gateset override for this individual circuit. If not specified, inherits from parent.\nWhen set, the circuit must use the appropriate gate format (Native)."}},"required":["circuit"],"type":"object","additionalProperties":false},"JsonMultiCircuitInput":{"properties":{"gateset":{"type":"string","enum":["qis","native"]},"circuits":{"items":{"anyOf":[{"$ref":"#/components/schemas/QISCircuit"},{"$ref":"#/components/schemas/NativeCircuit"}]},"type":"array"},"qubits":{"type":"integer","format":"int32","minimum":1}},"required":["gateset","circuits"],"type":"object"},"MultiCircuitJobCreationPayload":{"properties":{"name":{"type":"string"},"metadata":{"$ref":"#/components/schemas/JobMetadata","description":"User defined metadata"},"shots":{"type":"integer","format":"int32","default":100,"minimum":1,"maximum":1000000},"backend":{"$ref":"#/components/schemas/JobBackends"},"session_id":{"type":"string"},"settings":{"properties":{"error_mitigation":{"properties":{"debiasing":{"type":"boolean"}},"type":"object","description":"To turn on debiasing, you must request at least 500 shots"},"compilation":{"properties":{"opt":{"type":"number","format":"double"},"precision":{"type":"string"}},"type":"object"}},"type":"object"},"dry_run":{"type":"boolean"},"noise":{"$ref":"#/components/schemas/Noise"},"type":{"type":"string","enum":["ionq.multi-circuit.v1"],"nullable":false},"input":{"$ref":"#/components/schemas/JsonMultiCircuitInput","description":"Submit multiple circuits in a single job. Each circuit inherits the parent\n`input.gateset` unless overridden by `circuits[].gateset`."}},"required":["backend","type","input"],"type":"object","additionalProperties":false,"title":"JSON Multi Circuit Job","description":"Submit multiple circuits in a single job. Each circuit inherits the parent `input.gateset` unless overridden by `circuits[].gateset`.\n","example":{"type":"ionq.multi-circuit.v1","backend":"simulator","shots":500,"input":{"gateset":"native","qubits":2,"circuits":[{"name":"qis circuit override","gateset":"qis","circuit":[{"gate":"h","target":0},{"gate":"cnot","target":0,"control":1}]},{"name":"native circuit from parent","circuit":[{"gate":"ms","targets":[0,1],"phases":[0,0.25]},{"gate":"gpi2","target":0,"phase":0.75}]}]}}},"JobCreationPayload":{"anyOf":[{"$ref":"#/components/schemas/CircuitJobCreationPayload","title":"Single Circuit"},{"$ref":"#/components/schemas/MultiCircuitJobCreationPayload","title":"Multi Circuit"},{"$ref":"#/components/schemas/QuantumFunctionJobCreationPayload","title":"Quantum Function"},{"$ref":"#/components/schemas/QctrlQaoaJobCreationPayload","title":"QAOA Function"}],"example":{"type":"ionq.circuit.v1","input":{"qubits":1,"gateset":"qis","circuit":[{"gate":"h","target":0}]},"backend":"qpu.forte-1","shots":500,"settings":{"error_mitigation":{"debiasing":false}}}},"IsoTimestamp":{"type":"string"},"Failure":{"properties":{"code":{"type":"string","enum":["InvalidInput","CompilationError","ContractExpiredError","DebiasingError","InternalError","NotEnoughQubits","OptimizationError","PreflightError","QuantumCircuitComplexityError","QuantumComputerError","QuotaExhaustedError","SimulationError","SimulationTimeout","SystemCancel","TooLongPredictedExecutionTime","TooManyControls","TooManyGates","TooManyShots","UnknownBillingError","UnsupportedGate"]},"message":{"type":"string"}},"required":["code","message"],"type":"object","additionalProperties":false},"CostModel":{"type":"string","enum":["quantum_compute_time","execution_time"]},"JsonObject":{"properties":{},"type":"object","additionalProperties":{}},"BaseJob":{"properties":{"id":{"type":"string"},"status":{"$ref":"#/components/schemas/JobStatus"},"type":{"type":"string"},"backend":{"type":"string"},"dry_run":{"type":"boolean"},"submitter_id":{"type":"string","description":"The id of the user who submitted the job"},"project_id":{"type":"string","nullable":true},"parent_job_id":{"type":"string","nullable":true},"session_id":{"type":"string","nullable":true},"metadata":{"allOf":[{"$ref":"#/components/schemas/JobMetadata"}],"nullable":true},"name":{"type":"string","nullable":true},"submitted_at":{"$ref":"#/components/schemas/IsoTimestamp"},"started_at":{"allOf":[{"$ref":"#/components/schemas/IsoTimestamp"}],"nullable":true},"completed_at":{"allOf":[{"$ref":"#/components/schemas/IsoTimestamp"}],"nullable":true},"predicted_wait_time_ms":{"type":"integer","format":"int32","nullable":true},"predicted_execution_duration_ms":{"type":"integer","format":"int32","nullable":true},"execution_duration_ms":{"type":"integer","format":"int32","nullable":true,"description":"How long the job actually took to run on the QPU. Null if the job hasn't run yet."},"shots":{"type":"integer","format":"int32"},"noise":{"$ref":"#/components/schemas/Noise","description":"Only present in the response when `backend` is simulator."},"failure":{"allOf":[{"$ref":"#/components/schemas/Failure"}],"nullable":true},"cost_model":{"$ref":"#/components/schemas/CostModel","description":"The billing model used for this job."},"output":{"$ref":"#/components/schemas/JsonObject"},"settings":{"$ref":"#/components/schemas/JsonObject"},"stats":{"$ref":"#/components/schemas/JsonObject"},"results":{"allOf":[{"$ref":"#/components/schemas/JsonObject"}],"nullable":true}},"required":["id","status","type","backend","dry_run","submitter_id","project_id","parent_job_id","session_id","metadata","name","submitted_at","started_at","completed_at","predicted_wait_time_ms","predicted_execution_duration_ms","execution_duration_ms","failure","output","settings","stats","results"],"type":"object","additionalProperties":false},"GetJobsResponse":{"properties":{"jobs":{"items":{"$ref":"#/components/schemas/BaseJob"},"type":"array"},"next":{"type":"string","nullable":true}},"required":["jobs","next"],"type":"object","additionalProperties":false},"GetJobsQueryParams":{"properties":{"ids":{"items":{"type":"string"},"type":"array"},"parent_job_id":{"type":"string"},"status":{"$ref":"#/components/schemas/JobStatus"},"target":{"type":"string","description":"Filter jobs by backend target. Supports single target or comma-separated list of targets.","example":"simulator"},"session_id":{"type":"string"},"submitter_id":{"type":"string","description":"The id of another user within a shared project to view their submitted jobs. Ignored if not a project member."},"limit":{"type":"integer","format":"int32"},"next":{"type":"string"}},"type":"object","additionalProperties":false},"CircuitJobCompilationSettings":{"properties":{"precision":{"type":"string"},"opt":{"type":"number","format":"double"},"gate_basis":{"type":"string"},"service_version":{"type":"string"}},"type":"object","additionalProperties":false},"CircuitJobSettings":{"properties":{"compilation":{"$ref":"#/components/schemas/CircuitJobCompilationSettings"},"error_mitigation":{"properties":{"debiasing":{"anyOf":[{"properties":{"phi_chi_twirling":{"properties":{"p2q":{"type":"number","format":"double"},"t2q":{"type":"number","format":"double"},"t1q":{"type":"number","format":"double"}},"type":"object"}},"type":"object"},{"type":"boolean"}]}},"type":"object"}},"type":"object","additionalProperties":false},"NumberMap":{"properties":{},"type":"object","additionalProperties":{"type":"number","format":"double"}},"CircuitJobStats":{"properties":{"qubits":{"type":"integer","format":"int32"},"circuits":{"type":"integer","format":"int32"},"gate_counts":{"$ref":"#/components/schemas/NumberMap"},"kwh":{"type":"number","format":"double"},"predicted_quantum_compute_time_us":{"type":"integer","format":"int32"},"billed_quantum_compute_time_us":{"type":"integer","format":"int32"}},"type":"object","additionalProperties":false},"CircuitJobResult":{"properties":{"probabilities":{"properties":{"url":{"type":"string"}},"required":["url"],"type":"object"},"histogram":{"properties":{"url":{"type":"string"}},"required":["url"],"type":"object"},"shots":{"properties":{"url":{"type":"string"}},"required":["url"],"type":"object"}},"type":"object","additionalProperties":false},"GetCircuitJobResponse":{"properties":{"id":{"type":"string"},"status":{"$ref":"#/components/schemas/JobStatus"},"type":{"type":"string"},"backend":{"type":"string"},"dry_run":{"type":"boolean"},"submitter_id":{"type":"string","description":"The id of the user who submitted the job"},"project_id":{"type":"string","nullable":true},"parent_job_id":{"type":"string","nullable":true},"session_id":{"type":"string","nullable":true},"metadata":{"allOf":[{"$ref":"#/components/schemas/JobMetadata"}],"nullable":true},"name":{"type":"string","nullable":true},"submitted_at":{"$ref":"#/components/schemas/IsoTimestamp"},"started_at":{"allOf":[{"$ref":"#/components/schemas/IsoTimestamp"}],"nullable":true},"completed_at":{"allOf":[{"$ref":"#/components/schemas/IsoTimestamp"}],"nullable":true},"predicted_wait_time_ms":{"type":"integer","format":"int32","nullable":true},"predicted_execution_duration_ms":{"type":"integer","format":"int32","nullable":true},"execution_duration_ms":{"type":"integer","format":"int32","nullable":true,"description":"How long the job actually took to run on the QPU. Null if the job hasn't run yet."},"shots":{"type":"integer","format":"int32"},"noise":{"$ref":"#/components/schemas/Noise","description":"Only present in the response when `backend` is simulator."},"failure":{"allOf":[{"$ref":"#/components/schemas/Failure"}],"nullable":true},"cost_model":{"$ref":"#/components/schemas/CostModel","description":"The billing model used for this job."},"output":{"$ref":"#/components/schemas/JsonObject"},"settings":{"$ref":"#/components/schemas/CircuitJobSettings"},"stats":{"$ref":"#/components/schemas/CircuitJobStats"},"results":{"allOf":[{"$ref":"#/components/schemas/CircuitJobResult"}],"nullable":true},"child_job_ids":{"items":{"type":"string"},"type":"array","nullable":true}},"required":["id","status","type","backend","dry_run","submitter_id","project_id","parent_job_id","session_id","metadata","name","submitted_at","started_at","completed_at","predicted_wait_time_ms","predicted_execution_duration_ms","execution_duration_ms","failure","output","settings","stats","results","child_job_ids"],"type":"object","additionalProperties":false},"GetJobResponse":{"$ref":"#/components/schemas/GetCircuitJobResponse"},"GetJobCostResponse":{"properties":{"dry_run":{"type":"boolean","example":false},"estimated_cost":{"properties":{"value":{"type":"number","format":"double","example":24.83},"unit":{"type":"string","example":"usd"}},"required":["value","unit"],"type":"object"},"cost":{"properties":{"value":{"type":"number","format":"double","example":24.83},"unit":{"type":"string","example":"usd"}},"required":["value","unit"],"type":"object"}},"required":["dry_run","estimated_cost"],"type":"object","additionalProperties":false},"JobCanceledResponse":{"properties":{"id":{"type":"string","example":"617a1f8b-59d4-435d-aa33-695433d7155e"},"status":{"type":"string","enum":["canceled"],"nullable":false}},"required":["id","status"],"type":"object","additionalProperties":false},"JobsCanceledResponse":{"properties":{"ids":{"items":{"type":"string"},"type":"array","example":["617a1f8b-59d4-435d-aa33-695433d7155e","617a1f8b-59d4-435d-aa33-695433d7155f"]},"status":{"type":"string","enum":["canceled"],"nullable":false}},"required":["ids","status"],"type":"object","additionalProperties":false},"JobsBulkOperationRequest":{"properties":{"ids":{"items":{"type":"string"},"type":"array"}},"required":["ids"],"type":"object","additionalProperties":false},"JobDeletedResponse":{"properties":{"id":{"type":"string","example":"617a1f8b-59d4-435d-aa33-695433d7155e"},"status":{"type":"string","enum":["deleted"],"nullable":false}},"required":["id","status"],"type":"object","additionalProperties":false},"JobsDeletedResponse":{"properties":{"ids":{"items":{"type":"string"},"type":"array"},"status":{"type":"string","enum":["deleted"],"nullable":false}},"required":["ids","status"],"type":"object","additionalProperties":false},"GetJobEstimateQueryParams":{"properties":{"backend":{"$ref":"#/components/schemas/JobBackends"},"type":{"type":"string","default":"ionq.circuit.v1"},"qubits":{"type":"integer","format":"int32","default":25},"shots":{"type":"integer","format":"int32","default":1000},"1q_gates":{"type":"integer","format":"int32","default":0},"2q_gates":{"type":"integer","format":"int32","default":0},"error_mitigation":{"type":"boolean","default":false}},"required":["backend"],"type":"object","additionalProperties":false},"GetJobEstimateResponse":{"properties":{"input_values":{"$ref":"#/components/schemas/GetJobEstimateQueryParams"},"estimated_at":{"$ref":"#/components/schemas/IsoTimestamp"},"cost_unit":{"type":"string"},"rate_information":{"properties":{"job_cost_minimum":{"type":"number","format":"double"},"cost_2q_gate":{"type":"number","format":"double"},"cost_1q_gate":{"type":"number","format":"double"},"organization":{"type":"string"}},"required":["job_cost_minimum","cost_2q_gate","cost_1q_gate","organization"],"type":"object"},"estimated_cost":{"type":"number","format":"double"},"estimated_execution_time":{"type":"number","format":"double"},"current_predicted_queue_time":{"type":"number","format":"double"}},"required":["input_values","estimated_at","cost_unit","rate_information","estimated_cost","estimated_execution_time","current_predicted_queue_time"],"type":"object","additionalProperties":false},"AddJobResultsResponse":{"properties":{"job_id":{"type":"string"}},"required":["job_id"],"type":"object","additionalProperties":false},"JobQCtrlStatus":{"enum":["running","complete","max_iteration"],"type":"string"},"AddJobResultsPayload":{"properties":{"processing_status":{"$ref":"#/components/schemas/JobQCtrlStatus"},"optimal_cost":{"type":"number","format":"double"},"optimal_bitstring":{"type":"string"}},"required":["processing_status","optimal_cost","optimal_bitstring"],"type":"object","additionalProperties":false},"GetResultsResponse":{"properties":{},"type":"object","additionalProperties":{"type":"number","format":"double"}},"GetVariantResultsResponse":{"properties":{},"type":"object","additionalProperties":{"type":"number","format":"double"}},"SessionCostLimit":{"properties":{"unit":{"type":"string"},"value":{"type":"number","format":"double"}},"required":["unit","value"],"type":"object","additionalProperties":false},"SessionSettings":{"properties":{"job_count_limit":{"type":"integer","format":"int32"},"duration_limit_min":{"type":"integer","format":"int32"},"cost_limit":{"$ref":"#/components/schemas/SessionCostLimit"},"expires_at":{"type":"string","format":"date-time"}},"type":"object","additionalProperties":false},"SessionStatusEnum":{"enum":["created","started","ended"],"type":"string"},"Session":{"properties":{"id":{"type":"string","description":"The id of the session."},"created_at":{"type":"string","format":"date-time"},"organization_id":{"type":"string"},"backend":{"type":"string","nullable":true},"project_id":{"type":"string","nullable":true},"creator_id":{"type":"string","nullable":true},"ended_at":{"type":"string","format":"date-time","nullable":true},"ender_id":{"type":"string","nullable":true},"settings":{"$ref":"#/components/schemas/SessionSettings"},"active":{"type":"boolean"},"status":{"$ref":"#/components/schemas/SessionStatusEnum"},"started_at":{"type":"string","format":"date-time","nullable":true}},"required":["id","created_at","organization_id","backend","project_id","creator_id","ended_at","ender_id","active","status","started_at"],"type":"object","additionalProperties":false},"SessionSettingsRequest":{"properties":{"job_count_limit":{"type":"integer","format":"int32"},"duration_limit_min":{"type":"integer","format":"int32"},"cost_limit":{"$ref":"#/components/schemas/SessionCostLimit"}},"type":"object","additionalProperties":false},"CreateSessionRequest":{"properties":{"backend":{"type":"string"},"settings":{"$ref":"#/components/schemas/SessionSettingsRequest"}},"required":["backend"],"type":"object","additionalProperties":false},"SessionsResponse":{"properties":{"organization_id":{"type":"string"},"sessions":{"items":{"$ref":"#/components/schemas/Session"},"type":"array"}},"required":["organization_id","sessions"],"type":"object","additionalProperties":false},"GetSessionsQueryParams":{"properties":{"active":{"type":"boolean"}},"type":"object","additionalProperties":false},"QctrlQaoaJobInput":{"type":"object","properties":{"problem_type":{"type":"string","enum":["maxcut"]},"problem":{"type":"object","description":"A NetworkX adjacency_graph object","example":{"directed":false,"multigraph":false,"graph":[],"nodes":[{"id":0},{"id":1},{"id":2}],"adjacency":[[{"id":1},{"id":2}],[{"id":0},{"id":2}],[{"id":0},{"id":1}]]}}},"required":["problem_type","problem"]},"QuantumFunctionInput":{"oneOf":[{"$ref":"#/components/schemas/HamiltonianEnergyInput"},{"$ref":"#/components/schemas/GenericQuantumFunctionInput"}],"discriminator":{"propertyName":"type","mapping":{"hamiltonian-energy":"#/components/schemas/HamiltonianEnergyInput"}}},"QuantumFunctionJobCreationPayload":{"type":"object","properties":{"name":{"type":"string"},"metadata":{"$ref":"#/components/schemas/JobMetadata"},"shots":{"type":"integer","format":"int32","default":100,"maximum":1000000},"backend":{"$ref":"#/components/schemas/JobBackends"},"session_id":{"type":"string"},"settings":{"type":"object","properties":{"error_mitigation":{"type":"object","properties":{"debiasing":{"type":"boolean"}}}}},"dry_run":{"type":"boolean"},"type":{"type":"string","enum":["quantum-function"]},"input":{"$ref":"#/components/schemas/QuantumFunctionInput"}},"required":["backend","type","input"]},"QctrlQaoaJobCreationPayload":{"type":"object","description":"Submit a combinatorial optimization job to solve a maxcut problem using Q-CTRL's QAOA Solver. See our QAOA Job guide for more infromation.\n","properties":{"name":{"type":"string"},"metadata":{"$ref":"#/components/schemas/JobMetadata"},"shots":{"type":"integer","format":"int32","default":100,"maximum":1000000},"backend":{"$ref":"#/components/schemas/JobBackends"},"session_id":{"type":"string"},"settings":{"type":"object","properties":{"error_mitigation":{"type":"object","properties":{"debiasing":{"type":"boolean"}}}}},"dry_run":{"type":"boolean"},"type":{"type":"string","enum":["qctrl.qaoa.v1"]},"input":{"$ref":"#/components/schemas/QctrlQaoaJobInput"},"external_settings":{"type":"object","properties":{"api_credentials":{"description":"API Key for your Q-CTRL Account","type":"string"},"external_organization":{"description":"Optional unique slug for your target Q-CTRL organization","type":"string"}},"required":["api_credentials"]}},"required":["backend","type","input","external_settings"]},"GroupUsage":{"description":"A group's single date usage","properties":{"amount":{"description":"The cost amount for the group of the given date","example":144.39,"type":"number"},"group_id":{"description":"The unique ID from the group","example":"2bfd0fd5-5854-4916-917f-a907af586755","type":"string"},"group_name":{"description":"The group's descriptive name","example":"Project Jumping Lemming","type":"string"},"job_count":{"description":"The number of jobs run for the group on the given date","example":9,"type":"integer"},"time_us":{"description":"The QPU time in microseconds","example":1566154.312523,"type":"number"}},"type":"object"},"Usage":{"description":"Single date of QPU usage","properties":{"amount":{"description":"The amount as a cost in USD","example":1614.23,"type":"number"},"from":{"description":"Date for this group's usage","example":"2023-07-01","format":"date","type":"string"},"group_usages":{"description":"The top 5 usage groups in order of cost amount descending","items":{"$ref":"#/components/schemas/GroupUsage"},"type":"array"},"job_count":{"description":"The count of jobs for this group on the given from date","example":10,"type":"integer"},"time_us":{"description":"The QPU time in microseconds","example":5143166.13413,"type":"number"}},"required":["from","job_count","amount","time_us","group_usages"],"type":"object"},"Usages":{"description":"QPU usage details for a given modality and date range.","properties":{"amount_total":{"description":"The total cost amount for the given timeframe, in units given by usage_unit","example":151.31,"type":"number"},"group_type":{"$ref":"#/components/schemas/group_by"},"job_count":{"description":"The total number of jobs run in the timeframe","example":514,"type":"integer"},"modality":{"$ref":"#/components/schemas/modality"},"organization":{"$ref":"#/components/schemas/organization_id"},"time_us_total":{"description":"The total QPU time usage for the given timeframe, in microseconds","example":1566154.312523,"type":"number"},"usage_data":{"description":"The breakdown of usage by group type in date order most to least recent","items":{"$ref":"#/components/schemas/Usage"},"type":"array"},"usage_from":{"description":"Usage beginning RFC 3339 timestamp","example":"2025-10-01T00:00:00Z","format":"date-time","type":"string"},"usage_to":{"description":"Usage end RFC 3339 timestamp","example":"2025-11-01T00:00:00Z","format":"date-time","type":"string"},"usage_unit":{"description":"The currency of the total and job cost amounts","example":"USD","type":"string"}},"required":["start_date","end_date","group_type","modality"],"type":"object"},"group_by":{"description":"QPU Usage grouping","enum":["job","project","user"],"example":"project","type":"string"},"modality":{"description":"Report modality","enum":["daily","weekly","monthly"],"example":"daily","type":"string"},"organization_id":{"description":"UUID of an organization.","example":"71d164e-6ebe-4126-8839-f1529bb01a00","format":"uuid","type":"string"},"HamiltonianEnergyData":{"properties":{"hamiltonian":{"items":{"$ref":"#/components/schemas/HamiltonianPauliTerm"},"title":"Hamiltonian","type":"array"},"ansatz":{"$ref":"#/components/schemas/Ansatz"},"linear_constraints":{"default":[],"items":{"$ref":"#/components/schemas/LinearConstraint"},"title":"Linear Constraints","type":"array"},"quadratic_constraints":{"default":[],"items":{"$ref":"#/components/schemas/QuadraticConstraint"},"title":"Quadratic Constraints","type":"array"},"penalty":{"default":0,"nullable":true,"title":"Penalty","type":"number"},"cvar_alpha":{"default":null,"nullable":true,"title":"Cvar Alpha","type":"number"}},"required":["hamiltonian","ansatz"],"type":"object"},"Ansatz":{"properties":{"data":{"title":"Data","type":"string"}},"required":["data"],"type":"object"},"HamiltonianPauliTerm":{"properties":{"pauli_string":{"title":"Pauli String","type":"string"},"coefficient":{"title":"Coefficient","type":"number"}},"required":["pauli_string","coefficient"],"type":"object"},"LinearConstraint":{"description":"A class to model linear inequality constraints of the form\n\n.. math::\n\n A x \\leq b.","properties":{"coeffs":{"items":{"type":"number"},"title":"Coeffs","type":"array"},"rhs":{"title":"Rhs","type":"number"}},"required":["coeffs","rhs"],"type":"object"},"QuadraticConstraint":{"description":"A class to model quadratic inequality constraints of the form\n\n.. math::\n\n x^T P x + r^T x \\leq c.","properties":{"quadratic_coeff":{"items":{"items":{"type":"number"},"type":"array"},"title":"Quadratic Coeff","type":"array"},"linear_coeff":{"items":{"type":"number"},"title":"Linear Coeff","type":"array"},"rhs":{"title":"Rhs","type":"number"}},"required":["quadratic_coeff","linear_coeff","rhs"],"type":"object"},"HamiltonianEnergyInput":{"type":"object","properties":{"data":{"type":"object","properties":{"type":{"type":"string","enum":["hamiltonian-energy"]},"data":{"$ref":"#/components/schemas/HamiltonianEnergyData"}},"required":["type","data"]},"params":{"type":"array","items":{"type":"number"}}},"required":["data"]},"GenericQuantumFunctionInput":{"type":"object","properties":{"type":{"type":"string"},"data":{"type":"object"},"params":{"type":"array","items":{"type":"number"}}},"required":["type","data"]}},"responses":{"BadRequest":{"content":{"application/json":{"example":{"error":"Bad Request","message":"\"some-parameter\" was invalid.","statusCode":400,"validation":{"keys":["some-parameter"],"source":"params"}},"schema":{"$ref":"#/components/schemas/BadRequestError"}}},"description":"Invalid request parameters"},"Error":{"content":{"application/json":{"example":{"error":"Internal Server Error","message":"Internal service outage. Visit https://status.ionq.co/ to track this incident.","statusCode":500},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Error"},"NotFound":{"content":{"application/json":{"example":{"error":"Not Found Error","message":"Resource not found. See https://docs.ionq.com/ for details, or email support@ionq.co for help.","statusCode":404},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Resource was not found."},"Unauthorized":{"content":{"application/json":{"example":{"error":"Unauthorized Error","message":"Invalid key provided. See https://docs.ionq.com/#authentication for details, or email support@ionq.co for help.","statusCode":401},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Request was not authorized."},"Whoami":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Whoami"}}},"description":"Successfully retrieved a current of key from this session."},"GetBackend":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Backend"}}},"description":"Successfully retrieved backend."},"GetCharacterization":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Characterization"}}},"description":"Successfully retrieved current characterization"},"ListBackends":{"content":{"application/json":{"schema":{"description":"The list of backends.","items":{"$ref":"#/components/schemas/Backend"},"type":"array"}}},"description":"Successfully retrieved backend."},"ListCharacterizations":{"content":{"application/json":{"schema":{"description":"Response body from requesting characterization data.","properties":{"characterizations":{"description":"A page of characterizations measurements.","items":{"$ref":"#/components/schemas/Characterization"},"type":"array"},"pages":{"description":"The number of remaining pages of characterization measurements.","type":"integer"}},"required":["characterizations"],"type":"object"}}},"description":"Successfully retrieved characterizations."},"UsagesResponse":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usages"}}},"description":"Successfully retrieved a list of projects."}},"examples":{"Metadata":{"value":{"input":"{ \"format\": \"ionq.circuit.v0\", \"qubits\": 1, \"circuit\": [ { \"gate\": \"h\", \"target\": 0 } ] }","metadata":{"bar":2,"foo":1}}}},"securitySchemes":{"apiKeyAuth":{"description":"API keys are associated with a user and can be created on the [IonQ Quantum Cloud](https://cloud.ionq.com) application. To authenticate, prefix your API Key with `apiKey ` and place it in the `Authorization` request header. Ex: `Authorization: apiKey your-api-key`","in":"header","name":"Authorization","type":"apiKey"}},"parameters":{"backend":{"description":"A backend where jobs can run on.","in":"path","name":"backend","required":true,"schema":{"enum":["qpu.aria-1","qpu.aria-2","qpu.forte-1","qpu.forte-enterprise-1","qpu.forte-enterprise-2","qpu.forte-enterprise-3"],"type":"string"}},"pagination-limit":{"in":"query","name":"limit","schema":{"$ref":"#/components/schemas/pagination-limit"}},"pagination-next":{"in":"query","name":"next","schema":{"$ref":"#/components/schemas/pagination-next"}},"pagination-page":{"in":"query","name":"page","schema":{"$ref":"#/components/schemas/pagination-page"}},"uuid":{"description":"A UUID identifying a specific resource","example":"617a1f8b-59d4-435d-aa33-695433d7155e","in":"path","name":"UUID","required":true,"schema":{"format":"uuid","type":"string"}},"organization_id":{"description":"The UUID of the organization — this UUID is provided in the response on organization creation.","example":"71d164e-6ebe-4126-8839-f1529bb01a00","in":"path","name":"organization_id","required":true,"schema":{"format":"uuid","type":"string"}}},"requestBodies":{},"headers":{}}} From 73fbcbbb7ee4db66f6d4231587eb751fdffb2905 Mon Sep 17 00:00:00 2001 From: Spencer Churchill <25377399+splch@users.noreply.github.com> Date: Tue, 19 May 2026 14:11:37 -0700 Subject: [PATCH 3/4] Stop pre-commit from rewriting generated files The previous regen commit failed `generated.yml` because pre-commit's `trailing-whitespace` and `end-of-file-fixer` hooks rewrote the raw output of `openapi-python-client` locally (stripping docstring trailing spaces and collapsing double trailing newlines), but CI regenerates the files fresh and gets back those same artifacts. Two parts: - Re-commit the raw regen output for the 11 affected files in `ionq_core/api/` + `ionq_core/models/` so `git diff ionq_core/` is empty on a fresh regen. - Exclude generated paths (per `.gitattributes`) from the two whitespace hooks in `.pre-commit-config.yaml` so a future regen PR doesn't trip on the same thing. --- .pre-commit-config.yaml | 6 ++++++ ionq_core/api/default/create_job.py | 6 +++--- ionq_core/models/base_job.py | 3 ++- ionq_core/models/get_circuit_job_response.py | 3 ++- ionq_core/models/get_job_response.py | 3 ++- ionq_core/models/json_multi_circuit_input.py | 2 +- ionq_core/models/native_circuit_input.py | 3 ++- .../qctrl_qaoa_job_creation_payload_external_settings.py | 2 +- .../models/qctrl_qaoa_job_creation_payload_settings.py | 2 +- ...l_qaoa_job_creation_payload_settings_error_mitigation.py | 2 +- ionq_core/models/qctrl_qaoa_job_input.py | 2 +- ionq_core/models/qctrl_qaoa_job_input_problem.py | 2 +- 12 files changed, 23 insertions(+), 13 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 575b9a8..91df673 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,8 +2,14 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: + # Skip generated paths (see .gitattributes); openapi-python-client emits + # docstring trailing spaces and double-trailing-newlines that CI + # reproduces on every regen, so stripping them locally creates a + # generated.yml staleness mismatch. - id: trailing-whitespace + exclude: ^ionq_core/(__init__|client|errors|types)\.py$|^ionq_core/(api|models)/ - id: end-of-file-fixer + exclude: ^ionq_core/(__init__|client|errors|types)\.py$|^ionq_core/(api|models)/ - id: check-yaml - id: check-added-large-files diff --git a/ionq_core/api/default/create_job.py b/ionq_core/api/default/create_job.py index 42654d7..b75f365 100644 --- a/ionq_core/api/default/create_job.py +++ b/ionq_core/api/default/create_job.py @@ -29,16 +29,16 @@ def _get_kwargs( headers: dict[str, Any] = {} + - - + _kwargs: dict[str, Any] = { "method": "post", "url": "/jobs", } - + if isinstance(body, CircuitJobCreationPayload): _kwargs["json"] = body.to_dict() elif isinstance(body, JSONMultiCircuitJob): diff --git a/ionq_core/models/base_job.py b/ionq_core/models/base_job.py index e628549..5d6b39b 100644 --- a/ionq_core/models/base_job.py +++ b/ionq_core/models/base_job.py @@ -35,7 +35,7 @@ @_attrs_define class BaseJob: - """ + """ Attributes: id (str): status (JobStatus): @@ -430,3 +430,4 @@ def _parse_results(data: object) -> JsonObject | None: ) return base_job + diff --git a/ionq_core/models/get_circuit_job_response.py b/ionq_core/models/get_circuit_job_response.py index 6b989a0..2084de2 100644 --- a/ionq_core/models/get_circuit_job_response.py +++ b/ionq_core/models/get_circuit_job_response.py @@ -38,7 +38,7 @@ @_attrs_define class GetCircuitJobResponse: - """ + """ Attributes: id (str): status (JobStatus): @@ -467,3 +467,4 @@ def _parse_child_job_ids(data: object) -> list[str] | None: ) return get_circuit_job_response + diff --git a/ionq_core/models/get_job_response.py b/ionq_core/models/get_job_response.py index 177bf64..4447ab1 100644 --- a/ionq_core/models/get_job_response.py +++ b/ionq_core/models/get_job_response.py @@ -38,7 +38,7 @@ @_attrs_define class GetJobResponse: - """ + """ Attributes: id (str): status (JobStatus): @@ -467,3 +467,4 @@ def _parse_child_job_ids(data: object) -> list[str] | None: ) return get_job_response + diff --git a/ionq_core/models/json_multi_circuit_input.py b/ionq_core/models/json_multi_circuit_input.py index 888629a..dc24499 100644 --- a/ionq_core/models/json_multi_circuit_input.py +++ b/ionq_core/models/json_multi_circuit_input.py @@ -31,7 +31,7 @@ @_attrs_define class JsonMultiCircuitInput: - """ + """ Attributes: gateset (JsonMultiCircuitInputGateset): circuits (list[NativeCircuit | QISCircuit]): diff --git a/ionq_core/models/native_circuit_input.py b/ionq_core/models/native_circuit_input.py index a0da9f6..47c98e9 100644 --- a/ionq_core/models/native_circuit_input.py +++ b/ionq_core/models/native_circuit_input.py @@ -30,7 +30,7 @@ @_attrs_define class NativeCircuitInput: - """ + """ Attributes: circuit (list[GateNativeGate]): gateset (NativeCircuitInputGateset): @@ -100,3 +100,4 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: ) return native_circuit_input + diff --git a/ionq_core/models/qctrl_qaoa_job_creation_payload_external_settings.py b/ionq_core/models/qctrl_qaoa_job_creation_payload_external_settings.py index 378da90..ca5ca9c 100644 --- a/ionq_core/models/qctrl_qaoa_job_creation_payload_external_settings.py +++ b/ionq_core/models/qctrl_qaoa_job_creation_payload_external_settings.py @@ -25,7 +25,7 @@ @_attrs_define class QctrlQaoaJobCreationPayloadExternalSettings: - """ + """ Attributes: api_credentials (str): API Key for your Q-CTRL Account external_organization (str | Unset): Optional unique slug for your target Q-CTRL organization diff --git a/ionq_core/models/qctrl_qaoa_job_creation_payload_settings.py b/ionq_core/models/qctrl_qaoa_job_creation_payload_settings.py index cabe335..ec34215 100644 --- a/ionq_core/models/qctrl_qaoa_job_creation_payload_settings.py +++ b/ionq_core/models/qctrl_qaoa_job_creation_payload_settings.py @@ -28,7 +28,7 @@ @_attrs_define class QctrlQaoaJobCreationPayloadSettings: - """ + """ Attributes: error_mitigation (QctrlQaoaJobCreationPayloadSettingsErrorMitigation | Unset): """ diff --git a/ionq_core/models/qctrl_qaoa_job_creation_payload_settings_error_mitigation.py b/ionq_core/models/qctrl_qaoa_job_creation_payload_settings_error_mitigation.py index ab48cda..8b7bdca 100644 --- a/ionq_core/models/qctrl_qaoa_job_creation_payload_settings_error_mitigation.py +++ b/ionq_core/models/qctrl_qaoa_job_creation_payload_settings_error_mitigation.py @@ -25,7 +25,7 @@ @_attrs_define class QctrlQaoaJobCreationPayloadSettingsErrorMitigation: - """ + """ Attributes: debiasing (bool | Unset): """ diff --git a/ionq_core/models/qctrl_qaoa_job_input.py b/ionq_core/models/qctrl_qaoa_job_input.py index 001e80e..16b3f21 100644 --- a/ionq_core/models/qctrl_qaoa_job_input.py +++ b/ionq_core/models/qctrl_qaoa_job_input.py @@ -29,7 +29,7 @@ @_attrs_define class QctrlQaoaJobInput: - """ + """ Attributes: problem_type (QctrlQaoaJobInputProblemType): problem (QctrlQaoaJobInputProblem): A NetworkX adjacency_graph object Example: {'directed': False, 'multigraph': diff --git a/ionq_core/models/qctrl_qaoa_job_input_problem.py b/ionq_core/models/qctrl_qaoa_job_input_problem.py index e3a4ba2..5c5e8a9 100644 --- a/ionq_core/models/qctrl_qaoa_job_input_problem.py +++ b/ionq_core/models/qctrl_qaoa_job_input_problem.py @@ -39,7 +39,7 @@ class QctrlQaoaJobInputProblem: def to_dict(self) -> dict[str, Any]: - + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) From 115e210afeac505c14e0a768ad8da9325a2958b9 Mon Sep 17 00:00:00 2001 From: Spencer Churchill <25377399+splch@users.noreply.github.com> Date: Tue, 19 May 2026 14:42:15 -0700 Subject: [PATCH 4/4] Drop the pre-commit-config exclude The exclude was added in the previous commit to defend against a trap that turns out not to exist in practice: the project's recommended `pre-commit install` workflow has never been load-bearing here (no historical regen PR has failed `staleness`, and the on-commit hook strip would only fire for contributors who actually installed it), so the structural guard is purely speculative. The regen-output restoration in that commit was the load-bearing part; keep that, drop this. --- .pre-commit-config.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 91df673..575b9a8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,14 +2,8 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - # Skip generated paths (see .gitattributes); openapi-python-client emits - # docstring trailing spaces and double-trailing-newlines that CI - # reproduces on every regen, so stripping them locally creates a - # generated.yml staleness mismatch. - id: trailing-whitespace - exclude: ^ionq_core/(__init__|client|errors|types)\.py$|^ionq_core/(api|models)/ - id: end-of-file-fixer - exclude: ^ionq_core/(__init__|client|errors|types)\.py$|^ionq_core/(api|models)/ - id: check-yaml - id: check-added-large-files