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
- Always validate - Call validate endpoint after configuring BYOB storage
- Monitor migrations - Check progress periodically for large migrations
- Plan migrations - Schedule during off-peak hours for minimal impact
- Keep audit trail - Always provide meaningful reasons for changes
- Test credentials - Verify BYOB credentials before configuration
Related Documentation
- Storage Options Guide - Overview of storage types
- BYOB Setup Guide - Configure your own bucket
- Storage Migration Guide - Migration process
Questions? Contact support@archivusdms.com