Storage API

Admin endpoints for managing tenant storage configuration and migrations.

Authorization Required: Super Admin role


Overview

The Storage API allows administrators to configure storage providers for tenants, migrate files between storage types, and monitor storage usage.

Storage Provider Types

Type Description
shared Default Supabase shared bucket (all tenants)
dedicated Archivus-provisioned dedicated S3 bucket
s3_byob Customer’s own S3-compatible bucket

Storage Configuration

Get Storage Configuration

Retrieve the current storage configuration for a tenant.

GET /admin/storage/config/{tenant_id}

Path Parameters:

Parameter Type Description
tenant_id UUID The tenant’s unique identifier

Response (Configured):

{
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "provider_type": "dedicated",
  "bucket_name": "archivus-tenant-550e8400",
  "region": "us-east-1",
  "path_prefix": "",
  "validation_status": "valid",
  "validation_message": "Configuration validated successfully",
  "configured_at": "2024-01-15T10:30:00Z",
  "configured_by_email": "admin@example.com",
  "reason": "Upgrade to dedicated storage for compliance"
}

Response (Default/Shared):

{
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "provider_type": "shared",
  "is_default": true,
  "message": "Using shared storage (default)"
}

Configure Storage

Configure storage provider for a tenant.

POST /admin/storage/config/{tenant_id}

Request Body:

{
  "provider_type": "s3_byob",
  "bucket_name": "customer-archivus-bucket",
  "region": "us-east-1",
  "endpoint_url": "s3.us-east-1.wasabisys.com",
  "access_key": "AKIAIOSFODNN7EXAMPLE",
  "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "path_prefix": "archivus/production",
  "reason": "Migrating to customer-owned Wasabi storage"
}

Request Parameters:

Parameter Type Required Description
provider_type string Yes shared, dedicated, or s3_byob
bucket_name string If BYOB S3 bucket name
region string If BYOB AWS region or provider region
endpoint_url string If non-AWS S3-compatible endpoint URL
access_key string If BYOB S3 access key ID
secret_key string If BYOB S3 secret access key
path_prefix string No Optional path prefix for files
reason string Yes Reason for configuration change

Response:

{
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "provider_type": "s3_byob",
  "bucket_name": "customer-archivus-bucket",
  "region": "us-east-1",
  "endpoint_url": "s3.us-east-1.wasabisys.com",
  "path_prefix": "archivus/production",
  "validation_status": "pending",
  "configured_at": "2024-01-15T10:30:00Z",
  "configured_by_email": "admin@example.com"
}

Error Responses:

Status Code Description
403 TIER_REQUIRED Dedicated storage requires Teams+, BYOB requires Enterprise
400 INVALID_CONFIG Invalid configuration parameters

Validate Storage Configuration

Test the storage configuration for a tenant.

POST /admin/storage/config/{tenant_id}/validate

Response (Success):

{
  "valid": true,
  "checks": {
    "connection": "passed",
    "authentication": "passed",
    "read_permission": "passed",
    "write_permission": "passed",
    "delete_permission": "passed"
  },
  "message": "Storage configuration is valid"
}

Response (Failure):

{
  "valid": false,
  "checks": {
    "connection": "passed",
    "authentication": "failed",
    "read_permission": "skipped",
    "write_permission": "skipped",
    "delete_permission": "skipped"
  },
  "message": "Authentication failed: invalid credentials"
}

Reset to Shared Storage

Reset a tenant to use shared storage.

DELETE /admin/storage/config/{tenant_id}

Response:

{
  "message": "Storage reset to shared",
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "provider_type": "shared"
}

Provision Dedicated Bucket

Provision an Archivus-managed dedicated S3 bucket for a tenant.

POST /admin/storage/config/{tenant_id}/provision-dedicated

Request Body:

{
  "reason": "Customer upgraded to Teams plan, needs isolated storage"
}

Response:

{
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "provider_type": "dedicated",
  "bucket_name": "archivus-tenant-550e8400",
  "region": "us-east-1",
  "validation_status": "valid",
  "configured_at": "2024-01-15T10:30:00Z",
  "configured_by_email": "admin@example.com"
}

Error Responses:

Status Code Description
403 TIER_REQUIRED Dedicated storage requires Teams or Enterprise tier

Storage Migration

Initiate Migration

Start migrating files to a new storage provider.

POST /admin/storage/config/{tenant_id}/migrate

Request Body:

{
  "target_provider": "dedicated"
}

Request Parameters:

Parameter Type Required Description
target_provider string Yes Target: shared, dedicated, or s3_byob

Response:

{
  "id": "mig_abc123def",
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "source_provider": "shared",
  "target_provider": "dedicated",
  "status": "pending",
  "total_files": 1250,
  "total_bytes": 5368709120,
  "migrated_files": 0,
  "migrated_bytes": 0,
  "failed_files": 0,
  "skipped_files": 0,
  "started_at": "2024-01-15T10:30:00Z",
  "initiated_by_email": "admin@example.com"
}

Error Responses:

Status Code Description
409 MIGRATION_IN_PROGRESS Migration already in progress for tenant

Get Migration Status

Get the status of the current/latest migration for a tenant.

GET /admin/storage/migrations/{tenant_id}

