REST API Reference
The CloudKeep REST API gives you full programmatic access to your vaults and secrets. Use it to automate secret rotation, build custom integrations, or power your CI/CD pipelines.
Base URL
All API requests are made to:
https://app.cloudkeep.io/api/v1Every endpoint described below is relative to this base URL. All requests and responses use JSON with Content-Type: application/json.
Authentication
Authenticate by including your API token in the Authorization header. Tokens are created from Settings → API Tokens in the CloudKeep dashboard and always begin with the ck_live_ prefix.
Authorization: Bearer ck_live_abc123...Tokens inherit the permissions of the user who created them. Treat them like passwords — never commit tokens to source control. Store them in environment variables or a secrets manager.
Rate Limiting
The API enforces rate limits to ensure fair usage and platform stability:
- Standard tier: 60 requests per minute
- Pro tier: 300 requests per minute
- Enterprise tier: Custom limits
When you exceed the limit the API responds with 429 Too Many Requests. The Retry-After header indicates how many seconds to wait before retrying.
Vaults
Vaults are the top-level organisational unit. Every secret belongs to exactly one vault.
/vaultsRequires authRetrieve all vaults the authenticated user has access to.
GET /vaults
# Response 200
{
"data": [
{
"id": "vlt_8xK2mN",
"name": "Production",
"description": "Production environment secrets",
"secretCount": 42,
"createdAt": "2025-01-15T08:30:00Z",
"updatedAt": "2025-06-10T14:22:00Z"
}
]
}/vaultsRequires authCreate a new vault.
POST /vaults
Content-Type: application/json
{
"name": "Staging",
"description": "Staging environment secrets"
}
# Response 201
{
"data": {
"id": "vlt_9yL3nP",
"name": "Staging",
"description": "Staging environment secrets",
"secretCount": 0,
"createdAt": "2025-06-11T09:00:00Z",
"updatedAt": "2025-06-11T09:00:00Z"
}
}/vaults/:vaultIdRequires authRetrieve a single vault by ID.
GET /vaults/:vaultId
# Response 200
{
"data": {
"id": "vlt_8xK2mN",
"name": "Production",
"description": "Production environment secrets",
"secretCount": 42,
"createdAt": "2025-01-15T08:30:00Z",
"updatedAt": "2025-06-10T14:22:00Z"
}
}/vaults/:vaultIdRequires authUpdate a vault's name or description.
PATCH /vaults/:vaultId
Content-Type: application/json
{
"name": "Production (US-East)",
"description": "Updated description"
}
# Response 200
{
"data": { ... }
}/vaults/:vaultIdRequires authPermanently delete a vault and all its secrets.
DELETE /vaults/:vaultId
# Response 204 (No Content)Secrets
Secrets are encrypted key-value pairs stored inside a vault. The API returns decrypted values only when you provide a valid token with read access.
/vaults/:vaultId/secretsRequires authList all secrets in a vault.
GET /vaults/:vaultId/secrets
# Response 200
{
"data": [
{
"id": "sec_4aB7cD",
"key": "DATABASE_URL",
"value": "postgres://user:pass@host:5432/db",
"type": "credential",
"createdAt": "2025-03-01T12:00:00Z",
"updatedAt": "2025-06-10T14:22:00Z"
}
]
}/vaults/:vaultId/secretsRequires authCreate a new secret in a vault.
POST /vaults/:vaultId/secrets
Content-Type: application/json
{
"key": "STRIPE_SECRET_KEY",
"value": "sk_live_...",
"type": "api_key",
"notes": "Stripe production key"
}
# Response 201
{
"data": {
"id": "sec_5bC8eF",
"key": "STRIPE_SECRET_KEY",
"value": "sk_live_...",
"type": "api_key",
"createdAt": "2025-06-11T09:15:00Z",
"updatedAt": "2025-06-11T09:15:00Z"
}
}/vaults/:vaultId/secrets/:secretIdRequires authRetrieve a single secret including its decrypted value.
GET /vaults/:vaultId/secrets/:secretId
# Response 200
{
"data": {
"id": "sec_4aB7cD",
"key": "DATABASE_URL",
"value": "postgres://user:pass@host:5432/db",
"type": "credential",
"notes": "Primary database",
"createdAt": "2025-03-01T12:00:00Z",
"updatedAt": "2025-06-10T14:22:00Z"
}
}/vaults/:vaultId/secrets/:secretIdRequires authUpdate a secret's value, type, or notes.
PATCH /vaults/:vaultId/secrets/:secretId
Content-Type: application/json
{
"value": "postgres://user:newpass@host:5432/db"
}
# Response 200
{
"data": { ... }
}/vaults/:vaultId/secrets/:secretIdRequires authPermanently delete a secret.
DELETE /vaults/:vaultId/secrets/:secretId
# Response 204 (No Content)Templates
Templates provide pre-defined secret structures for common services (AWS, Stripe, database credentials, etc.). Use them to quickly scaffold secrets with the right keys.
/templatesRequires authList all available secret templates.
GET /templates
# Response 200
{
"data": [
{
"id": "tpl_aws",
"name": "AWS Credentials",
"fields": [
{ "key": "AWS_ACCESS_KEY_ID", "type": "api_key", "required": true },
{ "key": "AWS_SECRET_ACCESS_KEY", "type": "api_key", "required": true },
{ "key": "AWS_REGION", "type": "text", "required": false }
]
}
]
}Me (Profile)
Retrieve information about the authenticated user and their current subscription.
/meRequires authGet the authenticated user's profile.
GET /me
# Response 200
{
"data": {
"id": "usr_1xA2bC",
"name": "Jane Developer",
"email": "jane@example.com",
"plan": "pro",
"createdAt": "2025-01-01T00:00:00Z"
}
}Error Codes
The API uses standard HTTP status codes. Error responses include a JSON body with a code and human-readable message.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or expired API token."
}
}| Status | Code | Description |
|---|---|---|
400 | BAD_REQUEST | Invalid request body or parameters. |
401 | UNAUTHORIZED | Missing or invalid API token. |
403 | FORBIDDEN | Token lacks required permissions. |
404 | NOT_FOUND | Resource does not exist or is not accessible. |
409 | CONFLICT | Resource already exists (duplicate key). |
429 | RATE_LIMITED | Too many requests. Retry after the indicated delay. |
500 | INTERNAL_ERROR | Unexpected server error. Contact support if persistent. |