The Key Management API lets you generate, rotate, list, and retire your PQC cryptographic keys. Qpher supports four algorithms: Kyber768 and X-Wing for encryption, Dilithium3 and Composite-ML-DSA for digital signatures.
π Public keys only
The Key Management API returns public key material only. Private keys are stored exclusively inside the Qpher secure enclave and are never exposed through any API endpoint.
βΉοΈ Hybrid algorithms (Starter+)
The algorithm parameter now also accepts "X-Wing" (hybrid KEM) and "Composite-ML-DSA"
(hybrid signatures), in addition to "Kyber768" and "Dilithium3".
Hybrid keys follow the same lifecycle rules as PQC-only keys: explicit key_version,
active/retired/archived states, and no implicit "latest" default.
Generate Keyβ
POST /api/v1/kms/keys/generate Generate a new PQC key pair for the specified algorithm.
Creates a new key pair and sets it to active status. If an active key already exists for the given algorithm, the request is rejected β use Rotate Key to replace the active key instead.
Request bodyβ
Field Type Required Description algorithmstring Yes The PQC algorithm: "Kyber768", "Dilithium3", "X-Wing", or "Composite-ML-DSA".
Response (201 Created)β
Field Type Description data.key_versioninteger The version number assigned to this key. data.algorithmstring The algorithm used: "Kyber768", "Dilithium3", "X-Wing", or "Composite-ML-DSA". data.statusstring Always "active" for a newly generated key. data.public_keystring (base64) The public key, base64-encoded. data.created_atstring (ISO 8601) When the key was generated.
Exampleβ
X-API-Key: qph_your_key_here
Content-Type: application/json{
"algorithm": "Kyber768"
}{
"data": {
"key_version": 1,
"algorithm": "Kyber768",
"status": "active",
"public_key": "cHVibGljX2tleV9ieXRlcy4uLg==",
"created_at": "2026-01-15T10:00:00.000Z"
},
"request_id": "e5f6a7b8-c9d0-1234-5678-90abcdef0123",
"timestamp": "2026-01-15T10:00:00.000Z"
}
curl -X POST https://api.qpher.ai/api/v1/kms/keys/generate \
-H "X-API-Key: qph_your_key_here" \
-H "Content-Type: application/json" \
-d '{"algorithm": "Kyber768"}'Copy
HTTP Status Error Code Description 400 ERR_INVALID_001Invalid request β unsupported algorithm or active key already exists (use Rotate instead). 401 ERR_AUTH_001Missing or invalid API key. 429 ERR_RATE_LIMIT_001Rate limit exceeded β reduce request frequency or upgrade your plan.
Rotate Keyβ
POST /api/v1/kms/keys/rotate Rotate to a new key version, retiring the current active key.
Generates a new active key and moves the previous active key to retired status. Retired keys can still be used for decryption and signature verification but not for new encrypt or sign operations.
Request bodyβ
Field Type Required Description algorithmstring Yes The PQC algorithm: "Kyber768", "Dilithium3", "X-Wing", or "Composite-ML-DSA".
Response (201 Created)β
Field Type Description data.public_keystring (base64) The public key of the new active key, base64-encoded. data.key_versioninteger The version number of the new active key. data.algorithmstring The algorithm used. data.old_key_versioninteger The version number of the previously active key (now retired).
Exampleβ
X-API-Key: qph_your_key_here
Content-Type: application/json{
"algorithm": "Kyber768"
}{
"data": {
"public_key": "bmV3X3B1YmxpY19rZXkuLi4=",
"key_version": 2,
"algorithm": "Kyber768",
"old_key_version": 1
},
"request_id": "f6a7b8c9-d0e1-2345-6789-0abcdef01234",
"timestamp": "2026-02-01T12:00:00.000Z"
}
curl -X POST https://api.qpher.ai/api/v1/kms/keys/rotate \
-H "X-API-Key: qph_your_key_here" \
-H "Content-Type: application/json" \
-d '{"algorithm": "Kyber768"}'Copy
HTTP Status Error Code Description 400 ERR_INVALID_001Invalid request β unsupported algorithm. 401 ERR_AUTH_001Missing or invalid API key. 404 ERR_NOT_FOUND_001No active key found for the specified algorithm. Generate one first. 429 ERR_RATE_LIMIT_001Rate limit exceeded β reduce request frequency or upgrade your plan.
List Keysβ
GET /api/v1/kms/keys List all PQC keys for the authenticated tenant.
Returns all keys for your tenant, optionally filtered by algorithm.
Query parametersβ
Parameter Type Required Description algorithmstring No Filter by algorithm: "Kyber768", "Dilithium3", "X-Wing", or "Composite-ML-DSA". statusstring No Filter by status: "active", "retired", or "archived".
Response (200 OK)β
Field Type Description data.keysarray Array of key objects. data.keys[].key_versioninteger Key version number. data.keys[].algorithmstring "Kyber768", "Dilithium3", "X-Wing", or "Composite-ML-DSA".data.keys[].statusstring "active", "retired", or "archived".data.keys[].public_keystring (base64) The public key, base64-encoded. data.keys[].created_atstring (ISO 8601) When the key was generated. data.totalinteger Total number of keys returned.
Exampleβ
X-API-Key: qph_your_key_here{
"data": {
"keys": [
{
"key_version": 2,
"algorithm": "Kyber768",
"status": "active",
"public_key": "bmV3X3B1YmxpY19rZXkuLi4=",
"created_at": "2026-02-01T12:00:00.000Z"
},
{
"key_version": 1,
"algorithm": "Kyber768",
"status": "retired",
"public_key": "cHVibGljX2tleV9ieXRlcy4uLg==",
"created_at": "2026-01-15T10:00:00.000Z"
}
],
"total": 2
},
"request_id": "a7b8c9d0-e1f2-3456-7890-abcdef012345",
"timestamp": "2026-02-01T12:05:00.000Z"
}
curl -X GET "https://api.qpher.ai/api/v1/kms/keys?algorithm=Kyber768" \
-H "X-API-Key: qph_your_key_here"Copy
HTTP Status Error Code Description 401 ERR_AUTH_001Missing or invalid API key. 429 ERR_RATE_LIMIT_001Rate limit exceeded β reduce request frequency or upgrade your plan.
Get Active Keyβ
GET /api/v1/kms/keys/active Get the current active key for a specific algorithm.
Returns the single active key for the specified algorithm. Each algorithm has exactly one active key at any time.
Query parametersβ
Parameter Type Required Description algorithmstring Yes The algorithm: "Kyber768", "Dilithium3", "X-Wing", or "Composite-ML-DSA".
Response (200 OK)β
Same shape as a single key object from the list endpoint.
Exampleβ
X-API-Key: qph_your_key_here{
"data": {
"key_version": 1,
"algorithm": "Dilithium3",
"status": "active",
"public_key": "ZGlsaXRoaXVtX3B1YmxpY19rZXkuLi4=",
"created_at": "2026-01-15T10:00:00.000Z"
},
"request_id": "b8c9d0e1-f2a3-4567-8901-bcdef0123456",
"timestamp": "2026-01-15T10:05:00.000Z"
}
HTTP Status Error Code Description 400 ERR_INVALID_001Invalid or missing algorithm parameter. 401 ERR_AUTH_001Missing or invalid API key. 404 ERR_NOT_FOUND_001No active key found for the specified algorithm. Generate one first. 429 ERR_RATE_LIMIT_001Rate limit exceeded β reduce request frequency or upgrade your plan.
Retire Keyβ
POST /api/v1/kms/keys/retire Retire a specific key version, preventing new encrypt/sign operations.
Moves a key from active to retired status. Retired keys can still be used for decryption and verification, but not for new encryption or signing.
Request bodyβ
Field Type Required Description algorithmstring Yes The PQC algorithm: "Kyber768", "Dilithium3", "X-Wing", or "Composite-ML-DSA". key_versioninteger Yes The key version to retire.
Response (200 OK)β
Field Type Description data.key_versioninteger The retired key version. data.algorithmstring The algorithm. data.statusstring "retired".data.public_keystring (base64) The public key. data.created_atstring (ISO 8601) Original creation time.
Exampleβ
X-API-Key: qph_your_key_here
Content-Type: application/json{
"algorithm": "Kyber768",
"key_version": 1
}{
"data": {
"key_version": 1,
"algorithm": "Kyber768",
"status": "retired",
"public_key": "cHVibGljX2tleV9ieXRlcy4uLg==",
"created_at": "2026-01-15T10:00:00.000Z"
},
"request_id": "c9d0e1f2-a3b4-5678-9012-cdef01234567",
"timestamp": "2026-02-15T08:00:00.000Z"
}
HTTP Status Error Code Description 400 ERR_INVALID_001Invalid algorithm or key_version. 401 ERR_AUTH_001Missing or invalid API key. 404 ERR_NOT_FOUND_001Key version not found. 429 ERR_RATE_LIMIT_001Rate limit exceeded β reduce request frequency or upgrade your plan.
Archive Keyβ
POST /api/v1/kms/keys/archive Archive a retired key and securely delete the private key material.
Moves a key from retired to archived status and securely deletes the private key file. Archived keys cannot perform any cryptographic operations.
β οΈ Irreversible operation
Archiving permanently deletes the private key. You will no longer be able to decrypt or verify with this key version.
βΉοΈ Portal UI only
Key archival is only available through the Qpher Portal UI at portal.qpher.ai .
API calls to this endpoint return 403 ERR_KMS_020. This restriction prevents accidental key destruction
by scripts, SDKs, or AI agents.
Request bodyβ
Field Type Required Description algorithmstring Yes The PQC algorithm: "Kyber768", "Dilithium3", "X-Wing", or "Composite-ML-DSA". key_versioninteger Yes The version number of the retired key to archive.
Response (200 OK)β
Same shape as the key response from other endpoints.
HTTP Status Error Code Description 400 ERR_INVALID_001Invalid algorithm, key_version, or key is not in retired status. 401 ERR_AUTH_001Missing or invalid API key. 403 ERR_KMS_020Archive is restricted to Portal UI only. API and SDK calls are blocked. 404 ERR_NOT_FOUND_001Key version not found. 429 ERR_RATE_LIMIT_001Rate limit exceeded β reduce request frequency or upgrade your plan.
Get Key by Versionβ
GET /api/v1/kms/keys/{key_version} Retrieve metadata for a specific key version.
Returns key metadata (public key, status, algorithm) for a specific version. Useful for inspecting individual keys after rotation.
Path parametersβ
Parameter Type Required Description key_versioninteger Yes The key version number.
Query parametersβ
Parameter Type Required Description algorithmstring Yes The algorithm: "Kyber768", "Dilithium3", "X-Wing", or "Composite-ML-DSA".
Response (200 OK)β
Same shape as the key response from other endpoints.
HTTP Status Error Code Description 401 ERR_AUTH_001Missing or invalid API key. 404 ERR_NOT_FOUND_001Key version not found for the specified algorithm. 429 ERR_RATE_LIMIT_001Rate limit exceeded β reduce request frequency or upgrade your plan.
Key Lifecycleβ
Keys move through three statuses during their lifetime:
ACTIVE ββrotateβββΊ ACTIVE (new version) β β β ββ(old becomes)ββΊ RETIRED ββarchiveβββΊ ARCHIVED β βββretireβββΊ RETIRED ββarchiveβββΊ ARCHIVED
Status Encrypt Decrypt Sign Verify activeYes Yes Yes Yes retiredNo Yes No Yes archivedNo No No No
π‘ Key rotation best practice
Rotate keys periodically (for example, every 90 days). After rotation, update your application to use the new key_version for encrypt and sign operations. Existing ciphertext and signatures remain valid with the retired key.