/api/wallets/backup
POSTCreates a complete ZIP archive backup of a wallet with timestamped filename.
Description
The `/api/wallets/backup` endpoint creates a complete ZIP archive of a specified wallet, including all coins, transaction history, and configuration files. The backup is saved with a timestamped filename format: `CloudCoin-Wallet-Backup_{wallet_name}_{date}.zip`.
The backup includes:
- Bank folder: All authenticated coins (13+ RAIDA passes)
- Fracked folder: Partially authenticated coins (needs healing)
- Counterfeit folder: Rejected coins
- Import/Export folders: Incoming and outgoing coins
- Receipts folder: Complete transaction logs
- Data folder: transactions.csv and configuration files
Schedule regular backups to prevent data loss. Store backups in multiple secure locations (encrypted drives, offline storage, cloud with encryption).
Backup files contain your complete wallet including all CloudCoin authenticity numbers (ANs). Store backups in secure, encrypted locations only. Anyone with access to a backup can access your coins.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
destination |
string | Yes | Absolute path to the directory where the backup ZIP file will be saved. The directory will be created if it doesn't exist. |
The destination parameter must be an absolute path (e.g., C:\Backups on Windows or /home/user/backups on Linux). Relative paths are not supported.
The server canonicalizes destination with _fullpath / realpath and refuses any path that resolves inside the program's own Client_Data directory. This includes ../ traversal and symlinks pointing into Client_Data. Pick a folder outside the program's data directory (e.g. E:\Backups).
If /api/system/login has set a password, the backup walks each Bank/Fracked .bin and:
- Adds already-encrypted files verbatim (whatever key they were under).
- Re-encrypts plaintext files on the fly through a scratch tempfile under the current login key, so the ZIP never contains plaintext when the user is logged in. Counts surface in the response (
files_reencrypted_for_backup,files_added_plaintext). - Adds plaintext files verbatim if no key is set (the user has not logged in).
Response
Returns a JSON object with backup details including the full path to the created ZIP file.
Response Properties
"wallet-backup".true on a 200 response."Default").{destination}\{wallet_name}_backup.zip..bin files added to the ZIP across Bank and Fracked..bin files found inside a wallet folder. Should always be 0; multi-coin is export-only. A non-zero count is logged and indicates a bug elsewhere.Example Response (logged in, Bank had plaintext remnants)
{
"command": "wallet-backup",
"success": true,
"wallet_path": "E:\\Client_Data\\Wallets\\Default",
"wallet_name": "Default",
"zip_path": "E:\\Backups\\Default_backup.zip",
"destination": "E:\\Backups",
"files_added": 45,
"files_skipped": 0,
"files_reencrypted_for_backup": 45,
"files_added_plaintext": 0,
"files_added_multi_warned": 0,
"message": "Wallet backup created successfully"
}
Error Responses
Missing destination parameter (400 Bad Request)
{
"status": "error",
"error": "Missing required parameter: destination",
"error_code": 1
}
Destination directory does not exist (400 Bad Request)
{
"error": true,
"message": "Destination directory does not exist",
"code": 400
}
Destination inside Client_Data (400 Bad Request)
The destination canonicalized into the program's Client_Data directory (or a subdirectory). Pick a folder outside of it.
{
"error": true,
"message": "Backup destination cannot be inside Client_Data — choose a folder outside the program's data directory",
"code": 400
}
Destination path could not be canonicalized (400 Bad Request)
Returned when the destination cannot be resolved (e.g. broken symlink, malformed path).
{
"error": true,
"message": "Destination path could not be resolved",
"code": 400
}
Cannot create backup directory (500 Internal Server Error)
{
"status": "error",
"error": "Cannot create backup directory",
"error_code": 101
}
Failed to create ZIP archive (500 Internal Server Error)
{
"status": "error",
"error": "Failed to create backup zip file",
"error_code": 101
}
Examples
JavaScript (fetch)
const API_HOST = 'http://localhost:8080';
async function backupWallet(walletPath, destinationPath) {
try {
const params = new URLSearchParams({
wallet_path: walletPath,
destination: destinationPath
});
const response = await fetch(`${API_HOST}/api/wallets/backup?${params}`, {
method: 'POST'
});
const result = await response.json();
if (result.success) {
console.log('Backup created successfully!');
console.log(`Wallet: ${result.wallet_name}`);
console.log(`ZIP Path: ${result.zip_path}`);
console.log(`Files Added: ${result.files_added}`);
console.log(`Message: ${result.message}`);
} else {
console.error('Backup failed:', result.message || result.error);
}
return result;
} catch (error) {
console.error('Error creating backup:', error);
throw error;
}
}
// Usage - Windows
backupWallet('E:\\Client_Data\\Wallets\\Default', 'E:\\Backups');
// Usage - Linux/macOS
// backupWallet('E:/Client_Data/Wallets/Default', '/home/user/backups');
cURL
# Windows example
curl -X POST "http://localhost:8080/api/wallets/backup?wallet_path=E:/Client_Data/Wallets/Default&destination=E:/Backups"
# Linux/macOS example
# curl -X POST "http://localhost:8080/api/wallets/backup?wallet_path=E:/Client_Data/Wallets/Default&destination=/home/user/backups"
Go
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
const ApiHost = "http://localhost:8080"
type BackupResponse struct {
Status string `json:"status"`
Operation string `json:"operation"`
Wallet string `json:"wallet"`
Destination string `json:"destination"`
Filename string `json:"filename"`
FullPath string `json:"full_path"`
Message string `json:"message"`
}
type ErrorResponse struct {
Status string `json:"status"`
Error string `json:"error"`
ErrorCode int `json:"error_code"`
}
func backupWallet(walletPath, destination string) (*BackupResponse, error) {
// Build URL with query parameters
params := url.Values{}
params.Add("wallet_path", walletPath)
params.Add("destination", destination)
url := fmt.Sprintf("%s/api/wallets/backup?%s", ApiHost, params.Encode())
req, err := http.NewRequest("POST", url, nil)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
// Check for error response
if resp.StatusCode != http.StatusOK {
var errResp ErrorResponse
if err := json.Unmarshal(body, &errResp); err != nil {
return nil, fmt.Errorf("failed to parse error response: %w", err)
}
return nil, fmt.Errorf("backup failed: %s (code %d)", errResp.Error, errResp.ErrorCode)
}
var result BackupResponse
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
return &result, nil
}
func main() {
// Windows example
walletPath := "E:\\Client_Data\\Wallets\\Default"
destination := "E:\\Backups"
// Linux/macOS example
// walletPath := "E:/Client_Data/Wallets/Default"
// destination := "/home/user/backups"
result, err := backupWallet(walletPath, destination)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Backup created successfully!\n")
fmt.Printf("Wallet: %s\n", result.Wallet)
fmt.Printf("Filename: %s\n", result.Filename)
fmt.Printf("Full Path: %s\n", result.FullPath)
fmt.Printf("Message: %s\n", result.Message)
}
Backup Process Details
The backup process follows these steps:
- Validate Parameters: Checks that destination path is provided and not empty
- Verify Active Wallet: Ensures a wallet is currently active
- Generate Filename: Creates timestamped filename with format: CloudCoin-Wallet-Backup_{wallet_name}_{YYYY-MM-DD}.zip
- Create Directory: Creates destination directory if it doesn't exist (with appropriate permissions)
- Archive Wallet: Uses platform-specific ZIP compression (PowerShell on Windows, zip command on Linux/Unix)
- Verify Success: Checks that ZIP file was created successfully
- Return Details: Returns JSON response with full path and metadata
The backup filename includes both the wallet name and date for easy identification. Example: CloudCoin-Wallet-Backup_Default_2025-01-31.zip
This makes it simple to track multiple backups across different wallets and dates.
Restoring from Backup
To restore a wallet from a backup ZIP file:
- Extract ZIP: Unzip the backup file to a new directory
- Add Location: Use
/api/wallets/locationsto register the extracted wallet - Verify Balance: Use
/api/wallets/balancewith the restoredwallet_pathto confirm all coins are present
After restoring a wallet, verify the coin count and balance match the pre-backup state. You may want to run /api/wallets/show-coins to inspect individual coins.
Related Endpoints
/api/wallets/locations
Register a new wallet location or restore a wallet from backup by adding its extracted directory.
/api/wallets/show-coins
View all coins in a wallet before creating a backup to verify contents. Requires wallet_path.
/api/wallets/balance
Check wallet balance before and after backup/restore to verify coin integrity. Requires wallet_path.