The Tenant API lets you create tenants (workspaces), retrieve tenant details, and rotate API keys. Each tenant is an isolated workspace with its own keys, quotas, and billing plan.
Create Tenant
POST /api/v1/tenants Create a new tenant workspace and receive an API key.
Creates a new tenant with the specified name and plan. Returns the tenant details.
💡 Create an API key next
This endpoint creates the tenant only. To obtain an API key, call POST /api/v1/tenants/{tenant_id}/api-keys after creation. The API key is shown only once in that response — store it securely.
Request body
Field Type Required Description namestring Yes A human-readable name for the tenant (1–255 characters). planstring No Pricing plan: "free", "starter", "growth", "pro", or "enterprise". Defaults to "free".
Response (201 Created)
Field Type Description data.idstring (UUID) The unique tenant identifier. data.namestring The tenant name. data.planstring The selected plan. data.statusstring Tenant status, initially "active". data.created_atstring (ISO 8601) When the tenant was created. data.updated_atstring (ISO 8601) When the tenant was last updated.
Example
Content-Type: application/json{
"name": "Acme Corp",
"plan": "starter"
}{
"data": {
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "Acme Corp",
"plan": "starter",
"status": "active",
"created_at": "2026-01-15T10:00:00.000Z",
"updated_at": "2026-01-15T10:00:00.000Z"
},
"request_id": "d0e1f2a3-b4c5-6789-0123-456789abcdef",
"timestamp": "2026-01-15T10:00:00.000Z"
}
curl -X POST https://api.qpher.ai/api/v1/tenants \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corp",
"plan": "starter"
}'Copy
Errors
HTTP Status Error Code Description 400 ERR_INVALID_001Invalid request body — missing name, invalid plan, or name too short/long. 409 ERR_CONFLICT_001A tenant with this name already exists.
Create API Key
POST /api/v1/tenants/{id}/api-keys Create a new API key for the tenant.
Creates a new API key. The plaintext key is returned only once in the response. Key quota is enforced per plan tier.
⚠️ API key shown once
The api_key field is included only in this response. It is never returned again. Copy it immediately and store it in a secure location such as a secrets manager or encrypted vault.
Path parameters
Parameter Type Required Description idstring (UUID) Yes The tenant ID.
Response (201 Created)
Field Type Description data.api_keystring The plaintext API key. Shown only once. data.key_last4string Last 4 characters of the key (for display). data.versioninteger Key version number. data.statusstring Key status (always "active"). data.created_atstring (ISO 8601) When the key was created.
Example
Content-Type: application/json{
"data": {
"api_key": "qph_live_abc123def456ghi789",
"key_last4": "h789",
"version": 1,
"status": "active",
"created_at": "2026-01-15T10:00:00.000Z"
},
"request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2026-01-15T10:00:00.000Z"
}
Errors
HTTP Status Error Code Description 400 ERR_INVALID_001Key quota exceeded for the current plan. 401 ERR_AUTH_001Missing or invalid API key. 404 ERR_NOT_FOUND_001Tenant not found. 429 ERR_RATE_LIMIT_001Rate limit exceeded — reduce request frequency or upgrade your plan.
List API Keys
GET /api/v1/tenants/{tenant_id}/api-keys List all API keys for a tenant (metadata only, no plaintext).
Returns all API keys for the specified tenant. The plaintext key is never returned — only metadata such as key_last4, version, and status.
Path parameters
Parameter Type Required Description tenant_idstring (UUID) Yes The tenant ID.
Response (200 OK)
Field Type Description data.api_keysarray Array of API key metadata objects. data.api_keys[].key_last4string Last 4 characters of the key (for display). data.api_keys[].versioninteger Key version number. data.api_keys[].statusstring "active" or "revoked".data.api_keys[].created_atstring (ISO 8601) When the key was created. data.api_keys[].revoked_atstring | null When the key was revoked, or null if still active. data.totalinteger Total number of API keys.
Example
X-API-Key: qph_your_key_here{
"data": {
"api_keys": [
{
"key_last4": "h789",
"version": 2,
"status": "active",
"created_at": "2026-02-01T12:00:00.000Z",
"revoked_at": null
},
{
"key_last4": "d456",
"version": 1,
"status": "revoked",
"created_at": "2026-01-15T10:00:00.000Z",
"revoked_at": "2026-02-01T12:00:00.000Z"
}
],
"total": 2
},
"request_id": "b2c3d4e5-f6a7-8901-2345-678901abcdef",
"timestamp": "2026-02-01T12:05:00.000Z"
}
Errors
HTTP Status Error Code Description 401 ERR_AUTH_001Missing or invalid API key. 404 ERR_NOT_FOUND_001Tenant not found.
Get Tenant
GET /api/v1/tenants/{id} Retrieve details for a specific tenant.
Returns tenant details. The API key is not included in this response for security reasons.
Path parameters
Parameter Type Required Description idstring (UUID) Yes The tenant ID.
Response (200 OK)
Field Type Description data.idstring (UUID) The tenant identifier. data.namestring The tenant name. data.planstring The current plan. data.statusstring Tenant status: "active", "suspended", etc. data.created_atstring (ISO 8601) When the tenant was created. data.updated_atstring (ISO 8601) When the tenant was last updated.
Example
X-API-Key: qph_your_key_here{
"data": {
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "Acme Corp",
"plan": "starter",
"status": "active",
"created_at": "2026-01-15T10:00:00.000Z",
"updated_at": "2026-01-15T10:00:00.000Z"
},
"request_id": "e1f2a3b4-c5d6-7890-1234-567890abcdef",
"timestamp": "2026-01-15T10:05:00.000Z"
}
curl -X GET https://api.qpher.ai/api/v1/tenants/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
-H "X-API-Key: qph_your_key_here"Copy
Errors
HTTP Status Error Code Description 401 ERR_AUTH_001Missing or invalid API key. 404 ERR_NOT_FOUND_001Tenant not found.
Rotate API Key
POST /api/v1/tenants/{id}/api-keys/rotate Rotate the API key for a tenant, revoking the old key.
Generates a new API key and immediately revokes the old one. There is a brief concurrent window where both keys are valid to allow for zero-downtime rotation.
⚠️ API key shown once
The new api_key inside data.new_key is included only in this response. Store it immediately. The old key will stop working shortly after rotation.
Path parameters
Parameter Type Required Description idstring (UUID) Yes The tenant ID.
Response (200 OK)
Field Type Description data.new_key.api_keystring The new API key. Shown only once. data.new_key.key_last4string Last 4 characters of the new key (for display). data.new_key.versioninteger Version number of the new key. data.new_key.statusstring Key status (always "active"). data.new_key.created_atstring (ISO 8601) When the new key was created. data.revoked_versioninteger | null Version of the revoked key, or null if none.
Example
X-API-Key: qph_your_key_here
Content-Type: application/json{
"data": {
"new_key": {
"api_key": "qph_new_rotated_key_here",
"key_last4": "here",
"version": 2,
"status": "active",
"created_at": "2026-02-01T12:00:00.000Z"
},
"revoked_version": 1
},
"request_id": "f2a3b4c5-d6e7-8901-2345-678901abcdef"
}
curl -X POST https://api.qpher.ai/api/v1/tenants/f47ac10b-58cc-4372-a567-0e02b2c3d479/api-keys/rotate \
-H "X-API-Key: qph_your_key_here" \
-H "Content-Type: application/json"Copy
Errors
HTTP Status Error Code Description 401 ERR_AUTH_001Missing or invalid API key. 404 ERR_NOT_FOUND_001Tenant not found. 429 ERR_RATE_LIMIT_001Rate limit exceeded — reduce request frequency or upgrade your plan.
Revoke API Key
DELETE /api/v1/tenants/{tenant_id}/api-keys/{version} Revoke a specific API key by version number.
Revokes an API key immediately. The key stops working as soon as it is revoked.
⚠️ Irreversible operation
Revoking an API key is permanent. The key cannot be reactivated. If you need a new key, use POST /api/v1/tenants/{tenant_id}/api-keys to create one.
Path parameters
Parameter Type Required Description tenant_idstring (UUID) Yes The tenant ID. versioninteger Yes The API key version to revoke.
Response (200 OK)
Field Type Description data.key_last4string Last 4 characters of the revoked key. data.versioninteger The revoked key version. data.statusstring "revoked".data.created_atstring (ISO 8601) When the key was originally created. data.revoked_atstring (ISO 8601) When the key was revoked.
Example
X-API-Key: qph_your_key_here{
"data": {
"key_last4": "d456",
"version": 1,
"status": "revoked",
"created_at": "2026-01-15T10:00:00.000Z",
"revoked_at": "2026-03-01T08:00:00.000Z"
},
"request_id": "c3d4e5f6-a7b8-9012-3456-789012abcdef",
"timestamp": "2026-03-01T08:00:00.000Z"
}
Errors
HTTP Status Error Code Description 401 ERR_AUTH_001Missing or invalid API key. 404 ERR_NOT_FOUND_001Tenant or API key version not found.
Plan Tiers
Plan Monthly Price Requests/min PQC Keys Free $0 100 2 Starter $99 500 10 Growth $179 1,000 25 Pro $299 5,000 100 Enterprise From $999 Custom Unlimited
💡 Upgrading your plan
To change your plan, use the Qpher Portal at portal.qpher.ai or contact sales for Enterprise pricing.