REST API Overview
The k&z API is a RESTful JSON API that provides full programmatic control over your quantum workloads. All endpoints accept and return JSON, use standard HTTP verbs, and follow consistent error-handling conventions. The API is versioned — the current stable version is v1.
Base URLs
| Environment | Base URL | Purpose |
|---|---|---|
| Production | https://api.kandz.co/v1 | Live quantum workloads |
| Staging | https://api.staging.kandz.co/v1 | Pre-production testing |
| Sandbox | https://api.sandbox.kandz.co/v1 | Simulated QPU for development |
Authentication
Every API request must include a valid credential. We support two authentication methods:
API Keys
API keys are long-lived credentials intended for server-to-server communication. Include your key in the Authorization header:
Authorization: Bearer kz_live_abc123def456ghi789
API keys are scoped to an organization and can be granted read-only, write, or admin permissions. You can create and revoke keys from the k&z Console under Settings → API Keys.
OAuth 2.0
For interactive applications and delegated access, use OAuth 2.0 with the authorization code flow. Register your application to receive a client_id and client_secret, then exchange an authorization code for a bearer token:
POST https://auth.kandz.co/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTH_CODE_HERE
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&redirect_uri=https://yourapp.com/callback
Access tokens expire after 1 hour. Use the returned refresh_token to obtain new access tokens without re-authentication.
Endpoint Categories
Capacity — /v1/devices
Discover available quantum processors, query qubit counts, connectivity graphs, gate sets, and real-time calibration data.
GET /v1/devices— List all available QPUs and their current status.GET /v1/devices/{device_id}— Retrieve detailed specs for a specific device.GET /v1/devices/{device_id}/calibration— Fetch the latest calibration data (T1, T2, gate fidelities).GET /v1/devices/{device_id}/queue— Check current queue depth and estimated wait time.
Jobs — /v1/jobs
Submit quantum circuits, monitor execution status, and manage your workload queue.
POST /v1/jobs— Submit a new quantum job.GET /v1/jobs— List all jobs for your organization (paginated).GET /v1/jobs/{job_id}— Retrieve the status and metadata of a specific job.DELETE /v1/jobs/{job_id}— Cancel a queued or running job.
Results — /v1/results
Retrieve measurement outcomes, quasi-probability distributions, and mitigated expectation values.
GET /v1/jobs/{job_id}/results— Fetch results for a completed job.GET /v1/jobs/{job_id}/results/counts— Raw measurement counts.GET /v1/jobs/{job_id}/results/quasi-dists— Quasi-probability distributions (with mitigation).
Billing — /v1/billing
Monitor consumption, retrieve invoices, and manage payment methods.
GET /v1/billing/usage— Current billing period usage summary.GET /v1/billing/invoices— List past invoices.GET /v1/billing/invoices/{invoice_id}— Download a specific invoice.
Rate Limits
To ensure fair access across all users, the k&z API enforces the following rate limits:
| Tier | Requests/min | Jobs/hour | Burst |
|---|---|---|---|
| Free / Sandbox | 60 | 20 | 10 req/sec |
| Standard | 300 | 200 | 30 req/sec |
| Enterprise | 3,000 | Unlimited | 100 req/sec |
Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. When a limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header.
Sample Request & Response
Submit a Job
POST /v1/jobs HTTP/1.1
Host: api.kandz.co
Authorization: Bearer kz_live_abc123def456ghi789
Content-Type: application/json
{
"device": "qpu-zurich-72q",
"shots": 4096,
"circuit": {
"format": "openqasm3",
"source": "OPENQASM 3.0;\ninclude \"stdgates.inc\";\nqubit[2] q;\nbit[2] c;\nh q[0];\ncx q[0], q[1];\nc = measure q;"
},
"options": {
"optimization_level": 2,
"mitigation": "readout",
"priority": "normal"
}
}
Response — 201 Created
{
"job_id": "job_7f3a9b2c-e4d1-4f8a-b6c5-d2e1f0a9b8c7",
"status": "queued",
"device": "qpu-zurich-72q",
"shots": 4096,
"created_at": "2026-03-01T14:32:07Z",
"estimated_start": "2026-03-01T14:33:00Z",
"queue_position": 3,
"links": {
"self": "/v1/jobs/job_7f3a9b2c-e4d1-4f8a-b6c5-d2e1f0a9b8c7",
"results": "/v1/jobs/job_7f3a9b2c-e4d1-4f8a-b6c5-d2e1f0a9b8c7/results",
"cancel": "/v1/jobs/job_7f3a9b2c-e4d1-4f8a-b6c5-d2e1f0a9b8c7"
}
}
Retrieve Results
GET /v1/jobs/job_7f3a9b2c-e4d1-4f8a-b6c5-d2e1f0a9b8c7/results HTTP/1.1
Host: api.kandz.co
Authorization: Bearer kz_live_abc123def456ghi789
Response — 200 OK
{
"job_id": "job_7f3a9b2c-e4d1-4f8a-b6c5-d2e1f0a9b8c7",
"status": "completed",
"device": "qpu-zurich-72q",
"shots": 4096,
"execution_time_ms": 847,
"results": {
"counts": {
"00": 2038,
"11": 2058
},
"quasi_distributions": [
{"00": 0.498, "11": 0.502}
],
"metadata": {
"mitigation_applied": "readout",
"optimization_level": 2,
"transpiled_depth": 4,
"transpiled_gate_count": 3
}
}
}
Error Handling
All errors return a consistent JSON structure with an HTTP status code, error type, and human-readable message:
{
"error": {
"type": "invalid_request",
"message": "The 'shots' parameter must be between 1 and 100000.",
"param": "shots",
"request_id": "req_a1b2c3d4"
}
}
Common status codes: 400 (bad request), 401 (unauthorized), 403 (forbidden), 404 (not found), 429 (rate limited), 500 (internal error), 503 (device unavailable).