# null Source: https://docs.ionq.com/CLAUDE # CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Development Commands ### Local Development * Install Mintlify CLI globally: `npm i -g mintlify` * Start local development server: `mintlify dev` * Install dependencies if dev server fails: `mintlify install` ### Spell Checking * Install cspell: `npm -g install cspell` * Check spelling in all MDX files: `npx cspell **/*.mdx` * Add new technical terms to `/project-words.txt` ### API Documentation Generation * Generate API docs from OpenAPI spec: `npx @mintlify/scraping@latest openapi-file api-reference/spec.yaml -o api-reference` ## Repository Architecture ### Content Structure This is a documentation repository for IonQ's Quantum Cloud platform built with Mintlify. The site structure is: * **API Reference** (`/api-reference/`): Auto-generated from OpenAPI specs in `spec.yaml` files * v0.3 and v0.4 API versions with separate specs * Additional manual `.mdx` files for navigation and custom content * **Guides** (`/guides/`): Step-by-step tutorials for specific tasks * **User Manual** (`/user-manual/`): Reference documentation for platform features * **SDKs** (`/sdks/`): Documentation for various quantum computing SDKs (Qiskit, Cirq, PennyLane, qBraid, etc.) * **Partners** (`/partners/`): Integration guides for cloud partners (AWS Braket, Azure Quantum, etc.) * **Snippets** (`/snippets/`): Reusable content blocks ### Key Configuration Files * `mint.json`: Mintlify configuration defining navigation, theming, and site structure * `cspell.json`: Spell checker configuration * `project-words.txt`: Custom dictionary for technical terms * OpenAPI specs: * `/api-reference/v0.3/spec.yaml` * `/api-reference/v0.4/spec-backends.yaml` * `/api-reference/v0.4/spec-api-users.yaml` ### Content Types 1. **API Reference**: Generated from OpenAPI specs, with `.mdx` files as navigation pointers 2. **Guides**: Focus on single, specific actions with step-by-step instructions 3. **User Manual**: Concise reference organized around core platform objects (Accounts, Backends, Jobs, Organizations, Projects) ## Style Guidelines * Use lowercase in titles: "Resetting your password" not "Resetting Your Password" * Prefer small, short sections with linkable headers * Always use `IONQ_API_KEY` as the environment variable name in examples * Content is written in MDX format (Markdown with JSX components) ## Navigation Management * All page navigation is defined in `mint.json` * Pages can be viewed locally before being added to navigation by accessing their URL directly * Use the `redirects` section in `mint.json` for URL changes ## Content Guidelines * Target audience: Quantum software developers using Python, Qiskit, Windows/Mac desktop users * Focus on practical, actionable content * Screenshots and media stored in `_media/` subdirectories * Use project-specific terminology found in `project-words.txt` * Local test environments can be run using the `mint` CLI tool, which can be installed with `npm i -g mint` if needed. * This project uses Mintlify to build and deploy the site. It's documentation can be found at [https://mintlify.com/docs](https://mintlify.com/docs) * When working on pages with API examples, try testing those examples using a local key if one is available. This can be accessed through a Bash environment variable in \$IONQ\_API\_KEY # null Source: https://docs.ionq.com/GEMINI This file provides guidance to AI agents when working with code in this repository. ## Development Commands ### Local Development * Install Mintlify CLI globally: `npm i -g mintlify` * Start local development server: `mintlify dev` * Install dependencies if dev server fails: `mintlify install` ### Spell Checking * Install cspell: `npm -g install cspell` * Check spelling in all MDX files: `npx cspell **/*.mdx` * Add new technical terms to `/project-words.txt` ### API Documentation Generation * Generate API docs from OpenAPI spec: `npx @mintlify/scraping@latest openapi-file api-reference/spec.yaml -o api-reference` ## Repository Architecture ### Content Structure This is a documentation repository for IonQ's Quantum Cloud platform built with Mintlify. The site structure is: * **API Reference** (`/api-reference/`): Auto-generated from OpenAPI specs in `spec.yaml` files * v0.3 and v0.4 API versions with separate specs * Additional manual `.mdx` files for navigation and custom content * **Guides** (`/guides/`): Step-by-step tutorials for specific tasks * **User Manual** (`/user-manual/`): Reference documentation for platform features * **SDKs** (`/sdks/`): Documentation for various quantum computing SDKs (Qiskit, Cirq, PennyLane, qBraid, etc.) * **Partners** (`/partners/`): Integration guides for cloud partners (AWS Braket, Azure Quantum, etc.) * **Snippets** (`/snippets/`): Reusable content blocks ### Key Configuration Files * `mint.json`: Mintlify configuration defining navigation, theming, and site structure * `cspell.json`: Spell checker configuration * `project-words.txt`: Custom dictionary for technical terms * OpenAPI specs: * `/api-reference/v0.3/spec.yaml` * `/api-reference/v0.4/spec-backends.yaml` * `/api-reference/v0.4/spec-api-users.yaml` ### Content Types 1. **API Reference**: Generated from OpenAPI specs, with `.mdx` files as navigation pointers 2. **Guides**: Focus on single, specific actions with step-by-step instructions 3. **User Manual**: Concise reference organized around core platform objects (Accounts, Backends, Jobs, Organizations, Projects) ## Style Guidelines * Use lowercase in titles: "Resetting your password" not "Resetting Your Password" * Prefer small, short sections with linkable headers * Always use `IONQ_API_KEY` as the environment variable name in examples * Content is written in MDX format (Markdown with JSX components) ## Navigation Management * All page navigation is defined in `mint.json` * Pages can be viewed locally before being added to navigation by accessing their URL directly * Use the `redirects` section in `mint.json` for URL changes ## Content Guidelines * Target audience: Quantum software developers using Python, Qiskit, Windows/Mac desktop users * Focus on practical, actionable content * Screenshots and media stored in `_media/` subdirectories * Use project-specific terminology found in `project-words.txt` * Local test environments can be run using the `mint` CLI tool, which can be installed with `npm i -g mint` if needed. * This project uses Mintlify to build and deploy the site. It's documentation can be found at [https://mintlify.com/docs](https://mintlify.com/docs) * When working on pages with API examples, try testing those examples using a local key if one is available. This can be accessed through a Bash environment variable in \$IONQ\_API\_KEY # Get Backends Source: https://docs.ionq.com/api-reference/v0.3/backends/get-backends api-reference/v0.3/spec.yaml get /backends Retrieve a list of all available backends. # Get a Characterization Source: https://docs.ionq.com/api-reference/v0.3/characterizations/get-a-characterization api-reference/v0.3/spec.yaml get /characterizations/{UUID} This endpoint retrieves a characterization. # Get All Backend Characterizations Source: https://docs.ionq.com/api-reference/v0.3/characterizations/get-all-backend-characterizations api-reference/v0.3/spec.yaml get /characterizations/backends/{backend} This endpoint retrieves an array of all available backend characterizations, with pagination. # Get the Most Recent Backend Characterization Source: https://docs.ionq.com/api-reference/v0.3/characterizations/get-the-most-recent-backend-characterization api-reference/v0.3/spec.yaml get /characterizations/backends/{backend}/current This endpoint retrieves the most recent backend characterization data available. # API Core Concepts Source: https://docs.ionq.com/api-reference/v0.3/core-concepts This page details some concepts specific to how the API works. There is also a more-general [platform glossary](/user-manual/glossary) as well as a [quantum-focused glossary on ionq.com](https://ionq.com/resources/glossary). ## Jobs A **job** is the basic unit of work on the IonQ cloud. Whether you're simulating a simple circuit, or submitting a program to run on our world-class hardware, you'll send it along as a job. *** ## Quantum Programs Quantum programs are collections of circuits to be run on a QPU. They are submitted to a job in the `input` parameter. Examples can be found on the [Writing Quantum Programs](/api-reference/v0.3/writing-quantum-programs) page. *** ## Metadata Updatable resources (such as a [Job](/api-reference/v0.3/jobs)) can store arbitrary metadata for your convenience — we store but ignore it. For example, you could tag different algorithms or projects for later analysis, or if you're building an app, tag jobs submitted by customers with a unique customer ID. You can specify up to 10 keys, with names up to 40 characters long and values up to 40000 characters long. ```json theme={null} { "metadata": { "custom_key": "a string, maximum 400 chars" }, "input": { ... } } ``` *** ## Authorization 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. For example: ``` Authorization: apiKey {your-api-key} ``` If you're new to managing API keys, [learn more in our guide](/guides/managing-api-keys). *** ## Pagination You can bulk fetch any resource (for example, [list all jobs](/api-reference/v0.3/jobs/get-jobs) you have access to). In addition to any specific query parameters those endpoints may support for filtering, all endpoints returning multiple resources take two parameters for pagination: next and limit. limit tells us how many objects to return; next identifies the next chunk of the iteration. When loading a paginated resource, you'll receive a next key with each page. Pass it to subsequent queries with a `next` querystring to fetch the next batch. ```bash theme={null} curl -H "Authorization: apiKey ..." "https://api.ionq.co/v0.3/jobs?limit=100&next=dce01d5c-987e-48e8-b2b7-41c24d69d711" { "jobs": [ ... ], "next": "38f525e4-f865-48f6-a996-dab85ba1f7b0" } ``` *** ## HTTP Responses IonQ uses standard HTTP response status codes to indicate the result of a request. ### Success A successful response will have a status code in the `2XX` range. Successful responses are documented above on a per-endpoint basis. ### Bad Request A request that contained invalid input data will have a `400` response status code and response data indicating the invalid items: ```json theme={null} { "statusCode": 400, "error": "Bad Request", "message": "\"some-parameter\" was invalid.", "validation": { "keys": [ "some-parameter" ], "source": "params" } } ``` ### Unauthorized A request that fails API Authentication will receive a `401`. See [Authorization](#authorization) for more details. ```json theme={null} { "statusCode": 401, "error": "Unauthorized Error", "message": "Invalid key provided. See https://docs.ionq.com/#authentication for details, or email support@ionq.co for help." } ``` ### Not Found A request whose resource does not exist will have a `404` response status code and some detail about the missing resource: ```json theme={null} { "statusCode": 404, "error": "Not Found Error", "message": "Resource not found. See https://docs.ionq.com/ for details, or email support@ionq.co for help." } ``` ### Internal Server Error Any unexpected errors are indicated by the `500` response status code. Internal service outage. Visit [https://status.ionq.co/](https://status.ionq.co/) to track this incident. ```json theme={null} { "statusCode": 500, "error": "Internal Server Error", "message": "Internal service outage. Visit https://status.ionq.co/ to track this incident." } ``` # v0.3 Error Codes Source: https://docs.ionq.com/api-reference/v0.3/error-codes When a request fails, the API will respond with an appropriate 400 or 500 error in the following format in the body of the response: ```javascript theme={null} { 'error': 'Error Name', 'message': 'A description of the specific error conditions.', 'statusCode': 400 } ``` | Error | Description | | --------------------- | -------------------------------------------------------------------------------------------- | | Bad Request | Generic request error. The message should indicate the specific parameter which was invalid. | | Forbidden | The request failed to authenticate the supplied API key | | Unauthorized | The supplied API key failed authorization for the requested resource | | Not Found | The specified resource does not exist or could not be found. | | Internal Server Error | A service was unexpectedly offline, unavailable, or failed in an unknown manner. | *** ## Job Errors The following errors are specific to the `/job` ([API reference](/api-reference/v0.3/jobs/)) resource: | Error | Description | | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | BillingError | Generic error inside of the billing service | | CompilationError | Generic failure in our compilation service | | ContractExpiredError | The billing service shows that the contract governing the key being used has expired | | DebiasingError | Unknown execution error when using debiasing (an IonQ-provided error mitigation technique) | | InternalError | An unattributable internal error | | NotEnoughQubits | The backend you are submitting to has fewer qubits than this job requires | | OptimizationError | Generic error in our optimization service | | PreflightError | Generic error during preflight checks. This most often occurs when the input circuit is syntax checked and includes malformed gates, commands, formats, or similar | | QuantumCircuitComplexityError | This failure occurs when the coherent program used to execute this circuit cannot be feasibly run on the system targeted. Reducing the number of gates requested can often resolve this issue. | | QuantumComputerError | Generic failure that occured while the job was being processed on-QPU | | QuotaExhaustedError | The billing system shows that your user, project, or organization has an inadequate credit balance to run this job | | SimulationError | Generic failure in our simulation service | | SimulationTimeout | Timeout error in our compilation service. This is most commonly caused by simulations that are too large for the service to simulate before hitting our runaway process timeout | | SystemCancel | A member of IonQ staff has manually cancelled your job. This most often occurs as a result of a customer request, but can sometimes represent manual resolution of an unknown failure mode | | TooLongPredictedExecutionTime | preflight error of a specific type: the predicted execution time for the circuit was longer than the single-job timeout duration for a given backend | | TooManyControls | The job submitted includes a multi-control gate with more control qubits (7 or more) than the target backend allows | | TooManyGates | Preflight error of a specific type: the job submitted includes more gates per circuit than the target backend allows | | TooManyShots | Preflight error of a specific type: the job submitted requested more shots than the target backend allows | | UnknownBillingError | Unknown error related to but not originating from our billing service. This most often means the service is briefly unavailable for some reason. | | UnsupportedGate | Preflight error of a specific type: the job submitted uses a gate that the target backend does not allow | *** # Introduction Source: https://docs.ionq.com/api-reference/v0.3/introduction Our API uses the [REST](https://en.wikipedia.org/wiki/Representational_State_Transfer) architectural style, which means we provide unsurprising, resource-oriented URLs and take advantage of built-in HTTP response codes, authentication, verbs, and other features. We allow cross-site requests from any domain, and return JSON responses. *** ## Working with APIs While you can work [directly](/guides/direct-api-submission) with our APIs if you'd like, most users will find it more convenient to work through one of the available SDKs. For new users, we tend to recommend [Qiskit](https://github.com/Qiskit/qiskit), and have provided a [getting started guide](/guides/qiskit) for it. *** ## System status We continuously report the status of our APIs and our QPU fleet at [https://status.ionq.co/](https://status.ionq.co/). On that page, you can subscribe for automated updates when we perform maintenance or experience an outage. System status is also displayed within the IonQ Quantum Cloud application on the [Backends](https://cloud.ionq.com/backends) page. # Cancel a Job Source: https://docs.ionq.com/api-reference/v0.3/jobs/cancel-a-job api-reference/v0.3/spec.yaml put /jobs/{UUID}/status/cancel Cancel the execution of a single job by ID. # Cancel many Jobs Source: https://docs.ionq.com/api-reference/v0.3/jobs/cancel-many-jobs api-reference/v0.3/spec.yaml put /jobs/status/cancel Cancel the execution of many jobs at once by passing a list of jobs. # Create a Job Source: https://docs.ionq.com/api-reference/v0.3/jobs/create-a-job api-reference/v0.3/spec.yaml post /jobs To submit a program to be simulated or executed on our quantum hardware, `POST` it to the `jobs` endpoint. # Delete a Job Source: https://docs.ionq.com/api-reference/v0.3/jobs/delete-a-job api-reference/v0.3/spec.yaml delete /jobs/{UUID} Permanently delete a job from our service. This cannot be undone. # Delete many Jobs Source: https://docs.ionq.com/api-reference/v0.3/jobs/delete-many-jobs api-reference/v0.3/spec.yaml delete /jobs Permanently remove many jobs from our platform. This cannot be undone. # Get a specific Job Source: https://docs.ionq.com/api-reference/v0.3/jobs/get-a-specific-job api-reference/v0.3/spec.yaml get /jobs/{UUID} Retrieve a specific job by UUID. # Get a Job's output Source: https://docs.ionq.com/api-reference/v0.3/jobs/get-a-specific-jobs-output api-reference/v0.3/spec.yaml get /jobs/{UUID}/results Retrieve a specific job's results by UUID. # Get Jobs Source: https://docs.ionq.com/api-reference/v0.3/jobs/get-jobs api-reference/v0.3/spec.yaml get /jobs **NOTE**: If request filters are provided, this endpoint will limit responses to 1 or more specific jobs based on those filters.

