Backup API
Initialize backup sessions, report progress, upload chunks via presigned URLs, and complete backup runs.
Backup Flow Overview
A backup run consists of three phases: initialization, chunk upload, and completion. The client communicates with the control plane (Supabase Edge Functions) for orchestration, and uploads encrypted chunks directly to object storage via presigned URLs.
- •Init: The client sends a file manifest to the control plane, which responds with a list of chunks that need to be uploaded (new chunks not already in storage).
- •Upload: For each new chunk, the client requests a presigned PUT URL and uploads the encrypted chunk directly to storage.
- •Complete: The client notifies the control plane that all chunks have been uploaded, and the backup run is finalized.
Initialize Backup
The init endpoint receives the file manifest (list of files and their chunk hashes) and returns which chunks need to be uploaded. Chunks that already exist in storage are skipped (deduplication).
POST /functions/v1/backup/init
Authorization: Bearer <access_token>
Content-Type: application/json
{
"device_id": "dev_abc123",
"backup_set": "Documents",
"files": [
{
"path": "/Users/me/Documents/report.docx",
"size": 245760,
"modified": "2025-12-15T10:30:00Z",
"chunks": [
{ "hash": "sha256:a1b2c3d4...", "size": 16384 },
{ "hash": "sha256:e5f6g7h8...", "size": 24576 },
{ "hash": "sha256:i9j0k1l2...", "size": 8192 }
]
}
]
}
// Response:
{
"session_id": "bak_session_xyz789",
"chunks_needed": [
{ "hash": "sha256:e5f6g7h8...", "size": 24576 }
],
"chunks_deduped": 2,
"chunks_to_upload": 1
}ℹ Note
Upload Chunks
For each chunk that needs uploading, request a presigned PUT URL from the control plane, then upload the encrypted chunk directly to storage. Chunks must be encrypted client-side before upload.
// Step 1: Get presigned URL
POST /functions/v1/backup/presign
Authorization: Bearer <access_token>
Content-Type: application/json
{
"session_id": "bak_session_xyz789",
"chunk_hash": "sha256:e5f6g7h8...",
"chunk_size": 24576
}
// Response:
{
"upload_url": "https://e2-us.backupengine.com/chunks/sha256%3Ae5f6g7h8...?X-Amz-Signature=...",
"expires_in": 900,
"method": "PUT",
"headers": {
"Content-Type": "application/octet-stream",
"Content-Length": "24576"
}
}
// Step 2: Upload encrypted chunk directly to storage
PUT https://e2-us.backupengine.com/chunks/sha256%3Ae5f6g7h8...?X-Amz-Signature=...
Content-Type: application/octet-stream
Content-Length: 24576
<encrypted chunk bytes>
// Response: 200 OK⚠ Warning
Report Progress and Complete
During upload, the client periodically reports progress. After all chunks are uploaded, the client calls the complete endpoint to finalize the backup run.
// Report progress (optional, every 30 seconds or every 100 chunks)
POST /functions/v1/backup/progress
Authorization: Bearer <access_token>
Content-Type: application/json
{
"session_id": "bak_session_xyz789",
"chunks_uploaded": 847,
"chunks_total": 1842,
"bytes_uploaded": 52428800
}
// Complete the backup run
POST /functions/v1/backup/complete
Authorization: Bearer <access_token>
Content-Type: application/json
{
"session_id": "bak_session_xyz789",
"stats": {
"files_processed": 3847,
"chunks_new": 1842,
"chunks_deduped": 14203,
"bytes_scanned": 5368709120,
"bytes_uploaded": 1288490188,
"duration_seconds": 912
}
}
// Response:
{
"backup_id": "bak_run_abc123",
"status": "completed",
"restore_point": "2025-12-15T02:15:12Z",
"storage_used_bytes": 1288490188,
"dedup_savings_percent": 88.5
}