Synced with current routes

Complete API Reference

Global

  • GET /api/health — Service health check
  • POST /api/v1/servers/register — Register new server (master token auth)

Public File Access (no auth)

  • GET /api/v1/public/{token} — Get share metadata
  • POST /api/v1/public/{token}/verify — Verify share password: { password }
  • GET /api/v1/public/{token}/download — Download shared file

Module Management (Global, DCC)

  • GET /v1/modules — List all modules
  • GET /v1/modules/grouped — Modules grouped by menu
  • GET /v1/modules/storage-paths — List storage path names
  • POST /v1/modules — Create module: { key, display_name, storage_path, ... }
  • GET /v1/modules/{key} — Get module
  • PUT /v1/modules/{key} — Update module
  • DELETE /v1/modules/{key} — Delete module
  • POST /v1/modules/{key}/sync — Queue sync to all servers
  • POST /v1/modules/{key}/sync-now — Sync immediately
  • POST /v1/modules/sync-all — Queue sync all modules
  • POST /v1/modules/sync-all-now — Sync all immediately
  • POST /v1/modules/clear-cache — Clear module cache

Server Management

  • GET /v1/{server_code}/ — Server info (includes legacy_mode, is_migrating)
  • PUT /v1/{server_code}/ — Update server: { server_name?, status?, storage_quota_mb?, api_rate_limit? }
  • GET /v1/{server_code}/stats — Storage stats (files_count, directories_count)
  • PUT /v1/{server_code}/storage-config — Set storage config (legacy): { storage_provider, storage_config }

Storage Providers (per-provider config)

  • GET /v1/{server_code}/storage/configs — List all configured providers
  • POST /v1/{server_code}/storage/configs/test — Test draft config: { provider, config: { host, port, ... } }
  • POST /v1/{server_code}/storage/configs — Save config: { provider, config, name?, description?, activate? }
  • PUT /v1/{server_code}/storage/configs/{provider} — Update config: { config, name?, activate? }
  • DELETE /v1/{server_code}/storage/configs/{provider} — Delete config (cannot delete active)
  • POST /v1/{server_code}/storage/configs/{provider}/test — Retest saved config
  • POST /v1/{server_code}/storage/configs/{provider}/activate — Activate provider (requires connection_test_passed)

Path-Based Storage (Recommended)

  • POST /v1/{sc}/storage/upload — Multipart: file (required), path (required), metadata? (JSON string), overwrite? (bool, default true)
  • GET /v1/{sc}/storage/download?path=... — Stream file download
  • GET /v1/{sc}/storage/lookup?path=... — File metadata (id, name, mime_type, size, module, record_id)
  • GET /v1/{sc}/storage/list?directory=...&recursive=...&per_page=... — List files/dirs (note: param is "directory" not "path")
  • GET /v1/{sc}/storage/exists?path=...&type=file|directory — Check if file/dir exists
  • DELETE /v1/{sc}/storage?path=... — Delete file
  • POST /v1/{sc}/storage/copy — { source_path, dest_path }
  • POST /v1/{sc}/storage/move — { source_path, dest_path }
  • POST /v1/{sc}/storage/rename — { path, new_name } (new_name is filename only, not full path)
  • POST /v1/{sc}/storage/mkdir — { path }
  • DELETE /v1/{sc}/storage/rmdir — { path } (deletes dir + all files inside)
  • POST /v1/{sc}/storage/compress — { paths: [...], archive_name?, dest_path? }
  • POST /v1/{sc}/storage/extract — { path (zip file), dest_path? }
  • POST /v1/{sc}/storage/share — { path, expires_at?, password? (min 4), download_limit? }
  • POST /v1/{sc}/storage/bulk-copy — { paths: [...], target_path (directory) }
  • POST /v1/{sc}/storage/bulk-move — { paths: [...], target_path (directory) }
  • POST /v1/{sc}/storage/bulk-delete — { paths: [...] }

Storage Migration

  • GET /v1/{sc}/storage/migration/status — Check if migration in progress
  • GET /v1/{sc}/storage/migration/jobs — List last 50 migrations
  • POST /v1/{sc}/storage/migration/start — { source_provider, destination_provider, delete_source_files?, overwrite_existing?, preserve_directory_structure?, file_pattern?, activate_destination? }
  • POST /v1/{sc}/storage/migration/{id}/cancel — Cancel running migration
  • POST /v1/{sc}/storage/migration/{id}/retry — Retry failed files only

