API Cheat Sheet
Base URL: https://api.qpher.ai
Authentication: x-api-key: qph_live_<your-key> header on every request.
Response format: { "data": { ... }, "request_id": "uuid", "timestamp": "ISO-8601" }
KEM Encryption
Encrypt
POST /api/v1/kem/encrypt
| Parameter | Type | Required | Description |
|---|---|---|---|
plaintext | string (base64) | Yes | Data to encrypt |
key_version | integer | Yes | Active key version |
algorithm | string | No | "Kyber768" (default) or "X-Wing" (Pro/Enterprise) |
mode | string | No | "standard" (default) or "deterministic" |
salt | string (base64) | No | Required if mode is deterministic |
curl -X POST https://api.qpher.ai/api/v1/kem/encrypt \
-H "x-api-key: qph_live_abc123" \
-H "Content-Type: application/json" \
-d '{"plaintext": "SGVsbG8gV29ybGQ=", "key_version": 1}'
Response:
{
"data": {
"ciphertext": "base64-encoded-ciphertext...",
"key_version": 1,
"algorithm": "Kyber768"
},
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-02-23T12:00:00Z"
}
Decrypt
POST /api/v1/kem/decrypt
| Parameter | Type | Required | Description |
|---|---|---|---|
ciphertext | string (base64) | Yes | Data to decrypt |
key_version | integer | Yes | Key version used to encrypt |
algorithm | string | No | "Kyber768" (default) or "X-Wing" (Pro/Enterprise) |
curl -X POST https://api.qpher.ai/api/v1/kem/decrypt \
-H "x-api-key: qph_live_abc123" \
-H "Content-Type: application/json" \
-d '{"ciphertext": "base64-encoded-ciphertext...", "key_version": 1}'
Response:
{
"data": {
"plaintext": "SGVsbG8gV29ybGQ=",
"key_version": 1,
"algorithm": "Kyber768"
}
}
Key Wrap
POST /api/v1/kem/wrap
| Parameter | Type | Required | Description |
|---|---|---|---|
symmetric_key | string (base64) | Yes | Symmetric key to wrap |
key_version | integer | Yes | Active key version |
algorithm | string | No | "Kyber768" (default) or "X-Wing" (Pro/Enterprise) |
curl -X POST https://api.qpher.ai/api/v1/kem/wrap \
-H "x-api-key: qph_live_abc123" \
-H "Content-Type: application/json" \
-d '{"symmetric_key": "c3ltbWV0cmljX2tleV8zMl9ieXRlcw==", "key_version": 1}'
Response:
{
"data": {
"wrapped_key": "base64-encoded-wrapped-key...",
"key_version": 1,
"algorithm": "Kyber768",
"wrapping_method": "KEM-DEM"
}
}
Key Unwrap
POST /api/v1/kem/unwrap
| Parameter | Type | Required | Description |
|---|---|---|---|
wrapped_key | string (base64) | Yes | Wrapped key to unwrap |
key_version | integer | Yes | Key version used to wrap |
algorithm | string | No | "Kyber768" (default) or "X-Wing" (Pro/Enterprise) |
curl -X POST https://api.qpher.ai/api/v1/kem/unwrap \
-H "x-api-key: qph_live_abc123" \
-H "Content-Type: application/json" \
-d '{"wrapped_key": "base64-encoded-wrapped-key...", "key_version": 1}'
Response:
{
"data": {
"symmetric_key": "c3ltbWV0cmljX2tleV8zMl9ieXRlcw==",
"key_version": 1,
"algorithm": "Kyber768"
}
}
Signatures
Sign
POST /api/v1/signature/sign
| Parameter | Type | Required | Description |
|---|---|---|---|
message | string (base64) | Yes | Message to sign |
key_version | integer | Yes | Active signing key version |
algorithm | string | No | "Dilithium3" (default) or "Composite-ML-DSA" (Pro/Enterprise) |
curl -X POST https://api.qpher.ai/api/v1/signature/sign \
-H "x-api-key: qph_live_abc123" \
-H "Content-Type: application/json" \
-d '{"message": "SW52b2ljZSAjMTIzNA==", "key_version": 1}'
Response:
{
"data": {
"signature": "base64-encoded-signature...",
"key_version": 1,
"algorithm": "Dilithium3"
}
}
Verify
POST /api/v1/signature/verify
| Parameter | Type | Required | Description |
|---|---|---|---|
message | string (base64) | Yes | Original message |
signature | string (base64) | Yes | Signature to verify |
key_version | integer | Yes | Signing key version |
algorithm | string | No | "Dilithium3" (default) or "Composite-ML-DSA" (Pro/Enterprise) |
curl -X POST https://api.qpher.ai/api/v1/signature/verify \
-H "x-api-key: qph_live_abc123" \
-H "Content-Type: application/json" \
-d '{"message": "SW52b2ljZSAjMTIzNA==", "signature": "base64...", "key_version": 1}'
Response:
{
"data": {
"valid": true,
"key_version": 1,
"algorithm": "Dilithium3"
}
}
Sign Hash
POST /api/v1/signature/sign-hash
| Parameter | Type | Required | Description |
|---|---|---|---|
hash | string (base64) | Yes | Pre-computed hash digest to sign |
hash_algorithm | string | Yes | "SHA-256", "SHA-384", or "SHA-512" |
key_version | integer | Yes | Active signing key version |
algorithm | string | No | "Dilithium3" (default) or "Composite-ML-DSA" (Pro/Enterprise) |
curl -X POST https://api.qpher.ai/api/v1/signature/sign-hash \
-H "x-api-key: qph_live_abc123" \
-H "Content-Type: application/json" \
-d '{"hash": "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=", "hash_algorithm": "SHA-256", "key_version": 1}'
Response:
{
"data": {
"signature": "base64-encoded-signature...",
"key_version": 1,
"algorithm": "Dilithium3",
"hash_algorithm": "SHA-256",
"signature_type": "detached"
}
}
Verify Hash
POST /api/v1/signature/verify-hash
| Parameter | Type | Required | Description |
|---|---|---|---|
hash | string (base64) | Yes | Pre-computed hash digest |
hash_algorithm | string | Yes | "SHA-256", "SHA-384", or "SHA-512" |
signature | string (base64) | Yes | Signature to verify |
key_version | integer | Yes | Signing key version |
algorithm | string | No | "Dilithium3" (default) or "Composite-ML-DSA" (Pro/Enterprise) |
curl -X POST https://api.qpher.ai/api/v1/signature/verify-hash \
-H "x-api-key: qph_live_abc123" \
-H "Content-Type: application/json" \
-d '{"hash": "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=", "hash_algorithm": "SHA-256", "signature": "base64...", "key_version": 1}'
Response:
{
"data": {
"valid": true,
"key_version": 1,
"algorithm": "Dilithium3",
"hash_algorithm": "SHA-256"
}
}
Key Management
Generate Key Pair
POST /api/v1/kms/keys/generate
| Parameter | Type | Required | Description |
|---|---|---|---|
algorithm | string | Yes | "Kyber768", "Dilithium3", "X-Wing" (Pro/Enterprise), or "Composite-ML-DSA" (Pro/Enterprise) |
curl -X POST https://api.qpher.ai/api/v1/kms/keys/generate \
-H "x-api-key: qph_live_abc123" \
-H "Content-Type: application/json" \
-d '{"algorithm": "Kyber768"}'
Response:
{
"data": {
"key_version": 1,
"algorithm": "Kyber768",
"status": "active",
"public_key": "base64-encoded-public-key...",
"created_at": "2026-02-23T12:00:00Z"
}
}
Rotate Key
POST /api/v1/kms/keys/rotate
| Parameter | Type | Required | Description |
|---|---|---|---|
algorithm | string | Yes | "Kyber768", "Dilithium3", "X-Wing" (Pro/Enterprise), or "Composite-ML-DSA" (Pro/Enterprise) |
Creates a new active key. The previous active key becomes retired (can still decrypt/verify, but not encrypt/sign).
Get Active Key
GET /api/v1/kms/keys/active?algorithm=Kyber768
Returns the current active key for the specified algorithm.
List Keys
GET /api/v1/kms/keys?algorithm=Kyber768&status=active
| Parameter | Type | Required | Description |
|---|---|---|---|
algorithm | string | No | Filter by algorithm |
status | string | No | Filter: active, retired, archived |
Retire Key
POST /api/v1/kms/keys/retire
| Parameter | Type | Required | Description |
|---|---|---|---|
algorithm | string | Yes | Algorithm of key to retire |
key_version | integer | Yes | Version to retire |
Error Codes
| Code | HTTP | Meaning |
|---|---|---|
ERR_AUTH_001 | 401 | Missing or invalid API key |
ERR_INVALID_001 | 400 | Invalid request parameters |
ERR_NOT_FOUND_001 | 404 | Resource not found |
ERR_FORBIDDEN_001 | 403 | Access denied by policy |
ERR_RATE_001 | 429 | Rate limit exceeded |
ERR_KEM_001 | 400 | KEM operation: invalid plaintext |
ERR_KEM_002 | 400 | KEM operation: invalid key_version |
ERR_KEM_003 | 400 | KEM operation: key not active |
ERR_KEM_004 | 500 | KEM operation: cryptographic error |
ERR_KEM_010 | 400 | KEM wrap: invalid symmetric_key or key_version |
ERR_KEM_011 | 400 | KEM wrap: symmetric key too large |
ERR_KEM_012 | 400 | KEM unwrap: corrupt wrapped_key or wrong key_version |
ERR_SIG_001 | 400 | Signature: invalid message |
ERR_SIG_002 | 400 | Signature: invalid key_version |
ERR_SIG_010 | 400 | Signature: invalid hash or hash_algorithm |
ERR_SIG_011 | 400 | Signature: unsupported hash algorithm |
ERR_KMS_001 | 400 | KMS: invalid algorithm |
ERR_KMS_002 | 404 | KMS: key not found |
ERR_SERVICE_001 | 503 | Downstream service unavailable |
ERR_INTERNAL_001 | 500 | Internal server error |
Error response format:
{
"error": {
"error_code": "ERR_KEM_002",
"message": "Key version 5 not found or not active for Kyber768"
},
"request_id": "uuid",
"timestamp": "ISO-8601"
}
Quick Reference
| Operation | Method | Endpoint | Key Requirement |
|---|---|---|---|
| Encrypt | POST | /api/v1/kem/encrypt | active key |
| Decrypt | POST | /api/v1/kem/decrypt | active or retired key |
| Key Wrap | POST | /api/v1/kem/wrap | active key |
| Key Unwrap | POST | /api/v1/kem/unwrap | active or retired key |
| Sign | POST | /api/v1/signature/sign | active key |
| Verify | POST | /api/v1/signature/verify | active or retired key |
| Sign Hash | POST | /api/v1/signature/sign-hash | active key |
| Verify Hash | POST | /api/v1/signature/verify-hash | active or retired key |
| Generate Key | POST | /api/v1/kms/keys/generate | — |
| Rotate Key | POST | /api/v1/kms/keys/rotate | — |
| Get Active Key | GET | /api/v1/kms/keys/active | — |
| List Keys | GET | /api/v1/kms/keys | — |
| Retire Key | POST | /api/v1/kms/keys/retire | — |