Backup EnginebackupEngine
Docs/API Reference/Restore API

Restore API

Request file manifests, download chunks via presigned URLs, and verify data integrity on restore.

Restore Flow Overview

Restoring data is the reverse of the backup flow. The client requests the file manifest for a specific point in time, receives presigned download URLs for the required chunks, downloads and decrypts them, then reassembles the original files.

  • Manifest: Request the file manifest for a backup set at a specific point in time.
  • Download: Get presigned GET URLs for each chunk and download them directly from storage.
  • Decrypt and assemble: Decrypt each chunk with AES-256-GCM and reassemble files from their constituent chunks.
  • Verify: Validate GCM authentication tags during decryption and verify file integrity via SHA-256 hashes.

Request File Manifest

The manifest endpoint returns the complete file tree as it existed at a given backup point, including file paths, sizes, and the ordered list of chunk hashes that compose each file.

POST /functions/v1/restore/manifest
POST /functions/v1/restore/manifest
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "device_id": "dev_abc123",
  "backup_set": "Documents",
  "point_in_time": "2025-12-15T02:15:00Z",
  "path": "/Users/me/Documents/",
  "recursive": true
}

// Response:
{
  "restore_session_id": "rst_session_abc123",
  "point_in_time": "2025-12-15T02:15:00Z",
  "files": [
    {
      "path": "/Users/me/Documents/report.docx",
      "size": 245760,
      "modified": "2025-12-15T10:30:00Z",
      "chunks": [
        "sha256:a1b2c3d4...",
        "sha256:e5f6g7h8...",
        "sha256:i9j0k1l2..."
      ]
    },
    {
      "path": "/Users/me/Documents/notes.txt",
      "size": 4096,
      "modified": "2025-12-14T16:00:00Z",
      "chunks": [
        "sha256:m3n4o5p6..."
      ]
    }
  ],
  "total_files": 2,
  "total_chunks": 4,
  "unique_chunks": 4,
  "total_bytes": 249856
}

Download Chunks

Request presigned GET URLs for chunks and download them directly from storage. You can request URLs in batches for efficient parallel downloads.

Batch presigned download URLs
POST /functions/v1/restore/presign
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "restore_session_id": "rst_session_abc123",
  "chunk_hashes": [
    "sha256:a1b2c3d4...",
    "sha256:e5f6g7h8...",
    "sha256:i9j0k1l2...",
    "sha256:m3n4o5p6..."
  ]
}

// Response:
{
  "downloads": [
    {
      "hash": "sha256:a1b2c3d4...",
      "url": "https://e2-us.backupengine.com/chunks/sha256%3Aa1b2c3d4...?X-Amz-Signature=...",
      "size": 16384,
      "expires_in": 900
    },
    {
      "hash": "sha256:e5f6g7h8...",
      "url": "https://e2-us.backupengine.com/chunks/sha256%3Ae5f6g7h8...?X-Amz-Signature=...",
      "size": 24576,
      "expires_in": 900
    }
    // ... additional chunks
  ]
}

// Download each chunk directly from storage:
GET https://e2-us.backupengine.com/chunks/sha256%3Aa1b2c3d4...?X-Amz-Signature=...
// Response: <encrypted chunk bytes>

💡 Tip

Request presigned URLs in batches of up to 100 chunks to minimize API calls. Download chunks in parallel (4-8 concurrent connections) for maximum throughput.

Integrity Verification

BackupEngine verifies data integrity at multiple levels during the restore process to ensure that your data has not been tampered with or corrupted in storage.

  • GCM authentication tag: During decryption, the AES-256-GCM auth tag is verified automatically. If the tag does not match, the chunk has been tampered with and decryption is rejected.
  • Chunk hash verification: After decryption, the SHA-256 hash of the plaintext chunk is compared against the expected hash from the manifest. Any mismatch indicates corruption.
  • File integrity: After reassembling a file from its chunks, the total file size is verified against the manifest.
  • If any verification fails, the restore operation reports the specific file and chunk that failed, and the client can retry the download.
Verification pseudocode
for each chunk in file.chunks:
  // 1. Download encrypted blob
  encrypted = download(chunk.presigned_url)

  // 2. Extract IV, ciphertext, and GCM tag
  iv = encrypted[0:12]
  ciphertext = encrypted[12:-16]
  tag = encrypted[-16:]

  // 3. Decrypt and verify GCM tag (AES-256-GCM)
  plaintext = aes_256_gcm_decrypt(dek, iv, ciphertext, tag)
  // If tag verification fails, throws AuthenticationError

  // 4. Verify chunk hash
  actual_hash = sha256(plaintext)
  assert actual_hash == chunk.expected_hash

  // 5. Append to output file
  output_file.write(plaintext)

⚠ Warning

Never skip integrity verification. If a GCM tag or hash verification fails, do not use the restored data. Instead, retry the download from storage. If the issue persists, contact BackupEngine support as it may indicate a storage-level problem.