This API supports server-to-server secret creation and retrieval with one-time access semantics and optional password verification.
Base URL: your vault domain (for example https://vault.example.com)
Authentication: none
POST/api/v1/secretsapplication/json| Field | Type | Required | Rules |
|---|---|---|---|
payload | string | Yes | 4-5000 chars (normalized) |
password | string | No | If provided, 1-256 chars |
email | string | No | If provided, must be a valid email address; sends the code and secure link via Mailgun SMTP |
expiry | string | Yes | One of 1h, 4h, 1d, 1w, 1m |
payloadEncoding | string | No | plain (default) or ciphertext |
clientEncryption | object | Required when payloadEncoding=ciphertext | Optional metadata like algorithm, encoding, keyId |
curl -X POST "https://vault.example.com/api/v1/secrets" \
-H "Content-Type: application/json" \
-d '{
"payload": "Z2NtOmNhM0...base64-ciphertext",
"email": "recipient@example.com",
"expiry": "1h",
"payloadEncoding": "ciphertext",
"clientEncryption": {
"algorithm": "AES-256-GCM",
"encoding": "base64",
"keyId": "kms-key-01"
}
}'
201){
"secureLink": "https://vault.example.com/?code=AbC123...",
"code": "AbC123...",
"expiresAt": "2026-09-10T00:00:00+00:00",
"expiresInSeconds": 3600,
"payloadEncoding": "ciphertext",
"clientEncryption": {
"algorithm": "AES-256-GCM",
"encoding": "base64",
"keyId": "kms-key-01"
}
}
GET/api/v1/secrets/{code}X-Secret-Password (required when secret has a password hash)curl -X GET "https://vault.example.com/api/v1/secrets/AbC123..." \ -H "X-Secret-Password: StrongPassphrase123!"
200){
"code": "AbC123...",
"payload": "Z2NtOmNhM0...base64-ciphertext",
"payloadEncoding": "ciphertext",
"clientEncryption": {
"algorithm": "AES-256-GCM",
"encoding": "base64",
"keyId": "kms-key-01"
},
"expiresAt": "2026-09-10T00:00:00+00:00",
"retrievedAt": "2026-09-09T23:30:00+00:00"
}
POST{{baseUrl}}/api/v1/secretsContent-Type: application/json{
"payload": "Z2NtOmNhM0...base64-ciphertext",
"password": "StrongPassphrase123!",
"email": "recipient@example.com",
"expiry": "1h",
"payloadEncoding": "ciphertext",
"clientEncryption": {
"algorithm": "AES-256-GCM",
"encoding": "base64",
"keyId": "kms-key-01"
}
}
GET{{baseUrl}}/api/v1/secrets/{{code}}X-Secret-Password: StrongPassphrase123! (only when the secret was created with a password)Recommended Postman variables: baseUrl, code.
All API errors return JSON with:
{
"error": "validation_failed",
"message": "Expiry must be one of: 1h, 4h, 1d, 1w, 1m."
}
| Status | Error | When it happens |
|---|---|---|
400 | invalid_content_type, invalid_json | Wrong content type or malformed JSON. |
403 | invalid_password | Provided retrieve password does not verify. |
404 | not_found | Secret is missing, expired, or already consumed. |
405 | method_not_allowed | Method does not match endpoint contract. |
409 | unsupported_secret_type | Read endpoint only returns text secrets. |
422 | payload_too_large, validation_failed | Body too large or field validation failed. |
429 | rate_limited | More than 30 create requests per IP per 60 seconds (includes Retry-After header). |
500 | internal_error, email_delivery_failed | Unexpected secure-storage failures or SMTP email delivery failures. |
?code=... is one-time by default and removes the secret.GET /api/v1/secrets/{code} is also one-time by default.payloadEncoding=ciphertext, server stores payload as provided and treats it as client-encrypted content.email is supplied on create, the server sends a formatted message with the code and secure link using Mailgun SMTP environment configuration. const createRes = await fetch("https://vault.example.com/api/v1/secrets", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
payload: "encryptedBlob...",
password: "StrongPassphrase123!",
expiry: "1h",
payloadEncoding: "ciphertext",
clientEncryption: { algorithm: "AES-256-GCM", encoding: "base64" }
})
});
const created = await createRes.json();
const readRes = await fetch(`https://vault.example.com/api/v1/secrets/${created.code}`, {
headers: {
"X-Secret-Password": "StrongPassphrase123!"
}
});
const secret = await readRes.json();
import requests
headers = {"Content-Type": "application/json"}
create = requests.post(
"https://vault.example.com/api/v1/secrets",
headers=headers,
json={
"payload": "encryptedBlob...",
"expiry": "1h",
"payloadEncoding": "ciphertext",
"clientEncryption": {"algorithm": "AES-256-GCM", "encoding": "base64"},
},
)
code = create.json()["code"]
read = requests.get(
f"https://vault.example.com/api/v1/secrets/{code}",
headers={**headers, "X-Secret-Password": "StrongPassphrase123!"},
)
print(read.json())
$createHeaders = [
"Content-Type: application/json",
];
$createPayload = json_encode([
"payload" => "encryptedBlob...",
"password" => "StrongPassphrase123!",
"expiry" => "1h",
"payloadEncoding" => "ciphertext",
"clientEncryption" => ["algorithm" => "AES-256-GCM", "encoding" => "base64"],
]);
// POST create request, then GET /api/v1/secrets/{code} with:
// X-Secret-Password