Resources#

This chapter describes supported Solver Application Programming Interface (SAPI) resources and provides example usages.

Examples Setup#

The examples below use the following setup:

>>> import base64
>>> import hashlib
>>> import json
>>> import os
>>> import requests
>>> import struct
>>> from urllib.parse import urlencode
...
>>> SAPI_HOME = "https://na-west-1.cloud.dwavesys.com/sapi/v2"
... # Replace with your API token
>>> SAPI_TOKEN = "ABC-1234567...345678"     
...
>>> session = requests.Session()
>>> session.headers = {'X-Auth-Token': SAPI_TOKEN, 'Content-type': 'application/json'}

For some examples of uploading problems to the Leap service’s quantum-classical hybrid solvers, a serialized binary quadratic model (\(\text{E} = -ab\)) is also used. The following code uses Ocean software to serialize the problem to the required format.[1]

>>> import dimod
>>> bqm = dimod.BinaryQuadraticModel({}, {'xy': -1}, 'BINARY')
>>> bqm_ser = bqm.to_file().read()
$ export SAPI_HOME=https://na-west-1.cloud.dwavesys.com/sapi/v2
$ export SAPI_TOKEN=ABC-1234567...345678       # Replace with your API token

For some examples of uploading problems to the Leap service’s quantum-classical hybrid solvers, a serialized binary quadratic model (\(\text{E} = -ab\)) is also used. The dimod to_file() method is used to serialize the problem, which is saved to a file.

Example serialized file

The serialized file may look like this:

b'DIMODBQM\x02\x00\xb2\x00\x00\x00{"dtype": "float64", "itype": "int32",
"ntype": "int32", "shape": [2, 1], "type": "BinaryQuadraticModel", "variables": true,
"vartype": "BINARY"}\n                                \x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xbf
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xbfVARS8\x00\x00
\x00["x", "y"]

SAPI Resources#

SAPI provides the following resources and methods.

Table 59 SAPI Resources#

Resource

Method

Reference

/bqm/multipart

POST

Initiate Upload of Problem Data

/bqm/multipart/<problem_data_id>/part/<part>

PUT

Upload Problem Data

/bqm/multipart/<problem_data_id>/combine

POST

Submit a Checksum for a Problem Upload

/bqm/multipart/<problem_data_id>/status

GET

Status of a Problem Upload

/problems/

POST

Submit Problems

/problems/

DELETE

Cancel Multiple Problems

/problems/<problem_id>

DELETE

Cancel a Problem by ID

/problems/

GET

List Problems

/problems/<problem_id>/

GET

Retrieve a Problem

/problems/<problem_id>/info

GET

Retrieve Problem Information

/problems/<problem_id>/answer/

GET

Retrieve an Answer

/problems/<problem_id>/messages/

GET

Retrieve Problem Messages

/solvers/remote/

GET

Retrieve Available Solvers

/solvers/remote/<solver_id>/

GET

Retrieve Solver Fields

Initiate Upload of Problem Data#

