Ctrl + K

Snapshot Archives

Create long-term backups of your entire sandbox environment. Unlike checkpoints which are temporary, archives are permanent storage for complete environment states.

Create Archive

await sandbox.snapshots.archive({
  id: 'production-v1.0.0',
  options: {
    description: 'Production release 1.0.0'
  }
});

console.log('Archive created');
const response = await fetch(`${sandbox.url}/snapshot-archive/archive`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${sandbox.token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    id: 'production-v1.0.0',
    options: {
      description: 'Production release 1.0.0'
    }
  })
});

const result = await response.json();
curl -X POST https://sandbox.oblien.com/snapshot-archive/archive \
  -H "Authorization: Bearer YOUR_SANDBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "production-v1.0.0",
    "options": {
      "description": "Production release 1.0.0"
    }
  }'

Response:

{
  "success": true,
  "message": "Archive created successfully",
  "id": "production-v1.0.0",
  "size": 45678910,
  "timestamp": "2025-10-26T12:00:00Z"
}

List Archives

const archives = await sandbox.snapshots.listArchives();

console.log(`Found ${archives.archives.length} archives`);
archives.archives.forEach(archive => {
  console.log(`${archive.id} - ${archive.timestamp}`);
  console.log(`  Size: ${archive.size} bytes`);
});
const response = await fetch(`${sandbox.url}/snapshot-archive/archives`, {
  headers: {
    'Authorization': `Bearer ${sandbox.token}`
  }
});

const archives = await response.json();
curl https://sandbox.oblien.com/snapshot-archive/archives \
  -H "Authorization: Bearer YOUR_SANDBOX_TOKEN"

Response:

{
  "success": true,
  "archives": [
    {
      "id": "production-v1.0.0",
      "description": "Production release 1.0.0",
      "size": 45678910,
      "timestamp": "2025-10-26T12:00:00Z",
      "files": 342
    },
    {
      "id": "backup-2025-10-25",
      "description": "Daily backup",
      "size": 43210987,
      "timestamp": "2025-10-25T00:00:00Z",
      "files": 338
    }
  ],
  "total": 2
}

Get Archive Details

const archive = await sandbox.snapshots.getArchive('production-v1.0.0');

console.log('Archive:', archive.id);
console.log('Size:', archive.size);
console.log('Files:', archive.files);
console.log('Created:', archive.timestamp);
const response = await fetch(
  `${sandbox.url}/snapshot-archive/archive/production-v1.0.0`,
  {
    headers: {
      'Authorization': `Bearer ${sandbox.token}`
    }
  }
);

const archive = await response.json();
curl https://sandbox.oblien.com/snapshot-archive/archive/production-v1.0.0 \
  -H "Authorization: Bearer YOUR_SANDBOX_TOKEN"

Restore Archive

Restore your sandbox from an archive:

await sandbox.snapshots.restore({
  id: 'production-v1.0.0',
  override: false
});

console.log('Archive restored');
const response = await fetch(`${sandbox.url}/snapshot-archive/restore-archive`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${sandbox.token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    id: 'production-v1.0.0',
    override: false
  })
});

const result = await response.json();
curl -X POST https://sandbox.oblien.com/snapshot-archive/restore-archive \
  -H "Authorization: Bearer YOUR_SANDBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "production-v1.0.0",
    "override": false
  }'

Parameters:

  • id (string, required) - Archive ID
  • override (boolean) - Override existing files (default: false)

Delete Archive

Remove an archive permanently:

await sandbox.snapshots.deleteArchive('old-backup');

console.log('Archive deleted');
const response = await fetch(
  `${sandbox.url}/snapshot-archive/archive/old-backup`,
  {
    method: 'DELETE',
    headers: {
      'Authorization': `Bearer ${sandbox.token}`
    }
  }
);
curl -X DELETE https://sandbox.oblien.com/snapshot-archive/archive/old-backup \
  -H "Authorization: Bearer YOUR_SANDBOX_TOKEN"

Cleanup Archives

Remove all archives (careful!):

await sandbox.snapshots.cleanupArchives();

