Backup EnginebackupEngine
Docs/API Reference/Backup API

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
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

The init response tells the client exactly which chunks are new. In a typical incremental backup, 90% or more of chunks are already stored, so only a small fraction needs uploading.

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.

Request presigned URL and 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

Presigned URLs expire after 15 minutes. If an upload fails or times out, request a new presigned URL and retry. The client should implement exponential backoff for retries.

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.

Progress and completion
// 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
}