API Keys API
Manage API keys for authentication and access control
Overview
The API Keys API allows you to manage API keys used for authenticating requests to Clouisle. API keys provide scoped, revocable access to agents and workflows.
Base URL: /api/v1/api-keys
Authentication
All API-key management endpoints require an authenticated JWT user with the applicable permission. API keys cannot be used to manage other API keys.
Required permissions:
| Permission | Description |
|---|---|
apikey:read | View API keys |
apikey:create | Create API keys |
apikey:update | Update API keys |
apikey:delete | Delete API keys |
Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/api-keys | List all API keys |
| GET | /api/v1/api-keys/{key_id} | Get a specific API key |
| POST | /api/v1/api-keys | Create a new API key |
| PUT | /api/v1/api-keys/{key_id} | Update API key settings |
| DELETE | /api/v1/api-keys/{key_id} | Delete (revoke) an API key |
| GET | /api/v1/api-keys/stats | Get aggregate statistics |
| POST | /api/v1/api-keys/{key_id}/activate | Activate an API key |
| POST | /api/v1/api-keys/{key_id}/deactivate | Deactivate an API key |
List API Keys
Get a paginated list of all your API keys.
Endpoint: GET /api/v1/api-keys
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | No | 1 | Page number |
page_size | integer | No | 20 | Items per page |
status | array | No | - | Filter by status: active, inactive, expired (repeatable) |
user_id | array | No | - | Filter by owner user ID (admin only) |
search | string | No | - | Search by name or key prefix |
Request Example
curl -X GET "https://your-domain.com/api/v1/api-keys" \
-H "Authorization: Bearer YOUR_TOKEN"Response
200 OK:
{
"code": 0,
"data": {
"items": [
{
"id": "key-123",
"name": "Production API Key",
"key_prefix": "clou_a1b2c3d",
"user_id": "user-001",
"user": {
"id": "user-001",
"username": "alice"
},
"scopes": ["chat", "agent:read"],
"rate_limit": 1000,
"is_active": true,
"last_used_at": "2026-02-11T14:30:00Z",
"expires_at": "2027-02-11T00:00:00Z",
"agents": [
{
"id": "agent-001",
"name": "Customer Support Agent",
"icon": "🤖"
}
],
"workflows": [],
"created_at": "2026-02-11T10:00:00Z",
"updated_at": "2026-02-11T10:00:00Z"
}
],
"total": 1,
"page": 1,
"page_size": 20
},
"msg": "success"
}The actual API key value is only shown once during creation. After creation, only the key_prefix is returned for identification.
Get API Key
Get details of a specific API key.
Endpoint: GET /api/v1/api-keys/{key_id}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
key_id | string | Yes | API Key UUID |
Response
200 OK:
{
"code": 0,
"data": {
"id": "key-123",
"name": "Production API Key",
"key_prefix": "clou_a1b2c3d",
"user_id": "user-001",
"scopes": ["chat", "agent:read"],
"rate_limit": 1000,
"is_active": true,
"last_used_at": "2026-02-11T14:30:00Z",
"expires_at": "2027-02-11T00:00:00Z",
"agents": [],
"workflows": [],
"created_at": "2026-02-11T10:00:00Z",
"updated_at": "2026-02-11T10:00:00Z"
},
"msg": "success"
}Create API Key
Create a new API key. The full key value is returned only once in this response.
Endpoint: POST /api/v1/api-keys
Request Body
{
"name": "Production API Key",
"scopes": ["chat", "agent:read"],
"rate_limit": 1000,
"expires_at": "2027-02-11T00:00:00Z",
"agent_ids": ["agent-001"],
"workflow_ids": []
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | API key name (max 100 chars) |
scopes | array | No | List of permission scopes (default: ["chat"]) |
rate_limit | integer | No | Rate limit per minute, 0 means unlimited (default: 1000) |
expires_at | string | No | Expiration date (ISO 8601) |
agent_ids | array | No | Agent IDs this key can access (empty = no restriction) |
workflow_ids | array | No | Workflow IDs this key can access (empty = no restriction) |
Request Example
curl -X POST "https://your-domain.com/api/v1/api-keys" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production API Key",
"scopes": ["chat", "agent:read"],
"rate_limit": 1000,
"expires_at": "2027-02-11T00:00:00Z"
}'Response
200 OK:
{
"code": 0,
"data": {
"id": "key-789",
"name": "Production API Key",
"key": "clou_a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890a1b2c3d4e5f67890",
"key_prefix": "clou_a1b2c3d",
"user_id": "user-001",
"scopes": ["chat", "agent:read"],
"rate_limit": 1000,
"is_active": true,
"expires_at": "2027-02-11T00:00:00Z",
"created_at": "2026-02-11T16:00:00Z",
"updated_at": "2026-02-11T16:00:00Z"
},
"msg": "API key created successfully. Save this key securely - it won't be shown again."
}The key field is only returned once. Store it securely immediately. You cannot retrieve the full key later — only the key_prefix will be visible.
Update API Key
Update API key settings. All fields are optional — only include fields you want to update.
Endpoint: PUT /api/v1/api-keys/{key_id}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
key_id | string | Yes | API Key UUID |
Request Body
{
"name": "Production API Key (Updated)",
"scopes": ["chat", "agent:read"],
"rate_limit": 500,
"is_active": true,
"agent_ids": ["agent-001"],
"workflow_ids": []
}Request Example
curl -X PUT "https://your-domain.com/api/v1/api-keys/key-123" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production API Key (Updated)",
"rate_limit": 500,
"is_active": true
}'Response
200 OK:
{
"code": 0,
"data": {
"id": "key-123",
"name": "Production API Key (Updated)",
"is_active": true,
"updated_at": "2026-02-11T16:05:00Z"
},
"msg": "API key updated successfully"
}Updating scopes takes effect immediately for all requests.
Delete API Key
Permanently delete (revoke) an API key.
Endpoint: DELETE /api/v1/api-keys/{key_id}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
key_id | string | Yes | API Key UUID |
Request Example
curl -X DELETE "https://your-domain.com/api/v1/api-keys/key-123" \
-H "Authorization: Bearer YOUR_TOKEN"Response
200 OK:
{
"code": 0,
"data": null,
"msg": "API key deleted successfully"
}Deleted API keys cannot be recovered. All requests using this key will fail immediately.
Get API Key Stats
Get aggregate statistics across all API keys the current user can see.
Endpoint: GET /api/v1/api-keys/stats
Request Example
curl -X GET "https://your-domain.com/api/v1/api-keys/stats" \
-H "Authorization: Bearer YOUR_TOKEN"Response
200 OK:
{
"code": 0,
"data": {
"total": 3,
"active": 2,
"inactive": 0,
"expired": 1
},
"msg": "success"
}Activate / Deactivate API Key
Toggle a key between active and inactive without deleting it.
Endpoints:
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/api-keys/{key_id}/activate | Activate a key |
| POST | /api/v1/api-keys/{key_id}/deactivate | Deactivate a key |
Request Example
curl -X POST "https://your-domain.com/api/v1/api-keys/key-123/deactivate" \
-H "Authorization: Bearer YOUR_TOKEN"Response
200 OK:
{
"code": 0,
"data": {
"id": "key-123",
"name": "Production API Key",
"key_prefix": "clou_a1b2c3d",
"user_id": "user-001",
"scopes": ["chat", "agent:read"],
"rate_limit": 1000,
"is_active": false,
"expires_at": "2027-02-11T00:00:00Z",
"created_at": "2026-02-11T10:00:00Z",
"updated_at": "2026-02-11T16:00:00Z"
},
"msg": "success"
}Error Codes
| Code | Message | Description |
|---|---|---|
4000 | Not found | API key does not exist |
2001 | Invalid token | API key is invalid or expired |
3000 | Permission denied | Insufficient permissions |
1001 | Validation failed | Invalid request data |
No per-endpoint rate limits are implemented. The rate_limit field is stored for informational purposes and is not enforced by middleware.
Key Scopes
API keys support the following permission scopes:
| Scope | Description |
|---|---|
chat | Send messages to agents |
agent:read | Read agent information |
workflow:execute | Execute workflows |
knowledge:read | Access knowledge base |
Best Practices
Security
- Store API keys securely (environment variables, secret managers)
- Use different keys for different environments
- Rotate keys regularly (every 90 days)
- Use minimal required scopes
- Set expiration dates
- Monitor key usage
- Revoke unused keys
- Never commit keys to version control
Key Management
- Name keys descriptively (e.g., "Production Chatbot Key")
- Document key purposes and ownership
- Track key usage patterns
- Set up usage alerts
- Review keys regularly and remove unused ones
- Use grace period during rotation — test new keys before revoking old ones
Code Examples
Python
import requests
import os
def create_api_key(token, name, scopes, rate_limit=1000):
"""Create a new API key."""
url = "https://your-domain.com/api/v1/api-keys"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
data = {
"name": name,
"scopes": scopes,
"rate_limit": rate_limit,
"expires_at": "2027-02-11T00:00:00Z"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
if result['code'] == 0:
api_key = result['data']['key']
print(f"API Key created: {api_key}")
print("Save this key securely - it won't be shown again!")
return result['data']
else:
raise Exception(f"Error: {result['msg']}")
# Usage
token = os.getenv("USER_TOKEN")
new_key = create_api_key(
token,
"Production API Key",
["chat", "agent:read"]
)JavaScript
async function createApiKey(token, name, scopes, rateLimit = 1000) {
const response = await fetch(
'https://your-domain.com/api/v1/api-keys',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: name,
scopes: scopes,
rate_limit: rateLimit,
expires_at: '2027-02-11T00:00:00Z',
}),
}
);
const result = await response.json();
if (result.code === 0) {
const apiKey = result.data.key;
console.log(`API Key created: ${apiKey}`);
console.log('Save this key securely - it won\'t be shown again!');
return result.data;
} else {
throw new Error(result.msg);
}
}
// Usage
const token = process.env.USER_TOKEN;
const newKey = await createApiKey(
token,
'Production API Key',
['chat', 'agent:read']
);这篇文章对你有帮助吗?