console.log('All archives removed');
const response = await fetch(`${sandbox.url}/snapshot-archive/cleanup-archives`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${sandbox.token}`
  }
});
curl -X POST https://sandbox.oblien.com/snapshot-archive/cleanup-archives \
  -H "Authorization: Bearer YOUR_SANDBOX_TOKEN" \
  -H "Content-Type: application/json"

Complete Example

// Create archive before major deployment
console.log('Creating pre-deployment archive...');
await sandbox.snapshots.archive({
  id: `pre-deploy-${Date.now()}`,
  options: {
    description: 'Before production deployment'
  }
});

// Deploy changes
await sandbox.terminal.execute({
  command: 'npm run build && npm run deploy',
  cwd: '/opt/app'
});

// If deployment fails, restore from archive
try {
  const deployResult = await sandbox.terminal.execute({
    command: 'npm run verify-deployment',
    cwd: '/opt/app'
  });
  
  if (deployResult.exitCode === 0) {
    console.log('Deployment successful!');
    
    // Create success archive
    await sandbox.snapshots.archive({
      id: 'production-v1.0.0',
      options: {
        description: 'Successful production deployment v1.0.0'
      }
    });
  } else {
    throw new Error('Deployment verification failed');
  }
} catch (error) {
  console.log('Deployment failed, restoring...');
  
  // List archives to find latest
  const archives = await sandbox.snapshots.listArchives();
  const latest = archives.archives[0];
  
  // Restore
  await sandbox.snapshots.restore({
    id: latest.id,
    override: true
  });
  
  console.log('Restored from archive:', latest.id);
}

// Cleanup old archives (keep last 5)
const allArchives = await sandbox.snapshots.listArchives();
if (allArchives.archives.length > 5) {
  const toDelete = allArchives.archives.slice(5);
  
  for (const archive of toDelete) {
    await sandbox.snapshots.deleteArchive(archive.id);
    console.log('Deleted old archive:', archive.id);
  }
}
// Create archive
await fetch(`${sandbox.url}/snapshot-archive/archive`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${sandbox.token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    id: `pre-deploy-${Date.now()}`,
    options: {
      description: 'Before production deployment'
    }
  })
});

// (Deploy and verify)

// List archives
let response = await fetch(`${sandbox.url}/snapshot-archive/archives`, {
  headers: {
    'Authorization': `Bearer ${sandbox.token}`
  }
});

const archives = await response.json();

// Restore if needed
await fetch(`${sandbox.url}/snapshot-archive/restore-archive`, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${sandbox.token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    id: archives.archives[0].id,
    override: true
  })
});
curl -X POST https://sandbox.oblien.com/snapshot-archive/archive \
  -H "Authorization: Bearer YOUR_SANDBOX_TOKEN" \
  -H "Content-Type: application/json"

Use Cases

Production Releases

// Archive each release
await sandbox.snapshots.archive({
  id: 'v1.0.0',
  options: { description: 'Production release 1.0.0' }
});

Daily Backups

// Create daily backup
const date = new Date().toISOString().split('T')[0];
await sandbox.snapshots.archive({
  id: `backup-${date}`,
  options: { description: `Daily backup ${date}` }
});

Milestone Snapshots

// Archive important milestones
await sandbox.snapshots.archive({
  id: 'feature-complete',
  options: { description: 'All features implemented' }
});

Disaster Recovery

// Restore from archive after issue
const archives = await sandbox.snapshots.listArchives();
const lastGood = archives.archives.find(a => 
  a.description.includes('production')
);

await sandbox.snapshots.restore({
  id: lastGood.id,
  override: true
});

Best Practices

  1. Use descriptive IDs:

    id: 'production-v1.0.0'
    // Not: 'archive1'
  2. Include metadata: Add descriptions for context

  3. Regular backups: Archive important states automatically

  4. Cleanup old archives: Remove outdated backups periodically

  5. Test restores: Verify archives can be restored

  6. Version naming: Use semantic versioning for releases

Archives vs Checkpoints

FeatureCheckpointsArchives
PurposeTemporary stateLong-term backup
DurationSession-basedPermanent
SizeSmallerLarger (full backup)
SpeedFastSlower
Use caseExperimentsReleases

Next Steps