Skip to content
Learni
View all tutorials
API & Automatisation

How to Automate Acronis Cyber Protect via API in 2026

Lire en français

Introduction

Acronis Cyber Protect is a leading cybersecurity and cloud backup platform, offering a powerful REST API for advanced automation. In 2026, with the rise of hybrid environments and zero-trust models, integrating this API lets you orchestrate critical tasks like automatic device discovery, backup plan creation, and incident monitoring from your CI/CD pipelines or Node.js scripts.

This advanced tutorial, designed for senior developers, guides you step by step through building a production-ready TypeScript client. We cover OAuth2 authentication, key endpoints (/devices, /backup_plans), error handling, and webhooks. Why is it crucial? API integration cuts manual interventions by 80%, minimizes vulnerability windows, and works natively with Kubernetes or Terraform. By the end, you'll have a functional script to list 100+ devices and deploy backups in one call. Ready to boost your cyber resilience? (142 words)

Prerequisites

  • Acronis Cyber Protect account with API access enabled (Admin or API User role).
  • Client ID and Secret generated via Console > Integrations > Applications.
  • Node.js 20+ and npm/yarn installed.
  • Advanced knowledge of TypeScript, async/await, and REST APIs.
  • Tool like Postman for testing endpoints (optional).

Initialize the Node.js Project

terminal
mkdir acronis-api-client && cd acronis-api-client
npm init -y
npm install axios dotenv typescript @types/node ts-node
npm install -D @types/axios

tsc --init --target es2022 --module commonjs --outDir dist --rootDir src --strict true --esModuleInterop true

mkdir src
cp node_modules/.bin/ts-node ./ts-node

cat > .env << EOF
ACRONIS_BASE_URL=https://us-cloud.acronis.com
ACRONIS_CLIENT_ID=your_client_id_here
ACRONIS_CLIENT_SECRET=your_client_secret_here
ACRONIS_TENANT_ID=your_tenant_id_here
EOF

This script sets up a Node.js project with strict TypeScript, installs axios for HTTP calls and dotenv for secrets. It creates a secure .env file with your Acronis credentials (obtained from the console). Pitfall to avoid: Never commit .env; add it to .gitignore. The tsconfig.json is optimized for ES2022 and CommonJS modules for maximum compatibility.

TypeScript Types for the Acronis API

src/types.ts
export interface AcronisToken {
  access_token: string;
  expires_in: number;
  token_type: 'Bearer';
  scope: string;
}

export interface AcronisDevice {
  id: string;
  name: string;
  type: 'server' | 'workstation' | 'mobile';
  status: 'online' | 'offline' | 'unknown';
  agent_version: string;
  last_seen: string;
}

export interface AcronisBackupPlan {
  id: string;
  name: string;
  enabled: boolean;
  retention_period: number;
  schedule: { frequency: 'daily' | 'weekly'; time: string };
}

export type AcronisError = {
  code: number;
  message: string;
  details?: any;
};

These TypeScript interfaces model Acronis API responses (based on the official v2 docs). They enable IntelliSense autocompletion and static validation. Analogy: Like a GraphQL schema, they prevent 90% of runtime errors. Add them early to scale your client.

OAuth2 Authentication Function

src/auth.ts
import axios from 'axios';
import * as dotenv from 'dotenv';
import { AcronisToken } from './types';

dotenv.config();

const BASE_URL = process.env.ACRONIS_BASE_URL || 'https://us-cloud.acronis.com';
const CLIENT_ID = process.env.ACRONIS_CLIENT_ID!;
const CLIENT_SECRET = process.env.ACRONIS_CLIENT_SECRET!;

let cachedToken: AcronisToken | null = null;
let tokenExpiry = 0;

export async function getAcronisToken(): Promise<AcronisToken> {
  if (cachedToken && Date.now() < tokenExpiry) {
    return cachedToken;
  }

  const tokenResponse = await axios.post(
    `${BASE_URL}/api/2/idp/tokens`,
    new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: CLIENT_ID,
      client_secret: CLIENT_SECRET,
      scope: 'urn:acronis:cloud:default',
    }),
    {
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    }
  );

  cachedToken = tokenResponse.data;
  tokenExpiry = Date.now() + (tokenResponse.data.expires_in - 300) * 1000;
  return cachedToken;
}

This function implements OAuth2 client_credentials flow with token caching (3600s TTL minus 5min buffer). It uses URLSearchParams for the form-encoded body, per Acronis standards. Pitfall: Without caching, you risk rate-limiting (100 req/min). Test with console.log(await getAcronisToken()).

List Devices in a Tenant

src/devices.ts
import axios from 'axios';
import { getAcronisToken } from './auth';
import { AcronisDevice, AcronisError } from './types';

const TENANT_ID = process.env.ACRONIS_TENANT_ID!;

const BASE_URL = process.env.ACRONIS_BASE_URL || 'https://us-cloud.acronis.com';

