Skip to main content

SoftQCOS Python SDK

PyPI version Python 3.10+

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.0. 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 in 3.9.2
  • client.admin.backends_status: since <=3.8.0, removed in 3.9.2
  • client.admin.circuit_breaker_reset: since <=3.8.0, removed in 3.9.2
  • client.admin.circuit_breakers: since <=3.8.0, removed in 3.9.2
  • client.admin.health_live: since <=3.8.0, removed in 3.9.2
  • client.admin.health_ready: since <=3.8.0, removed in 3.9.2
  • client.admin.metrics: since <=3.8.0, removed in 3.9.2
  • client.admin.rate_limits: since <=3.8.0, removed in 3.9.2
  • client.admin.tenant_usage: since <=3.8.0, removed in 3.9.2
  • client.admin.tenants: since <=3.8.0, removed in 3.9.2
  • client.autopilot.execute: since <=3.8.0, removed in 3.9.2
  • client.autopilot.plan: since <=3.8.0, removed in 3.9.2
  • client.autopilot.recommend: since <=3.8.0, removed in 3.9.2
  • client.autopilot.vendors: since <=3.8.0, removed in 3.9.2
  • client.backends.add: since <=3.8.0, removed in 3.9.2
  • client.backends.delete: since <=3.8.0, removed in 3.9.2
  • client.backends.update: since <=3.8.0, removed in 3.9.2
  • client.backends.validate: since <=3.8.0, removed in 3.9.2
  • client.evidence.artifact: since <=3.8.0, removed in 3.8.3
  • client.evidence.artifacts: since <=3.8.0, removed in 3.8.3
  • client.evidence.capabilities: since <=3.8.0, removed in 3.8.3
  • client.evidence.download: since <=3.8.0, removed in 3.8.3
  • client.evidence.public_key: since <=3.8.0, removed in 3.8.3
  • client.evidence.runtime_execution_bundle: since <=3.8.0, removed in 3.8.3
  • client.gpu_qpu.qlink_profile: since <=3.8.0, removed in 3.9.2
  • client.gpu_qpu.qlink_simulate: since <=3.8.0, removed in 3.9.2
  • client.gpu_qpu.qlink_status: since <=3.8.0, removed in 3.9.2
  • client.gpu_qpu.qlink_transfer: since <=3.8.0, removed in 3.9.2
  • client.macro.energy_optimize: since <=3.8.0, removed in 3.9.2
  • client.macro.health: since <=3.8.0, removed in 3.9.2
  • client.macro.market_sizing: since <=3.8.0, removed in 3.9.2
  • client.macro.risk_analysis: since <=3.8.0, removed in 3.9.2
  • client.provider_hub.list: since <=3.8.0, removed in 3.9.2
  • client.provider_hub.register: since <=3.8.0, removed in 3.9.2
  • client.provider_hub.remove: since <=3.8.0, removed in 3.9.2
  • client.qlink.profile: since <=3.8.0, removed in 3.9.2
  • client.qlink.simulate: since <=3.8.0, removed in 3.9.2
  • client.qlink.status: since <=3.8.0, removed in 3.9.2
  • client.qlink.transfer: since <=3.8.0, removed in 3.9.2
  • client.qubo.energy_dispatch: since <=3.8.0, removed in 3.9.2
  • client.qubo.maxcut: since <=3.8.0, removed in 3.9.2
  • client.qubo.portfolio: since <=3.8.0, removed in 3.9.2
  • client.zne.mitigate: since <=3.8.0, removed in 3.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.

Metadata

Release files for softqcos-sdk 3.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for softqcos-sdk 3.11.0
File Size Uploaded
softqcos_sdk-3.11.0.tar.gz 93.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for softqcos-sdk 3.11.0
File Interpreter ABI Platform
softqcos_sdk-3.11.0-py3-none-any.whl Python 3 none any Details

Total release size: 215.2 kB

Release files / softqcos_sdk-3.11.0.tar.gz

Download URL softqcos_sdk-3.11.0.tar.gz
Size 93.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7426efab06c7edfd145360fdb24ac81fc42c79ec8e88591720a87c29fa2e93de
BLAKE2b-256 checksum
How to use checksums
95bf28c907e5458768944ee7b973e2adbf0664d9f4f6ac2b44b8778210b72148
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

Release files / softqcos_sdk-3.11.0-py3-none-any.whl

Download URL softqcos_sdk-3.11.0-py3-none-any.whl
Size 121.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
32820fd680d9f80e85ab4333062216ace45ed36e70f9d815a5c77792a9e02d50
BLAKE2b-256 checksum
How to use checksums
d1a06aa2d2eb65aede1a558a4eaff0f8ed977e3d682ec388569d4a365b7ef62a
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

Release history Release notifications | RSS feed

3.12.0

2 release files

This release

3.11.0 This release

2 release files

3.9.2

2 release files

3.8.2

2 release files

3.8.1

2 release files

3.8.0

2 release files

3.7.0

2 release files

3.6.1

1 release file

3.5.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page