Workload Credentials API | Pathfinder
The BeyondTrust Workload Credentials API provides secure, programmatic access to secrets, folders, and integrations. It supports secret versioning, tagging, folder management, and integration with external systems.
API Version: 2026-04-28
Base URL: https://api.beyondtrust.io/site/<site-id>/wlc
Getting started
Authentication
The API uses JWT Bearer Token or Personal Access Tokens (PATs) authentication. Include your access token in the Authorization header for all requests:
Authorization: Bearer <your-jwt-token>
or
Authorization: Bearer <your-pat-token>
API versioning
All requests must include the API version header:
bt-wlc-api-version: 2026-04-28
Example request
curl -X GET "https://api.beyondtrust.io/site/<site-id>/wlc/static/my-secret?folder=prod/db" \
-H "Authorization: Bearer <your-jwt-token>" \
-H "bt-wlc-api-version: 2026-04-28"API reference
Session
Check authentication session
Verify if the current authentication session is valid.
GET /session
Response (200):
{
"valid": true
}Static secrets
List secrets
Retrieve a list of secrets, optionally filtered by path, version, or deletion status.
GET /static
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| path | string | Path to filter items |
| recursive | boolean | List all items under the path recursively |
| versions | boolean | Include version history |
| deletedOnly | boolean | Only list deleted items |
Response (200):
{
"data": [
{
"path": "/prod/db/password",
"type": "static",
"metadata": {
"id": "b7e6f8a1-9c2d-4e3a-8b7a-2d6e4f1c9a2b",
"tags": { "env": "prod", "owner": "db" },
"version": 3,
"createdAt": "2025-09-12T14:00:00-06:00"
},
"versions": [
{ "version": 3, "createdAt": "2025-09-12T14:00:00-06:00" },
{ "version": 2, "createdAt": "2025-09-10T14:00:00-06:00" }
]
}
]
}Get secret by path
Retrieve a specific secret by its path.
GET /static/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the secret |
| version | integer | Specific version to retrieve |
| versions | boolean | Include all version history |
Response (200):
{
"path": "/prod/db/password",
"secret": {
"password": "supersecret"
},
"metadata": {
"id": "b7e6f8a1-9c2d-4e3a-8b7a-2d6e4f1c9a2b",
"tags": { "env": "prod", "owner": "db" },
"version": 3,
"createdAt": "2025-09-12T14:00:00-06:00"
},
"versions": [
{ "version": 3, "createdAt": "2025-09-12T14:00:00-06:00" },
{ "version": 2, "createdAt": "2025-09-10T14:00:00-06:00" }
]
}Create secret
Create a new secret at the specified path.
POST /static/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder to create the secret in |
Request Body:
{
"secret": {
"password": "supersecret",
"username": "admin"
}
}Response (201):
{
"path": "/prod/db/password",
"secret": {
"password": "supersecret"
},
"metadata": {
"id": "b7e6f8a1-9c2d-4e3a-8b7a-2d6e4f1c9a2b",
"tags": {},
"version": 1,
"createdAt": "2025-09-14T14:00:00-06:00"
}
}Update secret
Update the value or metadata of an existing secret using JSON Merge Patch (RFC 7396).
PATCH /static/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the secret |
Request Body:
{
"secret": {
"password": "newsecret"
},
"cas": 5
}Note: This endpoint uses JSON Merge Patch semantics:
- Fields present in the request will be updated with the provided values
- Fields set to
nullwill be deleted from the secret - Fields not present in the request remain unchanged
The optional cas field provides Check-and-Set semantics. If provided, the request only succeeds when the secret's current version equals this value; otherwise the server returns 409 Conflict with error code cas_mismatch. Use this to safely update a secret you've read recently — for example, to avoid silently overwriting another user's change. If omitted, the update proceeds without a version check (last writer wins).
Response: 204 No Content
Delete secret
Delete a secret at the specified path.
DELETE /static/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the secret |
| permanent | boolean | Permanently delete the secret |
Response: 204 No Content
Restore secret
Restore a previously deleted secret.
POST /static/{name}/restore
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the secret |
Response (200): Returns the restored secret object.
Get secret metadata
Retrieve metadata for a specific secret.
GET /static/{name}/metadata
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the secret |
Response (200):
{
"id": "b7e6f8a1-9c2d-4e3a-8b7a-2d6e4f1c9a2b",
"tags": { "env": "prod", "owner": "db" },
"version": 3,
"createdAt": "2025-09-12T14:00:00-06:00"
}Replace secret tags
Replace all tags for a secret.
PUT /static/{name}/metadata/tags
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the secret |
Request Body:
{
"env": "prod",
"owner": "db"
}Response (200): Returns the new set of tags.
Update secret tags
Add or remove tags for a secret using JSON Merge Patch (RFC 7396).
PATCH /static/{name}/metadata/tags
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the secret |
Request Body:
{
"newTag": "value",
"removeTag": null
}Note: Set a tag value to null to remove it.
Response: 204 No Content
Clear secret tags
Remove all tags from a secret.
DELETE /static/{name}/metadata/tags
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the secret |
Response: 204 No Content
Folders
List folders
Retrieve a list of folders.
GET /folders
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| path | string | Path to filter folders |
| recursive | boolean | List folders recursively |
| deletedOnly | boolean | Only list deleted folders |
Response (200):
{
"data": [
{
"path": "/prod",
"type": "folder",
"metadata": {
"id": "d1e2f3a4-5b6c-7d8e-9f0a-1b2c3d4e5f6a",
"tags": { "env": "prod" },
"createdAt": "2025-09-10T14:00:00-06:00"
}
}
]
}Create folder
Create a new folder at the specified path.
POST /folders/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the folder |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The parent folder path |
Response (201):
{
"id": "b7e8b7e2-1c2d-4e8a-9e7a-2b7e8b7e2c2d",
"path": "/example/folder",
"createdAt": "2025-09-12T14:00:00-06:00",
"metadata": {
"id": "b7e8b7e2-1c2d-4e8a-9e7a-2b7e8b7e2c2d",
"tags": {},
"version": 1,
"createdAt": "2025-09-12T14:00:00-06:00"
}
}Delete folder
Delete a folder at the specified path.
DELETE /folders/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the folder |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The parent folder path |
| permanent | boolean | Permanently delete the folder |
| recursive | boolean | Delete folder and all contents |
Response: 204 No Content
Restore folder
Restore a deleted folder and all its contents.
POST /folders/{name}/restore
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the folder |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The parent folder path |
Response (200): Returns the restored folder object.
Get folder metadata
Retrieve metadata for a specific folder.
GET /folders/{name}/metadata
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the folder |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The parent folder path |
Response (200):
{
"id": "d1e2f3a4-5b6c-7d8e-9f0a-1b2c3d4e5f6a",
"tags": { "env": "prod" },
"createdAt": "2025-09-10T14:00:00-06:00"
}Replace folder tags
Replace all tags for a folder.
PUT /folders/{name}/metadata/tags
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the folder |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The parent folder path |
Request Body:
{
"env": "prod",
"team": "platform"
}Response (200): Returns the new set of tags.
Update folder tags
Add or remove tags for a folder using JSON Merge Patch (RFC 7396).
PATCH /folders/{name}/metadata/tags
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the folder |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The parent folder path |
Request Body:
{
"newTag": "value",
"removeTag": null
}Response: 204 No Content
Clear folder tags
Remove all tags from a folder.
DELETE /folders/{name}/metadata/tags
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the folder |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The parent folder path |
Response: 204 No Content
Integrations
Integrations connect Workload Credentials to external systems such as AWS and Azure. Each integration is uniquely identified by the combination of its provider type and name, both of which appear in the URL.
List integrations
Retrieve a list of integrations across every provider.
GET /integrations
Response (200):
{
"data": [
{
"id": "fae8bacd-281c-43df-a91a-a49a2a48a07c",
"name": "my aws",
"type": "aws",
"createdAt": "2025-09-12T14:00:00-06:00"
},
{
"id": "2fb88d4e-86c6-4002-af6d-e04f9dc647aa",
"name": "my azure",
"type": "azure",
"createdAt": "2025-10-12T14:00:00-06:00"
}
]
}List integrations by type
Retrieve a list of integrations scoped to a single provider type.
GET /integrations/{type}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| type | string | The integration provider type (e.g., aws, azure) |
Response (200):
{
"data": [
{
"id": "fae8bacd-281c-43df-a91a-a49a2a48a07c",
"name": "my aws",
"type": "aws",
"createdAt": "2025-09-12T14:00:00-06:00"
}
]
}Create integration
Create a new integration.
POST /integrations/{type}/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| type | string | The integration provider type (e.g., aws, azure) |
| name | string | The name of the integration |
Request Body (AWS):
{
"type": "aws",
"roleArn": "arn:aws:iam::123456789012:role/MyRole"
}Request Body (Azure):
{
"type": "azure",
"tenantId": "00000000-0000-0000-0000-000000000000",
"clientId": "11111111-1111-1111-1111-111111111111",
"clientSecret": "..."
}Response (201):
{
"name": "my aws",
"type": "aws",
"config": {
"roleArn": "arn:aws:iam::123456789012:role/MyRole",
"externalId": "fae8bacd-281c-43df-a91a-a49a2a48a07c"
},
"metadata": {
"id": "fae8bacd-281c-43df-a91a-a49a2a48a07c",
"version": 1,
"createdAt": "2025-09-12T14:00:00-06:00"
}
}Get integration
Retrieve details for a specific integration.
GET /integrations/{type}/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| type | string | The integration provider type (e.g., aws, azure) |
| name | string | The name of the integration |
Response (200):
{
"name": "my-aws",
"type": "aws",
"config": {
"roleArn": "arn:aws:iam::123456789012:role/MyRole",
"externalId": "external-id-123"
},
"metadata": {
"id": "fae8bacd-281c-43df-a91a-a49a2a48a07c",
"version": 1,
"createdAt": "2025-09-12T14:00:00-06:00"
}
}Update integration
Update an existing integration using JSON Merge Patch (RFC 7396).
PATCH /integrations/{type}/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| type | string | The integration provider type (e.g., aws, azure) |
| name | string | The name of the integration |
Request Body (AWS):
{
"roleArn": "arn:aws:iam::123456789012:role/NewRole"
}Request Body (Azure):
{
"clientSecret": "new-client-secret"
}Response: 204 No Content
Delete integration
Delete an integration.
DELETE /integrations/{type}/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| type | string | The integration provider type (e.g., aws, azure) |
| name | string | The name of the integration |
Response: 204 No Content
List dynamic secrets using integration
Retrieve a list of dynamic secrets that use this integration.
GET /integrations/{type}/{name}/dynamic
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| type | string | The integration provider type (e.g., aws, azure) |
| name | string | The name of the integration |
Response (200): Returns a list of dynamic secrets with active lease counts.
Dynamic secrets
Dynamic secrets generate temporary credentials on demand.
List dynamic secrets
Retrieve a list of dynamic secrets.
GET /dynamic
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| path | string | Path to filter dynamic secrets |
| recursive | boolean | List recursively |
| deletedOnly | boolean | Only list deleted items |
Response (200):
{
"data": [
{
"path": "eks-role",
"type": "dynamic-aws",
"metadata": {
"id": "fae8bacd-281c-43df-a91a-a49a2a48a07c",
"createdAt": "2025-09-12T14:00:00-06:00"
}
},
{
"path": "azure/web-app",
"type": "dynamic-azure",
"metadata": {
"id": "2fb88d4e-86c6-4002-af6d-e04f9dc647aa",
"createdAt": "2025-10-12T14:00:00-06:00"
}
}
]
}Get dynamic secret
Retrieve a dynamic secret's configuration.
GET /dynamic/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the dynamic secret |
Response (200):
{
"path": "eks-role",
"config": {
"type": "aws",
"credentialType": "assumed_role",
"ttl": 900,
"integrationId": "87f59af6-894d-43ea-8821-a8dde45eb4fa",
"roleArn": "arn:aws:iam::507498906321:role/test-role-1",
"externalId": "xyz",
"policyArns": [
"arn:aws:iam::aws:policy/ReadOnlyAccess"
],
"policy": "{\"Version\":\"2012-10-17\",\"Statement\":[...]}",
"groups": ["Admins", "Developers"],
"awsTags": { "tag1": "val1" }
},
"metadata": {
"id": "fae8bacd-281c-43df-a91a-a49a2a48a07c",
"version": 1,
"createdAt": "2025-09-12T14:00:00-06:00"
}
}Create dynamic secret
Create a new dynamic secret.
POST /dynamic/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder to create the dynamic secret in |
Request Body (AWS):
{
"type": "aws",
"integrationName": "my-aws",
"credentialType": "assumed_role",
"roleArn": "arn:aws:iam::123456789012:role/MyRole",
"externalId": "external-id-123",
"ttl": 900,
"policyArns": ["arn:aws:iam::aws:policy/AdministratorAccess"],
"policy": "{\"Version\":\"2012-10-17\",\"Statement\":[...]}",
"groups": ["Developers", "Admins"],
"awsTags": { "env": "dev", "owner": "ops" }
}Request Body (Azure):
{
"type": "azure",
"integrationName": "my-azure",
"credentialType": "service_principal_password",
"applicationObjectId": "22222222-2222-2222-2222-222222222222",
"ttl": 3600
}Note: applicationObjectId is the target Azure AD app registration's Object ID (not the Application/Client ID). TTL must be between 3600 and 86400 seconds.
Response (201): Returns the created dynamic secret object.
Update dynamic secret
Update an existing dynamic secret using JSON Merge Patch (RFC 7396).
PATCH /dynamic/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the dynamic secret |
Request Body (AWS):
{
"type": "aws",
"ttl": 1800,
"roleArn": "arn:aws:iam::123456789012:role/UpdatedRole"
}Request Body (Azure):
{
"type": "azure",
"ttl": 7200,
"applicationObjectId": "33333333-3333-3333-3333-333333333333"
}Note: The type field is required. Arrays are replaced entirely, not merged element-by-element.
Response: 204 No Content
Delete dynamic secret
Delete a dynamic secret.
DELETE /dynamic/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the dynamic secret |
| permanent | boolean | Permanently delete |
Response: 204 No Content
Restore dynamic secret
Restore a deleted dynamic secret.
POST /dynamic/{name}/restore
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the dynamic secret |
Response (200): Returns the restored dynamic secret object.
Generate dynamic credential
Generate temporary credentials from a dynamic secret.
POST /dynamic/{name}/generate
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the dynamic secret |
The shape of secret depends on the dynamic secret type.
Response (201) — AWS:
{
"secret": {
"sessionToken": "********",
"secretAccessKey": "AKIA****",
"accessKeyId": "********",
"leaseId": "b7e6f8a1-9c2d-4e3a-8b7a-2d6e4f1c9a2b",
"expiration": "2025-09-14T15:00:00-06:00"
}
}Response (201) — Azure:
{
"secret": {
"client_id": "44444444-4444-4444-4444-444444444444",
"client_secret": "********",
"tenant_id": "00000000-0000-0000-0000-000000000000",
"key_id": "55555555-5555-5555-5555-555555555555",
"leaseId": "b7e6f8a1-9c2d-4e3a-8b7a-2d6e4f1c9a2b",
"expiration": "2025-09-14T15:00:00-06:00"
}
}Get dynamic secret metadata
Retrieve metadata for a dynamic secret.
GET /dynamic/{name}/metadata
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the dynamic secret |
Response (200): Returns metadata object.
Replace dynamic secret tags
Replace all tags for a dynamic secret.
PUT /dynamic/{name}/metadata/tags
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the dynamic secret |
Request Body:
{
"env": "prod",
"owner": "db"
}Response (200): Returns the new set of tags.
Update dynamic secret tags
Add or remove tags for a dynamic secret using JSON Merge Patch (RFC 7396).
PATCH /dynamic/{name}/metadata/tags
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the dynamic secret |
Request Body:
{
"newTag": "value",
"removeTag": null
}Response: 204 No Content
Clear dynamic secret tags
Remove all tags from a dynamic secret.
DELETE /dynamic/{name}/metadata/tags
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the dynamic secret |
Response: 204 No Content
Leases
Leases track generated dynamic credentials and their expiration.
List leases
Retrieve leases for a dynamic secret.
GET /leases/{name}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| name | string | The name of the dynamic secret |
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| folder | string | The folder containing the dynamic secret |
Response (200):
{
"data": [
{
"id": "1846c4e3-7c6b-4bfa-8f9e-a55a4b678d54",
"dynamicSecretType": "aws",
"expiration": "2025-09-12T15:00:00-06:00",
"createdAt": "2025-09-12T14:00:00-06:00",
"createdBy": "3b940186-58ea-4d20-9133-3da572256d2b"
}
]
}Get lease by ID
Retrieve lease details by its unique identifier.
GET /leases/id/{id}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| id | uuid | The lease ID |
Response (200):
{
"dynamicSecretId": "b7e6f8a1-9c2d-4e3a-8b7a-2d6e4f1c9a2b",
"dynamicSecretType": "aws",
"dynamicSecretPath": "eks-role",
"dynamicSecretConfig": {
"credentialType": "assumed_role",
"roleArn": "arn:aws:iam::123456789012:role/MyRole"
},
"externalEntityId": "arn:aws:iam::123456789012:assumed-role/test-role-2/bt-demo",
"expiration": "2025-09-14T15:00:00-06:00",
"metadata": {
"id": "b7e6f8a1-9c2d-4e3a-8b7a-2d6e4f1c9a2b",
"createdAt": "2025-09-14T14:00:00-06:00",
"createdBy": "3b940186-58ea-4d20-9133-3da572256d2b"
}
}Revoke lease by ID
Immediately revoke an active dynamic secret's lease. The upstream credentials are destroyed at the provider and the lease record is removed.
DELETE /leases/id/{id}
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
| id | uuid | The lease ID |
Response: 204 No Content
Note: Only lease types whose credentials support active revocation are accepted. Non-revocable types (for example, AWS STS assumed-role credentials) return 400 Bad Request with error code lease_not_revocable. If the provider call to remove the credential fails, the response is 502 Bad Gateway with error code lease_revoke_failed.
Error responses
| Status Code | Description |
|---|---|
| 400 Bad Request | The request is invalid (e.g., missing required field, invalid path) |
| 401 Unauthorized | Access token is missing or invalid |
| 403 Forbidden | Access token is valid but lacks required permissions |
| 404 Not Found | The requested resource does not exist |
| 409 Conflict | Resource already exists or is in a conflicting state |
| 500 Internal Server Error | Server-side error |
| 501 Not Implemented | The requested functionality is not supported |
| 502 Bad Gateway | An upstream provider call failed (e.g., during lease revocation) |
Error Response Format
{
"message": "Error description",
"code": "error_code"
}Error codes: Authentication and authorization
| Code | HTTP | Condition |
|---|---|---|
unauthorized | 401 | Access token is missing, malformed, expired, or otherwise invalid. |
forbidden | 403 | Access token is valid but the caller lacks the permissions required for this operation. |
Error codes: Folders
| Code | HTTP | Condition |
|---|---|---|
folder_not_found | 404 | No folder exists at the specified path, or the folder has been permanently destroyed. |
folder_already_exists | 403 | An active folder already exists at the specified path. |
deleted_folder_exists | 409 | A soft-deleted folder exists at the specified path. Restore it or permanently destroy it before creating a new folder here. |
folder_deleted | 409 | An ancestor of the specified path is soft-deleted. The operation cannot proceed until the ancestor is restored or permanently destroyed. |
folder_has_content | 409 | Cannot delete a non-empty folder without the recursive flag. |
folder_already_active | 409 | Restore was requested on a folder that is not currently soft-deleted. |
folder_depth_exceeded | 400 | The supplied folder path contains more nested segments than the configured maximum. SDK callers building paths programmatically can branch on this to truncate or re-plan. |
folder_path_length_exceeded | 400 | The combined folder path + name character count exceeds the configured maximum. |
Error codes: Static secrets
| Code | HTTP | Condition |
|---|---|---|
secret_not_found | 404 | No secret exists at the specified path, or the secret has been permanently destroyed. |
secret_version_not_found | 404 | The specified version of the secret does not exist. |
secret_version_deleted | 404 | The specified version of the secret was deleted. |
secret_already_exists | 409 | An active static secret already exists at the specified path. |
deleted_secret_exists | 409 | A soft-deleted static secret exists at the specified path. Restore it or permanently destroy it before creating a new secret here. |
secret_already_active | 409 | Restore was requested on a static secret that is not currently soft-deleted. |
secret_query_invalid | 400 | Conflicting or invalid query parameters (e.g., versions=true combined with version=N). |
secret_too_large | 400 | The static secret's serialized payload exceeds the configured size limit. Distinct from payload_too_large (413), which applies to the transport-level HTTP body size; secret_too_large is the application's content-policy limit on the secret value itself. |
cas_mismatch | 409 | A check-and-set update specified a cas value that did not match the secret's current version. The caller is racing with another writer; re-read the current version and retry with the new cas value. |
Error codes: Dynamic secrets
| Code | HTTP | Condition |
|---|---|---|
dynamic_secret_not_found | 404 | No dynamic secret exists at the specified path, or it has been permanently destroyed. |
dynamic_secret_already_exists | 409 | An active dynamic secret already exists at the specified path. |
deleted_dynamic_secret_exists | 409 | A soft-deleted dynamic secret exists at the specified path. Restore it or permanently destroy it before creating a new secret here. |
dynamic_secret_already_active | 409 | Restore was requested on a dynamic secret that is not currently soft-deleted. |
dynamic_secret_in_use | 409 | Cannot permanently destroy a dynamic secret while active leases reference it. Revoke or wait out the leases first. |
dynamic_secret_config_invalid | 400 | The dynamic secret configuration is malformed or fails validation specific to its provider (AWS, Azure, etc.). |
aws_permission_denied | 400 | The AWS integration's credentials lack the IAM permissions required to generate this dynamic secret. The IAM role/user policy must be updated. |
azure_permission_denied | 400 | The Azure integration's service principal lacks the Microsoft Graph permissions required to generate this dynamic secret. The service principal's API permissions must be updated. |
Error Codes: Integrations
| Code | HTTP | Condition |
|---|---|---|
integration_not_found | 404 | No integration exists with the specified type and name. |
integration_already_exists | 409 | An integration with the specified type and name already exists. |
integration_in_use | 409 | Cannot delete an integration while dynamic secrets reference it. Delete or repoint the dependent dynamic secrets first. |
integration_config_invalid | 400 | The integration configuration is malformed (missing required field, invalid value, or unsupported field for the integration type). |
aws_integration_test_failed | 400 | The AWS integration's credentials could not be validated against AWS during create or update. Check the role ARN, external ID, and IAM trust policy. |
azure_integration_test_failed | 400 | The Azure integration's credentials could not be validated against Azure during create or update. Check the tenant ID, client ID, and client secret. |
Error Codes: Leases
| Code | HTTP | Condition |
|---|---|---|
lease_not_found | 404 | No lease exists with the specified ID. On GET /leases/id/{id} this is a defensive race-window code (authz typically returns 403 first; 404 surfaces only when a tuple exists but the lease row has since been destroyed by expiration cleanup or concurrent revoke). On DELETE /leases/id/{id} (revoke) it is the primary, intentional signal — unlike data-removal DELETEs in this API, revoke is non-idempotent because returning 204 on a missing lease ID would mislead clients into believing they had invalidated a credential they hadn't. |
lease_not_revocable | 400 | This lease type does not support active revocation. The credential will expire naturally at the lease's expiration time. |
lease_revoke_failed | 502 | Revocation was attempted but the upstream provider (e.g., AWS) returned an error. Retrying may succeed; otherwise the credential will expire naturally. |
lease_revoke_timeout | 504 | Revocation was attempted but the upstream provider (e.g., Azure Entra) did not reach a consistent state within the retry budget. Retrying may succeed; otherwise the credential will expire naturally. |
Error Codes: Request validation and infrastructure
| Code | HTTP | Condition |
|---|---|---|
request_validation_failed | 400 | The request body or query parameters failed schema validation (wrong type, missing required field, invalid enum value, etc.). |
tag_key_empty | 400 | One or more tag keys in the request body is the empty string. Tag keys are required and must be non-empty. |
tag_key_too_long | 400 | One or more tag keys exceeds the configured maximum length. |
request_invalid | 4xx | Generic 4xx fallback used when no more specific code applies. May fire with status 400 (malformed body or content type), 405 (wrong method), 409 (conflict surfaced by request validation), 415 (unsupported media type), etc. When this code fires, consult the HTTP status to disambiguate — the code alone doesn't identify the specific situation. New specific codes will be added as patterns emerge. |
route_not_found | 404 | The requested URL does not match any documented endpoint. Distinct from domain-specific not-found codes (folder_not_found, etc.) which mean "this URL is valid but the resource doesn't exist". |
payload_too_large | 413 | The request body exceeds the maximum allowed size. |
rate_limited | 429 | The caller has exceeded the rate limit for this endpoint. Retry after the duration in the Retry-After response header. |
not_implemented | 501 | The endpoint exists in the API contract but is not yet implemented in this release. |
internal_error | 500 | An unexpected error occurred on the server. Quote the X-Trace-Id response header in support requests. |
concurrent_modification | 409 | A folder the request was authorized against was deleted or destroyed by another request before this one ran, so proceeding would have reached folders the authorization check did not cover. Retry: the check re-runs against the current shape of the tree. |
Data types
Tags
Key-value pairs for organizing resources. Keys are case-insensitive.
- Maximum 50 tags per resource
- Maximum 256 characters per value
- Set a tag value to
nullto remove it
Resource names
Valid characters: a-zA-Z0-9-_@~*^%
Maximum length: 100 characters
Full paths
Valid characters: a-zA-Z0-9-_@~*^%/
Maximum length: 500 characters
Item types
| Type | Description |
|---|---|
| folder | A folder for organizing secrets |
| static | A static secret with versioned values |
| dynamic-aws | An AWS dynamic secret |
| dynamic-azure | An Azure dynamic secret |
Dynamic secret credential types
| Type | Description |
|---|---|
| assumed_role | AWS STS assumed role credentials |
| service_principal_password | Azure service principal password credentials for a target Microsoft Entra ID app |
Updated 37 minutes ago