← Back to Home

FileVault Integration Guide

Comprehensive API Integration Documentation for Multi-Platform Support

Version 1.0 - Professional Edition

Document Information

Author: Zaid Yasyaf

Email: zaid.ug@gmail.com

Organization: Denning IT Sdn Bhd

Base URL: https://filevault.denning.online

Last Updated: November 2025

📚 Table of Contents

🚀 Quick Start Guide

Get started with FileVault integration in just 3 simple steps:

  1. Obtain Service Token: Request a service token from your system administrator (fv_xxxxxx...)
  2. Select Server Code: Choose your application's server code (e.g., MYAPP, API001, TS0004)
  3. Make API Requests: Start making HTTP requests to the FileVault API endpoints

That's all you need to begin! Continue reading for detailed implementation guides.

🔐 Authentication

Token Format: All FileVault tokens follow a strict format for security and validation.

Token Structure

Authentication Methods

FileVault supports three flexible authentication methods. Choose the one that best fits your implementation:

Method 1: Bearer Token (Recommended)

HTTP Header
Authorization: Bearer fv_your_token_here

Method 2: Custom Header

HTTP Header
X-API-Token: fv_your_token_here

Method 3: Query Parameter

URL Parameter
https://filevault.denning.online/api/v1/MYAPP/storage/list?token=fv_your_token_here

📁 File Path Convention

⚠️ Important: Never include your server code in the file path. The server code should only appear in the API endpoint URL.

Path Pattern Rules

FileVault supports two distinct path patterns depending on the module type:

Rule 1: Module-Based Paths (Most Modules)

Pattern: {module}/{recordId}/{sub_path}/{filename}
Applies to: staff, matters, clients, contacts, and other standard modules
Key Point: These modules require a recordId before you can perform file operations.

Examples (Module-Based):

Rule 2: Documents Module (Special Case)

Pattern: documents/{sub_path}/{filename}
Applies to: documents module only
Key Point: The documents module does NOT require a recordId - files go directly under documents/.

Examples (Documents Module):

Complete Path Examples

Status Path Type Example Notes
✅ Correct Module-based (with recordId) matters/12345/contract.pdf Standard module path
✅ Correct Documents (no recordId) documents/company/policy.pdf Documents module path
❌ Incorrect Including server code MYAPP/matters/12345/contract.pdf Never include server code
❌ Incorrect Documents with recordId documents/123/file.pdf Documents doesn't use recordId
❌ Incorrect Leading slash /matters/12345/file.pdf No leading slash
💡 How It Works: The full storage path FileVault creates is {serverCode}/{your_path}

Example:
• URL: https://filevault.denning.online/api/v1/MYAPP/storage/upload
• Path in request: matters/12345/contract.pdf
• Actual storage path: MYAPP/matters/12345/contract.pdf

💼 Core Operations

📤 Upload Files

Upload files to FileVault using multipart form data. All examples use the endpoint:

POST /api/v1/{serverCode}/storage/upload

C# / .NET Implementation

C# / .NET 4+
using System.Net.Http;
using System.IO;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer fv_your_token_here");

var content = new MultipartFormDataContent();
content.Add(new StreamContent(File.OpenRead("document.pdf")), "file", "document.pdf");
content.Add(new StringContent("matters/12345/document.pdf"), "path");
content.Add(new StringContent("user@example.com"), "uploaded_by");

var response = await client.PostAsync(
    "https://filevault.denning.online/api/v1/MYAPP/storage/upload",
    content
);

string result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);

JavaScript/Node.js Implementation

JavaScript/Node.js
const FormData = require('form-data');
const fs = require('fs');

const form = new FormData();
form.append('file', fs.createReadStream('document.pdf'));
form.append('path', 'matters/12345/document.pdf');
form.append('uploaded_by', 'user@example.com');

const response = await fetch('https://filevault.denning.online/api/v1/MYAPP/storage/upload', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer fv_your_token_here',
    ...form.getHeaders()
  },
  body: form
});

const result = await response.json();
console.log(result);

Python Implementation

Python
import requests

files = {'file': open('document.pdf', 'rb')}
data = {
    'path': 'matters/12345/document.pdf',
    'uploaded_by': 'user@example.com'
}
headers = {'Authorization': 'Bearer fv_your_token_here'}

response = requests.post(
    'https://filevault.denning.online/api/v1/MYAPP/storage/upload',
    headers=headers,
    files=files,
    data=data
)

print(response.json())

PHP Implementation

PHP
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://filevault.denning.online/api/v1/MYAPP/storage/upload');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer fv_your_token_here']);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'file' => new CURLFile('document.pdf'),
    'path' => 'matters/12345/document.pdf',
    'uploaded_by' => 'user@example.com'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo $response;

Go Implementation

Go
package main

import (
    "bytes"
    "io"
    "mime/multipart"
    "net/http"
    "os"
)