Response:

{
  "id": "mig_abc123def",
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "source_provider": "shared",
  "target_provider": "dedicated",
  "status": "in_progress",
  "total_files": 1250,
  "total_bytes": 5368709120,
  "migrated_files": 568,
  "migrated_bytes": 2442000000,
  "failed_files": 2,
  "skipped_files": 5,
  "progress_percent": 45.5,
  "current_file": "documents/reports/2024/quarterly-report.pdf",
  "started_at": "2024-01-15T10:30:00Z",
  "estimated_completion": "2024-01-15T11:15:00Z"
}

Migration Statuses:

Status Description
pending Migration created, waiting to start
in_progress Actively migrating files
completed All files successfully migrated
completed_with_errors Finished with some failures
failed Critical error occurred
cancelled Migration was cancelled

Error Responses:

Status Code Description
404 NOT_FOUND No migration found for tenant

Get Migration History

Get the migration history for a tenant (last 10 migrations).

GET /admin/storage/migrations/{tenant_id}/history

Response:

{
  "migrations": [
    {
      "id": "mig_abc123def",
      "source_provider": "shared",
      "target_provider": "dedicated",
      "status": "completed",
      "total_files": 1250,
      "migrated_files": 1248,
      "failed_files": 2,
      "skipped_files": 0,
      "total_bytes": 5368709120,
      "migrated_bytes": 5368000000,
      "started_at": "2024-01-15T10:30:00Z",
      "completed_at": "2024-01-15T11:20:00Z",
      "initiated_by_email": "admin@example.com"
    }
  ],
  "count": 1
}

Cancel Migration

Cancel an in-progress migration.

POST /admin/storage/migrations/{migration_id}/cancel

Request Body:

{
  "reason": "Discovered configuration issue, need to reconfigure"
}

Response:

{
  "message": "Migration cancelled",
  "migration_id": "mig_abc123def"
}

Error Responses:

Status Code Description
409 CANNOT_CANCEL Migration not found or already completed

Storage Statistics

Get Storage Statistics

Get aggregate storage statistics across all tenants.

GET /admin/storage/stats

Response:

{
  "provider_distribution": {
    "shared": 150,
    "dedicated": 25,
    "s3_byob": 5
  },
  "migrations": {
    "pending": 2,
    "in_progress": 1,
    "completed": 45,
    "failed": 3,
    "cancelled": 2,
    "total_bytes_migrated": 1073741824000
  }
}

Code Examples

Python - Configure BYOB Storage

import requests

API_BASE = "https://api.archivus.app/api/v1"
ADMIN_KEY = "YOUR_ADMIN_API_KEY"
TENANT_ID = "550e8400-e29b-41d4-a716-446655440000"

def configure_byob_storage(tenant_id, config):
    """Configure BYOB storage for a tenant."""
    response = requests.post(
        f"{API_BASE}/admin/storage/config/{tenant_id}",
        headers={"Authorization": f"Bearer {ADMIN_KEY}"},
        json=config
    )
    return response.json()

def validate_storage(tenant_id):
    """Validate storage configuration."""
    response = requests.post(
        f"{API_BASE}/admin/storage/config/{tenant_id}/validate",
        headers={"Authorization": f"Bearer {ADMIN_KEY}"}
    )
    return response.json()

# Configure BYOB
config = {
    "provider_type": "s3_byob",
    "bucket_name": "my-archivus-bucket",
    "region": "us-east-1",
    "endpoint_url": "s3.us-east-1.wasabisys.com",
    "access_key": "YOUR_ACCESS_KEY",
    "secret_key": "YOUR_SECRET_KEY",
    "reason": "Migrating to customer storage"
}

result = configure_byob_storage(TENANT_ID, config)
print(f"Configuration status: {result['validation_status']}")

# Validate
validation = validate_storage(TENANT_ID)
if validation['valid']:
    print("Storage configuration validated successfully!")
else:
    print(f"Validation failed: {validation['message']}")

JavaScript - Monitor Migration

async function monitorMigration(tenantId, apiKey) {
  const headers = { 'Authorization': `Bearer ${apiKey}` };
  const baseUrl = 'https://api.archivus.app/api/v1';

  const checkStatus = async () => {
    const response = await fetch(
      `${baseUrl}/admin/storage/migrations/${tenantId}`,
      { headers }
    );
    return response.json();
  };

  // Poll every 30 seconds
  const interval = setInterval(async () => {
    const status = await checkStatus();

    console.log(`Status: ${status.status}`);
    console.log(`Progress: ${status.progress_percent?.toFixed(1)}%`);
    console.log(`Files: ${status.migrated_files}/${status.total_files}`);

    if (['completed', 'failed', 'cancelled'].includes(status.status)) {
      clearInterval(interval);
      console.log('Migration finished!');
    }
  }, 30000);
}

Best Practices

  1. Always validate - Call validate endpoint after configuring BYOB storage
  2. Monitor migrations - Check progress periodically for large migrations
  3. Plan migrations - Schedule during off-peak hours for minimal impact
  4. Keep audit trail - Always provide meaningful reasons for changes
  5. Test credentials - Verify BYOB credentials before configuration


Questions? Contact support@archivusdms.com