Legacy Import & Sync

  • POST /v1/{sc}/storage/import — Start import: { provider: "ftp"|"sftp" }
  • GET /v1/{sc}/storage/import/status — Latest import/sync status and progress
  • GET /v1/{sc}/storage/import/history — List past 20 imports/syncs
  • POST /v1/{sc}/storage/import/sync — Re-sync: { provider: "ftp"|"sftp" } (requires prior completed import)
  • POST /v1/{sc}/storage/import/retry — Retry timed-out directories from last import (no body needed)
  • POST /v1/{sc}/storage/scan-directory — Sync single directory: { path } (legacy_mode only, synchronous)

Server Module Config (per-tenant overrides)

  • GET /v1/{sc}/modules — List server module configs
  • GET /v1/{sc}/modules/{key} — Get module config
  • POST /v1/{sc}/modules — Create module config
  • DELETE /v1/{sc}/modules/{key} — Delete module config
  • POST /v1/{sc}/modules/import — Import module configs
  • POST /v1/{sc}/modules/backup — Backup configs
  • POST /v1/{sc}/modules/restore — Restore from backup
  • POST /v1/{sc}/modules/reset — Reset to defaults
  • GET /v1/{sc}/modules/export — Export configs
  • GET /v1/{sc}/modules/health — Module health check
  • GET /v1/{sc}/modules/backups — List backups

Shares Management

  • GET /v1/{sc}/shares — List all shares for server
  • GET /v1/{sc}/shares/{shareId} — Get share details
  • PUT /v1/{sc}/shares/{shareId} — Update share
  • DELETE /v1/{sc}/shares/{shareId} — Delete share
  • POST /v1/{sc}/shares/{shareId}/activate — Activate share
  • POST /v1/{sc}/shares/{shareId}/deactivate — Deactivate share
  • GET /v1/{sc}/files/{fileId}/shares — List shares for a file
  • POST /v1/{sc}/files/{fileId}/shares — Create share for a file

File Permissions

  • GET /v1/{sc}/files/{fileId}/permissions — List permissions
  • POST /v1/{sc}/files/{fileId}/permissions — Grant permission
  • DELETE /v1/{sc}/files/{fileId}/permissions — Revoke permission
  • GET /v1/{sc}/files/{fileId}/permissions/check — Check permission

Legacy ID-Based API (use Path-Based instead)

  • GET|POST /v1/{sc}/files — List/create files
  • GET|PUT|DELETE /v1/{sc}/files/{fileId} — CRUD file by ID
  • GET /v1/{sc}/files/{fileId}/download — Download by ID
  • POST /v1/{sc}/files/{fileId}/copy|move|restore — File operations by ID
  • POST /v1/{sc}/files/bulk/delete|copy|move — Bulk operations by ID
  • GET|POST /v1/{sc}/directories — List/create directories
  • GET|PUT|DELETE /v1/{sc}/directories/{directoryId} — CRUD directory by ID

FileVault Integration Guide

Practical integration guide for services that consume FileVault.

1. Integration Contract

  • Base URL (example): https://filevault.denning.online
  • Server-scoped base: /api/v1/{server_code}
  • Auth token header:
    • Authorization: Bearer fv_<token>
    • or X-API-Token: fv_<token>
  • Caller identity header (recommended):
    • X-User-Email: <identity>
    • Denning services should send staffCode in this header.

2. Path Rules (Strict)

Do not send server_code inside path values.

Valid path formats:

  • Module-based: {module}/{recordId}/{sub_path}/{filename}
  • Documents module: documents/{sub_path}/{filename} (no recordId)

Examples:

  • matters/12345/evidence/contract.pdf
  • staff/101/avatar/photo.jpg
  • documents/policies/leave-policy.pdf

Invalid:

  • TS0004/matters/12345/contract.pdf
  • /matters/12345/contract.pdf
  • documents/12345/file.pdf

3. Access Levels and Metadata

The metadata field on upload controls file visibility and ownership tracking. It is optional — if omitted, the file defaults to access_level: "server" (visible to all firm users) and uploaded_by: "system".

Metadata fields:

  • uploaded_by — staff code or email of uploader (default: "system")
  • access_level — file visibility (default: "server"):
    • "server" — everyone in the same firm/tenant can see it
    • "private" — only the uploader can see it
    • "public" — anyone with the link

4. Core Path-Based Operations

Upload

Upload fields:

  • file (required) — the file to upload
  • path (required) — destination path, e.g. matters/12345/document.pdf
  • metadata (optional JSON string) — see Access Levels and Metadata above
  • overwrite (optional boolean, default true) — replace existing file at same path

