Create, list, and revoke API keys on the Hydra Node.
API Key Management
Manage API keys for authenticating against the node's /v1/* and /v1/stream endpoints. All endpoints require control-plane authentication.
GET /control/api-keys
List all API keys (without exposing the full key).
curl http://localhost:4002/control/api-keys \
-H "x-node-secret: my-secret"
Response: 200 OK
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Production Bot",
"keyPrefix": "hyd_a1b2c3d4",
"scopes": ["read"],
"createdAt": "2026-03-20T10:00:00Z",
"lastUsedAt": "2026-03-21T08:15:00Z",
"revoked": false
},
{
"id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"name": "Test Key",
"keyPrefix": "hyd_e5f6g7h8",
"scopes": ["read"],
"createdAt": "2026-03-19T14:30:00Z",
"lastUsedAt": null,
"revoked": true
}
]
| Field | Type | Description |
|---|---|---|
id |
string | UUID of the API key |
name |
string | Human-readable key name |
keyPrefix |
string | First 12 characters of the key (for identification) |
scopes |
string[] | Permission scopes |
createdAt |
string | ISO 8601 creation time |
lastUsedAt |
string | null | Last time the key was used |
revoked |
boolean | Whether the key has been revoked |
POST /control/api-keys
Create a new API key. The full key is only returned once in this response — store it securely.
curl -X POST http://localhost:4002/control/api-keys \
-H "x-node-secret: my-secret" \
-H "Content-Type: application/json" \
-d '{
"name": "My Bot Key",
"scopes": ["read"]
}'
Request Body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string | Yes | — | Human-readable key name |
scopes |
string[] | No | ["read"] |
Permission scopes |
Response: 201 Created
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "My Bot Key",
"key": "hyd_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0",
"keyPrefix": "hyd_a1b2c3d4",
"scopes": ["read"]
}
Important: The key field contains the full API key. This is the only time it will be returned. The node stores only the SHA-256 hash internally.
Key Format
Keys follow the format hyd_ + 64 hex characters (32 random bytes):
hyd_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0
DELETE /control/api-keys/{id}
Revoke an API key. The key immediately stops working for all endpoints.
curl -X DELETE http://localhost:4002/control/api-keys/550e8400-e29b-41d4-a716-446655440000 \
-H "x-node-secret: my-secret"
Path Parameters:
| Param | Type | Description |
|---|---|---|
id |
string | UUID of the API key to revoke |
Response: 200 OK
{
"status": "revoked",
"id": "550e8400-e29b-41d4-a716-446655440000"
}
Response: 404 Not Found
{
"error": "api key not found"
}
Example: Full lifecycle
# 1. Create a key
KEY=$(curl -s -X POST http://localhost:4002/control/api-keys \
-H "x-node-secret: my-secret" \
-H "Content-Type: application/json" \
-d '{"name": "test-key"}' | jq -r '.key')
echo "Created key: $KEY"
# 2. Use the key to fetch signals (port 4001 = data API)
curl http://localhost:4001/v1/signals \
-H "x-api-key: $KEY"
# 3. List all keys
curl http://localhost:4002/control/api-keys \
-H "x-node-secret: my-secret" | jq
# 4. Revoke the key
ID=$(curl -s http://localhost:4002/control/api-keys \
-H "x-node-secret: my-secret" | jq -r '.[0].id')
curl -X DELETE "http://localhost:4002/control/api-keys/$ID" \
-H "x-node-secret: my-secret"