For quantum-classical hybrid solvers in the Leap service, you must upload your problem using the $SAPI_HOME/bqm/multipart/* endpoints before submitting a SAPI request to run the problem. For large problems (starting from several megabytes and higher), upload the problem data in multiple parts.

  • Maximum problem size currently supported is 50 GB.

  • Size of all parts must be 5M (5242880 bytes), except the last, which may be smaller.

To initiate the uploading of a problem, in a single part for small problems or multiple parts for problems of several megabytes and higher, send an HTTP POST request to bqm/multipart.

The POST request body should contain the number of bytes—size, as an integer—required to store the problem.

SAPI returns an identifier, of type UUID, for the uploaded problem.

This example initiates an upload of the serialized BQM, bqm_ser, created in the Examples Setup section.

>>> size = len(bqm_ser)
>>> r = session.post(f"{SAPI_HOME}/bqm/multipart",
...                  json={"size": size})

This example sets the size of the uploaded problem, size, to the number of bytes of the serialized BQM of the Examples Setup section.

$ size=312
$ curl -H "X-Auth-Token: $SAPI_TOKEN" -H "Content-type: application/json" \
-X POST $SAPI_HOME/bqm/multipart/ -d '{"size": '"$size"'}'
{"id":"be806ff1-09d3-49d4-bba1-3008790c99d6"}
2xx responses

SAPI returns a 200 OK response with an identifier for the problem data that is to be uploaded.

>>> problem_data_id = r.json()["id"]
>>> print(problem_data_id)    
be806ff1-09d3-49d4-bba1-3008790c99d6
Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 400 for a failure to initiate upload

Below are some example error responses:

>>> r.status_code   
401
>>> r.reason   
'Unauthorized'

Upload Problem Data#

To upload a problem, or parts of a large problem, send an HTTP PUT request to bqm/multipart/<problem_data_id>/part/<part> (for each part, where <part> is an integer beginning at 1).

The POST request body should contain the data for (one part of) the problem, encoded as described in the dimod to_file() method, and the header should contain the MD5 checksum.

For a multi-part upload, data size for each part should be 5 MB (5242880 bytes), except for the last part, which may be smaller.

Calculating the MD5 Hash

The MD5 checksum can be found, for example, using the Python hashlib library. The following code example finds the checksum for the problem created in the Examples Setup section.

>>> import hashlib
>>> import base64
...
>>> # For small problems:
>>> hash_md5 = hashlib.md5()
>>> hash_md5.update(bqm_ser)
>>> part_hash = base64.b64encode(hash_md5.digest()).decode('utf-8')
>>> print(part_hash)
mkDiHuw5xZD3ocYSikE4nw==

>>> # For large problems:
>>> hash_md5 = hashlib.md5()
>>> with bqm.to_file() as f:    # for a saved file: with open("filename", "r")
...  for chunk in iter(lambda: f.read(4096), b""):
...   hash_md5.update(chunk)
>>> part_hash = (base64.b64encode(hash_md5.digest()).decode('utf-8'))
>>> print(part_hash)
mkDiHuw5xZD3ocYSikE4nw==

This example uses the identifier problem_data_id returned from the Initiate Upload of Problem Data example and an MD5 hash calculated above.

>>> r = session.put(f"{SAPI_HOME}/bqm/multipart/{problem_data_id}/part/1",
...                  headers={"Content-type": "application/octet-stream",
...                           "Content-MD5": "mkDiHuw5xZD3ocYSikE4nw=="},
...                  data=bqm_ser)

This example sets the identifier, problem_data_id, of the problem data to be uploaded to the value returned from the Initiate Upload of Problem Data example, the MD5 checksum, md5, to the value calculated above, and the uploaded data to the BQM of the Examples Setup section saved to file my_bqm.txt.

$ problem_data_id="be806ff1-09d3-49d4-bba1-3008790c99d6"
$ md5="mkDiHuw5xZD3ocYSikE4nw=="
$ curl -H "X-Auth-Token: $SAPI_TOKEN" -H "Content-MD5: $md5" -H \
"Content-type: application/octet-stream" -X PUT \
$SAPI_HOME/bqm/multipart/$problem_data_id/part/1 -T my_bqm.txt
2xx responses

SAPI returns a 200 OK response.

You can check the upload status using the method shown in the Status of a Problem Upload section.

>>> session.get(f"{SAPI_HOME}/bqm/multipart/{problem_data_id}/status").json()   
{'status': 'UPLOAD_IN_PROGRESS',
 'parts': [{'part_number': 1, 'checksum': '9a40e21eec39c590f7a1c6128a41389f'}]}
Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 400 for a failure to upload or invalid checksum

  • 404 for a failure to find the specified upload

  • 415 for incorrect media type

Below is and example error response to an incorrect MD5:

>>> r.status_code   
401
>>> r.reason   
'Bad Request'

Below is and example error response to an incorrect content type:

>>> r.status_code   
415
>>> r.reason   
'Unsupported Media Type'

Submit a Checksum for a Problem Upload#

To complete an upload of problem data, send an HTTP POST request to bqm/multipart/<problem_data_id>/combine.

The POST request body should contain the checksum for the entire problem, as a string.

Calculating the Checksum

The Leap service calculates the checksum of the combined file in a particular way: it concatenates all the checksums of the parts and then calculates the checksum of that concatenation. Your checksum must follow this same format.

The checksum can be found, for example, using the Python hashlib library. The examples below find the concatenated checksum for the problem of the Examples Setup section and for an artificial problem that reuses that same problem to represent two parts for the sole purpose of constructing a combined checksum.

>>> # For a problem uploaded in a single part:
>>> hash_md5 = hashlib.md5()
>>> hash_md5.update(bqm_ser)
>>> problem_checksum = (hashlib.md5(bytes.fromhex(hash_md5.hexdigest()))).hexdigest()
>>> print(problem_checksum)
baf79ab99e269f7fda21e927b33345e9

>>> # For large problems:
>>> hash_md5_1 = hashlib.md5()
>>> hash_md5_1.update(bqm_ser)  # replace bqm_ser with the part 1 data
>>> hash_md5_2 = hashlib.md5()
>>> hash_md5_2.update(bqm_ser)  # replace bqm_ser with the part 2 data
>>> print((hashlib.md5(bytes.fromhex(
...        hash_md5_1.hexdigest() +
...        hash_md5_2.hexdigest())
...        )).hexdigest())
65e5a89d30c855758d71844a927a8133

This example uses the identifier problem_data_id returned from the Initiate Upload of Problem Data example and a checksum calculated above.

>>> r = session.post(f"{SAPI_HOME}/bqm/multipart/{problem_data_id}/combine",
...                   json={"checksum": "baf79ab99e269f7fda21e927b33345e9"})

This example sets the identifier, problem_data_id, of the problem data to be uploaded to the value returned from the Initiate Upload of Problem Data example and the checksum, checksum, to the value calculated above.

$ problem_data_id="be806ff1-09d3-49d4-bba1-3008790c99d6"
$ checksum="baf79ab99e269f7fda21e927b33345e9"
$ curl  -H "X-Auth-Token: $SAPI_TOKEN" -H "Content-type: application/json" \
-X POST $SAPI_HOME/bqm/multipart/$problem_data_id/combine/ -d '{"checksum":'"$checksum"'}'
2xx responses

SAPI returns a 200 OK response.

You can check the upload status using the method shown in the Status of a Problem Upload section.

>>> session.get(f"{SAPI_HOME}/bqm/multipart/{problem_data_id}/status").json()
{'status': 'UPLOAD_COMPLETED', 'parts': []}
Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 400 for a failure to upload or missing or invalid checksum

  • 404 for a failure to find the specified upload

Below are some example error responses:

>>> r.reason   
Failed to combine the multipart upload

Status of a Problem Upload#

To query the status of an in-progress problem upload, send an HTTP GET request to bqm/multipart/<problem_data_id>/status.

The GET request should contain no body.

SAPI returns the status as a string with parts and checksums.

This example uses the identifier problem_data_id returned from the Initiate Upload of Problem Data example.

>>> r = session.get(f"{SAPI_HOME}/bqm/multipart/{problem_data_id}/status")

This example sets the identifier, problem_data_id, of the problem data being uploaded to the value returned from the Initiate Upload of Problem Data example.

$ problem_data_id="be806ff1-09d3-49d4-bba1-3008790c99d6"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/bqm/multipart/$problem_data_id/status
2xx responses

SAPI returns a 200 OK response.

For an ongoing upload, SAPI returns a status similar to the following:

>>> r.json()   
{'status': 'UPLOAD_IN_PROGRESS',
 'parts': [{'part_number': 1, 'checksum': '9a40e21eec39c590f7a1c6128a41389f'}]}

For a successfully completed upload, SAPI returns a status similar to the following:

>>> r.json()   
{'status': 'UPLOAD_COMPLETED', 'parts': []}
Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 404 for a failure to find the specified upload

Submit Problems#

To submit problems to a solver in the Leap service, send an HTTP POST request to problems.

The POST request body should contain the JSON-encoded fields described below. When possible, if you have more than one problem, submit them in a single query.[2]

Fields in Request Body

The JSON data for the submitted problem includes the following key-value pairs:

Table 60 Key-Value Pairs for problems Request#

Key

Value

data

Encoded problem data; see below.

label

Optional user-defined string to label the problem.

params

Solver-specific parameters.

solver

Solver to be used.

type

One of the supported problem types.

Table 61 Problem data Field and Encoding#

Key

Value and Encoding

format

Format of the problem data as a string. Supported values are:

lin

For data with format="qp", linear coefficients as base64-encoded little-endian doubles.

Set values for all qubits of the QPU’s working graph in the same order as the qubits solver property.

  • For qubits used to represent your problem (active qubits), set to the corresponding linear biases of your problem.

  • For qubits not used to represent your problem (inactive qubits), set to NaN.

For example, before encoding, a lin of length 5627 might have a value (-0.5, 0.5, nan, nan, ...) representing biases only on qubits 30 and 31 on an Advantage™ QPU for which the qubits property has a value starting as [30, 31, 32, 33, ... and a length of 5627 (a working graph of 5627 qubits). After encoding, it might look like AAAAAAAA4L8AAAAAAADgPw ... D4fw==.

Not used for data with format="ref".

quad

For data with format="qp", quadratic coefficients as base64-encoded little-endian doubles.

Set one value per active coupler in the same order as the couplers solver property. An active coupler means that both qubits the coupler is incident to are active. NaN values are not permitted.

For example, before encoding, a quad of length 1 might have a value (-1.0) representing a single interaction between qubits 30 and 31 on an Advantage QPU for which the couplers property has a value starting as [[30, 31], [31, 32], [32, 33], ... and a length of 40279. After encoding, it might look like AAAAAAAA8L8=.

Not used for data with format="ref".

For an example of sumitting a problem to a quantum processing unit (QPU) sampler, see the End-to-End Examples section.

This example uses the identifier problem_data_id returned from the Initiate Upload of Problem Data example and hybrid solver solver_hybrid_bqm selected as in the Submit a Problem to a Quantum-Classical Hybrid Solver section.

>>> r = session.post(f"{SAPI_HOME}/problems",
...                   json=[{"solver": solver_hybrid_bqm,
...                          "label": "REST Submission to hybrid BQM solver",
...                          "data": {"format": "ref", "data": problem_data_id},
...                          "type": "bqm",
...                          "params": {"time_limit": 5}}])

This example sets the identifier, problem_data_id, of the problem data being uploaded to the value returned from the Initiate Upload of Problem Data example and sets the requested solver to hybrid_binary_quadratic_model_version2p, a solver available to the user account that executed this example.

$ problem_data_id="be806ff1-09d3-49d4-bba1-3008790c99d6"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems -X POST \
-d '[{"type":"bqm","label": "REST Submission to hybrid BQM solver", \
"solver":"hybrid_binary_quadratic_model_version2p", \
"data":{"format": "ref", "data": "'"$problem_data_id"'"}, \
"params":{"time_limit":5}}]'
2xx responses

SAPI returns a 200 OK response with the problem identifier.

Below are some example 201 responses:

>>> r.json()   
{'status': 'IN_PROGRESS',
 'id': 'a239c000-10de-4663-b562-af8029c0c470',
 'solver': 'hybrid_binary_quadratic_model_version2p',
 'type': 'bqm',
 'submitted_on': '2022-09-01T16:48:36.052206Z',
 'label': 'REST Submission to hybrid BQM solver'}
>>> r.json()  
{'status': 'COMPLETED',
 'id': '51fa2c98-3f19-4dd9-9f2d-c4295278218f',
 'solver': 'Advantage_system4.1',
 'type': 'ising',
 'submitted_on': '2022-09-01T17:55:00.877038Z',
 'label': 'QPU REST submission 1',
 'solved_on': '2022-09-01T17:55:01.087126Z',
 'answer': {'solutions': 'AMA=',
            'energies': 'AAAAAAAA8L8AAAAAAADwvw==',
 ... # SNIPPED FOR BREVITY
            'num_variables': 5760}
}

The following table describes fields in the responses above.

Table 62 Problem Resource Fields#

Key

Value

answer

Content of the answer depends on the solver and parameters used.

id

Unique identifier of the problem. Can be used to retrieve problem information, solutions, and messages.

label

Optional user-defined string (label) for a problem.

status

One of the problem states as defined in SAPI Problem Lifecycle. For example, CANCELLED for cancelled problems.

submitted_on

Time when problem was submitted.

solved_on

If this problem is in terminal state (COMPLETED, CANCELLED or FAILED), time when problem was solved or cancelled.

type

One of the supported problem types.

The following table describes the answer field for a QPU solver.

Table 63 answer Field and Encoding for QPU Solvers#

Key

Value

format

String: qp

num_variables

Total number of variables (active or otherwise) that the solver has. JSON integer.

solutions

Base-64–encoded string of bit-packed solutions (with 0 = -1 for Ising problems). Bits are in little-endian order. Each solution is padded to end on a byte boundary and contains values for active qubits only. Ordered by the values of energies.

energies

Base-64–encoded string of energies, each a little-endian 8-byte floating-point number (doubles). Ordered from low to high.

active_variables

Base-64–encoded string of the indices of the problem’s active variables. The indices are 4-byte little-endian integers.

num_occurrences

Base-64–encoded string of the number of occurrences of each solution when answer_mode is histogram. The numbers are 4-byte little-endian integers. Ordered by the values of energies.

timing

Solver-specific JSON object reporting the time that the solver took to handle the problem.

For quantum-classical hybrid solvers, the answer field differs. For example, format might be bq and fields might include the type of variables (e.g., INTEGER), version, etc.

Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 400 for various failures

Below are some example error responses:

>>> r.json()   
{'error_code': 400,
 'error_msg': 'Problem type (cqm) is not supported by the solver.'}
>>> r.json()   
{'error_code': 400,
 'error_msg': 'Attempting to run a problem for less than the allowed minimum time_limit 3.0 s'}
>>> r.json()   
{'error_code': 400,
 'error_msg': 'Solver does not exist or apitoken does not have access'}

Cancel Multiple Problems#

To cancel pending problems (problems with status PENDING), send an HTTP DELETE request to problems.

The request body should be a JSON-encoded list of problem IDs; if the request body is empty, the request has no effect.

When possible, if you have more than one problem to cancel, submit them in a single query.

>>> id_list = ["74d9344c-0160-47bc-b7b1-e245b2ffd955",
...            "25f98470-bc55-476c-9042-120bbc0336cf"]
...
>>> r = session.delete(f"{SAPI_HOME}/problems", json=id_list)
$ id_list=[\"74d9344c-0160-47bc-b7b1-e245b2ffd955\",\"25f98470-bc55-476c-9042-120bbc0336cf\"]
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems -X DELETE -d $id_list
2xx responses

SAPI returns a 2xx response. Below are some example 2xx responses:

  • 200 for cancelled problem

  • 202 for cancellation request received for in-progress jobs. The problem is cancelled if the request was received in time; otherwise, it will complete.

>>> r.json()   
[{'status': 'CANCELLED',
  'id': '74d9344c-0160-47bc-b7b1-e245b2ffd955',
  'solver': 'hybrid_binary_quadratic_model_version2p',
  'type': 'bqm',
  'submitted_on': '2022-09-01T18:20:02.594833Z',
  'label': 'REST Submission to hybrid BQM solver',
  'solved_on': '2022-09-01T18:20:03.708681Z'}]
>>> r.json()   
[{'error_code': 202, 'error_msg': 'Attempting to cancel problem in progress.'},
 {'error_code': 202, 'error_msg': 'Attempting to cancel problem in progress.'}]
>>> r = session.get(SAPI_HOME + "/problems/74d9344c-0160-47bc-b7b1-e245b2ffd955/info") 
>>> r.json()['metadata']['status']       
'CANCELLED'
>>> r.json()   
[{'error_code': 202, 'error_msg': 'Attempting to cancel problem in progress.'},
 {'error_code': 202, 'error_msg': 'Attempting to cancel problem in progress.'}]
>>> r = session.get(SAPI_HOME + "/problems/7d341c42-0eea-460a-b7d0-82892a4a6726/info") 
>>> r.json()['metadata']['status']       
'COMPLETED'

The following table describes fields in the responses above.

Table 64 Problem Resource Fields#

Key

Value

answer

Content of the answer depends on the solver and parameters used.

id

Unique identifier of the problem. Can be used to retrieve problem information, solutions, and messages.

label

Optional user-defined string (label) for a problem.

status

One of the problem states as defined in SAPI Problem Lifecycle. For example, CANCELLED for cancelled problems.

submitted_on

Time when problem was submitted.

solved_on

If this problem is in terminal state (COMPLETED, CANCELLED or FAILED), time when problem was solved or cancelled.

type

One of the supported problem types.

Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 404 for nonexistent problem ID

  • 409 for a poblem that reached a terminal states before the request

Below are some example error responses:

>>> r.json()   
[{'error_code': 409, 'error_msg': 'Problem has been finished.'},
 {'error_code': 409, 'error_msg': 'Problem has been finished.'}]

Cancel a Problem by ID#

To cancel a previously submitted problem, make an HTTP DELETE request to problems/<problem_id>.

The request should contain no body.

>>> problem_id = "74d9344c-0160-47bc-b7b1-e245b2ffd955"
...
>>> r = session.delete(f"{SAPI_HOME}/problems/{problem_id}")
$ problem_id="74d9344c-0160-47bc-b7b1-e245b2ffd955"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems/$problem_id -X DELETE
2xx responses

SAPI returns a 2xx response. Below are some example 2xx responses:

  • 200 for cancelled problem

  • 202 for cancellation request received for in-progress jobs. The problem is cancelled if the request was received in time; otherwise, it will complete.

>>> r.json()   
{'status': 'CANCELLED',
 'id': 'd92d5b66-330b-4bfd-b26f-a6220b4d2710',
 'solver': 'hybrid_binary_quadratic_model_version2p',
 'type': 'bqm',
 'submitted_on': '2022-09-01T20:09:55.377688Z',
 'label': 'REST Submission to hybrid BQM solver',
 'solved_on': '2022-09-01T20:09:56.489498Z'}

The following table describes fields in the response above.

Table 65 Problem Resource Fields#

Key

Value

answer

Content of the answer depends on the solver and parameters used.

id

Unique identifier of the problem. Can be used to retrieve problem information, solutions, and messages.

label

Optional user-defined string (label) for a problem.

status

One of the problem states as defined in SAPI Problem Lifecycle. For example, CANCELLED for cancelled problems.

submitted_on

Time when problem was submitted.

solved_on

If this problem is in terminal state (COMPLETED, CANCELLED or FAILED), time when problem was solved or cancelled.

type

One of the supported problem types.

Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 404 for nonexistent problem ID

  • 409 for a poblem that reached a terminal states before the request

Below are some example error responses:

>>> r.json()   
{'error_code': 409,
 'error_msg': 'Problem has been finished.'}

List Problems#

To retrieve a list of previously submitted problems, send an HTTP GET request to problems.

The request should contain no body.

By default, the request blocks for up to one second unless at least one problem has completed processing.

You can customize polling by adding the optional timeout parameter to specify the blocking time, in seconds, for this request. Supported values are integers between 1 to 30.

You can filter the results using one or more optional filter keys, concatenated with an ampersand (”&”).

Filter Keys
Table 66 Key-Value Pairs for filtering Results of List Problems#

Key

Value

id

Comma-separated list of problem IDs

label

Labels that contain the given text.

max_results

Maximum number of results to return. Returns up to 1000 if not specified.

status

Problem state: COMPLETED, IN_PROGRESS, PENDING, FAILED, CANCELLED.

solver

Solver name (e.g., hybrid_binary_quadratic_model_version2p).

>>> r = session.get(f"{SAPI_HOME}/problems/?max_results=3")
$ filter="solver=Advantage_system4.1&max_results=3"
$ curl  -H "X-Auth-Token: $SAPI_TOKEN" -X GET "$SAPI_HOME/problems/?$filter"
2xx response

SAPI returns a 200 OK response.

>>> r.json()  
[{'id': 'fe863ae1-1d7e-4444-a18e-c1fe7708b8a0',
  'solver': 'Advantage_system4.1',
  'type': 'ising',
  'label': 'QPU REST submission 1',
  'submitted_on': '2022-08-29T15:13:11.532127Z',
  'solved_on': '2022-08-29T15:13:11.709085Z',
  'status': 'COMPLETED'},
 {'id': '25f98470-bc55-476c-9042-120bbc0336cf',
  'solver': 'Advantage_system4.1',
  'type': 'ising',
  'label': 'QPU REST submission 1',
  'submitted_on': '2022-08-29T15:12:10.461598Z',
  'solved_on': '2022-08-29T15:12:10.635163Z',
  'status': 'COMPLETED'},
 {'id': 'a56da5c5-f8a9-49ad-885b-d7e1b117639e',
  'solver': 'Advantage_system4.1',
  'type': 'ising',
  'label': 'QPU REST submission 1',
  'submitted_on': '2022-08-29T15:11:38.897970Z',
  'solved_on': '2022-08-29T15:11:39.088480Z',
  'status': 'COMPLETED'}]

The following table describes fields in the response above.

Table 67 Problem Resource Fields#

Key

Value

answer

Content of the answer depends on the solver and parameters used.

id

Unique identifier of the problem. Can be used to retrieve problem information, solutions, and messages.

label

Optional user-defined string (label) for a problem.

status

One of the problem states as defined in SAPI Problem Lifecycle. For example, CANCELLED for cancelled problems.

submitted_on

Time when problem was submitted.

solved_on

If this problem is in terminal state (COMPLETED, CANCELLED or FAILED), time when problem was solved or cancelled.

type

One of the supported problem types.

Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 400 if timeout is specified as an unsupported value

  • 404 for nonexistent or non-accessible problem ID

  • 410 for submitted problems that are no longer accessible

Below are some example error responses:

>>> r.text   
'Problem does not exist or apitoken does not have access'

Retrieve a Problem#

To retrieve a previously submitted problem, send an HTTP GET request to problems/<problem_id>.

The request should contain no body.

By default, the request blocks for up to one second if a submitted problem has not completed processing.

You can customize polling by adding the optional timeout parameter to specify the blocking time, in seconds, for this request. Supported values are integers between 1 to 30.

>>> problem_id = "74d9344c-0160-47bc-b7b1-e245b2ffd955"
...
>>> r = session.get(f"{SAPI_HOME}/problems/{problem_id}?timeout=5")
$ problem_id="74d9344c-0160-47bc-b7b1-e245b2ffd955"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems/$problem_id?timeout=5 -X GET
2xx responses

SAPI returns a 200 OK response.

>>> r.json()   
{'status': 'COMPLETED',
 'id': '74d9344c-0160-47bc-b7b1-e245b2ffd955',
 'solver': 'hybrid_binary_quadratic_model_version2p',
 'type': 'bqm',
 'submitted_on': '2022-08-31T14:27:47.822848Z',
 'label': 'hybrid BQM solver REST Submission python 2',
 'solved_on': '2022-08-31T14:27:55.497511Z',
 'answer': {'format': 'bq',
 ... # SNIPPED FOR BREVITY
 'charge_time': 4981622,
 'run_time': 4981622}}}}

The following table describes fields in the response above.

Table 68 Problem Resource Fields#

Key

Value

answer

Content of the answer depends on the solver and parameters used.

id

Unique identifier of the problem. Can be used to retrieve problem information, solutions, and messages.

label

Optional user-defined string (label) for a problem.

status

One of the problem states as defined in SAPI Problem Lifecycle. For example, CANCELLED for cancelled problems.

submitted_on

Time when problem was submitted.

solved_on

If this problem is in terminal state (COMPLETED, CANCELLED or FAILED), time when problem was solved or cancelled.

type

One of the supported problem types.

The following table describes the answer field for a QPU solver.

Table 69 answer Field and Encoding for QPU Solvers#

Key

Value

format

String: qp

num_variables

Total number of variables (active or otherwise) that the solver has. JSON integer.

solutions

Base-64–encoded string of bit-packed solutions (with 0 = -1 for Ising problems). Bits are in little-endian order. Each solution is padded to end on a byte boundary and contains values for active qubits only. Ordered by the values of energies.

energies

Base-64–encoded string of energies, each a little-endian 8-byte floating-point number (doubles). Ordered from low to high.

active_variables

Base-64–encoded string of the indices of the problem’s active variables. The indices are 4-byte little-endian integers.

num_occurrences

Base-64–encoded string of the number of occurrences of each solution when answer_mode is histogram. The numbers are 4-byte little-endian integers. Ordered by the values of energies.

timing

Solver-specific JSON object reporting the time that the solver took to handle the problem.

For quantum-classical hybrid solvers, the answer field differs. For example, format might be bq and fields might include the type of variables (e.g., INTEGER), version, etc.

Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 400 if timeout is specified as an unsupported value

  • 404 for nonexistent problem ID

  • 410 for submitted problems that are no longer accessible

Below are some example error responses:

>>> r.json()   
{'error_code': 404,
 'error_msg': 'Problem does not exist or apitoken does not have access'}

Retrieve Problem Information#

To retrieve information about a problem, send an HTTP GET request to problems/<problem_id>/info:

The request should contain no body.

>>> problem_id = "74d9344c-0160-47bc-b7b1-e245b2ffd955"
...
>>> r = session.get(f"{SAPI_HOME}/problems/{problem_id}/info")
$ problem_id="74d9344c-0160-47bc-b7b1-e245b2ffd955"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems/$problem_id/info -X GET
2xx responses

SAPI returns a 200 OK response.

>>> r.json()   
{'id': '7d341c42-0eea-460a-b7d0-82892a4a6726',
 'data': {'format': 'ref', 'data': 'be806ff1-09d3-49d4-bba1-3008790c99d6'},
 'params': {'time_limit': 5},
 'metadata': {'submitted_by': 'ABC-123456789...',
 'solver': 'hybrid_binary_quadratic_model_version2p',
 'type': 'bqm',
 'submitted_on': '2022-09-01T18:27:30.281252Z',
 'solved_on': '2022-09-01T18:27:35.473474Z',
 'status': 'COMPLETED',
 'messages': [],
 'label': 'REST Submission to hybrid BQM solver'},
 'answer': {'format': 'bq',
 ... # SNIPPED FOR BREVITY
 'run_time': 4998527}}}}

The following table describes fields in the response above.

Table 70 Problem Resource Fields#

Key

Value

answer

Content of the answer depends on the solver and parameters used.

id

Unique identifier of the problem. Can be used to retrieve problem information, solutions, and messages.

label

Optional user-defined string (label) for a problem.

status

One of the problem states as defined in SAPI Problem Lifecycle. For example, CANCELLED for cancelled problems.

submitted_on

Time when problem was submitted.

solved_on

If this problem is in terminal state (COMPLETED, CANCELLED or FAILED), time when problem was solved or cancelled.

type

One of the supported problem types.

The following table describes the answer field for a QPU solver.

Table 71 answer Field and Encoding for QPU Solvers#

Key

Value

format

String: qp

num_variables

Total number of variables (active or otherwise) that the solver has. JSON integer.

solutions

Base-64–encoded string of bit-packed solutions (with 0 = -1 for Ising problems). Bits are in little-endian order. Each solution is padded to end on a byte boundary and contains values for active qubits only. Ordered by the values of energies.

energies

Base-64–encoded string of energies, each a little-endian 8-byte floating-point number (doubles). Ordered from low to high.

active_variables

Base-64–encoded string of the indices of the problem’s active variables. The indices are 4-byte little-endian integers.

num_occurrences

Base-64–encoded string of the number of occurrences of each solution when answer_mode is histogram. The numbers are 4-byte little-endian integers. Ordered by the values of energies.

timing

Solver-specific JSON object reporting the time that the solver took to handle the problem.

For quantum-classical hybrid solvers, the answer field differs. For example, format might be bq and fields might include the type of variables (e.g., INTEGER), version, etc.

Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 404 for nonexistent problem ID

  • 410 for submitted problems that are no longer accessible

Below are some example error responses:

>>> r.json()   
{'error_code': 404,
 'error_msg': 'Problem does not exist or apitoken does not have access'}

Retrieve an Answer#

To retrieve an answer for a problem, send an HTTP GET request to problems/<problem_id>/answer. The answer consists of solution data in binary format or a URL to such solution data as well as additional problem information.

The request should contain no body.

>>> problem_id = "74d9344c-0160-47bc-b7b1-e245b2ffd955"
...
>>> r = session.get(f"{SAPI_HOME}/problems/{problem_id}/answer")
$ problem_id="74d9344c-0160-47bc-b7b1-e245b2ffd955"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems/$problem_id/answer -X GET
2xx responses
Quadratic models

SAPI returns a 200 OK response.

>>> r.json()   
{'answer': {'solutions': 'AMA=',
'energies': 'AAAAAAAA8L8AAAAAAADwvw==',
'timing': {'qpu_sampling_time': 769.4,
'qpu_anneal_time_per_sample': 20.0,
'qpu_readout_time_per_sample': 36.4,
'qpu_access_time': 15831.76,
'qpu_access_overhead_time': 6535.24,
'qpu_programming_time': 15062.36,
'qpu_delay_time_per_sample': 20.54,
'total_post_processing_time': 1853.0,
'post_processing_overhead_time': 1853.0},
'num_occurrences': 'BgAAAAQAAAA=',
'format': 'qp',
'active_variables': 'HgAAAB8AAAA=',
'num_variables': 5760}}

The following table describes the answer field for a QPU solver.

Table 72 answer Field and Encoding for QPU Solvers#

Key

Value

format

String: qp

num_variables

Total number of variables (active or otherwise) that the solver has. JSON integer.

solutions

Base-64–encoded string of bit-packed solutions (with 0 = -1 for Ising problems). Bits are in little-endian order. Each solution is padded to end on a byte boundary and contains values for active qubits only. Ordered by the values of energies.

energies

Base-64–encoded string of energies, each a little-endian 8-byte floating-point number (doubles). Ordered from low to high.

active_variables

Base-64–encoded string of the indices of the problem’s active variables. The indices are 4-byte little-endian integers.

num_occurrences

Base-64–encoded string of the number of occurrences of each solution when answer_mode is histogram. The numbers are 4-byte little-endian integers. Ordered by the values of energies.

timing

Solver-specific JSON object reporting the time that the solver took to handle the problem.

For quantum-classical hybrid solvers, the answer field differs. For example, format might be bq and fields might include the type of variables (e.g., INTEGER), version, etc.

Nonlinear models

SAPI returns a 200 OK response.

>>> r.json()    
{'answer': {'format': 'binary-ref',
'auth_method': 'sapi-token',
'url': 'https://cloud.dwavesys.com/sapi/v2/problems/74d9344c-0160-47bc-b7b1-e245b2ffd955/answer/data/',
'timing': {'qpu_access_time': 47512, 'warnings': [], 'charge_time': 1000000, 'run_time': 1067327},
'shape': {}}}
Table 73 Problem Resource Fields#

Key

Value

format

String: binary-ref.

auth_method

Authorization method required to download binary data specified in url.

url

URL to download the solution in binary format.

timing

Solver-specific JSON object reporting the time that the solver took to handle the problem.

shape

Shape of the nonlinear problem.

Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 404 for nonexistent problem ID

  • 410 for submitted problems that are no longer accessible

Below are some example error responses:

>>> r.text   
'Problem does not exist or apitoken does not have access'

Retrieve Problem Messages#

To retrieve messages for a problem, send an HTTP GET request to problems/<problem_id>/messages.

The request should contain no body.

>>> problem_id = "74d9344c-0160-47bc-b7b1-e245b2ffd955"
...
>>> r = session.get(f"{SAPI_HOME}/problems/{problem_id}/messages")
$ problem_id="74d9344c-0160-47bc-b7b1-e245b2ffd955"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/problems/$problem_id/messages -X GET
2xx responses

SAPI returns a 200 OK response.

>>> r.json()   
[]
Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 404 for nonexistent problem ID

  • 410 for submitted problems that are no longer accessible

Below are some example error responses:

>>> r.text   
'Problem does not exist or apitoken does not have access'

Retrieve Available Solvers#

To retrieve a list of available solvers from the Leap service, send an HTTP GET request to solvers/remote.

The request should contain no body.

The request supports the use of the If-None-Match request header. If the ETag (entity tag) value in the request header matches the one on the server, a 304 (Not Modified) response is returned; otherwise, the list of solvers is returned. You can use this feature to manage downloading and caching of this content.

By default, all solver fields are returned. You can use the filter parameter to get a subset of solver fields.

Filtering Solver Fields with the filter Parameter

To retrieve a subset of solver fields, create a list of the subset of solver fields by specifying the filter parameter via the following syntax:

filter={all|none}[,{+|-}field]... [,{+|-}field]

where:

all

Initializes the list with all solver fields. This is the default.

none

Initializes the list with no solver fields.

{+|-}field

Adds (+) or removes (-) a solver field to or from the list. The fields are evaluated left to right; for example, if a field is both added and removed, the last action prevails. To specify the solver properties in a solver’s properties dict, use dot notation as follows:

properties.property[.property]... [.property]

For example:

properties.problem_timing_data.typical_programming_time

If a field does not exist or a field does not contain a value, nothing is returned for that field. The maximum size of the SAPI URL in the request is 8 KB; thus, the specified filter parameter must not extend the URL beyond this maximum.

>>> filter = urlencode({"filter": "none,+id,+status,+avg_load,+properties.num_qubits,+properties.category"})
...
>>> r = session.get(f"{SAPI_HOME}/solvers/remote/?{filter}")
$ filter="filter=none%2C%2Bid%2C%2Bstatus"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/solvers/remote/?filter
2xx response

SAPI returns a 200 OK response.

The Cache-Control response header is returned with the following directives:

  • private

  • max-age: Specifies the time, in seconds, that the returned solver fields should be cached; the time depends on the expected longevity of the solver field values. Solver fields with values that change more frequently (e.g., avg_load) should probably be cached for a shorter time than fields with values that change infrequently (e.g., description and id). The value for this directive is based on the shortest cache-refresh time of the returned fields. (Use the filter parameter to return the desired subset of solver fields.)

>>> r = r.json()
>>> for i in range(len(r)):
...    print(f"{r[i]['id']} \n\tStatus: {r[i]['status']}    Load: {r[i]['avg_load']}")  
DW_2000Q_6
    Status: ONLINE    Load: 0.0
DW_2000Q_VFYC_6
    Status: ONLINE    Load: 0.0
hybrid_binary_quadratic_model_version2p
    Status: ONLINE    Load: 0.0
hybrid_discrete_quadratic_model_version1p
    Status: ONLINE    Load: 0.0
Advantage_system4.1
    Status: ONLINE    Load: 0.13
hybrid_constrained_quadratic_model_version1p
    Status: ONLINE    Load: 0.0
Advantage_system6.1
    Status: ONLINE    Load: 0.01
Advantage2_prototype1.1
    Status: ONLINE    Load: 0.0
Table 74 Solver Resource Fields#

Field

Description

avg_load

Average current load for the solver.

description

Description of the solver.

id

Unique ID (name) of the solver.

properties

Solver properties that reside in the properties dict; for example, supported problem types, active qubits, active couplers, total number of qubits, and so on.

status

Status of the solver; for example, a status of ONLINE is returned if it is available and OFFLINE if it is unavailable.

Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 304 for unmodified resource

Retrieve Solver Fields#

To retrieve the fields of a solver, send an HTTP GET request to solvers/remote/<solver_id>.

The request supports the If-None-Match request header. If the ETag (entity tag) value in the request header matches the one on the server, a 304 (Not Modified) response is returned; otherwise, the solver fields and values are returned. You can use this feature to manage downloading and caching of this content.

By default, all solver fields are returned. You can use the filter parameter to get a subset of solver fields.

Filtering Solver Fields with the filter Parameter

To retrieve a subset of solver fields, create a list of the subset of solver fields by specifying the filter parameter via the following syntax:

filter={all|none}[,{+|-}field]... [,{+|-}field]

where:

all

Initializes the list with all solver fields. This is the default.

none

Initializes the list with no solver fields.

{+|-}field

Adds (+) or removes (-) a solver field to or from the list. The fields are evaluated left to right; for example, if a field is both added and removed, the last action prevails. To specify the solver properties in a solver’s properties dict, use dot notation as follows:

properties.property[.property]... [.property]

For example:

properties.problem_timing_data.typical_programming_time

If a field does not exist or a field does not contain a value, nothing is returned for that field. The maximum size of the SAPI URL in the request is 8 KB; thus, the specified filter parameter must not extend the URL beyond this maximum.

>>> solver_name = "Advantage_system4.1"
>>> r = session.get(f"{SAPI_HOME}/solvers/remote/{solver_name}")
$ solver_name="Advantage_system4.1"
$ filter="none%2C%2Bstatus%2C%2Bavg_load%2C%2Bproperties.num_qubits"
$ curl -H "X-Auth-Token: $SAPI_TOKEN" $SAPI_HOME/solvers/remote/$solver_name/?filter
2xx response

SAPI returns a 200 OK response.

The Cache-Control response header is returned with the following directives:

  • private

  • max-age: Specifies the time, in seconds, that the returned solver fields should be cached; the time depends on the expected longevity of the solver field values. Solver fields with values that change more frequently (e.g., avg_load) should probably be cached for a shorter time than fields with values that change infrequently (e.g., description and id). The value for this directive is based on the shortest cache-refresh time of the returned fields. (Use the filter parameter to return the desired subset of solver fields.)

>>> r.json()['description']
'Advantage performance update'
Table 75 Solver Resource Fields#

Field

Description

avg_load

Average current load for the solver.

description

Description of the solver.

id

Unique ID (name) of the solver.

properties

Solver properties that reside in the properties dict; for example, supported problem types, active qubits, active couplers, total number of qubits, and so on.

status

Status of the solver; for example, a status of ONLINE is returned if it is available and OFFLINE if it is unavailable.

Error responses

In addition to generic client and server error responses, SAPI may return particular error codes.

  • 304 for unmodified resource