export async function listDevices(limit: number = 100): Promise<AcronisDevice[]> {
  try {
    const token = await getAcronisToken();
    const response = await axios.get(
      `${BASE_URL}/api/protect/v1/tenants/${TENANT_ID}/devices?limit=${limit}`,
      {
        headers: {
          Authorization: `Bearer ${token.access_token}`,
          'Content-Type': 'application/json',
        },
      }
    );
    return response.data.items || [];
  } catch (error: any) {
    const err = error.response?.data as AcronisError;
    throw new Error(`Failed to list devices: ${err?.message || error.message}`);
  }
}

// Usage exemple
(async () => {
  const devices = await listDevices(10);
  console.log(`Found ${devices.length} devices:`, devices.map(d => ({ name: d.name, status: d.status })));
})();

This module lists devices via GET /devices with pagination (limit). It propagates typed Acronis errors. Advanced: The main() script is self-executable for unit tests. Analogy: Like Kubernetes listing nodes, scalable to 10k+ devices.

Create a Backup Plan

src/backup-plans.ts
import axios from 'axios';
import { getAcronisToken } from './auth';
import { AcronisBackupPlan } from './types';

const TENANT_ID = process.env.ACRONIS_TENANT_ID!;
const BASE_URL = process.env.ACRONIS_BASE_URL || 'https://us-cloud.acronis.com';

export async function createBackupPlan(planName: string, deviceId: string, retentionDays: number = 30): Promise<AcronisBackupPlan> {
  const token = await getAcronisToken();

  const planPayload = {
    name: planName,
    enabled: true,
    retention_period: { days: retentionDays },
    schedule: {
      frequency: 'daily' as const,
      time: '02:00',
    },
    devices: [{ id: deviceId }],
    storage: { id: 'default_cloud' }, // Remplacez par votre storage ID
  };

  const response = await axios.post(
    `${BASE_URL}/api/protect/v1/tenants/${TENANT_ID}/backup_plans`,
    planPayload,
    {
      headers: {
        Authorization: `Bearer ${token.access_token}`,
        'Content-Type': 'application/json',
      },
    }
  );

  return response.data;
}

// Exemple
(async () => {
  const plan = await createBackupPlan('Daily Backup Plan', 'device-id-example');
  console.log('Created plan:', plan.id, plan.name);
})();

Creates a daily backup plan with customizable retention, assigned to a specific device. Payload matches Acronis v1 spec. Critical pitfall: Verify storage_id via /storages API first. Use in GitHub Actions pipelines for auto-deployment.

Main Orchestration Script

src/index.ts
import { listDevices } from './devices';
import { createBackupPlan } from './backup-plans';

async function main() {
  console.log('🚀 DĂ©marrage client Acronis API');
  
  const devices = await listDevices(5);
  if (devices.length === 0) {
    throw new Error('Aucun device trouvé. Vérifiez TENANT_ID.');
  }

  const criticalDevice = devices.find(d => d.status === 'online' && d.type === 'server');
  if (!criticalDevice) {
    throw new Error('Aucun serveur online trouvé.');
  }

  const plan = await createBackupPlan(`Auto-Plan-${new Date().toISOString().slice(0,10)}`, criticalDevice.id, 90);
  console.log(`✅ Backup plan créé pour ${criticalDevice.name}: ${plan.id}`);
}

main().catch(console.error);

This script orchestrates device listing plus conditional plan creation on the first online server. Ideal for cron jobs or Lambda. Advanced: Global error handling; extend with webhooks via /api/protect/v1/webhooks for real-time events.

Package.json and Running the Project

package.json
{
  "name": "acronis-api-client",
  "version": "1.0.0",
  "main": "dist/index.js",
  "scripts": {
    "dev": "ts-node src/index.ts",
    "build": "tsc",
    "start": "node dist/index.ts"
  },
  "dependencies": {
    "axios": "^1.7.2",
    "dotenv": "^16.4.5",
    "typescript": "^5.5.3"
  },
  "devDependencies": {
    "@types/node": "^22.3.0",
    "ts-node": "^10.9.2"
  }
}

Updates package.json with ready-to-use scripts. Run npm run dev to test instantly. Production: npm run build && npm start. Add nodemon for watch mode if needed.

Best Practices

  • Always secure tokens: Use Vault/SSM for production, rotate monthly.
  • Rate limiting: Implement exponential backoff (p-queue lib); Acronis limits to 100 req/min.
  • Structured logging: Integrate Winston or Pino to trace API calls with correlation IDs.
  • Unit tests: Mock axios with MSW; aim for 90% coverage (jest + msw).
  • Secure webhooks: Validate HMAC signatures for backup failed events.

Common Errors to Avoid

  • Missing scope: Forgetting urn:acronis:cloud:default blocks auth (401 Unauthorized).
  • Wrong Tenant ID: Check via Console > Tenants; causes 404 on /devices.
  • Expired token without refresh: Without caching, 50% of calls fail; always implement TTL.
  • Malformed payload: Use JSON Schema for validation; Acronis returns detailed 400s but breaks pipelines.

Next Steps

Dive deeper with the full Acronis API docs. Integrate with Kubernetes via custom operator or community Terraform provider. Check out our Learni training on DevOps & Cybersecurity for advanced certs. Contribute on GitHub: fork this repo and add /alerts endpoint!