Quickstart
Read and write your first secret in five minutes. Assumes you already have a ScaiVault instance (managed or self-hosted) and a user account.
1. Get an API token
ScaiVault authenticates with JWTs issued by ScaiKey. The simplest way to get a token for this quickstart is a personal access token.
From the admin UI: Access → Personal Tokens → Create. Scope it to secrets:read and secrets:write. Copy the token — it starts with skt_ and is shown exactly once.
For production you'll want either a ScaiKey-issued JWT (for humans) or a client-credentials token (for services). See Authentication for the full picture.
Export it:
| export SCAIVAULT_TOKEN="skt_..."
|
2. Check you can reach the service
| curl -H "Authorization: Bearer $SCAIVAULT_TOKEN" \
https://scaivault.scailabs.ai/v1/auth/whoami
|
You should get back your identity:
| {
"identity_id": "user:alice@acme.example",
"identity_type": "user",
"tenant_id": "tnt_acme_prod",
"partner_id": "ptn_acme",
"scopes": ["secrets:read", "secrets:write"]
}
|
If you get 401 authentication_required, the token is wrong or expired. If you get 403 access_denied, the token is valid but lacks the scope you're asking for.
3. Write your first secret
Store a Salesforce OAuth credential at environments/production/salesforce/api-credentials.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | curl -X PUT https://scaivault.scailabs.ai/v1/secrets/environments/production/salesforce/api-credentials \
-H "Authorization: Bearer $SCAIVAULT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"client_id": "3MVG9...",
"client_secret": "REDACTED"
},
"secret_type": "json",
"metadata": {
"description": "Salesforce OAuth credentials",
"tags": ["salesforce", "production"]
}
}'
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | import os
import httpx
resp = httpx.put(
"https://scaivault.scailabs.ai/v1/secrets/environments/production/salesforce/api-credentials",
headers={"Authorization": f"Bearer {os.environ['SCAIVAULT_TOKEN']}"},
json={
"data": {
"client_id": "3MVG9...",
"client_secret": "REDACTED",
},
"secret_type": "json",
"metadata": {
"description": "Salesforce OAuth credentials",
"tags": ["salesforce", "production"],
},
},
)
resp.raise_for_status()
print(resp.json())
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | const resp = await fetch(
"https://scaivault.scailabs.ai/v1/secrets/environments/production/salesforce/api-credentials",
{
method: "PUT",
headers: {
"Authorization": `Bearer ${process.env.SCAIVAULT_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
data: {
client_id: "3MVG9...",
client_secret: "REDACTED",
},
secret_type: "json",
metadata: {
description: "Salesforce OAuth credentials",
tags: ["salesforce", "production"],
},
}),
},
);
console.log(await resp.json());
|
Response:
| {
"path": "environments/production/salesforce/api-credentials",
"secret_type": "json",
"version": 1,
"created": true,
"created_at": "2026-04-23T14:00:00Z"
}
|
The response doesn't include the plaintext data you just wrote. Writes return metadata only.
4. Read it back
| curl -H "Authorization: Bearer $SCAIVAULT_TOKEN" \
https://scaivault.scailabs.ai/v1/secrets/environments/production/salesforce/api-credentials
|
| import os
import httpx
resp = httpx.get(
"https://scaivault.scailabs.ai/v1/secrets/environments/production/salesforce/api-credentials",
headers={"Authorization": f"Bearer {os.environ['SCAIVAULT_TOKEN']}"},
)
secret = resp.json()
print(secret["data"]["client_id"])
|
| const resp = await fetch(
"https://scaivault.scailabs.ai/v1/secrets/environments/production/salesforce/api-credentials",
{ headers: { "Authorization": `Bearer ${process.env.SCAIVAULT_TOKEN}` } },
);
const secret = await resp.json();
console.log(secret.data.client_id);
|
Response:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | {
"path": "environments/production/salesforce/api-credentials",
"secret_type": "json",
"version": 1,
"data": {
"client_id": "3MVG9...",
"client_secret": "REDACTED"
},
"metadata": {
"description": "Salesforce OAuth credentials",
"tags": ["salesforce", "production"]
},
"created_at": "2026-04-23T14:00:00Z",
"updated_at": "2026-04-23T14:00:00Z"
}
|
That's the full round-trip — your application can call ScaiVault any time it needs the credential, and always get the current value.
5. Update it
Writing again at the same path creates version 2. The previous version stays readable.
| curl -X PUT https://scaivault.scailabs.ai/v1/secrets/environments/production/salesforce/api-credentials \
-H "Authorization: Bearer $SCAIVAULT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"client_id": "3MVG9...",
"client_secret": "NEW_REDACTED"
},
"secret_type": "json"
}'
|
Response:
| {
"path": "environments/production/salesforce/api-credentials",
"version": 2,
"created": false,
"previous_version": 1,
"updated_at": "2026-04-23T14:05:00Z"
}
|
Read version 1 explicitly with ?version=1:
| curl -H "Authorization: Bearer $SCAIVAULT_TOKEN" \
"https://scaivault.scailabs.ai/v1/secrets/environments/production/salesforce/api-credentials?version=1"
|
6. List what you've written
| curl -H "Authorization: Bearer $SCAIVAULT_TOKEN" \
"https://scaivault.scailabs.ai/v1/secrets?prefix=environments/production/"
|
1
2
3
4
5
6
7
8
9
10
11
12
13 | {
"secrets": [
{
"path": "environments/production/salesforce/api-credentials",
"secret_type": "json",
"version": 2,
"updated_at": "2026-04-23T14:05:00Z",
"tags": ["salesforce", "production"]
}
],
"cursor": null,
"has_more": false
}
|
That's it. You just wrote, versioned, and read a secret from ScaiVault.
What's next