Minimal example (most common — all firm users can see):

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/upload" \
  -H "Authorization: Bearer fv_your_token" \
  -H "X-User-Email: ST0001" \
  -F "file=@document.pdf" \
  -F "path=matters/12345/document.pdf"

With metadata (restrict to uploader only):

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/upload" \
  -H "Authorization: Bearer fv_your_token" \
  -H "X-User-Email: ST0001" \
  -F "file=@document.pdf" \
  -F "path=matters/12345/document.pdf" \
  -F 'metadata={"uploaded_by":"ST0001","access_level":"private"}'

Note: If you skip metadata, the file defaults to access_level: "server" (visible to all firm users) and uploaded_by: "system".

Download

curl "https://filevault.denning.online/api/v1/TS0004/storage/download?path=matters/12345/document.pdf" \
  -H "Authorization: Bearer fv_your_token" \
  -H "X-User-Email: ST0001" \
  -o document.pdf

Lookup (metadata)

curl "https://filevault.denning.online/api/v1/TS0004/storage/lookup?path=matters/12345/document.pdf" \
  -H "Authorization: Bearer fv_your_token" \
  -H "X-User-Email: ST0001"

List

curl "https://filevault.denning.online/api/v1/TS0004/storage/list?directory=matters/12345&recursive=false&per_page=100" \
  -H "Authorization: Bearer fv_your_token" \
  -H "X-User-Email: ST0001"

Exists

Check if a file exists:

curl "https://filevault.denning.online/api/v1/TS0004/storage/exists?path=matters/12345/document.pdf" \
  -H "Authorization: Bearer fv_your_token"

Check if a directory/folder exists (pass type=directory):

curl "https://filevault.denning.online/api/v1/TS0004/storage/exists?path=matters/12345&type=directory" \
  -H "Authorization: Bearer fv_your_token"

Response:

{ "status": "success", "exists": true, "path": "matters/12345", "type": "directory" }

Delete

curl -X DELETE "https://filevault.denning.online/api/v1/TS0004/storage" \
  -H "Authorization: Bearer fv_your_token" \
  -H "Content-Type: application/json" \
  -d '{"path":"matters/12345/document.pdf"}'

5. Bulk Operations (Path-Based)

Use these for cross-file operations. Responses may be:

  • status: success (all passed)
  • status: partial (some failed; inspect data.errors)

Bulk Copy

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/bulk-copy" \
  -H "Authorization: Bearer fv_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "paths": ["matters/12345/a.pdf", "matters/12345/b.pdf"],
    "target_path": "matters/12345/archive"
  }'

Bulk Move

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/bulk-move" \
  -H "Authorization: Bearer fv_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "paths": ["matters/12345/draft1.pdf", "matters/12345/draft2.pdf"],
    "target_path": "matters/12345/final"
  }'

Bulk Delete

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/bulk-delete" \
  -H "Authorization: Bearer fv_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "paths": ["matters/12345/old1.pdf", "matters/12345/old2.pdf"]
  }'

6. Tenant Storage Provider Management

Each tenant (server_code) can store multiple provider configs and activate one.

Supported providers:

  • system, s3, azure, gcp, alibaba, ftp, sftp, local

List configs

curl "https://filevault.denning.online/api/v1/TS0004/storage/configs" \
  -H "Authorization: Bearer fv_your_token"

Add config

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/configs" \
  -H "Authorization: Bearer fv_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "s3",
    "name": "Tenant S3",
    "config": {
      "bucket": "tenant-bucket",
      "region": "ap-southeast-1",
      "key": "AKIA...",
      "secret": "..."
    },
    "activate": false
  }'

Activate provider

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/configs/s3/activate" \
  -H "Authorization: Bearer fv_your_token"

7. Storage Migration

Migration is async and requires queue workers.

Start migration

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/migration/start" \
  -H "Authorization: Bearer fv_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "source_provider": "system",
    "destination_provider": "s3",
    "activate_destination": true,
    "overwrite_existing": false
  }'

Check status

curl "https://filevault.denning.online/api/v1/TS0004/storage/migration/status" \
  -H "Authorization: Bearer fv_your_token"

Retry failed files

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/migration/{migrationId}/retry" \
  -H "Authorization: Bearer fv_your_token"

8. Retry and Failure Handling

Recommended client strategy:

  1. Retry network/5xx errors with exponential backoff.
  2. Do not retry 4xx validation/permission errors without fixing payload/identity.
  3. For bulk operations, read data.errors and retry only failed paths.
  4. For migration, use:
    • GET /storage/migration/status
    • GET /storage/migration/jobs
    • POST /storage/migration/{migrationId}/retry