func main() {
    file, _ := os.Open("document.pdf")
    defer file.Close()

    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)
    part, _ := writer.CreateFormFile("file", "document.pdf")
    io.Copy(part, file)
    writer.WriteField("path", "matters/12345/document.pdf")
    writer.WriteField("uploaded_by", "user@example.com")
    writer.Close()

    req, _ := http.NewRequest("POST",
        "https://filevault.denning.online/api/v1/MYAPP/storage/upload", body)
    req.Header.Set("Content-Type", writer.FormDataContentType())
    req.Header.Set("Authorization", "Bearer fv_your_token_here")

    client := &http.Client{}
    resp, _ := client.Do(req)
    defer resp.Body.Close()
}

cURL (Command Line)

Bash/cURL
curl -X POST "https://filevault.denning.online/api/v1/MYAPP/storage/upload" \
  -H "Authorization: Bearer fv_your_token_here" \
  -F "file=@document.pdf" \
  -F "path=matters/12345/document.pdf" \
  -F "uploaded_by=user@example.com"

📥 Download Files

Retrieve files from FileVault using a simple GET request:

GET /api/v1/{serverCode}/storage/download

C# / .NET Implementation

C# / .NET 4+
using System.Net.Http;
using System.IO;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer fv_your_token_here");

var response = await client.GetAsync(
    "https://filevault.denning.online/api/v1/MYAPP/storage/download?path=matters/12345/document.pdf"
);

byte[] fileBytes = await response.Content.ReadAsByteArrayAsync();
File.WriteAllBytes("downloaded.pdf", fileBytes);

JavaScript Implementation

JavaScript
const response = await fetch(
  'https://filevault.denning.online/api/v1/MYAPP/storage/download?path=matters/12345/document.pdf',
  {
    headers: { 'Authorization': 'Bearer fv_your_token_here' }
  }
);

const blob = await response.blob();
// Save blob to file or process as needed

Python Implementation

Python
import requests

response = requests.get(
    'https://filevault.denning.online/api/v1/MYAPP/storage/download',
    headers={'Authorization': 'Bearer fv_your_token_here'},
    params={'path': 'matters/12345/document.pdf'}
)

with open('downloaded.pdf', 'wb') as f:
    f.write(response.content)

PHP Implementation

PHP
$ch = curl_init();
$url = 'https://filevault.denning.online/api/v1/MYAPP/storage/download?path=matters/12345/document.pdf';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer fv_your_token_here']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$file = curl_exec($ch);
file_put_contents('downloaded.pdf', $file);

📋 List Files

Retrieve a listing of files and directories:

GET /api/v1/{serverCode}/storage/list

Implementation Examples

C# / .NET 4+
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer fv_your_token_here");

var response = await client.GetAsync(
    "https://filevault.denning.online/api/v1/MYAPP/storage/list?directory=matters/12345"
);

string result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
JavaScript
const response = await fetch(
  'https://filevault.denning.online/api/v1/MYAPP/storage/list?directory=matters/12345',
  {
    headers: { 'Authorization': 'Bearer fv_your_token_here' }
  }
);

const files = await response.json();
console.log(files);
Python
response = requests.get(
    'https://filevault.denning.online/api/v1/MYAPP/storage/list',
    headers={'Authorization': 'Bearer fv_your_token_here'},
    params={'directory': 'matters/12345'}
)

print(response.json())

🗑️ Delete Files

Remove files from FileVault:

DELETE /api/v1/{serverCode}/storage

Implementation Examples

JavaScript
const response = await fetch(
  'https://filevault.denning.online/api/v1/MYAPP/storage',
  {
    method: 'DELETE',
    headers: {
      'Authorization': 'Bearer fv_your_token_here',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ path: 'matters/12345/document.pdf' })
  }
);
Python
response = requests.delete(
    'https://filevault.denning.online/api/v1/MYAPP/storage',
    headers={'Authorization': 'Bearer fv_your_token_here'},
    json={'path': 'matters/12345/document.pdf'}
)

🔧 Advanced Operations

File Management Operations

Copy Files

POST /api/v1/{serverCode}/storage/copy
Example 1: Within Documents Module (No recordId)
{
  "source_path": "documents/templates/original.pdf",
  "dest_path": "documents/company/copy.pdf"
}
Example 2: Within Module-Based Path (With recordId)
{
  "source_path": "matters/12345/contract.pdf",
  "dest_path": "matters/12345/backup/contract.pdf"
}
Example 3: From Module-Based to Documents
{
  "source_path": "matters/12345/template.pdf",
  "dest_path": "documents/templates/matter-template.pdf"
}

Move/Rename Files

POST /api/v1/{serverCode}/storage/move
Example 1: Move Within Documents Module
{
  "source_path": "documents/drafts/file.pdf",
  "dest_path": "documents/final/file.pdf"
}
Example 2: Move Within Module-Based Path
{
  "source_path": "clients/987/old.pdf",
  "dest_path": "clients/987/archive/old.pdf"
}

