API Overview
The Qpher API gives you programmatic access to post-quantum cryptographic operations — key encapsulation (KEM), digital signatures, key management, and tenant administration — through a single, consistent REST interface.
Base URL
All API requests are made to:
https://api.qpher.ai
Every endpoint is prefixed with /api/v1/. For example, the KEM encrypt endpoint is:
POST https://api.qpher.ai/api/v1/kem/encrypt
Authentication
Authenticate every request by including your API key in the X-API-Key header.
curl -X GET https://api.qpher.ai/api/v1/kms/keys/active?algorithm=Kyber768 \
-H "X-API-Key: qph_your_key_here" \
-H "Content-Type: application/json"Your API key is shown only once at creation time. Store it in a secrets manager or environment variable — never commit it to source control.
Content Type
All request and response bodies use JSON. Set the Content-Type header on every request:
Content-Type: application/json
Response Format
Success responses
Every successful response follows this structure:
{
"data": {
},
"request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2026-01-15T10:30:00.000Z"
}
| Field | Type | Description |
|---|---|---|
data | object | The endpoint-specific result payload. |
request_id | string (UUID) | Unique identifier for this request. Use it when contacting support. |
timestamp | string (ISO 8601) | UTC timestamp of when the response was generated. |
Error responses
Errors return an error object instead of data:
{
"error": {
"error_code": "ERR_AUTH_001",
"message": "Missing or invalid API key"
},
"request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2026-01-15T10:30:00.000Z"
}
| Field | Type | Description |
|---|---|---|
error.error_code | string | A stable, machine-readable code like ERR_KEM_001. See the Error Codes reference. |
error.message | string | A human-readable description of what went wrong. |
request_id | string (UUID) | Same request ID — always include it in bug reports. |
timestamp | string (ISO 8601) | UTC timestamp of the error. |
Rate Limiting
Rate limits are enforced per tenant using a sliding window. The default limit is 1,000 requests per minute, though this varies by plan tier.
When you exceed the limit, the API returns HTTP 429 Too Many Requests with a Retry-After header indicating how many seconds to wait:
/api/v1/kem/encryptX-API-Key: qph_your_key_here
Content-Type: application/json{
"plaintext": "SGVsbG8=",
"key_version": 1
}{
"error": {
"error_code": "ERR_RATE_LIMIT_001",
"message": "Rate limit exceeded. Retry after 12 seconds."
},
"request_id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
"timestamp": "2026-01-15T10:30:05.000Z"
}Implement exponential backoff in your client. Respect the Retry-After header value to avoid cascading failures.
Rate limits by plan
| Plan | Requests per minute |
|---|---|
| Free | 100 |
| Starter | 500 |
| Growth | 1,000 |
| Pro | 5,000 |
| Enterprise | Custom |
Request IDs
Every response includes a request_id (UUID). If you send an X-Request-ID header with your request, the API will use your value; otherwise it generates one automatically.
Request IDs are essential for debugging. Always log them on your side, and include them in any support ticket:
X-Request-ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
HTTP Status Codes
| Code | Meaning |
|---|---|
200 | Success |
400 | Bad request — invalid input or parameters |
401 | Unauthorized — missing or invalid API key |
403 | Forbidden — policy denied the request |
404 | Not found — resource does not exist |
409 | Conflict — duplicate or concurrent operation |
422 | Unprocessable entity — valid JSON but invalid values |
429 | Too many requests — rate limit exceeded |
500 | Internal server error |
502 | Bad gateway — downstream service failure |
503 | Service unavailable — fail-closed safety mode |
504 | Gateway timeout |
Next Steps
- KEM API — Encrypt and decrypt with Kyber768
- Signature API — Sign and verify with Dilithium3
- Key Management API — Generate, rotate, and manage PQC keys
- Error Codes — Full error code reference