Lewati ke konten utama

Primitives dengan REST API

Langkah-langkah dalam topik ini menjelaskan cara menjalankan dan mengonfigurasi beban kerja primitives dengan REST API, serta mendemonstrasikan cara memanggilnya di program apa pun yang kamu pilih.

catatan

Dokumentasi ini menggunakan modul Python requests untuk mendemonstrasikan Qiskit Runtime REST API. Namun, alur kerja ini bisa dijalankan menggunakan bahasa atau framework apa pun yang mendukung REST API. Lihat dokumentasi referensi API untuk detailnya.

Estimator primitive dengan REST API​

1. Inisialisasi akun​

Karena Qiskit Runtime Estimator adalah layanan terkelola, kamu perlu menginisialisasi akun terlebih dahulu. Setelah itu, kamu bisa memilih perangkat yang ingin digunakan untuk menghitung nilai ekspektasi.

Temukan detail cara menginisialisasi akun, melihat Backend yang tersedia, dan membatalkan token di topik ini.

2. Buat Circuit QASM​

Kamu membutuhkan setidaknya satu Circuit sebagai input untuk primitive Estimator.

Definisikan Circuit kuantum QASM. Contohnya:

qasm_string='''
OPENQASM 3;
include "stdgates.inc";
qreg q[2];
creg c[2];
x q[0];
cx q[0], q[1];
c[0] = measure q[0];
c[1] = measure q[1];
'''

Cuplikan kode berikut mengasumsikan bahwa qasm_string telah ditranspilasi ke string baru resulting_qasm.

3. Jalankan Circuit kuantum menggunakan Estimator V2 API​

catatan

Job-job berikut menggunakan Qiskit Runtime V2 primitives. Baik SamplerV2 maupun EstimatorV2 menerima satu atau lebih primitive unified blocs (PUBs) sebagai input. Setiap PUB adalah tuple yang berisi satu Circuit dan data yang disiarkan ke Circuit tersebut, yang bisa berupa beberapa observabel dan parameter. Setiap PUB mengembalikan satu hasil.

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}

job_input = {
'program_id': 'estimator',
"backend": backend,
"params": {
"pubs": [ #primitive unified blocs (PUBs) containing one circuit each.
[resulting_qasm, # QASM circuit
{"IIZII": 1, "XIZZZ": 2.3}, # Observable
None # parameter values
]]
}}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")

4. Periksa status job dan dapatkan hasilnya​

Selanjutnya, masukkan job_id ke API:

response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')

Output

>>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad
>>> Job Status: JobStatus.RUNNING

Dapatkan hasil job:

response_result= requests.get(url+'/'+job_id+'/results', headers=headers)

res_dict=response_result.json()

estimator_result=res_dict['results']
print(estimator_result)

Output

[{'data': {'evs': 0.7428980350102542, 'stds': 0.029884014518789213, 'ensemble_standard_error': 0.03261147170624149}, 'metadata': {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}}]

5. Bekerja dengan opsi Runtime​

Teknik mitigasi error memungkinkan pengguna mengurangi error pada Circuit dengan memodelkan noise perangkat saat eksekusi berlangsung. Hal ini biasanya menghasilkan overhead pra-pemrosesan kuantum terkait pelatihan model, serta overhead pasca-pemrosesan klasikal untuk mengurangi error pada hasil mentah menggunakan model yang dihasilkan.

Teknik mitigasi error yang sudah terintegrasi ke dalam primitives adalah opsi resilience tingkat lanjut. Untuk menentukan opsi-opsi ini, gunakan opsi resilience_level saat mengirimkan job kamu.

Contoh-contoh berikut mendemonstrasikan opsi default untuk dynamical decoupling, twirling, dan TREX + ZNE. Temukan lebih banyak opsi dan detail lebih lanjut di topik Teknik mitigasi dan supresi error.

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "BACKEND_NAME"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'estimator',
"backend": backend,
"params": {
"pubs": [ #primitive unified blocs (PUBs) containing one circuit each
[resulting_qasm, # QASM circuit
{"IIZII": 1, "XIZZZ": 2.3}, # Observable
None # parameter values
]]
"options": {
"resilience": {
"measure_mitigation": True,
"zne_mitigation": True,
"zne": {
"extrapolator":["exponential", "linear"],
"noise_factors":[1, 3, 5],
},
},
},
}
}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")

Sampler primitive with REST API​

1. Initialize the account​

Because Qiskit Runtime Sampler is a managed service, you first need to initialize your account. You can then select the device you want to use to run your calculations on.

Find details on how to initialize your account, view available backends, and invalidate tokens in this topic.

2. Create a QASM circuit​

You need at least one circuit as the input to the Sampler primitive.

Define a QASM quantum circuit:

qasm_string='''
OPENQASM 3;
include "stdgates.inc";
qreg q[2];
creg c[2];
x q[0];
cx q[0], q[1];
c[0] = measure q[0];
c[1] = measure q[1];
'''

The code snippets given below assume that the qasm_string has been transpiled to a new string resulting_qasm.

3. Run the quantum circuit using Sampler V2 API​

catatan

The jobs below use Qiskit Runtime V2 primitives. Both SamplerV2 and EstimatorV2 take one or more primitive unified blocs (PUBs) as the input. Each PUB is a tuple that contains one circuit and the data broadcasted to that circuit, which can be multiple observables and parameters. Each PUB returns a result.

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
"pubs": [[resulting_qasm],[resulting_qasm,None,500]] # primitive unified blocs (PUBs) containing one circuit each.
}}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")

4. Check job status and get results​

Next, pass the job_id to the API:

response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')

Output

>>> Job ID: 58223448-5100-4dec-a47a-942fb30edced
>>> Job Status: JobStatus.RUNNING

Get job results:

response_result= requests.get(url+'/'+job_id+'/results', headers=headers)

res_dict=response_result.json()

# Get results for the first PUB
counts=res_dict['results'][0]['data']['c']['samples']

print(counts[:20])

Output

['0x3', '0x0', '0x2', '0x1', '0x0', '0x3', '0x0', '0x3', '0x1', '0x2', '0x2', '0x0', '0x2', '0x0', '0x3', '0x3', '0x2', '0x0', '0x1', '0x0']

5. Work with Runtime options​

Error mitigation techniques allow users to mitigate circuit errors by modeling the device noise at the time of execution. This typically results in quantum pre-processing overhead related to model training, and classical post-processing overhead to mitigate errors in the raw results by using the generated model.

The error mitigation techniques built in to primitives are advanced resilience options. To specify these options, use the resilience_level option when submitting your job. Sampler V2 does not support specifying resilience levels. However, you can turn on or off individual error mitigation / suppression methods.

The following examples demonstrate the default options for dynamical decoupling and twirling. Find more options and further details in the Error mitigation and suppression techniques topic.

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
"pubs": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each.
"options": {
"dynamical_decoupling": {
"enable": True,
"sequence_type": 'XpXm',
"extra_slack_distribution": 'middle',
"scheduling_method": 'alap',
},
},
}
}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")

Sampler primitive with REST API and parameterized circuits​

1. Initialize the account​

Because Qiskit Runtime is a managed service, you first need to initialize your account. You can then select the device you want to use to run your calculations on.

Find details on how to initialize your account, view available backends, and invalidate tokens in this topic.

2. Define parameters​

import requests
import qiskit_ibm_runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.qasm3 import dumps
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit import transpile

service = QiskitRuntimeService(channel='ibm_quantum')
backend = service.backend("<SPECIFY BACKEND>")

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)

theta = Parameter('theta')
phi = Parameter('phi')
parameter_values = {'theta': 1.57, 'phi': 3.14} # In case we want to pass a dictionary

3. Create a quantum circuit and add parameterized gates​

qc = QuantumCircuit(2)

# Add parameterized gates
qc.rx(theta, 0)
qc.ry(phi, 1)
qc.cx(0, 1)
qc.measure_all()

# Draw the original circuit
qc.draw('mpl')

# Get an ISA circuit
isa_circuit = pm.run(qc)

4. Generate QASM 3 code​

qasm_str = dumps(isa_circuit)
print("Generated QASM 3 code:")
print(qasm_str)

5. Run the quantum circuit using Sampler V2 API​

catatan

The following jobs use Qiskit Runtime V2 primitives. Both SamplerV2 and EstimatorV2 take one or more primitive unified blocs (PUBs) as the input. Each PUB is a tuple that contains one circuit and the data broadcasted to that circuit, which can be multiple observables and parameters. Each PUB returns a result.

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}

job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
# Choose one option: direct parameter transfer or through a dictionary
#"pubs": [[qasm_str,[1,2],500]], # primitive unified blocs (PUBs) containing one circuit each.
"pubs": [[qasm_str,parameter_values,500]], # primitive unified blocs (PUBs) containing one circuit each.
}}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print(f"Job created: {response.text}")
else:
print(f"Error: {response.status_code}")
print(response.text)

6. Check job status and get results​

Next, pass the job_id to the API:

response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers)
response_status_singlejob.json().get('state')

Output

{'status': 'Completed'}

Get job results:

response_result = requests.get(f"{url}/{job_id}/results", headers=headers)

res_dict=response_result.json()

# Get results for the first PUB
counts=res_dict['results'][0]['data']['c']['samples']

print(counts[:20])

Output

['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']

Langkah selanjutnya​

Rekomendasi
Source: IBM Quantum docs β€” updated 27 Apr 2026
English version on doQumentation β€” updated 7 Mei 2026
This translation based on the English version of 11 Mar 2026