SoftQCOS Python SDK
A typed, synchronous Python client for the QCOS REST API at
https://api.softquantus.com. The SDK has no privileges of its own: each method
is one call to /api/v1/* (a few older ones to /v1/* or /api/v2/*), made
with your API key.
The SDK, the CLI (softqcos) and the MCP server (softqcos-mcp) are released
together and always carry the same version number. The table at the end of this
page lists what each version added, so you can tell whether the method you are
reading about exists in the version you have installed:
pip show softqcos-sdk
Install
pip install softqcos-sdk
Python 3.10 or newer. The base install calls the whole API and verifies
evidence offline (it includes cryptography for RSA-PSS and Ed25519 seals).
Optional extras pull in the frameworks you may want to convert circuits from:
qiskit, cirq, pennylane, simulation (Qiskit + Aer), ibm, braket,
azure. pqc adds liboqs-python to verify ML-DSA (FIPS 204) seals. It is
only the binding: the native liboqs shared library must be installed too, either
by running python -c "import oqs" once (liboqs-python downloads and builds it
into ~/_oqs; needs git, cmake and a C compiler) or by setting
OQS_INSTALL_PATH to the prefix of a shared build. Verification never builds it
for you: without the library an ML-DSA record verifies as signature_valid: None,
with the reason. all installs every extra:
pip install "softqcos-sdk[all]"
Authenticate
Create an API key at https://platform.softquantus.com/#apikeys.
from softqcos_sdk import QCOSClient
client = QCOSClient() # finds the key itself, see below
QCOSClient(api_key=None, base_url=None, timeout=30.0) resolves each setting
in this order. If no key is found it raises AuthenticationError.
| Setting | 1. argument | 2. environment | 3. file | default |
|---|---|---|---|---|
| key | api_key= |
QCOS_API_KEY |
~/.softqcos/config.json |
none |
| URL | base_url= |
QCOS_API_URL |
~/.softqcos/config.json |
https://api.softquantus.com |
The file is the one softqcos auth login writes, so a machine already signed
in with the CLI needs no further setup. Never put the key in source code.
Pointing base_url at localhost, 127.0.0.1 or [::1] makes the client
check for a local license at QCOS_PLATFORM_URL
(default https://platform.softquantus.com). Set QCOS_SKIP_LICENSE_CHECK=true
to skip it when you run QCOS yourself.
First job, on a simulator
from softqcos_sdk import QCOSClient
BELL = """OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0],q[1];
measure q -> c;
"""
client = QCOSClient()
quote = client.jobs.estimate(BELL, shots=1024, backend_id="simulator_aer")
job = client.jobs.submit(BELL, shots=1024, backend_id="simulator_aer")
done = client.jobs.wait(job["job_id"], timeout=300.0)
print(done["status"], done.get("result"))
jobs.execute(...) is submit followed by wait. Every jobs method takes
backend_id; a QPU backend costs money, and max_cost_usd= refuses a run whose
estimate is above it.
Methods
Each attribute of the client is one product area. Their methods mirror the REST routes under the prefix shown.
| Attribute | Product | REST prefix |
|---|---|---|
client.jobs |
jobs: submit, get, wait, result, list, cancel, artifacts, estimate | /v1/jobs, /v1/estimate |
client.circuits |
circuit management, optimization, simulation | /api/v1/circuits |
client.algorithms |
Shor, Grover, QFT, QPE, QAOA and other runners | /api/v1/algorithms |
client.backends |
backends and your own provider credentials | /api/v1/backends |
client.evidence |
sealed execution records, verified offline | /api/v1/runtime/evidence |
client.state |
state analysis: Bloch/Pauli, purity, Wigner | /api/v1/runtime/state |
client.dynamics |
geometric complexity analysis (experimental) | /api/v1/runtime/dynamics |
client.generate |
seeded generation with entropy provenance | /api/v1/runtime/generate |
client.hal |
hardware abstraction layer jobs and backends | /api/v1/hal |
client.bench |
reproducible benchmarks | /api/v1/bench |
client.calibration, client.glassbox |
device state, calibration, compilation transparency | /api/v1/glassbox |
client.coherence |
T1/T2 drift and pre-flight checks | /api/v1/coherence |
client.dri |
Device Reliability Index | /api/v1/dri |
client.qec |
error correction, surface codes | /api/v1/qec |
client.qec_service |
fault-tolerant middleware | /api/v1/qec-service |
client.chemistry |
VQE and molecular properties | /api/v1/chemistry |
client.network |
multi-QPU networking | /api/v1/network |
client.isolation |
crosstalk isolation zones | /api/v1/isolation |
client.gpu_qpu |
GPU-QPU link | /api/v1/gpu-qpu |
client.energy |
energy-aware scheduling | /api/v1/energy |
client.marketplace |
marketplace and multi-cloud routing | /api/v1/marketplace |
client.provider_hub |
provider health | /api/v1/providers/health |
client.navcore |
GNSS/PNT and post-quantum signatures | /api/v1/navcore |
client.acos |
infrastructure certification | /api/v1/acos |
client.ledger |
usage accounting | /api/v1/ledger |
client.billing |
ROI calculator, provider and plan catalogue (prices are the platform's) | /api/v1/roi |
client.use_cases |
use-case discovery and feasibility | /api/v1/use-cases |
client.research |
preregistered studies, evidence, claims | /api/v1/research |
client.research_apps |
research app registry and planner (experimental) | /api/v1/research-apps |
client.science |
Scientific Runtime: algorithm catalog, Solver Planner, eigensolve / evolve / optimize / validate (experimental; CPU and exact statevector, no QPU) | /api/v1/science |
client.sandbox |
sandboxed code execution | /api/v1/sandbox |
client.webhooks |
HMAC-signed job events | /api/v1/webhooks |
client.batch, client.workflow, client.session, client.visualize |
batches, workflows, sessions, plots | /api/v2/... |
Removed in 3.9.2: client.admin, client.macro, client.autopilot,
client.qlink, client.qubo and client.zne. Every one of their methods
called a route the API does not serve, so each raised on a 404.
client.get/post/put/delete(path, ...) reach any other route with the same key
and error handling.
Evidence, verified without trusting QCOS
Each execution can leave a sealed record. Fetch it with the client, then verify it locally: the hashes, the QuantumLock signature, and that the key was valid when it signed. The key history comes from QuantumLock, not from QCOS, so that the check does not depend on trusting QCOS:
import httpx
from softqcos_sdk.api.evidence import verify_offline
page = client.evidence.list(limit=5)
record = client.evidence.get(page["items"][0]["evidence_id"])
# QuantumLock's public key history. No key needed; pin a copy you have checked.
trust_bundle = httpx.get(
"https://quantumlock.softquantus.com/api/v1/kms/trust-bundle", timeout=10
).json()
report = verify_offline(record, trust_bundle=trust_bundle)
print(report["confirmed_level"], report["evidence_valid"], report.get("key_reason"))
verify_offline itself makes no network call. A record whose hashes check out
but which nobody signed is reported as SEALED_UNSIGNED, never as more than it
is. report carries the four checks separately: hashes_valid,
signature_valid, key_valid and evidence_valid.
As of 2026-10-02 the published trust bundle lists no keys ("keys": []), so
key_valid is False for every signed record and evidence_valid stays
False. The signature check still runs if you pass the key yourself
(public_key_b64=), but the key's validity window cannot be confirmed until
QuantumLock publishes it.
client.evidence.trust() is a different thing: it describes how this QCOS
deployment seals and stores records (store.survives_restart), not the key
history.
Generation with provenance
client.generate asks for a world, a character, a branch or a distribution and
gets back structured data plus the origin of the entropy behind it. The
output is classically derived from a quantum seed — it is not computed on a QPU,
and it is not faster because a QPU exists. What is certifiable is the seed's
origin, and the response names it along with the digest and the expander, so a
third party can reproduce the result without running our code.
gen = client.generate.terrain(width=128, height=128, biomes=6)
gen.data["heightmap"] # the world
gen.provenance.quantum # observed from the backend that answered — never echoed
gen.provenance.backend # e.g. "cloud_ibm" or "simulated"
gen.provenance.seed_sha256 # what makes the world reproducible
print(gen.provenance_line()) # the line you can publish
Every method returns a Generation, which cannot be built without provenance:
a response missing it raises ProvenanceMissingError rather than degrading into
bare data.
quantum_required=True fails rather than substituting. It defaults to
False on every method — today most deployments have no quantum entropy source
reachable, so True by default would fail every call. Set it whenever the
origin will be claimed publicly:
from softqcos_sdk import QuantumEntropyUnavailableError
try:
gen = client.generate.seed(quantum_required=True) # or client.generate.quantum_seed()
except QuantumEntropyUnavailableError:
... # no quantum source answered. Decide explicitly — this SDK will not
# quietly retry classically on your behalf and hand back a result
# you would go on to describe as quantum.
Already have a result and only now need to claim its origin?
gen.require_quantum() raises unless provenance.quantum is true.
Scientific Runtime (experimental)
client.science states a problem — a Hamiltonian, a lattice model or a QUBO —
and gets back one ScientificDataset: the numbers, the plan that was followed,
the provenance and a validation against a classical reference. VQE, QAOA,
Lanczos and the rest are algorithms registered in one catalog, not separate
products, and the Solver Planner tells you what each would cost before you run
anything.
tfim = {"model": "transverse_field_ising", "sites": 4, "coupling": 1.0, "field": 1.0}
# What exists, and what actually runs here
client.science.capabilities()
client.science.algorithms(capability="eigensolve", status="available")
# Strategies A, B, C with resources, runtime and expected error. Computes nothing.
plan = client.science.plan("eigensolve", system=tfim, tolerance=1e-6)
# Ground and first excited state; the planner picks the algorithm
dataset = client.science.eigensolve(system=tfim, n_states=2)
dataset["validation"]["status"] # PASSED, FAILED, SELF_CONSISTENT or NOT_VALIDATED
# The same model with a variational quantum algorithm, on the exact simulator
vqe = client.science.eigensolve(system=tfim, algorithm="vqe", seed=7)
vqe["validation"]["abs_error"] # how far above the exact energy it stopped
# Real-time dynamics: follow <Z0> for two time units, Trotterised
client.science.evolve(
system=tfim,
total_time=2.0,
algorithm="trotter_suzuki",
observables=[{"name": "Z0", "pauli": "ZIII"}],
)
# Minimise -x0 - 2*x1 + x2 + 3*x0*x1 - 2*x1*x2 over binary x
client.science.optimize(
qubo={"linear": [-1.0, -2.0, 1.0], "quadratic": [[0, 1, 3.0], [1, 2, -2.0]]}
)
# What the problem would cost on a fault-tolerant machine; nothing is executed
client.science.resource_estimate(system=tfim, tolerance=1e-3)
# Check someone else's number against the classical reference
client.science.validate(system=tfim, claimed_value=-4.7588, tolerance=1e-3)
Three things this is not. Nothing here reaches a QPU or a GPU: the quantum
algorithms run on the API host's exact statevector simulator, up to the limits
capabilities() reports (16 qubits by default). A result that misses its
tolerance is still returned, as HTTP 200 with validation.status == "FAILED"
— a variational run that stops above the exact energy says so instead of being
presented as the answer. And the catalog is larger than what runs: entries
with status planned (PDE solvers, particle methods, tensor networks) are
listed and not executable, quantum linear-system algorithms are flagged
experimental_quantum, and QPE and qubitization are resource_estimate_only —
costed, never run.
The catalog, capabilities() and plan() need qcos:read; the six
computations need qcos:execute.
More examples
# Calibration
devices = client.calibration.devices()
state = client.calibration.device_state("ibm_fez")
# Benchmark: the API requires backend_id
report = client.bench.run(backend_id="aer_simulator", workloads=["bell_state"], shots=1024)
client.bench.verify(report["benchmark_id"])
# Billing and ROI
plans = client.billing.plans()
roi = client.billing.calculate(provider="aws_rigetti", shots_per_eval=1000)
# NavCore post-quantum signatures. The keys are client-held: pqc_keypair
# returns the private key once, the server keeps no copy, and pqc_sign takes
# it back as a request field. navcore.algorithms() reports what the
# deployment can sign with. Messages travel base64-encoded.
import base64
b64_message = base64.b64encode(b"position fix 2026-10-02T12:00Z").decode()
kp = client.navcore.pqc_keypair(algorithm="ml-dsa-65")
sig = client.navcore.pqc_sign(
message=b64_message, private_key=kp["private_key"], key_id=kp["key_id"]
)
ok = client.navcore.pqc_verify(
message=b64_message,
signature=sig["signature"],
public_key=kp["public_key"],
algorithm=sig["mechanism"], # the exact mechanism, matched exactly
)["valid"]
# Network
topo = client.network.topology()
Errors
from softqcos_sdk import AuthenticationError, QCOSError, RateLimitError
try:
result = client.jobs.submit("invalid", backend_id="simulator_aer")
except RateLimitError as e:
print(f"Rate limited — retry after {e.retry_after}s")
except AuthenticationError:
print("Invalid API key")
except QCOSError as e:
print(f"API error: {e}")
QCOSError is the base class. The others are ValidationError,
JobNotFoundError, TimeoutError, LicenseError (with
LicenseNotFoundError and LicenseExpiredError), ProvenanceMissingError and
QuantumEntropyUnavailableError.
Async
There is no AsyncQCOSClient; every method is synchronous. async with QCOSClient(...) enters without complaint, but await client.jobs.submit(...)
fails because submit is not a coroutine. Run the client in a thread instead:
import asyncio
result = await asyncio.to_thread(client.jobs.execute, BELL, backend_id="simulator_aer")
What each version added
Generated from the code at release time, so it cannot drift from what this version runs.
Package version on this source tree: 3.11.1. softqcos-sdk, softqcos and
softqcos-mcp always carry the same number, so the row a name sits in is the
first version of THIS package that has it. A version is listed once it is tagged;
it reaches PyPI when that release is published, and
pip index versions softqcos-sdk shows which versions PyPI has.
| Version | Added |
|---|---|
| 3.11.0 | client.science.export_vtk, client.science.graph_plan, client.science.jobspec, client.science.physics, client.science.resolve_solver, client.science.run_graph, client.science.simulate, client.science.simulate_plan, client.science.solver, client.science.solvers, client.science.train_surrogate |
| 3.10.0 | client.science.algorithm, client.science.algorithms, client.science.capabilities, client.science.eigensolve, client.science.evolve, client.science.optimize, client.science.plan, client.science.resource_estimate, client.science.simulate_quantum_system, client.science.validate |
| 3.9.2 | client.backends.add_credential, client.backends.credential, client.backends.credentials, client.backends.delete_credential, client.backends.update_credential, client.backends.validate_credential |
| 3.9.0 | client.hal.backend, client.hal.backends, client.hal.cancel, client.hal.result, client.hal.status, client.hal.submit, client.quantus.analyze_problem, client.quantus.backends, client.quantus.build_problem, client.quantus.compile_problem, client.quantus.evidence, client.quantus.execute, client.quantus.execution_store, client.quantus.explain_coefficient, client.quantus.explain_execution, client.quantus.get_advantage, client.quantus.get_execution, client.quantus.lifecycle, client.quantus.normalize, client.quantus.routing_rules, client.quantus.seal, client.quantus.suitability, client.quantus.validate_problem, client.research_apps.get_app, client.research_apps.list_apps, client.research_apps.plan, client.research_apps.run_molecular_vqe |
| 3.8.3 | client.evidence.check_key, client.evidence.check_seal, client.evidence.get, client.evidence.iter_all, client.evidence.list, client.evidence.trust, client.evidence.verify_hashes_offline, client.evidence.verify_offline, client.evidence.verify_signature |
| 3.8.2 | client.dynamics.analyze, client.state.analyze |
| <=3.8.0 | 337 methods, all present in 3.8.0, the first version of the shared numbering |
Removed (no longer exists):
client.admin.backend_capabilities: since<=3.8.0, removed in3.9.2client.admin.backends_status: since<=3.8.0, removed in3.9.2client.admin.circuit_breaker_reset: since<=3.8.0, removed in3.9.2client.admin.circuit_breakers: since<=3.8.0, removed in3.9.2client.admin.health_live: since<=3.8.0, removed in3.9.2client.admin.health_ready: since<=3.8.0, removed in3.9.2client.admin.metrics: since<=3.8.0, removed in3.9.2client.admin.rate_limits: since<=3.8.0, removed in3.9.2client.admin.tenant_usage: since<=3.8.0, removed in3.9.2client.admin.tenants: since<=3.8.0, removed in3.9.2client.autopilot.execute: since<=3.8.0, removed in3.9.2client.autopilot.plan: since<=3.8.0, removed in3.9.2client.autopilot.recommend: since<=3.8.0, removed in3.9.2client.autopilot.vendors: since<=3.8.0, removed in3.9.2client.backends.add: since<=3.8.0, removed in3.9.2client.backends.delete: since<=3.8.0, removed in3.9.2client.backends.update: since<=3.8.0, removed in3.9.2client.backends.validate: since<=3.8.0, removed in3.9.2client.evidence.artifact: since<=3.8.0, removed in3.8.3client.evidence.artifacts: since<=3.8.0, removed in3.8.3client.evidence.capabilities: since<=3.8.0, removed in3.8.3client.evidence.download: since<=3.8.0, removed in3.8.3client.evidence.public_key: since<=3.8.0, removed in3.8.3client.evidence.runtime_execution_bundle: since<=3.8.0, removed in3.8.3client.gpu_qpu.qlink_profile: since<=3.8.0, removed in3.9.2client.gpu_qpu.qlink_simulate: since<=3.8.0, removed in3.9.2client.gpu_qpu.qlink_status: since<=3.8.0, removed in3.9.2client.gpu_qpu.qlink_transfer: since<=3.8.0, removed in3.9.2client.macro.energy_optimize: since<=3.8.0, removed in3.9.2client.macro.health: since<=3.8.0, removed in3.9.2client.macro.market_sizing: since<=3.8.0, removed in3.9.2client.macro.risk_analysis: since<=3.8.0, removed in3.9.2client.provider_hub.list: since<=3.8.0, removed in3.9.2client.provider_hub.register: since<=3.8.0, removed in3.9.2client.provider_hub.remove: since<=3.8.0, removed in3.9.2client.qlink.profile: since<=3.8.0, removed in3.9.2client.qlink.simulate: since<=3.8.0, removed in3.9.2client.qlink.status: since<=3.8.0, removed in3.9.2client.qlink.transfer: since<=3.8.0, removed in3.9.2client.qubo.energy_dispatch: since<=3.8.0, removed in3.9.2client.qubo.maxcut: since<=3.8.0, removed in3.9.2client.qubo.portfolio: since<=3.8.0, removed in3.9.2client.zne.mitigate: since<=3.8.0, removed in3.9.2
License
Apache License, Version 2.0 — see LICENSE and NOTICE.
Copyright 2024-2026 SoftQuantus innovative OÜ (registry code 17048927, Tallinn, Estonia). QCOS™ and SoftQuantus™ are trademarks of SoftQuantus innovative OÜ; the license does not grant trademark rights. The QCOS service reached through this package is governed by the SoftQuantus Terms of Service, not by this license.
- Terms: https://softquantus.com/legal/terms
- Privacy: https://softquantus.com/legal/privacy
- Portal: https://platform.softquantus.com
Metadata
Release files for softqcos-sdk 3.11.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| softqcos_sdk-3.11.1.tar.gz | 93.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| softqcos_sdk-3.11.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 215.2 kB
Release files / softqcos_sdk-3.11.1.tar.gz
| Download URL | softqcos_sdk-3.11.1.tar.gz |
|---|---|
| Size | 93.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fc2ff24b7f765dbf92b7f5d075529037eb253c9a5e2b2ad9cc0baad8489997c9
|
|
BLAKE2b-256 checksum How to use checksums |
27c810e3780ad984f7be5bbf152dcb1b5918ee941d5e131f014c22022dbfe34c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency logRelease files / softqcos_sdk-3.11.1-py3-none-any.whl
| Download URL | softqcos_sdk-3.11.1-py3-none-any.whl |
|---|---|
| Size | 122.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
04be202db1760fef70b85cf4538dab1339bd273d90e514bf9d5aafa1b200cdc7
|
|
BLAKE2b-256 checksum How to use checksums |
17f2cab352dce56b299abd45acca695c998ef6dab411ecc35e52dc78fe01daf7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.
Transparency log