Create Directory

POST /api/v1/{serverCode}/storage/mkdir
Example 1: Create Directory in Documents Module
{
  "path": "documents/new-category"
}
Example 2: Create Directory in Module-Based Path
{
  "path": "matters/12345/evidence"
}

Bulk Operations

📦 Bulk Operations: Perform actions on multiple files simultaneously for improved efficiency.

Bulk Copy (Path-Based)

POST /api/v1/{serverCode}/storage/bulk-copy
JavaScript
const response = await fetch(
  'https://filevault.denning.online/api/v1/MYAPP/storage/bulk-copy',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer fv_your_token_here',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      paths: [
        'temp/file1.pdf',
        'temp/file2.pdf'
      ],
      target_path: 'documents/archive'
    })
  }
);

Bulk Move (Path-Based)

POST /api/v1/{serverCode}/storage/bulk-move
Python
data = {
    'paths': ['temp/file1.pdf', 'temp/file2.pdf'],
    'target_path': 'documents/final'
}

response = requests.post(
    'https://filevault.denning.online/api/v1/MYAPP/storage/bulk-move',
    headers={'Authorization': 'Bearer fv_your_token_here'},
    json=data
)

Bulk Delete (Path-Based)

POST /api/v1/{serverCode}/storage/bulk-delete
cURL
curl -X POST "https://filevault.denning.online/api/v1/MYAPP/storage/bulk-delete" \
  -H "Authorization: Bearer fv_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "paths": [
      "temp/old_file1.pdf",
      "temp/old_file2.pdf",
      "drafts/obsolete.doc"
    ]
  }'

ID-Based Bulk Operations

Note: ID-based bulk operations require file IDs obtained from listing operations. Path-based operations are recommended for most use cases.
Operation Endpoint Required Parameters
Bulk Copy (ID) /files/bulk/copy file_ids[], to_directory_id
Bulk Move (ID) /files/bulk/move file_ids[], to_directory_id
Bulk Delete (ID) /files/bulk/delete file_ids[]

Compression & Extraction

Compress Files

POST /api/v1/{serverCode}/storage/compress
Request Body
{
  "paths": ["file1.pdf", "file2.doc", "file3.xlsx"],
  "archive_name": "documents.zip",
  "dest_path": "archives"
}

Extract Archive

POST /api/v1/{serverCode}/storage/extract
Request Body
{
  "archive_path": "archives/documents.zip",
  "dest_path": "extracted"
}

Share Files

POST /api/v1/{serverCode}/storage/share
Request Body
{
  "path": "documents/report.pdf",
  "expires_at": "2025-12-31T23:59:59Z",
  "password": "optional_password",
  "download_limit": 5
}

📖 Complete API Reference

Base URL: https://filevault.denning.online/api/v1/{serverCode}
Operation Method Endpoint Parameters
Upload POST /storage/upload multipart: file, path, uploaded_by
Download GET /storage/download query: path
List GET /storage/list query: directory
Exists GET /storage/exists query: path
Delete DELETE /storage json: {path}
Copy POST /storage/copy json: {source_path, dest_path}
Move POST /storage/move json: {source_path, dest_path}
Rename POST /storage/rename json: {path, new_name}
Make Directory POST /storage/mkdir json: {path}
Remove Directory DELETE /storage/rmdir json: {path}
Compress POST /storage/compress json: {paths[], archive_name, dest_path}
Extract POST /storage/extract json: {archive_path, dest_path}
Share POST /storage/share json: {path, expires_at, password, download_limit}
Bulk Copy POST /storage/bulk-copy json: {paths[], target_path}
Bulk Move POST /storage/bulk-move json: {paths[], target_path}
Bulk Delete POST /storage/bulk-delete json: {paths[]}
💡 Recommendation: Path-based bulk operations (/storage/bulk-*) are recommended over ID-based operations for better usability and consistency.

👨‍💼 Administration

Token Management for Administrators

⚠️ Administrative Access Required: The following commands require server access and administrative privileges.

Generate New Service Token

Command Line Interface
php artisan filevault:generate-token "My Application" --description="Production service"

This command will:

Rotate Compromised Token

Command Line Interface
# Regenerate token - will prompt for confirmation before revoking old token
php artisan filevault:generate-token "My Application"
⚠️ Critical Note: When a token is revoked, it stops working immediately. Ensure you update your service configuration with the new token before revoking the old one to avoid service interruption.

Security Best Practices

🔍 Troubleshooting

Common Issues and Solutions

🔴 401 Unauthorized

Possible Causes: Solution:

🟡 400 Bad Request

Possible Causes: Solution:

🔴 404 Not Found

Possible Causes: Solution:

🟡 413 Payload Too Large

Possible Causes: Solution:

Performance Optimization Tips