Idempotency notes:

  • upload is replace-by-default (overwrite=true default).
  • move and bulk-move are not safe to blind-retry unless you verify source/destination state.
  • delete and bulk-delete should re-check with exists or list.

9. Denning Service Notes

  • dp-api and dcc-api should call path-based endpoints (/storage/*) only.
  • Send staff identity consistently via X-User-Email using staffCode.
  • Keep a valid server_code in service config (example: DCC01) and keep path values server-code-free.

10. Endpoint Summary

Group Method Endpoint
Health GET /api/health
Global modules GET/POST/PUT/DELETE /api/v1/modules/*
Server GET/PUT /api/v1/{server_code}
Server stats GET /api/v1/{server_code}/stats
Storage (path-based) Various /api/v1/{server_code}/storage/*
Storage providers Various /api/v1/{server_code}/storage/configs*
Storage migration Various /api/v1/{server_code}/storage/migration/*
Module config (server) Various /api/v1/{server_code}/modules/*
Legacy files/directories Various /api/v1/{server_code}/files/*, /api/v1/{server_code}/directories/*

FileVault API Reference

Versioned API reference aligned with current routes.

1. Base Paths

  • Health: /api/health
  • Global: /api/v1
  • Server-scoped: /api/v1/{server_code}

{server_code} format: uppercase alphanumeric, 4-20 chars (example: TS0004, DCC01).

2. Authentication

Required for all protected endpoints.

  • Authorization: Bearer fv_<64_hex>
  • or X-API-Token: fv_<64_hex>

Optional caller identity (used in access checks):

  • X-User-Email: <caller-id> (Denning convention: staffCode)

3. Path Validation

Do not include server_code inside path params/body.

Accepted path patterns:

  • {module}/{recordId}/{sub_path}/{filename}
  • documents/{sub_path}/{filename}

Rejected examples:

  • TS0004/matters/123/file.pdf
  • /matters/123/file.pdf
  • ../../../etc/passwd

4. Common Response Shapes

Success:

{
  "status": "success",
  "message": "Operation completed",
  "data": {}
}

Partial (bulk operations):

{
  "status": "partial",
  "message": "Copied 2 of 3 files",
  "data": {
    "errors": []
  }
}

Error:

{
  "status": "error",
  "message": "Validation failed",
  "errors": {}
}

5. Public and Global Endpoints

Method Endpoint Description
GET /api/health Service health
POST /api/v1/servers/register Register server (requires X-Master-Token)
GET /api/v1/public/{token} Public share info
POST /api/v1/public/{token}/verify Verify share password
GET /api/v1/public/{token}/download Download shared file

Global Module Registry (not server-scoped)

Method Endpoint
GET /api/v1/modules
POST /api/v1/modules
GET /api/v1/modules/grouped
GET /api/v1/modules/storage-paths
POST /api/v1/modules/sync-all
POST /api/v1/modules/sync-all-now
POST /api/v1/modules/clear-cache
GET /api/v1/modules/{key}
PUT /api/v1/modules/{key}
DELETE /api/v1/modules/{key}
POST /api/v1/modules/{key}/sync
POST /api/v1/modules/{key}/sync-now

6. Server Endpoints

Method Endpoint Description
GET /api/v1/{server_code} Server details
PUT /api/v1/{server_code} Update server profile/quota/rate limit
GET /api/v1/{server_code}/stats Storage and file stats
PUT /api/v1/{server_code}/storage-config Update active provider and config map

7. Path-Based Storage Endpoints (Recommended)

Method Endpoint
POST /api/v1/{server_code}/storage/upload
GET /api/v1/{server_code}/storage/download
GET /api/v1/{server_code}/storage/lookup
GET /api/v1/{server_code}/storage/list
GET /api/v1/{server_code}/storage/exists
DELETE /api/v1/{server_code}/storage
POST /api/v1/{server_code}/storage/copy
POST /api/v1/{server_code}/storage/move
POST /api/v1/{server_code}/storage/rename
POST /api/v1/{server_code}/storage/mkdir
DELETE /api/v1/{server_code}/storage/rmdir
POST /api/v1/{server_code}/storage/compress
POST /api/v1/{server_code}/storage/extract
POST /api/v1/{server_code}/storage/share
POST /api/v1/{server_code}/storage/bulk-copy
POST /api/v1/{server_code}/storage/bulk-move
POST /api/v1/{server_code}/storage/bulk-delete

7.1 Upload

Multipart form fields:

  • file (required) — the file to upload
  • path (required) — destination path, e.g. matters/6000-6280/contract.pdf
  • metadata (optional JSON string) — controls file visibility and tracking:
    • uploaded_by — staff code or email of uploader (default: "system")
    • access_level — file visibility (default: "server"):
      • "server" — everyone in the same firm/tenant can see it
      • "private" — only the uploader can see it
      • "public" — anyone with the link
  • overwrite (optional boolean, default true) — replace existing file at same path

Minimal example (most common — all firm users can see):

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/upload" \
  -H "Authorization: Bearer fv_token" \
  -F "file=@contract.pdf" \
  -F "path=matters/12345/evidence/contract.pdf"

With metadata (restrict to uploader only):

curl -X POST "https://filevault.denning.online/api/v1/TS0004/storage/upload" \
  -H "Authorization: Bearer fv_token" \
  -F "file=@contract.pdf" \
  -F "path=matters/12345/evidence/contract.pdf" \
  -F 'metadata={"uploaded_by":"ST0001","access_level":"private"}'

Note: If you skip metadata, the file defaults to access_level: "server" (visible to all firm users) and uploaded_by: "system".

7.2 Read/List

  • download query: path
  • lookup query: path
  • exists query: path, type (optional: file or directory, default: file)
  • list query:
    • directory (optional)
    • recursive (optional boolean)
    • per_page (optional, max 100)

7.3 File/Directory Mutations

copy body:

{ "source_path": "...", "dest_path": "..." }

move body:

{ "source_path": "...", "dest_path": "..." }

rename body:

{ "path": "...", "new_name": "new-file.pdf" }

mkdir body:

{ "path": "...", "access_level": "private", "created_by": "ST0001" }

rmdir body:

{ "path": "..." }

delete body:

{ "path": "..." }

7.4 Archive

compress body:

{
  "paths": ["matters/123/a.pdf", "matters/123/b.pdf"],
  "archive_name": "archive.zip",
  "dest_path": "matters/123/archives"
}

extract body:

{
  "path": "matters/123/archives/archive.zip",
  "dest_path": "matters/123/extracted"
}

7.5 Sharing

share body:

{
  "path": "matters/123/contract.pdf",
  "expires_at": "2026-03-01T00:00:00Z",
  "password": "1234",
  "download_limit": 10
}

7.6 Bulk

bulk-copy and bulk-move:

{
  "paths": ["matters/123/a.pdf", "matters/123/b.pdf"],
  "target_path": "matters/123/archive"
}

bulk-delete:

{
  "paths": ["matters/123/a.pdf", "matters/123/b.pdf"]
}

8. Tenant Storage Provider Configuration

Supported providers:

  • system, s3, azure, gcp, alibaba, ftp, sftp, local
Method Endpoint
GET /api/v1/{server_code}/storage/configs
POST /api/v1/{server_code}/storage/configs
PUT /api/v1/{server_code}/storage/configs/{provider}
DELETE /api/v1/{server_code}/storage/configs/{provider}
POST /api/v1/{server_code}/storage/configs/{provider}/test
POST /api/v1/{server_code}/storage/configs/{provider}/activate

Create/update payload:

{
  "provider": "s3",
  "config": {},
  "name": "Tenant S3",
  "description": "Primary tenant storage",
  "visibility": "private",
  "driver": "aws_s3",
  "activate": false
}

9. Storage Migration

Method Endpoint
GET /api/v1/{server_code}/storage/migration/status
GET /api/v1/{server_code}/storage/migration/jobs
POST /api/v1/{server_code}/storage/migration/start
POST /api/v1/{server_code}/storage/migration/{migrationId}/cancel
POST /api/v1/{server_code}/storage/migration/{migrationId}/retry

Start payload:

{
  "source_provider": "system",
  "destination_provider": "s3",
  "delete_source_files": false,
  "overwrite_existing": false,
  "preserve_directory_structure": true,
  "file_pattern": "*.pdf",
  "activate_destination": true
}

Notes:

  • One active migration per tenant.
  • Migration uses queued jobs; run a queue worker.
  • Retry re-queues only failed file IDs.

10. Server-Scoped Module Configuration

Method Endpoint
GET /api/v1/{server_code}/modules
POST /api/v1/{server_code}/modules
GET /api/v1/{server_code}/modules/export
GET /api/v1/{server_code}/modules/health
GET /api/v1/{server_code}/modules/backups
GET /api/v1/{server_code}/modules/{key}
DELETE /api/v1/{server_code}/modules/{key}
POST /api/v1/{server_code}/modules/import
POST /api/v1/{server_code}/modules/backup
POST /api/v1/{server_code}/modules/restore
POST /api/v1/{server_code}/modules/reset

11. Legacy Compatibility Endpoints

Still available for older consumers:

Group Endpoint Pattern
Legacy files /api/v1/{server_code}/files/*
Legacy directories /api/v1/{server_code}/directories/*
File permissions /api/v1/{server_code}/files/{fileId}/permissions*
File-specific shares /api/v1/{server_code}/files/{fileId}/shares*
Share management /api/v1/{server_code}/shares*

For new integrations, use /storage/*.

12. Operational Notes

  • Access control is enforced for private and server files.
  • Bulk endpoints may return partial; always process data.errors.
  • 404 typically means missing file/path/config/job.
  • 409 typically means conflict (already exists, migration in progress, active config deletion).
  • 422 indicates validation errors or unsupported provider input.

Developer Onboarding - FileVault

Setup and integration checklist for engineers working with FileVault.

1. Local Setup

composer install
cp .env.example .env
php artisan key:generate
php artisan migrate
php artisan serve

Recommended for async features (migration/jobs):

php artisan queue:work

2. Service Integration Contract

Every consuming service must provide:

  • FILEVAULT_URL
  • FILEVAULT_TOKEN
  • FILEVAULT_SERVER_CODE

Request headers:

  • Authorization: Bearer <token>
  • X-User-Email: <caller-identity> (use staffCode in Denning services)

3. API Choice

Use path-based API for all new work:

  • /api/v1/{server_code}/storage/*

Legacy endpoints are still present for compatibility:

  • /api/v1/{server_code}/files/*
  • /api/v1/{server_code}/directories/*

4. Path Design Rules

Paths must be server-code-free and follow:

  • {module}/{recordId}/{sub_path}/{filename}
  • documents/{sub_path}/{filename}

Do not send:

  • server code in path
  • leading /
  • traversal segments (../)

5. Access and Identity

The metadata field on upload is optional and controls file visibility and ownership. If omitted, files default to access_level: "server" (visible to all firm users) and uploaded_by: "system".

Metadata fields:

  • uploaded_by — staff code or email of uploader (default: "system")
  • access_level — file visibility (default: "server"):
    • "server" — everyone in the same firm/tenant can see it
    • "private" — only the uploader can see it
    • "public" — anyone with the link

Example (restrict to uploader only):

{
  "uploaded_by": "ST0001",
  "access_level": "private"
}

Most uploads do not need metadata — just send file and path, and the file will be visible to all users in the firm.

If caller identity is missing (X-User-Email), access checks for private/server files may deny reads.

6. Tenant Storage Provider Support

Per tenant (server_code) you can:

  • Save multiple provider configs (storage/configs)
  • Test connectivity (storage/configs/{provider}/test)
  • Activate selected provider (storage/configs/{provider}/activate)

Supported providers:

  • system, s3, azure, gcp, alibaba, ftp, sftp, local

7. Storage Migration Workflow

Migration endpoints:

  • GET /storage/migration/status
  • GET /storage/migration/jobs
  • POST /storage/migration/start
  • POST /storage/migration/{migrationId}/cancel
  • POST /storage/migration/{migrationId}/retry

Important:

  • One active migration per tenant.
  • Queue worker must be running.
  • Retry only failed file IDs from previous run.

8. Reliability Patterns for Consumers

Use these rules in dp-api/dcc-api/other services:

  1. Retry network and 5xx errors with exponential backoff.
  2. Do not retry 4xx blindly; fix payload or permissions first.
  3. For bulk operations, parse status=partial and retry only failed paths.
  4. Before retrying destructive operations (move, delete), verify state with exists or list.
  5. Persist file paths in your service DB so users can retry actions safely.

9. Quick Verification Checklist

  • Health endpoint returns healthy.
  • Upload/list/download/lookup works for your server_code.
  • X-User-Email is passed from caller context.
  • Path values never include server_code.
  • Bulk operations handle partial responses.
  • Storage config endpoints work for tenant-managed providers.
  • Migration can start and report progress with queue worker active.

10. Useful Links

  • API contract: docs/API_REFERENCE.md
  • Integration patterns: docs/INTEGRATION_GUIDE.md
  • Bruno collection: docs/bruno-collection/
  • Web docs page: /integration-guide