This endpoint retrieves all jobs this API key is authorized to view. # Migrating from old versions Source: https://docs.ionq.com/api-reference/v0.3/migrating-from-old-versions ### Breaking changes * Body has been renamed to `input`, and is always a JSON payload. The `format` field in input replaces lang as a means of controlling what kind of input is being run. * Results are no longer served alongside the job body when fetching jobs; now use the results\_url field to fetch. * *(v0.1 only)* **Calibrations** endpoints has been deprecated in favor of [Characterizations](/api-reference/v0.3/characterizations). ### New features * Error mitigation is now controllable via API. Debiasing can improve performance via randomized qubit mappings and intelligent post-processing of noise. * Ability to specify target hardware generation on Job creation. (e.g. `qpu.aria-1`) ## Non-breaking changes * Histogram example expanded to include scientific notation for a JSON numeric value. # Multicircuit Jobs Source: https://docs.ionq.com/api-reference/v0.3/multicircuit-jobs This guide covers everything from setting up a multicircuit job, submitting it to IonQ's backend, and retrieving the results. Jobs contain a circuit to be executed on a QPU, and in the case of *multicircuit* jobs, multiple circuits are being submitted in a single job payload. The advantage of this approach is that it simplifies the submission process, allowing for example, all of the circuits of a gradient calculation to be submitted in a single HTTP request, instead of over hundreds. When submitting work from a local environment with a poor internet connection, this can also help overcome job submissions failing intermittently from network issues. To ensure smooth processing, please format your quantum programs in `ionq.circuit.v0` as demonstrated below. ## Creating a Multicircuit Job Below is a JSON object that describes a multicircuit job for IonQ's simulator. This job includes two distinct circuits: ```json theme={null} { "target": "simulator", "shots": 1024, "name": "Multicircuit Job Example", "input": { "format": "ionq.circuit.v0", "gateset": "qis", "qubits": 3, "circuits": [ { "name": "Circuit 1", "circuit": [ { "gate": "rz", "targets": [0], "rotation": -0.7853981633974474 }, { "gate": "ry", "targets": [0], "rotation": 3.141592653589793 } ] }, { "name": "Circuit 2", "circuit": [ { "gate": "h", "targets": [1] }, { "gate": "x", "targets": [2], "controls": [1] } ] } ] } } ``` ## Submitting the Job To submit this multicircuit job to IonQ, use the following `curl` command. Make sure to replace `your-api-key` with your actual API key: ```bash theme={null} curl -X POST "https://api.ionq.co/v0.3/jobs" \ -H "Authorization: apiKey your-api-key" \ -H "Content-Type: application/json" \ -d '{...}' # JSON data from the creation step ``` ### Expected Response You should receive a JSON response containing the job ID and status, similar to this: ```json theme={null} { "id": "unique-job-id", "status": "ready", "request": 1234567890 } ``` ## Retrieving Job Results Once the job is complete, fetch the results using the job's UUID provided in the job submission response: ```bash theme={null} curl "https://api.ionq.co/v0.3/jobs/unique-job-id/results" \ -H "Authorization: apiKey your-api-key" ``` ### Result Example ```json theme={null} { "circuit1-uuid": { "0": 0.5, "6": 0.5 }, "circuit2-uuid": { "1": 1.0 } } ``` Each UUID represents a circuit within your job, and the results show the probability distribution of the qubit measurements. If you are interested in implementing these steps using the Qiskit SDK, check out this detailed [multicircuit guide with Qiskit and IonQ](https://docs.ionq.com/guides/sdks/qiskit#submitting-multiple-circuits-in-a-single-job). # Using native gates with the IonQ API Source: https://docs.ionq.com/api-reference/v0.3/native-gates-api Learn how to use our hardware-native gateset to run a circuit with the IonQ API This guide covers how to use IonQ's native gates via our API. To learn more about what the native gates are and when to use them, refer to our guide on [getting started with native gates](/guides/getting-started-with-native-gates). Building and submitting circuits using IonQ's hardware-native gateset enables you to bypass our compiler and optimizer, providing more control and transparency than the default abstract gateset (though often at the cost of performance and convenience). Before working with native gates, we recommend reviewing our guides on [Getting Started with Native Gates](/guides/getting-started-with-native-gates) and [Writing Quantum Programs](/api-reference/v0.3/writing-quantum-programs). Native gates are also supported in [Qiskit](/sdks/qiskit/native-gates-qiskit), [Cirq](/sdks/cirq/native-gates-cirq), [PennyLane](/sdks/pennylane/native-gates-pennylane), and [qBraid](/sdks/qbraid/native-gates-qbraid). This is an advanced-level feature. Using the hardware-native gate interface without a thorough understanding of quantum circuits is likely to result in less-optimal circuit structure and worse algorithmic performance overall than using our abstract gate interface. *** ## Native gate JSON specification If you have used our abstract gate specification, the native gate specification should feel quite familiar. Its parameters are slightly different though, and we'll walk through them here. To specify a circuit using native gates, you must do two things: 1. Set the parameter `gateset` to `"native"` inside the circuit body. This is an optional parameter that defaults to `"qis"`, which signifies our abstract gateset based on the general-purpose gates of quantum information science (QIS). 2. Your `circuit` array must only use native gates. These are formatted similar to [QIS gates](/api-reference/v0.3/writing-quantum-programs#supported-gates). The only gates allowed in a native gate circuit are `gpi`, `gpi2`, and either `ms` or `zz` depending on the backend. You cannot mix and match native and abstract gates in the same circuit. Much more detailed information about the native gate definitions can be found in our [native gates guide](/guides/getting-started-with-native-gates#introducing-the-native-gates) ### Parameters Available parameters (depending on gate type) are: * `gate`: a string representation of the gate name. This works just like the abstract gate interface, but you can only use the available native gates: `gpi`, `gpi2`, `ms`, and `zz`. If you submit any other gates in the array, you'll receive an error. * `phase` or `phases`: a number representation of the phase parameter or parameters in the gate. It is represented in *turns*, where one turn is 2π radians. We accept floating point values between -1 and 1 for this parameter. * `angle`: an optional number representation of the angle parameter, available for the MS gate only. This value is also represented in turns and can range from 0 to 0.25 (fully entangling), with 0.25 being the default. * `target` or `targets`: the number index (starting from zero) of the qubit to apply the gate to. For two-qubit gates, use an array of qubit indices labeled `targets` instead. The parameters in the IonQ native gate specification are always defined in *turns*, not in radians. One turn is 2π radians. ### Gates | Gate | Description | Parameters | | ------ | ----------------------------------------------------------------------------------------------------- | --------------------------------------- | | `gpi` | [GPI gate](/guides/getting-started-with-native-gates#gpi) | `phase`, `target` | | `gpi2` | [GPI2 gate](/guides/getting-started-with-native-gates#gpi2) | `phase`, `target` | | `ms` | [Mølmer–Sørensen gate](\(/guides/getting-started-with-native-gates#ms-gates\)) (only on Aria systems) | `phases`, `angle` (optional), `targets` | | `zz` | [ZZ gate](\(/guides/getting-started-with-native-gates#zz-gates\)) (only on Forte systems) | `angle`, `targets` | *** ## Basic example Here's a simple example circuit using native gates with the IonQ API. ```json theme={null} { "name": "Hello native gates!", "shots": 1024, "target": "simulator", "input": { "gateset": "native", "qubits": 2, "circuit": [ { "gate": "ms", "targets": [0, 1], "phases": [0, 0] }, { "gate": "gpi", "phase": 0, "target": 0 }, { "gate": "gpi2", "phase": 0, "target": 1 } ] } } ``` Like any other [API job](/guides/direct-api-submission), you can save this to a file, like `native_gates_circuit.json`, and submit it: ```bash theme={null} curl -X POST "https://api.ionq.co/v0.3/jobs" \ -H "Authorization: apiKey $IONQ_API_KEY" \ -H "Content-Type: application/json" \ -d @native_gates_circuit.json ``` *** ## Additional resources * [Direct API submission](/guides/direct-api-submission) * [API reference for POST /jobs](/api-reference/v0.3/jobs/create-a-job) * [Writing quantum programs](/api-reference/v0.3/writing-quantum-programs) * [Getting started with native gates](/guides/getting-started-with-native-gates) * Using native gates with [Qiskit](/sdks/qiskit/native-gates-qiskit), [Cirq](/sdks/cirq/native-gates-cirq), [PennyLane](/sdks/pennylane/native-gates-pennylane), and [qBraid](/sdks/qbraid/native-gates-qbraid) # Get an Organization’s Report Source: https://docs.ionq.com/api-reference/v0.3/reports/get-an-organizations-report api-reference/v0.3/spec.yaml get /report/organizations/{org_id} Get a usage report for the given organization from the start_date and end_date, detailing how much usage went to each QPU during that period. If no start_date or end_date are provided, period defaults to last 30 days until current time. # Writing Quantum Programs Source: https://docs.ionq.com/api-reference/v0.3/writing-quantum-programs For the best results, please submit quantum programs in the `ionq.circuit.v0` format, as demonstrated below. In the compilation and optimization process, your submitted circuit will be converted to an equivalent, optimized circuit expressed in terms of IonQ's native gates, which may involve combining or canceling out some operations. If you wish to guarantee that the quantum computer executes the exact series of operations that you define, you can submit a circuit using our [native gates](/api-reference/v0.3/native-gates-api), which will bypass our compiler. For more examples and the full API specification for defining circuits, refer to [the API reference](/api-reference/v0.3/jobs/create-a-job). To write a quantum program using [Qiskit](/guides/sdks/qiskit) or another SDK, refer to our SDK guides. *** ## Bell State We can create a maximally entangled [Bell state](https://en.wikipedia.org/wiki/Bell_state) by applying a Hadamard gate to a single qubit, and applying a controlled-not gate to a second qubit. Half of the time the second qubit will be measured as $|0⟩$, the other half will be measured as $|1⟩$. ```json theme={null} { "format": "ionq.circuit.v0", "gateset": "qis", // The fields above are optional, as they are the default. "qubits": 2, "circuit": [ { "gate": "h", "target": 0 }, { "gate": "cnot", "target": 1, "control": 0 } ] } ``` *** ## GHZ State We can create a three qubit [GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state) by first applying a Hadamard gate to a single qubit, and then using it as the control qubit for a series of controlled-not gates. ```json theme={null} { "qubits": 4, "circuit": [ { "gate": "h", "target": 0 }, { "gate": "cnot", "control": 0, "target": 1 }, { "gate": "cnot", "control": 0, "target": 2 }, { "gate": "cnot", "control": 0, "target": 3 } ] } ``` *** ## Toffoli gate The [Toffoli gate](https://en.wikipedia.org/wiki/Toffoli_gate), or controlled-controlled-not gate, is a universal reversible logic gate. We can simply apply a cnot to our target qubit, with two control qubits provided via array. ```json theme={null} { "qubits": 3, "circuit": [ { "gate": "cnot", "target": 0, "controls": [1, 2] } ] } ``` *** ## Supported Gates For actual execution, gates will be compiled into optimal operations for our trapped ion hardware. For convenience, we provide a more expressive gateset for programming. We accept these gates as well as their controlled and multi-controlled variants: | Gate | Description | | ------ | ---------------------------------------------- | | `x` | Pauli X gate | | `y` | Pauli Y gate | | `z` | Pauli Z gate | | `rx` | X-axis rotation | | `ry` | Y-axis rotation | | `rz` | Z-axis rotation | | `h` | Hadamard gate | | `not` | Convenient alias for Pauli-X gate | | `cnot` | Convenient alias for controlled-not gate | | `s` | S gate | | `si` | Conjugate transpose of S gate | | `t` | T gate | | `ti` | Conjugate transpose of T gate | | `v` | Square root of not gate | | `vi` | Conjugate transpose of square-root-of-not gate | | `swap` | Swaps two qubits | Each operation in a circuit specifies a `gate` and a `target` qubit index (or a list of multiple `targets`). Rotation gates also specify a `rotation` in radians. In addition, any gate can be expressed as a controlled gate by specifying a `control` qubit, or as its multi-controlled variant by specifying a list of up to seven `controls` (for any gate except `swap`). This can often be used to simplify the circuit's description. In general, circuits expressed in fewer QIS gates will be further optimized for runtime, so using multi-controlled variants of gates is recommended. Examples: * Hadamard gate: `{"gate": "h", "target": 0}` * Controlled-not gate: `{"gate": "cnot", "target": 1, "control": 0}` * Toffoli gate (multi-controlled not gate): `{"gate": "cnot", "target": 0, "controls": [1, 2]}` * Rx gate with $\pi/2$ rotation: `{"gate": "rx", "target": 0, "rotation": 1.5708}` * Swap gate: `{"gate": "swap", "targets": [0,1]}` For more examples and the full API specification for defining circuits, refer to [the API reference](/api-reference/v0.3/jobs/create-a-job). ## Native Specification For information about writing quantum programs using IonQ's hardware-native gate set, refer to our guides on [getting started with native gates](/guides/getting-started-with-native-gates) and [using native gates with the IonQ API](/api-reference/v0.3/native-gates-api). *** ## Other Formats (experimental) Support for submitting programs in [QASM/OpenQASM](https://github.com/Qiskit/openqasm/) and [Quipper](https://www.mathstat.dal.ca/~selinger/quipper/) is currently experimental. If you use these languages, we will compile your code to a logically-equivalent representation using our [supported gates](#supported-gates). (For billing purposes, we'll calculate your program's resource requirements **after** it's been compiled this way.) ### OpenQASM ```json theme={null} { "format": "openqasm", "data": "string" } ``` ### QASM ```json theme={null} { "format": "qasm", "data": "string" } ``` ### Quipper ```json theme={null} { "format": "quipper", "data": "string" } ``` *** Is there a language format you'd like to see supported? [Drop us a line](mailto:support@ionq.com) and let us know. # Get a Characterization Source: https://docs.ionq.com/api-reference/v0.4/backends/get-a-characterization api-reference/v0.4/spec-backends.yaml get /backends/{backend}/characterizations/{UUID} Retrieve detailed performance data for a characterization. Retrieve detailed performance data for a specific [characterization](/user-manual/glossary#characterizations) of a [backend](/user-manual/glossary#backend). This includes comprehensive fidelity metrics, gate error rates, and timing information that can help you understand the quantum hardware's performance at a particular point in time. Learn more about [interpreting characterization data](/user-manual/backends#characterizations). # Get a Backend Source: https://docs.ionq.com/api-reference/v0.4/backends/get-backend-by-name api-reference/v0.4/spec-backends.yaml get /backends/{backend} Retrieve detailed information about a specific backend. Retrieve detailed information about a specific [backend](/user-manual/glossary#backend) including its current status, qubit count, queue times, and performance characteristics. Use this to check if a backend is available before submitting jobs or to get technical specifications. Learn more about [backend specifications](/user-manual/backends). # Get Backends Source: https://docs.ionq.com/api-reference/v0.4/backends/get-backends api-reference/v0.4/spec-backends.yaml get /backends List all available backends including QPUs and simulators. List all available [backends](/user-manual/glossary#backend) including both [QPUs](/user-manual/glossary#qpu) and [simulators](/user-manual/glossary#simulator). This shows each backend's current status (available, unavailable, degraded), number of qubits, average queue time, and links to performance [characterizations](/user-manual/glossary#characterizations). Learn more about [available backends](/user-manual/backends). # Get All Backend Characterizations Source: https://docs.ionq.com/api-reference/v0.4/backends/get-characterizations api-reference/v0.4/spec-backends.yaml get /backends/{backend}/characterizations Retrieve historical characterizations for a backend. Retrieve historical performance [characterizations](/user-manual/glossary#characterizations) for a specific [backend](/user-manual/glossary#backend) with optional date filtering and pagination. Characterizations provide snapshots of quantum hardware performance including fidelity measurements and gate operation speeds over time. Learn more about [backend characterizations](/user-manual/backends#characterizations). # API v0.4 Reference Source: https://docs.ionq.com/api-reference/v0.4/introduction The IonQ Quantum Cloud API lets you submit quantum circuits, manage jobs, and access quantum computing resources programmatically. 🎉 **API v0.4 is now available in beta!** Check out the [migration guide](/api-reference/v0.4/migration-from-v0.3) to for a high-level overview. This is only available to select customers today, but reach out to [support@ionq.com](mailto:support@ionq.com) to have it enabled for your organization. Note that during the beta, resources are subject to change as we gather bug reports and feedback. Please let us know if you run into any bugs or have other feedback for us. Send bug reports to [support@ionq.com](mailto:support@ionq.com) or feel free to drop a report in the [Community Slack](https://join.slack.com/t/ionqcommunity/shared_invite/zt-2ohj4fkvb-ErVKebhkwaP7S~lt2Gq0_w). ## Quick Start * **New to IonQ?** Most users start with an [SDK like Qiskit](/sdks) rather than calling the API directly. * **Migrating from v0.3?** Check our [migration guide](/api-reference/v0.4/migration-from-v0.3) for breaking changes and new features. * **Need help?** Join our [community Slack](https://join.slack.com/t/ionqcommunity/shared_invite/zt-2ohj4fkvb-ErVKebhkwaP7S~lt2Gq0_w) or contact [support@ionq.com](mailto:support@ionq.com). *** ## What's New in v0.4 * **Enhanced cost tracking** - New dedicated endpoint for job billing details * **Improved results structure** - Cleaner separation of job metadata and probability data * **Better backend organization** - Characterizations now nested under backends * **Streamlined pagination** - Consistent filtering across list endpoints *** ## System Status Check real-time API and hardware status at [status.ionq.co](https://status.ionq.co) or view backend availability in the [Quantum Cloud console](https://cloud.ionq.com/backends). # Cancel a job Source: https://docs.ionq.com/api-reference/v0.4/jobs/cancel-job https://api.ionq.co/v0.4/api-docs PUT /jobs/{UUID}/status/cancel Stop the execution of job in queue. Stop the execution of a [job](/user-manual/glossary#job) that is currently queued or running. Canceled jobs will not consume additional [usage](/user-manual/glossary#usage) time, but any partial execution that has already occurred may still be billed. # null Source: https://docs.ionq.com/api-reference/v0.4/jobs/cancel-jobs https://api.ionq.co/v0.4/api-docs PUT /jobs/status/cancel Cancel multiple jobs simultaneously. Cancel multiple [jobs](/user-manual/glossary#job) simultaneously by providing a list of job UUIDs. This is useful for batch operations when you need to stop several queued or running jobs at once. # null Source: https://docs.ionq.com/api-reference/v0.4/jobs/create-job https://api.ionq.co/v0.4/api-docs POST /jobs Submit a quantum circuit to run on a backend. Submit a quantum [circuit](/user-manual/glossary#circuit) to run on a [backend](/user-manual/glossary#backend) by creating a new [job](/user-manual/glossary#job). You can specify the number of [shots](/user-manual/glossary#shots), target backend (QPU or simulator), and optional settings like error mitigation. The job will be queued and executed according to the platform's scheduling system. Learn more about [submitting circuits via API](/guides/direct-api-submission). # null Source: https://docs.ionq.com/api-reference/v0.4/jobs/delete-job https://api.ionq.co/v0.4/api-docs DELETE /jobs/{UUID} Permanently remove a job and its associated data. Permanently remove a [job](/user-manual/glossary#job) and its associated data from your [project](/user-manual/glossary#project). This action cannot be undone and will delete all job metadata, results, and history. # null Source: https://docs.ionq.com/api-reference/v0.4/jobs/delete-jobs https://api.ionq.co/v0.4/api-docs DELETE /jobs Permanently remove multiple jobs and their data. Permanently remove multiple [jobs](/user-manual/glossary#job) and their associated data by providing a list of job UUIDs. This bulk operation cannot be undone and will delete all job metadata, results, and history for the specified jobs. # null Source: https://docs.ionq.com/api-reference/v0.4/jobs/get-job https://api.ionq.co/v0.4/api-docs GET /jobs/{UUID} Retrieve detailed information about a specific job. Retrieve detailed information about a specific [job](/user-manual/glossary#job) using its unique identifier. This returns the job's current [status](/user-manual/glossary#job-status), execution details, results (if completed), and metadata including timing information, gate counts, and failure details if applicable. Learn more about [viewing job results](/user-manual/jobs#viewing-results). # null Source: https://docs.ionq.com/api-reference/v0.4/jobs/get-job-cost https://api.ionq.co/v0.4/api-docs GET /jobs/{UUID}/cost Retrieve billing information for a specific job. Retrieve the billing information for a specific [job](/user-manual/glossary#job), including both estimated and actual [cost](/user-manual/glossary#cost) in USD. This shows how much [usage](/user-manual/glossary#usage) time the job consumed and the corresponding charges based on your [contract](/user-manual/glossary#contract) rates. Learn more about [billing and budgets](/user-manual/projects#billing-and-budgets). # null Source: https://docs.ionq.com/api-reference/v0.4/jobs/get-job-estimate https://api.ionq.co/v0.4/api-docs GET /jobs/estimate Retrieve cost estimate for a job. # null Source: https://docs.ionq.com/api-reference/v0.4/jobs/get-jobs https://api.ionq.co/v0.4/api-docs GET /jobs List all jobs in your project with optional filtering. List all [jobs](/user-manual/glossary#job) in your [project](/user-manual/glossary#project) with optional filtering by [job status](/user-manual/glossary#job-status) (submitted, ready, started, canceled, failed, completed). This provides a paginated overview of your job history including basic metadata and timing information for each job. # null Source: https://docs.ionq.com/api-reference/v0.4/jobs/get-jobs-probabilities-aggregated https://api.ionq.co/v0.4/api-docs GET /jobs/{UUID}/results/probabilities/aggregated Retrieve aggregated probability results from jobs. # Migrating to API v0.4 Source: https://docs.ionq.com/api-reference/v0.4/migration-from-v0.3 See what's new in API v0.4 and how to migrate from v0.3. This guide covers the key changes when upgrading from IonQ's API v0.3 to v0.4. The new version introduces several structural improvements and new features while maintaining compatibility for most existing workflows. *** ## Compatibility Notes ### Backward Compatibility * **Base functionality**: Core job submission and retrieval workflows remain similar * **Authentication**: API key authentication unchanged * **Job lifecycle**: Job statuses and workflow unchanged * **Circuit formats**: Input circuit formats remain compatible ### Breaking Changes Requiring Updates 1. **Result retrieval**: Must update to use new probabilities endpoint - change from parsing `output` field to calling `GET /jobs/{UUID}/results/probabilities` 2. **Characterization URLs**: All characterization endpoints require URL updates to new nested structure under `/backends/` 3. **Date parameters**: Update timestamp formats in characterization filtering from Unix timestamps to ISO date strings 4. **Response parsing**: Update code to handle new response field structure including `results.probabilities.url` field *** ## Jobs ### Enhanced Results Structure Job results are now organized into dedicated sub-endpoints with `results.probabilities.url` field instead of direct `output` field, requiring updates to result retrieval logic to use the new `GET /jobs/{UUID}/results/probabilities` endpoint. **v0.3**: Job results included directly in job response with `output` field **v0.4**: Results moved to dedicated endpoint structure with `results.probabilities.url` field ### New Job Cost Endpoint v0.4 introduces `GET /jobs/{UUID}/cost` for retrieving detailed billing information including estimated and actual costs in USD, enabling better cost tracking and budget management at the job level. ### Response Field Additions Job responses now include additional fields: `child_job_ids`, `session_id`, and timing prediction fields for improved job monitoring and workflow management. ### Endpoint Naming Updates * **Job result retrieval**: `GET /jobs/{UUID}/output` → `GET /jobs/{UUID}/results/probabilities` *** ## Backends ### Restructured Characterizations API Characterizations now use a more intuitive REST structure with endpoints nested under backends and pagination support. **v0.3 Endpoints:** * `GET /characterizations/{backend}/all` * `GET /characterizations/{backend}/current` * `GET /characterizations/{characterization_id}` **v0.4 Endpoints:** * `GET /backends/{backend}/characterizations` (with pagination) * `GET /backends/{backend}/characterizations/{characterization_id}` * `GET /backends/{backend}` (individual backend details) ### Enhanced Backend Information Backend responses now include `degraded` status flag and `characterization_id` linking for better backend selection and status monitoring capabilities. ### Date Parameter Format Changes Characterization filtering now uses ISO date strings (e.g., `start=2025-12-31`) instead of Unix timestamps (e.g., `start=1585713600000`). ### Query Parameter Enhancements Characterization endpoints now include `limit` and `page` parameters for improved pagination control alongside the updated date string format. # null Source: https://docs.ionq.com/api-reference/v0.4/sessions/create-session https://api.ionq.co/v0.4/api-docs POST /sessions Create a new session for quantum computing jobs. This feature is in beta and only available to select customers today, reach out to [support@ionq.com](mailto:support@ionq.com) to request enabling it on your organization. Note: Beta features are subject to change as we gather feedback. Please report any bugs or send feedback to [support@ionq.com](mailto:support@ionq.com) or feel free to drop a report in the [Community Slack](https://join.slack.com/t/ionqcommunity/shared_invite/zt-2ohj4fkvb-ErVKebhkwaP7S~lt2Gq0_w). # null Source: https://docs.ionq.com/api-reference/v0.4/sessions/end-session https://api.ionq.co/v0.4/api-docs POST /sessions/{session_id}/end End a session by its id and cancel any incomplete jobs in queue This feature is in beta and only available to select customers today, reach out to [support@ionq.com](mailto:support@ionq.com) to request enabling it on your organization. Note: Beta features are subject to change as we gather feedback. Please report any bugs or send feedback to [support@ionq.com](mailto:support@ionq.com) or feel free to drop a report in the [Community Slack](https://join.slack.com/t/ionqcommunity/shared_invite/zt-2ohj4fkvb-ErVKebhkwaP7S~lt2Gq0_w). # null Source: https://docs.ionq.com/api-reference/v0.4/sessions/get-session https://api.ionq.co/v0.4/api-docs GET /sessions/{session_id} Retrieve detailed information about a specific session. This feature is in beta and only available to select customers today, reach out to [support@ionq.com](mailto:support@ionq.com) to request enabling it on your organization. Note: Beta features are subject to change as we gather feedback. Please report any bugs or send feedback to [support@ionq.com](mailto:support@ionq.com) or feel free to drop a report in the [Community Slack](https://join.slack.com/t/ionqcommunity/shared_invite/zt-2ohj4fkvb-ErVKebhkwaP7S~lt2Gq0_w). # null Source: https://docs.ionq.com/api-reference/v0.4/sessions/get-sessions https://api.ionq.co/v0.4/api-docs GET /sessions List and filter all sessions in your organization. This feature is in beta and only available to select customers today, reach out to [support@ionq.com](mailto:support@ionq.com) to request enabling it on your organization. Note: Beta features are subject to change as we gather feedback. Please report any bugs or send feedback to [support@ionq.com](mailto:support@ionq.com) or feel free to drop a report in the [Community Slack](https://join.slack.com/t/ionqcommunity/shared_invite/zt-2ohj4fkvb-ErVKebhkwaP7S~lt2Gq0_w). # Get current key Source: https://docs.ionq.com/api-reference/v0.4/util/whoami api-reference/v0.4/spec-api-users.yaml get /whoami Gets information about the current token. # null Source: https://docs.ionq.com/guides/cloud-usage # Connecting a SAML Identity Provider Source: https://docs.ionq.com/guides/connecting-saml-identity-providers Enhance security and simplify user management by authenticating with your SAML-based SSO provider IonQ Quantum Cloud can be integrated with any [SAML 2.0](https://en.wikipedia.org/wiki/SAML_2.0) compatible Single sign-on (SSO) provider, such as Azure Active Directory, Okta, or JumpCloud. By federating IonQ with your Provider, you can easily provide access to anyone in your organization and manage that access centrally. *** ## Before you begin To successfully complete this integration, you'll need: * The ability to create or register a new Application in your Identity system * Your Identity provider's Entity ID, SAML SSO URL, and Public Key certificate. *** ## Configuring Your Identity Provider Your Identity Provider must be configured to recognize IonQ Quantum Cloud as a new application. How this works varies by provider, but typically you'll find an Applications section within your Admin control panel. When you create the new application, you'll set the following: 1. Assertion Consumer Service (ACS) URL: `https://ionq.firebaseapp.com/__/auth/handler` 2. Application Entity ID: `app.ionq.com` Once the App has been added to your system, you'll be able to create access rules for your users. Again, how this is configured varies by provider, but typically App access is set for either specific roles or specific users. *** ## IonQ Configuration Once the App has been added on the Identity Provider side, email the following information to [support@ionq.co](mailto:support@ionq.co): > 1. Identity provider's Entity ID: A URI that identifies the identity provider. > 2. Identity provider's SAML SSO URL: The URL of the identity provider's sign-in page. > 3. Identity provider's public key certificate: The certificate used to validate tokens signed by the identity provider. Once received, our team will configure the provider in our production environment within 2 business days. *** ## Testing and Support Once we've registered your provider with IonQ Quantum Cloud, the IonQ team will get in touch to work with you so you can debug and test the configuration before enabling it on your organization. If you need further assistance, or have any questions about this process, please reach out at [support@ionq.co](mailto:support@ionq.co) or contact the Customer Success manager for your Organization. # Direct API Submissions Source: https://docs.ionq.com/guides/direct-api-submission Learn how to submit jobs directly to the IonQ API v0.4 Most users will submit jobs and interact with IonQ through an SDK like [Qiskit](/sdks/index#qiskit), but in some instances direct API submission is preferred. This guide walks you through the basics of using the IonQ Quantum Cloud to write and run quantum programs. You'll learn how to use the latest v0.4 Quantum Cloud API to define quantum circuits, submit them as jobs, and access the results. ## Before you begin Before you get started, ensure you have an [IonQ Quantum Cloud](https://cloud.ionq.com) account and have created an API key. For guidance on setting up and managing your API keys, please refer to our [dedicated guide](/guides/managing-api-keys). This guide assumes you have completed these steps and stored your API key as a local environment variable named `IONQ_API_KEY`. *** ## Writing a quantum circuit We'll need to create a quantum circuit to submit as your first job. Let's use a simple [GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state) using three qubits, first applying a Hadamard gate to a single qubit, and then using it as the control qubit for a series of controlled-NOT gates on the other two. A three-qubit GHZ circuit can be visualized like this: A visualization of a Greenberger-Horne-Zeilinger (GHZ) state. In IonQ's language-agnostic JSON circuit representation, the circuit looks like this: ```json theme={null} { "input": { "qubits": 3, "gateset": "qis", "circuit": [ { "gate": "h", "target": 0 }, { "gate": "cnot", "control": 0, "target": 1 }, { "gate": "cnot", "control": 0, "target": 2 } ] } } ``` *** ## Submitting a quantum circuit as a job For the purposes of this guide we'll use `curl` on the command line, but in the real world example, you'd likely want to use an [SDK](/sdks/index). Before submitting our circuit, we need to provide some additional information. This includes specifying the circuit type, the number of times the circuit should be executed (shots), and the desired backend for the job (e.g., `simulator` or `qpu.aria-1`). We can also assign a name to the job for easier reference. For a full list of options that can be passed to this resource, check out the API reference for [POST /jobs](/api-reference/v0.4/jobs/create-job). In this case, we'll submit a job to the simulator so that we get our results quickly: ```json theme={null} { "type": "ionq.circuit.v1", "name": "Hello many worlds", "shots": 1024, "backend": "simulator", "input": { "qubits": 3, "gateset": "qis", "circuit": [ { "gate": "h", "target": 0 }, { "gate": "cnot", "control": 0, "target": 1 }, { "gate": "cnot", "control": 0, "target": 2 } ] } } ``` Paste this in your text editor of choice and then save it using a memorable name—something like `ghz-job.json`. We're now ready to submit our job to the IonQ Quantum Cloud API. We'll use a `POST` request to send our JSON job data to the job creation endpoint. This request will include two headers: one for authorization using the API key we created earlier, and another to specify that the request body is in JSON format. In this example, we give the `backend` key the value `simulator`, which sends the job to our QPU simulator: ```bash theme={null} curl -X POST "https://api.ionq.co/v0.4/jobs" \ -H "Authorization: apiKey $IONQ_API_KEY" \ -H "Content-Type: application/json" \ -d @ghz-job.json ``` This will return a response similar to the following: ```json theme={null} { "id": "7135ca98-176f-48c9-8616-8f53ec505028", "status": "submitted", "session_id": null } ``` The returned `id` can then be used to manage the submitted job, including [canceling it](/api-reference/v0.4/jobs/cancel-job) and [checking its status](/api-reference/v0.4/jobs/get-job). *** ## Retrieving a job status To retrieve the status of a job, we can use a `GET` request to its unique resource URL, identified by the job ID: ```bash theme={null} curl "https://api.ionq.co/v0.4/jobs/{your-job-id}" \ -H "Authorization: apiKey $IONQ_API_KEY" ``` Remember to replace `{your-job-id}` with the ID you just got back. This request retrieves the current status of the job. Because we submitted the job to the simulator, it should be completed almost immediately. If you submitted the job to a QPU, you'll need to wait for it to progress through the queue. The job status response to our `GET` request will resemble the following: ```json theme={null} { "id": "7135ca98-176f-48c9-8616-8f53ec505028", "submitted_by": "65e8b97c521dcf001299126b", "name": "Hello many worlds", "status": "completed", "backend": "simulator", "qubits": 3, "circuits": 1, "gate_counts": { "1q": 1, "2q": 2 }, "cost_usd": 0, "project_id": "428499cb-c392-4ab1-ad8e-c954a1a99ff5", "created_time": "2024-06-13T21:02:31Z", "started_time": "2024-06-13T21:02:34Z", "completed_time": "2024-06-13T21:02:34Z", "execution_time": 78, "predicted_execution_time": 8, "shots": 1024, "session_id": null, "child_job_ids": [] } ``` ## Retrieving job results With the job completed, we can retrieve the results using the probabilities endpoint: ```bash theme={null} curl "https://api.ionq.co/v0.4/jobs/{your-job-id}/results/probabilities" \ -H "Authorization: apiKey $IONQ_API_KEY" ``` This will return a dictionary containing the job results: ```json theme={null} { "0": 0.4619140625, "1": 0.017578125, "2": 0.0185546875, "3": 0.0244140625, "4": 0.0185546875, "5": 0.025390625, "6": 0.0107421875, "7": 0.4228515625 } ``` The results request provides a histogram representing the probabilities of each measured state across all 1024 shots. It's important to note that this histogram is sparse, meaning it only includes data for outcomes that were actually measured. For example, if you ran 1024 shots of a 3-qubit circuit, there are 8 possible outcomes (000, 001, 010, 011, 100, 101, 110, 111). However, if only states 000, 011, and 111 were measured, the histogram would only contain entries for those states, omitting the others. Additionally, the output keys are formatted as big-endian integers, where the leftmost bit corresponds to the qubit with index zero from the submitted program. For example, 0 represents 000, 2 represents 010, 3 represents 011, and so on. ## Getting job cost information API v0.4 also provides a dedicated endpoint to retrieve detailed billing information for a job: ```bash theme={null} curl "https://api.ionq.co/v0.4/jobs/{your-job-id}/cost" \ -H "Authorization: apiKey $IONQ_API_KEY" ``` This will return cost details including estimated and actual costs in USD. *** ## Additional Resources If you're working on your own tools to interact with the API, the full [API Reference](/api-reference/v0.4) has details on HTTP verbs and endpoints, expected response formats, and other features not covered in this guide. Additionally, our [best practices page](https://ionq.com/best-practices) provides detailed instructions for getting the most out of our trapped-ion systems, and our [QPU submission checklist](/guides/qpu-submission-checklist) is great to run through before submitting a job to one of our QPUs. # IonQ API Key Management with dotenv Integration Source: https://docs.ionq.com/guides/dotenv-project-api-keys Discover how to effortlessly manage IonQ API keys across various projects by leveraging dotenv's automatic loading feature, enhancing security and codebase cleanliness. ## Leveraging dotenv for IonQ API Key Management Storing and managing API keys securely is paramount in software development, especially when dealing with sensitive services like IonQ's quantum computing API. There are a couple of methods for securely storing your IonQ API key where integrations like `qiskit_ionq` can automatically find it: you can [store it locally in an environment variable on your system](/guides/managing-api-keys#storing-keys) as described in our main API key guide, or use dotenv as shown here. This guide introduces a streamlined approach to handle IonQ API keys using dotenv, which automatically loads `.env` files, thus simplifying the management process across different projects. Using dotenv may be easier than using your system's environment variables, depending on your particular setup and preferences. ## Prerequisites Before diving in, ensure you have: * Registered on the [IonQ Quantum Cloud](https://cloud.ionq.com) and generated your API keys. Visit IonQ's [API key management guide](/guides/managing-api-keys) for detailed instructions. * Python 3.11 installed on your computer. Confirm your Python version with `python --version` via command line. To prevent dependency conflicts, consider utilizing an environment manager like [virtualenv](https://virtualenv.pypa.io/en/latest/) or [conda](https://docs.conda.io/en/latest/). ## Step 1: Creating a .env File Navigate to the root directory of your project and create a `.env` file. This file will host your project-specific settings, including the IonQ API key, keeping them secure and easily accessible. ## Step 2: Adding the IonQ API Key to the .env File Open the `.env` file in a text editor and insert your IonQ API key as shown below: ```plaintext theme={null} IONQ_API_KEY=your_api_key_here ``` Replace `your_api_key_here` with your actual IonQ API key. After saving the file, your key is securely stored and ready for use. Don't forget that sharing the `.env` file that contains your API key would mean sharing access to your IonQ account and resources. If you unintentionally share the file, you can always revoke an API key from the IonQ Cloud Console. ## Step 3: Ensure dotenv Package Installation The IonQ Provider for Qiskit has been designed to check for and automatically load `.env` files. If you haven't already, ensure the `python-dotenv` package is installed in your environment: ```bash theme={null} pip install python-dotenv ``` ## Step 4: Using the IonQ API Key in Your Project With the `python-dotenv` package installed and your `.env` file configured, the `IonQProvider` is now set to automatically load and use the API key from the `.env` file without any additional code for dotenv loading in your script. With this automatic loading feature, accessing the IonQ API key in your project code is straightforward. Here's an example with the IonQ Provider for Qiskit: ```python theme={null} from qiskit_ionq import IonQProvider # The IonQProvider automatically looks for the IONQ_API_KEY in your environment provider = IonQProvider() ``` This setup ensures your IonQ API key is automatically detected and utilized, streamlining the development process. ## Conclusion You've successfully learned how to manage IonQ API keys more efficiently using dotenv's automatic loading functionality. This approach not only secures your API keys by keeping them out of your codebase but also simplifies configuration management across multiple projects. For additional information on quantum computing and project management with IonQ, explore the comprehensive [IonQ documentation](https://ionq.com/docs). # Error Mitigation - Debiasing Source: https://docs.ionq.com/guides/error-mitigation-debiasing Getting started with IonQ's built-in error mitigation While many different error mitigation methods can be used when running jobs on IonQ's trapped-ion QPUs, **debiasing** is a general error mitigation technique that is built into our platform. Debiasing doesn't address all sources of error in our systems, but it can help reduce the effect of systematic error on result fidelity. This technique also provides the option to aggregate results via **sharpening**, a post-processing technique that can further reduce error for certain types of applications. You can find more details about debiasing in [our 2023 arXiv paper](https://arxiv.org/abs/2301.07233) (where this technique is referred to as "symmetrization"). More error mitigation settings and techniques will also be available in the future. ## What is debiasing? Debiasing, sometimes called symmetrization or diversification, is a compiler-level error mitigation strategy that works by creating and running many symmetric variations of a given circuit. Debiasing reduces the overall impact of stochastic noise on the computed result — the deterministic inaccuracies largely cancel out while random noise does not get amplified. This approach effectively mitigates the impact of hardware control errors and qubit decoherence, which are major sources of imperfection in modern quantum technologies. Debiased mapping relies on identifying certain symmetries that arise at multiple levels of quantum computer hardware and using them to generate variant circuit implementations. That is, we identify and create variations of a circuit that should be identical on a noiseless machine, but in practice are not due to stochastic error. Different qubit assignments, gate decompositions, and pulse sequences can all be used to create variant implementations. Example of ideal and per-execution results for a quantum circuit run with debiasing In this simplified example, a two-qubit circuit that should give an equal distribution of 00 and 11 measurements is run using four different qubit pairs on a four-qubit system, with each qubit assignment giving a slightly different result. In practice, when a quantum job is run with debiasing, we require at least 500 shots which are automatically divided into 25 executions, each with a different but equivalent implementation of the same circuit (including qubit assignments but also other types of variants). If there is a specific qubit pair whose fidelity has drifted out of calibration, or a pulse sequence that happens to amplify noise in the context of the circuit, these errors won't be present in every execution, so their effect on the overall result quality will be reduced. Debiasing is very general and very efficient. It adds a small amount of classical compute overhead for generating the circuit variants, separately running each variant on the QPU, and aggregating results. However, it doesn't increase the number of circuits, shots, qubits, or gates required (except for small changes in gate count related to different gate decompositions). ### Default settings and availability Debiasing is available for all IonQ QPUs, but it is not currently available for the IonQ Quantum Cloud simulator, including the simulator with noise model. Debiasing can't be used for jobs with fewer than 500 shots, since each execution needs a meaningful number of shots. For any job with fewer than 500 shots, debiasing is automatically disabled and cannot be turned on. For jobs submitted to the IonQ Quantum Cloud in standard QIS gates, debiasing is enabled by default for jobs with 500 or more shots, but it can be turned off. For jobs submitted to the IonQ Quantum Cloud using [IonQ's native gateset](/guides/getting-started-with-native-gates), debiasing is disabled by default. However, it can be turned on if the job has 500 or more shots. You may want to turn on debiasing for a native-gate job if you are looking to maximize performance, but you may prefer not to use it if your experiment requires a consistent qubit mapping. Some integrations and cloud partners may have different default settings or require more shots for debiasing. ### Effect on job cost While debiasing doesn't increase the number of circuits or shots in the job, it adds a small amount of classical overhead which can be relatively significant for small jobs (few gates and/or few shots). To account for this, the minimum per-circuit-job cost for a system is higher when debiasing is enabled. However, for larger jobs, the job cost is not affected by debiasing. Our [resource estimator tool](https://ionq.com/programs/research-credits/resource-estimator), [job estimate API endpoint](/api-reference/v0.4/jobs/get-job-estimate), and [dry run job submission option](/api-reference/v0.4/jobs/create-job#body-dry-run) all take the debiasing setting into account when estimating job cost. You can use any of these tools to determine whether turning debiasing on or off will change the expected cost of a job. In general, we recommend keeping debiasing on for medium and large circuits in order to maximize performance, since it will not affect job cost in these cases. However, for very shallow circuits or small test jobs, turning debiasing off can give similar results while conserving credit. ### How to use debiasing In the [IonQ v0.3 API](/api-reference/v0.3/jobs/create-a-job#body-error-mitigation), the create job request should include `"error_mitigation": { "debias": True }` or `"error_mitigation": { "debias": False }`. In the [IonQ v0.4 API](api-reference/v0.4/jobs/create-job#body-settings), debiasing is in the create job request under the "settings" field. ```json theme={null} "settings": { "error_mitigation": { "debiasing": False } } ``` In [Qiskit](/sdks/qiskit/error-mitigation-qiskit), import `ErrorMitigation` from `qiskit-ionq` and pass `error_mitigation=ErrorMitigation.DEBIASING` or `error_mitigation=ErrorMitigation.NO_DEBIASING` when calling `backend.run()`. In [Cirq](/sdks/cirq/index), pass `error_mitigation={"debias": True}` or `error_mitigation={"debias": False}` when calling `service.run()` or `service.create_job()`. Here's several examples of a "Hello world" circuit with 1000 shots where debiasing is turned off (overriding the default, where it would be turned on): ```python Qiskit theme={null} from qiskit import QuantumCircuit from qiskit_ionq import IonQProvider, ErrorMitigation provider = IonQProvider() qpu_backend = provider.get_backend("qpu.forte-1") # Create a basic Bell State circuit: qc = QuantumCircuit(2, name="Qiskit job without debiasing") qc.h(0) qc.cx(0, 1) qc.measure_all() # Submit the circuit to IonQ Forte: job = qpu_backend.run( qc, shots=1000, error_mitigation=ErrorMitigation.NO_DEBIASING ) ``` ```python API v0.4 theme={null} import requests url = "https://api.ionq.co/v0.4/jobs" # Define the job payload = { "type": "ionq.circuit.v1", "name": "API v0.4 job without debiasing", "input": { "qubits": 2, "gateset": "qis", "circuit": [ { "gate": "h", "target": 0 }, { "gate": "cnot", "control": 0, "target": 1 } ] }, "backend": "qpu.forte-1", "shots": 1000, "settings": { "error_mitigation": { "debiasing": False } } } headers = { "Authorization": "", "Content-Type": "application/json" } # Submit the job response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```python Cirq theme={null} import cirq import cirq_ionq # Create a basic Bell State circuit: q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit( cirq.H(q0), cirq.CNOT(q0, q1), cirq.measure(q0, q1, key='x') ) service = cirq_ionq.Service() # Submit the circuit to IonQ Forte: result = service.create_job( circuit=circuit, repetitions=1000, target='qpu.forte-1', name="Cirq job without debiasing" error_mitigation={"debias": False} ) ``` ## Aggregating job results over executions When a job is run with debiasing, we also provide two options for combining the results from the different executions (circuit variants) that were run. The default aggregation can be used with any type of algorithm, application, or result type, while *sharpening* provides an option for additional post-processing that can amplify signal for results that should have a small number of high-probability states. Debiasing *enables* sharpening by splitting the job into distinct executions, but sharpening is not required when using debiasing. ### Default - averaging By default, the measurements from each execution are directly combined into one histogram, providing a probability distribution that represents the average over all executions. The results from each individual execution are not provided separately, but the overall result reflects the combination of all executions. This approach (debiasing without additional post-selection) is versatile and can be used for most, if not all, types of algorithms and applications. ### Sharpening Optionally, the results from each execution can be combined via sharpening (also known as plurality voting). With this option, all counts from each execution are assigned to the highest-probability bitstring from that execution. For jobs where the expected probability distribution features one or a few quantum states, or where you are trying to identify the highest-probability quantum state, sharpening can amplify the desired signal and remove counts for low-probability states. Example of per-execution voting and averaged vs sharpened results In this simplified visualization, where each symbol represents a different measured quantum state, the job was split into five executions, each with four shots. For averaging (left), the result is aggregated by counting the overall occurrences of each symbol. With sharpening (voting, right), we take the most frequently occurring symbol from each row (execution), which yields two rows for the green triangle, two rows for the blue diamond, and one row which is skipped because there is no "winner" in the voting. The result is a histogram where all of the probability is assigned to the 00 and 11 states, matching the ideal distribution for the example circuit. For applications with a more complex probability distribution, or where you need to quantify the relative probabilities of several different states, sharpening will not improve the result. In these cases, sharpening could distort the true probability distribution and should not be used. As a safeguard, if an execution has no clear highest-probability bitstring during sharpening, the shots from that execution are automatically counted as-is (just as when sharpening is not used), rather than discarded as in the above example. ### Retrieving job results with sharpening While debiasing is set "on" or "off" when the job is submitted, sharpening is an option used for result retrieval. When retrieving the results from a job that was run with debiasing, you can always choose to apply sharpening or not (or you can retrieve the result both ways for comparison). If you request a sharpened result from a job that was not run with debiasing, you'll receive an error. Sharpening is "opt-in": the default setting is always to retrieve the result **without** sharpening. In the [IonQ v0.3 API](/api-reference/v0.3/jobs/get-a-specific-jobs-output) and the [IonQ v0.4 API](/api-reference/v0.4/jobs/get-job-probabilities), use the query parameter `sharpen` to retrieve a job result with sharpening. In Python, this looks like passing `params={"sharpen": True}` to the request call. Note that the specific request URL format is different between v0.3 (`.../{job_id}/results`) and v0.4 (`.../{job_id}/results/probabilities`). In [Qiskit](/sdks/qiskit/error-mitigation-qiskit), use `job.result(sharpen=True).get_counts()` rather than `job.get_counts()` to retrieve a job result with sharpening. In [Cirq](/sdks/cirq/index), use `job.results(sharpen=True)` to retrieve a job result with sharpening. In all of these examples, setting this value to `False` or omitting it will give the default, non-sharpened result. Here's several examples of retrieving a sharpened job result, given a job ID: ```python Qiskit theme={null} from qiskit_ionq import IonQProvider provider = IonQProvider() qpu_backend = provider.get_backend("qpu.forte-1") job_id = "..." # Retrieve the job job = qpu_backend.retrieve_job(job_id) # Retrieve the sharpened result result_sharpened = job.result(sharpen=True).get_counts() print(result_sharpened) # Retrieve the averaged (unsharpened) result # This is equivalent to just doing job.get_counts() result_averaged = job.result(sharpen=False).get_counts() print(result_averaged) ``` ```python API v0.4 theme={null} import requests job_id = "..." url = f"https://api.ionq.co/v0.4/jobs/{job_id}/results/probabilities" headers = { "Authorization": "", "Content-Type": "application/json" } params = {"sharpen": True} response = requests.post(url, headers=headers, params=params) print(response.json()) ``` ```python Cirq theme={null} import cirq import cirq_ionq service = cirq_ionq.Service() job_id = "..." # Retrieve the job job = service.get_job(job_id) # Retrieve the sharpened result result_sharpened = job.results(sharpen=True) print(result_sharpened) # Retrieve the averaged (unsharpened) result # This is equivalent to job.results() result_averaged = job.results(sharpen=False) print(result_averaged) ``` ## Summary and recommendations Debiasing can be used with any type of quantum circuit job, as long as the job has 500 or more shots. For jobs submitted in QIS gates, debiasing is on by default; for jobs submitted in IonQ native gates, debiasing is off by default. While debiasing doesn't address all types of error, it doesn't add overhead in qubits, gates, or shots. For large circuits, debiasing can improve result quality and won't increase job cost (though it may increase cost for small jobs). It can also be combined with many other types of error mitigation. Sharpening is an *optional* post-selection technique for aggregating the results from a debiased job. It can amplify signal in cases where the expected result contains one or a few high-probability states. For more detail about debiasing, refer to [our 2023 arXiv paper](https://arxiv.org/abs/2301.07233). Stay tuned for more error mitigation options and techniques that will be available for our systems in the future! # Native Gates Source: https://docs.ionq.com/guides/getting-started-with-native-gates Getting started with IonQ's hardware-native gateset This is a general guide covering what the native gates are and why you might want to use them. To learn *how* to use these native gates, refer to our native gate guides for the [IonQ API](/api-reference/v0.3/native-gates-api), [Qiskit](/sdks/qiskit/native-gates-qiskit), [Cirq](/sdks/cirq/native-gates-cirq), and [PennyLane](/sdks/pennylane/native-gates-pennylane). The IonQ Quantum Cloud has one of the best—-maybe *the* best—-optimizing compilers in quantum computing. This allows users to focus on the details of their algorithms instead of the details of our quantum system. You can submit quantum circuits using a large, diverse set of quantum gates that allows for maximum flexibility in how to define your problem, and our compilation and optimization stack ensures that your circuit runs on our QPUs in the most compact, streamlined, hardware-optimized form possible. This flexibility in circuit definition also allows for high portability of algorithm code. We don't restrict you to hardware-native basis gates, so you're free to define your circuit in [standard QIS gates (including controlled and multi-controlled variants of these)](/api-reference/v0.3/writing-quantum-programs#supported-gates) and then simply submit to IonQ hardware as-is. No changes necessary! While this is ideal for many applications, the hardware-native basis gateset allows for more customizability, flexibility, and what-you-submit-is-what-you-get control. Being as "close to the metal" as possible allows for control over each individual gate and qubit, unlocking avenues of exploration that are impossible with a compiler between you and the qubits. Debias stuff often. Debiasing is great. Currently, submitting circuits defined in native gates is the only way to bypass the compiler and optimizer. Read on to get started with our hardware-native gate specification, learn how it works, and run an example circuit using this powerful new ability. This is an advanced-level feature. Using the hardware-native gate interface without a thorough understanding of quantum circuits is likely to result in less-optimal circuit structure and worse algorithmic performance overall than using our abstract gate interface. *** ## When to use native gates Native gates are not the right solution for every problem. As the warning above states, the native gate specification is an advanced-level feature. If your goal is simply to run a quantum circuit for evaluation or algorithm investigation purposes, using native gates will *often* result in lower-quality output than simply using the abstract gate interface. The native gate interface is the simplest, most direct way to run a circuit on IonQ hardware: we run exactly the gates you submitted, as submitted, and we return the results. That's it. Comparison of submitting via the native gate interface (blue) and the abstract interface (black) This means that our proprietary compilation and optimization toolchain is **fully turned off** when we execute a "native" circuit. (Error mitigation is also turned off by default, though you can choose to override this setting and turn on debiasing.) To take full advantage of our compilation, optimization, and error mitigation, you must submit your circuit using our default abstract gate interface, and if you are looking for maximum algorithmic performance from our systems, it is likely that you'll find it by doing just that. But, this toolchain performs a number of transformations on submitted circuits that we consider proprietary, and we therefore do not disclose the full details of how it works. By the time a circuit you submit through the abstract gate interface actually runs on hardware, it has been changed, sometimes considerably. Extraneous gates are optimized away or commuted into different places, they are transpiled into native gates using special heuristics and optimized again, and so on. So, we recommend only using native gates when you cannot use the abstract interface to accomplish your goals - when you need to know exactly what circuit was run, or when you specifically want to run circuits that are not optimized. This might involve investigation and characterization of noise, designing noise-aware circuits, or exploring new error mitigation techniques, as well as the development and testing of circuit optimization and compilation methods. *** ## Introducing the native gates The native gateset is the set of quantum gates that are physically executed on IonQ hardware by addressing ions with resonant lasers via stimulated Raman transitions. The physical implementation of Raman gates differs between Forte and Aria, which means they support a slightly different set of native gates: | Gate Type | Aria Systems | Forte Systems | | --------- | ------------ | ------------- | | GPi | ✓ | ✓ | | GPi2 | ✓ | ✓ | | MS | ✓ | - | | ZZ | - | ✓ | We currently expose two single-qubit gates and one two-qubit entangling gate for each QPU. Other native gates may be provided in the future. All gate parameters are measured in *turns* rather than in radians: a value of 1 turn corresponds to 2π radians. We track the phase at the pulse level as units of turns--or, more accurately, as units of how long a turn takes--so, we expose the controls in the same way to you. This reduces floating point conversion error between what you submit and what runs. ### Single-qubit gates The "textbook" way to think about single-qubit gates is as rotations along different axes on the Bloch sphere, but another way to think about them is as rotations along a *fixed* axis while rotating the Bloch sphere itself. Because, in physical reality, the Bloch sphere itself *is* rotating--that is, the phase is advancing in time--changing the orientation of the Bloch sphere is virtually noiseless on hardware. As such, we manipulate qubit states in this "noiseless" phase space whenever possible. #### GPi The GPi ("Gate PI") gate can be considered a π or bit-flip rotation with an embedded phase. It always *rotates* π radians in the polar angle--hence the name--but can rotate on any longitudinal axis of the Bloch sphere. The axis of rotation is set by the parameter ϕ, which is measured in turns. At a ϕ of 0 turns the GPi gate is equivalent to an X gate, and at a ϕ of 0.25 turns (π/2 radians) it is equivalent to a Y gate, but it can also be mapped to any other azimuthal angle. In terms of standard quantum gates, a GPi gate can be decomposed as: ``` GPi(ϕ) = RZ(-ϕ) · X · RZ(ϕ) ``` $GPI(\phi) = \begin{bmatrix} 0 & e^{-2\pi i\phi} \\ e^{2\pi i\phi} & 0 \end{bmatrix}$ A single-qubit gate is physically implemented as a Rabi oscillation made with a two-photon Raman transition, i.e. driving the qubits on resonance using a pair of lasers in a Raman configuration. For more details on the physical gate implementation, we recommend [this paper](https://www.nature.com/articles/s41467-019-13534-2) from the IonQ staff. #### GPi2 The GPi2 gate could be considered an RX(π/2)--or RY(π/2)--rotation with an embedded phase. It always *rotates* π/2 radians but can rotate on any longitudinal axis of the Bloch sphere. In practice, a GPi2 gate works similarly to a GPi gate but uses either a lower amplitude or shorter duration physical pulse (we do not expose this implementation detail). While it's technically possible to set arbitrary rotation angles, using just π/2 rotations along with phase control is sufficient for universal quantum computation. As with the GPi gate, the axis of rotation is set by the parameter ϕ, defined in turns. At a ϕ of 0.5 turns (π radians) the GPi2 gate is equivalent to RX(π/2), and at a ϕ of 0.25 turns (π/2 radians) it is equivalent to RY(π/2), but it can also be mapped to any other azimuthal angle. $GPI2(\phi)= \frac{1}{\sqrt{2}} \begin{bmatrix} 1 & -ie^{-2\pi i\phi} \\ -ie^{2\pi i\phi} & 1 \end{bmatrix}$ Like the GPi gate, the GPi2 gate is physically implemented as a Rabi oscillation made with a two-photon Raman transition. #### Virtual Z We do not expose or implement a "true" Z gate (sometimes also called a P, Phase Gate, or RZ gate), where we wait for the phase to advance in time. Instead, a Virtual RZ can be performed by simply advancing or retarding the phase of the following operation in the circuit. This process, called "phase propagation," removes RZ gates by adding their angles to the phase parameters of subsequent gates. $Virtual Z(\theta)= \begin{bmatrix} e^{-i\pi\theta} & 0 \\ 0 & e^{i\pi\theta} \end{bmatrix}$ For example, to add RZ(θ)--an RZ with an arbitrary rotation θ--to a qubit where the subsequent operation is GPi(0.5), we can just add that rotation to the phases of the following gates: > \--RZ(θ)--GPI(0.5)--GPI2(0) = --GPI(θ + 0.5)--GPI2(θ + 0) ### Entangling gates For entangling gates, we offer different options for each QPU: the [Mølmer-Sørenson gate](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.82.1835) on Aria-class systems, and the ZZ gate on our Forte-class systems. #### MS gates Invented in 1999 by [several groups simultaneously](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.59.R2539), the Mølmer-Sørenson gate along with single-qubit gates constitutes a universal gate set. By irradiating any two ions in the chain with a predesigned set of pulses, we can couple the ions' internal states with the chain's normal modes of motion to create entanglement. While it is *possible* to entangle many qubits simultaneously with the Mølmer-Sørenson interaction via global MS, or GMS, we only offer two-qubit MS gates at this time. **Fully entangling MS** The fully entangling MS gate is an XX gate--a simultaneous, entangling π/2 rotation on both qubits. Like our single-qubit gates, they nominally follow the X axis as they occur, but take two phase parameters that make e.g. YY or XY also possible. The first phase parameter ϕ0 refers to the first qubit's phase (measured in turns) as it acts on the second one, the second parameter ϕ1 refers to the second qubit's phase (measured in turns) as it acts on the first one. If both are set to zero, there is no advancing phase between the two qubits because the transition is driven on both qubits simultaneously, in-phase. That is, the *relative* phase between the two qubits remains the same during the operation unless a phase offset is provided. $MS(\phi_0, \phi_1) = \frac{1}{\sqrt{2}} \begin{bmatrix} 1 & 0 & 0 & -ie^{-2\pi i(\phi_0 + \phi_1)} \\ 0 & 1 & -ie^{-2\pi i(\phi_0 - \phi_1)} & 0 \\ 0 & -ie^{2\pi i(\phi_0 - \phi_1)} & 1 & 0 \\ -ie^{2\pi i(\phi_0 + \phi_1)} & 0 & 0 & 1 \end{bmatrix}$ Note that while two distinct ϕ parameters are provided here (one for each qubit, effectively), they always act on the unitary together. This means that there are multiple ways to get to the same relative phase relationship between the two qubits for this gate; two parameters just makes the recommended approach of "Virtual Z" phase accounting on each qubit across the entire circuit a little neater. **Partially entangling MS** In addition to the fully entangling MS gate described above, we also support partially entangling MS gates, which are useful in some cases. To implement these gates, we add a third (optional) arbitrary angle θ: $\text{MS}(\phi_0,\phi_1,\theta) = \begin{bmatrix} \cos (\pi\theta) & 0 & 0 & -i e^{-2\pi i(\phi_0+\phi_1)} \sin (\pi\theta) \\ 0 & \cos (\pi\theta) & -i e^{-2\pi i(\phi_0-\phi_1)} \sin (\pi\theta) & 0 \\ 0 & -i e^{2\pi i(\phi_0-\phi_1)} \sin (\pi\theta) & \cos (\pi\theta) & 0 \\ -i e^{2\pi i(\phi_0+\phi_1)} \sin (\pi\theta) & 0 & 0 & \cos (\pi\theta) \end{bmatrix}$ This parameter is also measured in turns, and can be any floating-point value between 0 (identity) and 0.25 (fully-entangling); in practice, the physical hardware is limited to around three decimal places of precision. Requesting an MS gate without this parameter will always run the fully entangling version. Partially entangling MS gates yield more compact circuits: to produce the same effect as one arbitrary-angle MS gate would require up to two fully-entangling MS gates plus four single-qubit rotations. This offers a potential reduction in gate depth that can indirectly improve performance by removing unnecessary gates in certain circuits. Additionally, small-angle MS gates are generally more performant: for smaller angles, these gates are implemented by lower-power laser pulses, and therefore experience lower light shift and other power-dependent errors. We do not currently have a detailed characterization of how much more performant these gates are on our current-generation systems, but in our (now-decommissioned) system described in [this paper](https://www.nature.com/articles/s41467-019-13534-2), we saw an improvement from \~97.5% to \~99.6% two qubit fidelity when comparing angles of π/2 and π/100, which is described [in more detail here](https://www.nature.com/articles/s41534-020-0259-3). #### ZZ gates Our Forte systems use the ZZ gate, which is another option for creating entanglement between two qubits. Unlike the Mølmer-Sørenson gate, the ZZ gate only requires a single parameter, θ, to set the phase of the entanglement. $ZZ(\theta) = \exp\left(-i \pi \theta Z{\otimes}Z\right) = \begin{pmatrix} e^{-i \pi \theta} & 0 & 0 & 0 \\ 0 & e^{i \pi \theta} & 0 & 0 \\ 0 & 0 & e^{i \pi \theta} & 0 \\ 0 & 0 & 0 & e^{-i \pi \theta} \end{pmatrix}$ *** ## Converting to native gates You can write a quantum circuit using native gates directly, but you can also convert an abstract-gate circuit into native gates. To do this automatically, we [support Qiskit's transpiler](/sdks/qiskit/native-gates-qiskit#transpiling-a-circuit-to-native-gates). Here, we'll walk through the general approach for manually translating circuits into native gates. Each quantum circuit submitted to the IonQ Cloud must use a consistent gateset throughout--you cannot mix and match native gates and abstract gates in the same circuit. ### General algorithm To translate anything into native gates, the following general approach works well: 1. Decompose the gates used in the circuit so that each gate involves at most two qubits. 2. Convert all easy-to-convert gates into RX, RY, RZ, and CNOT gates. 3. Convert CNOT gates into XX gates using the decomposition described [here](https://arxiv.org/abs/1603.07678) and at the bottom of this section. 4. For hard-to-convert gates, first calculate the matrix representation of the unitary, then use either [KAK decomposition](https://arxiv.org/abs/quant-ph/0507171) or the method introduced in [this paper](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.77.066301) to implement the unitary using RX, RY, RZ and XX. Note that Cirq and Qiskit also have subroutines that can do this automatically, although potentially not optimally. See [cirq.linag.kak\_decomposition](https://quantumai.google/reference/python/cirq/kak_decomposition) and [qiskit.synthesis.TwoQubitBasisDecomposer](https://docs.quantum.ibm.com/api/qiskit/qiskit.synthesis.TwoQubitBasisDecomposer). 5. Write RX, RY, RZ and XX into GPi, GPi2 and MS gates as documented above (making sure to convert all angles and phases from radians to turns). #### CNOT to XX decomposition A CNOT gate can be expressed in XX, RX, and RY gates which can be directly converted to IonQ's native gates. ```python theme={null} ----@----- ----| RY(π/2) |----| |----| RX(-π/2) |----| RY(-π/2) |----- | = | XX(π/4) | ----X----- -------------------| |----| RX(-π/2) |--------------------- ``` Many more advanced approaches, decompositions, and optimizations for trapped-ion native gates, including a parameterizable version of this decomposition can be found in [Basic circuit compilation techniques for an ion-trap quantum machine](https://arxiv.org/abs/1603.07678), where this decomposition is described. *** ## Additional resources To learn how to use native gates via the IonQ API and supported SDKs: * [Native gates in the IonQ API](/api-reference/v0.3/native-gates-api) * [Native gates in Qiskit](/sdks/qiskit/native-gates-qiskit) * [Native gates in Cirq](/sdks/cirq/native-gates-cirq) * [Native gates in PennyLane](/sdks/pennylane/native-gates-pennylane) For those interested in learning more about trapped-ion quantum computers as a physical apparatus, the implementation of gates, etc, we recommend [the PhD theses from our cofounder Chris Monroe's lab](https://iontrap.umd.edu/publications/theses/) as a starting point, especially those of Debnath, Egan, Figgat, Landsman, and Wright. The hardware they describe is in many ways the "first iteration" of IonQ's hardware, and much of the fundamental physics of the trapped-ion approach carries over. # Hosted Hybrid Service Source: https://docs.ionq.com/guides/hosted-hybrid-service Run hybrid execution loops using functions managed by IonQ's Cloud. The Hosted Hybrid service is currently in a limited preview and only available to customers with an active contract. Please contact [support@ionq.co](mailto:support@ionq.co) for more information. IonQ's Hosted Hybrid Service allows users to run hybrid quantum-classical workloads without needing to write or host the classical optimization logic. This means that you can run a hybrid algorithm like a VQE, optimize the inputs with a method like SPSA, and do it all without having to write-or-run any of the code yourself. This service introduces a two new things to our platform: A ***Quantum Function*** is an abstraction that represents a composition of classical and quantum logic to perform simple computations. We currently expose two types of Quantum Functions: * **Hamiltonian Energy**, which takes an ansatz and a hamiltonian to perform hamiltonian energy evaluation. * **Quadratically Constrained Quadratic Program** that models the objective of a (constrained) quadratic program. This `QuantumFunction` can be used to solve constrained quadratic programs. An ***Optimization*** looks for the optimal parameters for a Quantum Function using a supported optimization function. Once completed, the solution returned is the minimum energy value and the optimal parameters used to achieve it. These new tools allow you take a problem that you want to solve, represent it in the form of a function, and run it through an optimization routine—without having to run any of the classical code yourself in a local notebook, or manage a remote execution environment. *** ## Setup To run hybrid workloads with this tool, you'll need: We recommend using a version manager such as [pyenv](https://github.com/pyenv/pyenv) or [asdf](https://asdf-vm.com/guide/introduction.html) to simplify management and upgrades. ```bash theme={null} pip install 'ionq[all]' ``` We'll start by setting up our our `Client` which will allow us to connect to IonQ's platform, then select a backend to use with it. ```python theme={null} # Initialize backend from ionq.client import Client from ionq import Backend # Initialize a client for connecting to the IonQ API client = Client() # Note: Assuming it's stored as $IONQ_API_KEY in your environment, # the SDK (and any other quantum SDK) will find it automatically. # However, if you wanted to specify it directly, you could with: # client = Client(api_key="aaa-bbb-ccc") # Select a backend to use. We'll stick with the simulator for now, but you can backend = Backend(name="simulator", client=client) ``` *** ## Creating a demo workload In practice, you'd be using our hamiltonian energy evaluations to evaluate *your own* hamiltonians and ansatze, but for this guide we'll build a couple of functions for creating random inputs -- but if you can provide your own, more the better. So first, we'll build an example hamiltonian: ```python theme={null} import random import math from itertools import product from qiskit.quantum_info import SparsePauliOp # Create our example hamiltonian num_qubits = 2 # or more, but it scales rapidly! pauli_list = [ (ps, random.uniform(-1, 1)) for ps in [ "".join(p) for p in list(product(["I", "X", "Y", "Z"], repeat=num_qubits)) ] ] # Create and display an example hamiltonian hamiltonian = SparsePauliOp.from_list(pauli_list) ``` Which, if we `print`ed it, would look something like: > ```python theme={null} > print(hamiltonian.to_matrix()) > > [[-0.66819263+0.j -1.36722223-1.22394246j 1.61219673+1.45550222j > 0.1523982 -1.25363417j] > [-1.36722223+1.22394246j 1.40731579+0.j -1.42421166+0.51092863j > -0.16465104-0.43298482j] > [ 1.61219673-1.45550222j -1.42421166-0.51092863j 0.86269394+0.j > -0.388201 -0.74335051j] > [ 0.1523982 +1.25363417j -0.16465104+0.43298482j -0.388201 +0.74335051j > 2.28670504+0.j ]] > ``` Now we'll do the same for an example ansatz and some initial parameters: ```python theme={null} from qiskit import QuantumCircuit from qiskit.circuit import Parameter params = [Parameter(f"θ{i}") for i in range(2 * num_qubits)] ansatz = QuantumCircuit(num_qubits) # Add a layer of single-qubit parameterized rotations (Ry and Rz) for i in range(num_qubits): ansatz.ry(params[i], i) ansatz.rz(params[i + num_qubits], i) ansatz.barrier() # Add CNOT gates to entangle the qubits for i in range(num_qubits - 1): ansatz.cx(i, i + 1) # Set up some initial parameters initial_params = { params[i]: random.uniform(0, 2 * math.pi) for i in range(2 * num_qubits) } ``` Which will produce an ansatz that looks something like: > ```python theme={null} > ansatz.draw(output="mpl") > ``` > > Image *** ## Example 1: Running a simple circuit As a simple demonstration of functionality, let's take our backend and submit a basic circuit job to it using our example ansatz. This is *not* a hybrid workflow, but a normal circuit job. Note: We're using `ionq.ionq_qiskit`, which is a helper library we are providing for translating Qiskit circuits into IonQ-native QIS. ```python theme={null} from ionq.utils import ionq_qiskit # Create a circuit using a helper that translates Qiskit circuits to QIS circuit = ionq_qiskit.to_circuit( [ansatz.assign_parameters(initial_params, inplace=False)] ) # And submit it to our backend circuit_job = backend.run( circuit, name="Example 1: Circuit Workload" ) ``` And plotting this circuit we'll see something like: > ```python theme={null} > circuit_results = circuit_job.results() > for results in circuit_results: > results.plot_results() > ``` > > Circuit Workload Histogram *** ## Example 2: Running a Quantum Function Now we're build on this by submitting a *`QuantumFunction`* instead of just a simple circuit. A quantum function is a workload that has some predefined logic built in to it. In this case, we'll pass it an ansatz and a hamiltonian, and when we send it to the backend along with a set of parameters, it will submit circuits and do an Hamiltonian Energy evaluation. ```python theme={null} from ionq.jobs import HamiltonianEnergy from ionq.utils import ionq_qiskit # Build a QuantumFunction qfunc = HamiltonianEnergy( ansatz=ionq_qiskit.to_ansatz(ansatz), hamiltonian=ionq_qiskit.to_hamiltonian(hamiltonian), ) # Submit it to the backend qfunc_job = backend.run( qfunc, params=list(initial_params.values()), name="Example 2: Quantum Function Workload", ) ``` *** ## Example 3: Quadratically Constrained Quadratic Program Objective We can also prepare the model for a constrained quadratic program, by creating a Quantum Function that takes an ansatz, a QUBO matrix, and a list of constraints. This can then be used to solve constrained quadratic programs with classical optimization methods. Let's first model it, with some simple linear constraints and confirm it runs with a random set of parameters. ```python theme={null} import numpy as np from ionq.problems.quadratic import LinearConstraint from ionq.problems import QCQPObjective from ionq.utils import ionq_qiskit Q = np.array([[4, -6], [-6, 10]]) constraints = [ LinearConstraint( coeffs=[1, 2], rhs=5, ), LinearConstraint( coeffs=[3, 4], rhs=6, ) ] print(f"{Q=}", "\n\n", f"{constraints=}") # Build our QuantumFunction qfunc = QCQPObjective( ansatz=ionq_qiskit.to_ansatz(ansatz), qp_objective=Q, linear_constraints=constraints, penalty=random.uniform(-1, 1), ) # Submit it to the backend qfunc_job = backend.run( qfunc, params=list(initial_params.values()), name="Example 3: Quantum Function (with constraints and a penalty)", ) ``` *** ## Example 4: Optimizations We can also run a (IonQ hosted!) classical loop to optimize our parameters. Here we'll take the same quantum function we ran in Example 3, but we'll add a 5-iteration optimization using SPSA. It doesn't add that much complexity here, only requiring some simple additions: 1. What `method` to use for optimization 2. The maximum desired number of iterations 3. The learning rate, and perturbation for each iteration These values will define how each iteration in the series will change based on the results of the previous job. ```python theme={null} from ionq.jobs import Optimization from ionq.jobs import OptimizationMethod opt = Optimization( quantum_function=qfunc, method=OptimizationMethod.SPSA, initial_params=list(initial_params.values()), log_interval=1, options={"maxiter": 5, "learning_rate": 0.1, "perturbation": 0.5}, maxiter=5, ) # Run the optimization job opt_job = backend.run( opt, name="Example 4: Optimization" ) ``` As before, we've provided some useful helpers for visualization. running `plot_results()` gives us: > ```python theme={null} > opt_results = opt_job.results() > opt_results.plot_results() > ``` > > A graph of the results of an optimization job. And retrieving the "results" of this job will identify the `minimum_value` and `optimal_parameters` for the problem: > ```python theme={null} > "solution": { > "minimum_value": -0.6128005853629444, > "optimal_parameters": [ > 4.915170460439439, > 3.228145593574783, > 5.550801246532398, > -0.012326729967622713 > ] > } > ``` *** ## Learn more This service is still in a private alpha at this time, but reach out to [sales@ionq.co](mailto:sales@ionq.co) for more information, or contact your account manager. # Managing API keys Source: https://docs.ionq.com/guides/managing-api-keys Learn how to create and manage your IonQ API keys for secure access through SDKs and APIs. An **API key** is similar to a password—it's a string of text used to authenticate yourself with our systems and allow the system to authorize that you have access to the action you're attempting to take. IonQ uses API keys to manage access to our systems. Users must provide a valid key when using APIs both directly or through an SDK. ## Creating API keys API keys are created in the [IonQ Quantum Cloud](https://cloud.ionq.com/settings/keys) application under the API Keys page found in the top menu. This page provides a comprehensive view of your API key management, allowing you to see a list of all your currently active keys, track their usage by viewing when they were last used, and maintain security by revoking (deleting) any keys that are no longer needed.