Managing jobs
Estimate what a job will cost, label and track it, read its cost and timing, see what ran on the device, and reconnect to it later.
API Reference: qbraid.runtime.native
Everything on this page works the same on every device you reach through QbraidProvider, whichever vendor or submission path it uses. The examples use the free QIR simulator, qbraid:qbraid:sim:qir-sv:
from qbraid.runtime import QbraidProvider
provider = QbraidProvider()
device = provider.get_device("qbraid:qbraid:sim:qir-sv")
bell = """
OPENQASM 3.0;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
h q[0];
cx q[0], q[1];
c = measure q;
"""Before you submit
Check the device
device.status()
# <DeviceStatus.ONLINE: 'ONLINE'>
device.queue_depth()
# 0device.run() warns when a device isn’t ONLINE: the job may be refused, or wait a long time. provider.get_devices() lists the devices you can submit to now. Pass include_retired=True to also list devices that have been retired.
Estimate the cost
provider.client.estimate_cost prices a job before you submit it, in qBraid credits:
estimate = provider.client.estimate_cost("aws:iqm:qpu:garnet", shots=100)
estimate.pricingAvailable
# True
estimate.estimatedCost
# Credits('44.5')Some devices are priced dynamically by their vendor, so no estimate is possible in advance. For those, pricingAvailable is False and reason says why, such as 'dynamic_pricing_unavailable'. Devices with openquantum: IDs estimate 0, because they spend credits from your linked Open Quantum account rather than qBraid credits.
The device catalog shows the same prices.
Check your balance
balance = provider.client.get_credits_balance()
balance["qbraidCredits"]The balance belongs to the organization your API key is tied to.
Submitting
job = device.run(
bell,
shots=100,
name="bell-test",
tags={"experiment": "docs-managing-jobs"},
)
job.id
# 'qbraid:qbraid:sim:qir-sv-8ce1-qjob-6ad8144c34188ba734e7a279'| Argument | Effect |
|---|---|
shots | Number of shots. |
name | A name for the job, shown in Quantum Jobs. |
tags | Key-value labels, with string, integer or boolean values. Find jobs by tag later. |
runtime_options | Options passed to the device. See Runtime options. |
Keep job.id: it is all you need to get the job back later.
To run several circuits at once, see Batch & group jobs.
While it runs
job.status()
# <QUEUED: 'job is queued'>
job.queue_position()
# 3queue_position() returns None once the job has left the queue, or when the device doesn’t report positions.
A job moves through INITIALIZING, QUEUED, RUNNING, and then one of COMPLETED, FAILED or CANCELLED. job.is_terminal_state() tells you whether it has finished.
Wait for it
job.result() blocks until the job finishes. Pass timeout, in seconds, to give up waiting. The job keeps running.
result = job.result(timeout=600)job.wait_for_final_state(timeout=600, poll_interval=5) waits without fetching the result. In async code, await job.async_result() waits without blocking the event loop.
Cancel it
job.cancel()cancel() raises JobStateError if the job has already finished. A job that has started running on a QPU may finish before the cancellation reaches it.
Results
result.success
# True
result.data.get_counts()
# {'00': 46, '11': 54}result.data also has get_probabilities(), and measurements for the individual shots where the device returns them.
Cost and timing
result.details records what the job actually cost and how long it took:
result.details["cost"]
# Credits('0')
result.details["time_stamps"]
# TimeStamps(createdAt=datetime.datetime(2026, 10, 21, 1, 24, 30, tzinfo=datetime.timezone.utc),
# endedAt=datetime.datetime(2026, 10, 21, 1, 24, 30, tzinfo=datetime.timezone.utc),
# executionDuration=12)executionDuration is in milliseconds.
When a job fails
A job that doesn’t complete still returns a result, with success set to False and no data. When the platform gives a reason, it is in details["status_message"]:
result = job.result()
if not result.success:
print(result.details["status"])
print(result.details.get("status_message"))After it runs
What you submitted
job.program() returns the program as qBraid received it, after any conversion from your framework:
job.program()
# Program(format='qasm3', data='OPENQASM 3.0;\ninclude "stdgates.inc";\nqubit[2] q; ...')What ran on the device
job.compiled_program() returns the program the device’s compiler produced. On a QPU this shows which physical qubits your circuit ran on and the native gates it was compiled to, which the counts alone can’t tell you:
compiled = job.compiled_program()
compiled.format
# 'qir.ll'| Devices | Format |
|---|---|
| IQM through Amazon Braket | qasm3 |
| Rigetti, direct or through Amazon Braket | quil |
| QIR simulator | qir.ll |
It returns None when there is no compiled program: the job hasn’t finished, the device doesn’t report one, or the job predates this feature. A batch job returns a list, one program per circuit.
Reconnect to a job
A job ID is enough to get a job back, for example after restarting a notebook kernel, or on another machine:
from qbraid.runtime import load_job
job = load_job("qbraid:qbraid:sim:qir-sv-8ce1-qjob-6ad8144c34188ba734e7a279", provider="qbraid")
job.status()
# <COMPLETED: 'job has successfully run'>The returned job supports everything on this page.
Find past jobs
provider.client.list_jobs searches your jobs. Filter by tag, status or text:
jobs = provider.client.list_jobs(tags={"experiment": "docs-managing-jobs"})
[(j.jobQrn, j.name, j.status) for j in jobs]
# [('qbraid:qbraid:sim:qir-sv-8ce1-qjob-6ad8144c34188ba734e7a279', 'bell-test', <COMPLETED: ...>)]| Filter | Example |
|---|---|
tags | {"experiment": "bell-state"} |
status | "COMPLETED", "FAILED" |
status_group | "pending" (not finished yet), "returned" (finished), "all" |
search | Text matched against your jobs |
page, limit | Pagination |
Pass a result’s jobQrn to load_job to work with that job. Quantum Jobs shows the same jobs in your account.
Related links
- Run on qBraid: installing the SDK and saving your qBraid API key
- Batch & group jobs: running several circuits as separate, batch, or group jobs
- Calibrations: live calibration data for choosing qubits
- Visualization: plotting results
Thanks for your feedback.

