Developer API Reference
Welcome to the EpesiCloud Vault API reference. Vault abstracts Cloudflare R2, AWS S3, and MinIO storage providers behind a single, tenant-partitioned object router. Applications can create containers, upload files, and download private objects with securely signed links.
tenants/{tenantId}/{containerSlug}/{uuid}/{filename}.
Authentication
To authorize API requests to the Vault Platform, generate a rate-limited API Key in the Settings page and supply it in the Authorization header or the custom x-api-key header.
Header Format
Authorization: Bearer epesi_vault_your_api_key_here
1-Request Multipart Upload (Primary)
The **most convenient and recommended** way to upload files. Send exactly **1 standard multipart/form-data request** containing one or more files. Vault handles the secure transmission directly to Cloudflare R2 / S3 on the backend, registers the file metadata in the Vault registry, and returns the direct access links in a single round-trip.
Form Parameters (Multipart/Form-Data)
| Field | Type | Required | Description |
|---|---|---|---|
| file / files | file binary (single or array) | Yes | One or more binary file payloads. Any form field name is accepted. |
| container | string | No | Slug of destination container. Defaults to default. (Alias containerSlug is also supported). |
| generateTemporaryUrl | boolean | No | Defaults to true. Generates and returns a pre-signed temporary S3 URL (temporaryUrl) directly in the response. |
| temporaryUrlExpiresIn | number | No | Defaults to 86400 (24 hours). Expiration lifetime of the generated temporary S3 URL in seconds. |
Response Example (JSON Array)
[
{
"objectId": "obj_3605f04f...",
"filename": "invoice.pdf",
"path": "tenants/demo_company/default/61cb5358/invoice.pdf",
"providerKey": "r2://my-bucket/tenants/demo_company/default/61cb5358/invoice.pdf",
"mimeType": "application/pdf",
"size": 14205,
"downloadUrl": "https://vault.epesicloud.com/api/v1/objects/obj_3605f04f.../download",
"temporaryUrl": "https://my-bucket.r2.cloudflarestorage.com/tenants/demo_company/default/61cb5358/invoice.pdf?X-Amz-Signature=..."
}
]
Option 2: 3-Step Client Upload Protocol
For client applications (like web browsers) uploading large files (e.g. >100MB), you can use the 3-step handshake protocol. This avoids piping massive file binaries through the Vault API server, sending them directly to the storage bucket network for maximum speed and efficiency:
- Step 1 (Initialize): Call
POST /api/v1/uploads/prepareto generate a pre-signed PUT S3 URL. - Step 2 (Direct Upload): Perform a
PUTrequest directly to that pre-signed URL carrying the raw binary. - Step 3 (Complete): Call
POST /api/v1/uploads/:id/complete. Vault runs a check on the bucket to confirm, then registers it.
Containers
Retrieve a list of containers configured for this tenant, which segment upload sizes and partition buckets.
cURL Example
curl -X GET "https://vault.epesicloud.com/api/v1/containers" \
-H "Authorization: Bearer epesi_vault_your_key"
Upload File (1-Request)
Standard endpoint for uploading files directly in 1 request. See 1-Request Upload for details.
Upload Session Init (3-Step)
Initialize an upload session. Returns the pre-signed S3 URL for step 2 of the 3-step flow.
Body Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| container | string | No | Slug of destination container. Defaults to default. (Alias containerSlug is also supported). |
| filename | string | Yes | Original file name (e.g. contract.pdf). |
| mimeType | string | Yes | Standard MIME type (e.g. application/pdf). |
| size | number | No | File size in bytes (checked against container ceiling). |
Response Example (JSON)
{
"id": "ups_9a12c85b",
"presignedUrl": "https://my-bucket.r2.cloudflarestorage.com/tenants/demo_company/default/4b2fa81c/contract.pdf?X-Amz-Signature=...",
"providerKey": "tenants/demo_company/default/4b2fa81c/contract.pdf"
}
Complete Handshake
Confirm the direct S3 PUT upload has finished. Vault runs verification and registers the object.
Body Parameters (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
| generateTemporaryUrl | boolean | No | Defaults to true. Generates and returns a pre-signed temporary S3 URL (temporaryUrl) directly in the response. |
| temporaryUrlExpiresIn | number | No | Defaults to 86400 (24 hours). Expiration lifetime of the generated temporary S3 URL in seconds. |
Response Example (JSON)
{
"ok": true,
"objectId": "obj_3605f04f...",
"filename": "invoice.pdf",
"path": "tenants/demo_company/default/61cb5358/invoice.pdf",
"providerKey": "r2://my-bucket/tenants/demo_company/default/61cb5358/invoice.pdf",
"mimeType": "application/pdf",
"size": 14205,
"downloadUrl": "https://vault.epesicloud.com/api/v1/objects/obj_3605f04f.../download",
"temporaryUrl": "https://my-bucket.r2.cloudflarestorage.com/tenants/demo_company/default/61cb5358/invoice.pdf?X-Amz-Signature=..."
}
Objects & Links
Manage files and request temporary download URLs for private containers.
Request pre-signed download link
Request signed-url with custom expiry
Provide {"expiresIn": 7200} (seconds) in request body. Defaults to 3600 (1 hour).
Node.js: 1-Request Upload (Recommended)
Demonstrates uploading any file directly to the singular endpoint in exactly one request:
const API_KEY = "epesi_vault_your_api_key";
const VAULT_URL = "https://vault.epesicloud.com";
async function uploadFile(fileBuffer, filename, mimeType) {
const fileBlob = new Blob([fileBuffer], { type: mimeType });
const formData = new FormData();
formData.append("file", fileBlob, filename);
formData.append("container", "default"); // optional (or containerSlug)
const response = await fetch(`${VAULT_URL}/api/v1/upload`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`
},
body: formData
});
const result = await response.json();
console.log("Uploaded successfully! Download URL:", result.downloadUrl);
return result.objectId;
}
Node.js: 3-Step Upload (Option 2)
Demonstrates the multi-step handshake protocol directly to S3:
const API_KEY = "epesi_vault_your_api_key";
const VAULT_URL = "https://vault.epesicloud.com";
async function uploadFileThreeStep(fileBuffer, filename, mimeType) {
const size = fileBuffer.length;
console.log("1. Initializing upload...");
const initRes = await fetch(`${VAULT_URL}/api/v1/uploads/prepare`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ container: "default", filename, mimeType, size })
});
const { id: sessionId, presignedUrl } = await initRes.json();
console.log("2. Direct PUT uploading binary to Cloudflare R2 / S3...");
await fetch(presignedUrl, {
method: "PUT",
headers: { "Content-Type": mimeType },
body: fileBuffer
});
console.log("3. Confirming upload with server...");
const confirmRes = await fetch(`${VAULT_URL}/api/v1/uploads/${sessionId}/complete`, {
method: "POST",
headers: { "Authorization": `Bearer ${API_KEY}` }
});
const result = await confirmRes.json();
console.log("Success! Object ID:", result.objectId);
}