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.

Design Note: All files uploaded to a shared bucket are automatically isolated at the physical bucket layer inside a path patterned as: 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.

POST /api/v1/upload

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:

  1. Step 1 (Initialize): Call POST /api/v1/uploads/prepare to generate a pre-signed PUT S3 URL.
  2. Step 2 (Direct Upload): Perform a PUT request directly to that pre-signed URL carrying the raw binary.
  3. 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.

GET /api/v1/containers

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.

POST /api/v1/upload

Upload Session Init (3-Step)

Initialize an upload session. Returns the pre-signed S3 URL for step 2 of the 3-step flow.

POST /api/v1/uploads/prepare

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.

POST /api/v1/uploads/:id/complete

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

GET /api/v1/objects/:id/download

Request signed-url with custom expiry

POST /api/v1/objects/:id/signed-url

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