Skip to main content

Key Management API

The Key Management API lets you generate, rotate, list, and retire your PQC cryptographic keys. Qpher supports two algorithms: Kyber768 for encryption and Dilithium3 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.


Generate Key​

POST/api/v1/kms/keys/generateGenerate 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 existing key is automatically retired.

Request body​

FieldTypeRequiredDescription
algorithmstringYesThe PQC algorithm: "Kyber768" or "Dilithium3".

Response (200 OK)​

FieldTypeDescription
data.key_versionintegerThe version number assigned to this key.
data.algorithmstringThe algorithm used: "Kyber768" or "Dilithium3".
data.statusstringAlways "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​

RequestPOST/api/v1/kms/keys/generate
X-API-Key: qph_your_key_here
Content-Type: application/json
{
  "algorithm": "Kyber768"
}
Response200
{
  "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"
}
Generate key
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"}'

Errors​

HTTP StatusError CodeDescription
400ERR_KMS_001Invalid algorithm. Must be "Kyber768" or "Dilithium3".
401ERR_AUTH_001Missing or invalid API key.

Rotate Key​

POST/api/v1/kms/keys/rotateRotate 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​

FieldTypeRequiredDescription
algorithmstringYesThe PQC algorithm: "Kyber768" or "Dilithium3".

Response (200 OK)​

FieldTypeDescription
data.new_keyobjectThe newly created active key (same shape as generate response).
data.retired_keyobjectThe previously active key, now with status: "retired".

Example​

RequestPOST/api/v1/kms/keys/rotate
X-API-Key: qph_your_key_here
Content-Type: application/json
{
  "algorithm": "Kyber768"
}
Response200
{
  "data": {
    "new_key": {
      "key_version": 2,
      "algorithm": "Kyber768",
      "status": "active",
      "public_key": "bmV3X3B1YmxpY19rZXkuLi4=",
      "created_at": "2026-02-01T12:00:00.000Z"
    },
    "retired_key": {
      "key_version": 1,
      "algorithm": "Kyber768",
      "status": "retired",
      "public_key": "cHVibGljX2tleV9ieXRlcy4uLg==",
      "created_at": "2026-01-15T10:00:00.000Z"
    }
  },
  "request_id": "f6a7b8c9-d0e1-2345-6789-0abcdef01234",
  "timestamp": "2026-02-01T12:00:00.000Z"
}
Rotate key
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"}'

Errors​

HTTP StatusError CodeDescription
400ERR_KMS_001Invalid algorithm.
401ERR_AUTH_001Missing or invalid API key.
409ERR_KMS_003A key rotation is already in progress.

List Keys​

GET/api/v1/kms/keysList all PQC keys for the authenticated tenant.

Returns all keys for your tenant, optionally filtered by algorithm.

Query parameters​

ParameterTypeRequiredDescription
algorithmstringNoFilter by algorithm: "Kyber768" or "Dilithium3".

Response (200 OK)​

FieldTypeDescription
data.keysarrayArray of key objects.
data.keys[].key_versionintegerKey version number.
data.keys[].algorithmstring"Kyber768" or "Dilithium3".
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.

Example​

RequestGET/api/v1/kms/keys?algorithm=Kyber768
X-API-Key: qph_your_key_here
Response200
{
  "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"
      }
    ]
  },
  "request_id": "a7b8c9d0-e1f2-3456-7890-abcdef012345",
  "timestamp": "2026-02-01T12:05:00.000Z"
}
List keys
curl -X GET "https://api.qpher.ai/api/v1/kms/keys?algorithm=Kyber768" \
  -H "X-API-Key: qph_your_key_here"

Errors​

HTTP StatusError CodeDescription
401ERR_AUTH_001Missing or invalid API key.

Get Active Key​

GET/api/v1/kms/keys/activeGet 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​

ParameterTypeRequiredDescription
algorithmstringYesThe algorithm: "Kyber768" or "Dilithium3".

Response (200 OK)​

Same shape as a single key object from the list endpoint.

Example​

RequestGET/api/v1/kms/keys/active?algorithm=Dilithium3
X-API-Key: qph_your_key_here
Response200
{
  "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"
}

Errors​

HTTP StatusError CodeDescription
400ERR_KMS_001Invalid or missing algorithm parameter.
401ERR_AUTH_001Missing or invalid API key.
404ERR_KMS_002No active key found for the specified algorithm. Generate one first.

Retire Key​

POST/api/v1/kms/keys/retireRetire 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​

FieldTypeRequiredDescription
algorithmstringYesThe PQC algorithm: "Kyber768" or "Dilithium3".
key_versionintegerYesThe key version to retire.

Response (200 OK)​

FieldTypeDescription
data.key_versionintegerThe retired key version.
data.algorithmstringThe algorithm.
data.statusstring"retired".
data.public_keystring (base64)The public key.
data.created_atstring (ISO 8601)Original creation time.

Example​

RequestPOST/api/v1/kms/keys/retire
X-API-Key: qph_your_key_here
Content-Type: application/json
{
  "algorithm": "Kyber768",
  "key_version": 1
}
Response200
{
  "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"
}

Errors​

HTTP StatusError CodeDescription
400ERR_KMS_001Invalid algorithm or key_version.
401ERR_AUTH_001Missing or invalid API key.
404ERR_KMS_002Key version not found.

Key Lifecycle​

Keys move through three statuses during their lifetime:

ACTIVE ──rotate──► ACTIVE (new version)
β”‚ β”‚
β”‚ └─(old becomes)─► RETIRED ──archive──► ARCHIVED
β”‚
└──retire──► RETIRED ──archive──► ARCHIVED
StatusEncryptDecryptSignVerify
activeYesYesYesYes
retiredNoYesNoYes
archivedNoNoNoNo
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.