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

# Direct API Submissions

> 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:

<img src="https://mintcdn.com/ionq/KP8cXNscCAA57Ku7/guides/_media/direct-api-submission-ghz-circuit.png?fit=max&auto=format&n=KP8cXNscCAA57Ku7&q=85&s=d9ae3c5f17a57a083bad8d46c58ae76c" alt="A visualization of a Greenberger-Horne-Zeilinger (GHZ) state." width="587" height="345" data-path="guides/_media/direct-api-submission-ghz-circuit.png" />

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

<Note>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).</Note>

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.forte-1`). We can also assign a name to the job for easier reference.

<Note>
  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).
</Note>

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"
```

<Tip>Remember to replace `{your-job-id}` with the ID you just got back.</Tip>

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.
