Back to Vault API endpoint: /api/v1/secrets

PIPs Vault API Documentation (v1)

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

Create Secret

Request Body

FieldTypeRequiredRules
payloadstringYes4-5000 chars (normalized)
passwordstringNoIf provided, 1-256 chars
emailstringNoIf provided, must be a valid email address; sends the code and secure link via Mailgun SMTP
expirystringYesOne of 1h, 4h, 1d, 1w, 1m
payloadEncodingstringNoplain (default) or ciphertext
clientEncryptionobjectRequired when payloadEncoding=ciphertextOptional metadata like algorithm, encoding, keyId

Example Request

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"
    }
  }'

Success Response (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"
  }
}

Read Secret

Example Request

curl -X GET "https://vault.example.com/api/v1/secrets/AbC123..." \
  -H "X-Secret-Password: StrongPassphrase123!"

Success Response (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"
}

Postman Examples

Create Secret request

{
  "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"
  }
}

Read Secret request

Recommended Postman variables: baseUrl, code.

Error Handling

All API errors return JSON with:

{
  "error": "validation_failed",
  "message": "Expiry must be one of: 1h, 4h, 1d, 1w, 1m."
}
StatusErrorWhen it happens
400invalid_content_type, invalid_jsonWrong content type or malformed JSON.
403invalid_passwordProvided retrieve password does not verify.
404not_foundSecret is missing, expired, or already consumed.
405method_not_allowedMethod does not match endpoint contract.
409unsupported_secret_typeRead endpoint only returns text secrets.
422payload_too_large, validation_failedBody too large or field validation failed.
429rate_limitedMore than 30 create requests per IP per 60 seconds (includes Retry-After header).
500internal_error, email_delivery_failedUnexpected secure-storage failures or SMTP email delivery failures.

Behavior and Limits

Client SDK Examples

JavaScript (fetch)

            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();

Python (requests)

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())

PHP (cURL)

$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