Skip to main content

Veeam v13 REST API Automation: Authentication, Job Orchestration, and Monitoring

  • April 1, 2026
  • 4 comments
  • 54 views

eblack
Forum|alt.badge.img+1

 

1. What the REST API Is and Why It Matters

Veeam Backup and Replication v13 exposes its entire operational surface through a REST API running on port 9419 over HTTPS. This is not the Enterprise Manager REST API. This is the VBR server's own API, available on every VBR installation without Enterprise Manager deployed. The distinction matters because the two APIs have different endpoints, different authentication models, and different capability sets. If you are reading Veeam documentation and see references to the EM REST API, that is a separate thing entirely.

The VBR REST API uses OAuth 2.0 bearer token authentication, returns JSON, and conforms to OpenAPI Specification 3.0. The full spec is available as a swagger.json file in the VBR installation directory and through the built-in Swagger UI at https://<vbr-server>:9419/api/swagger/ui/index.html. The current API revision for v13.0.1 is 1.3-rev1.

Why use it instead of the PowerShell module? Three reasons. First, the REST API is language-agnostic. You can call it from Python, Go, Bash with curl, a monitoring platform webhook, or an automation tool like n8n or Ansible. Second, it does not require the Veeam PowerShell module to be installed on the machine making the call. Third, for MSPs running VSPC v9, REST API proxying lets you route API calls through VSPC to all managed VBR servers using a single API key, which is significantly cleaner than managing PowerShell remoting sessions across dozens of backup servers.

TWO APIS, TWO PORTS

The VBR REST API runs on port 9419. The Enterprise Manager REST API runs on port 9398 (by default). They are not interchangeable. This article covers the VBR REST API exclusively.


 

2. Prerequisites and Connectivity

The REST API service starts automatically with VBR. No additional installation or configuration is required. During the VBR install, a self-signed TLS certificate is generated and bound to port 9419. If you are calling the API from a script, you will need to either trust that certificate or skip certificate validation in your HTTP client.

Requirements

1. VBR v13.0.1 or later installed and running. The REST API was introduced in v11 but v13.0.1 massively expanded the endpoint coverage.

2. Network access to port 9419/TCP on the VBR server from the machine running your scripts.

3. A Veeam user account with appropriate RBAC role. Backup Administrator for full access, Backup Operator for read-only monitoring.

4. An HTTP client. PowerShell with Invoke-RestMethod, curl, Python requests, or any tool that speaks HTTPS.


 

Verify connectivity before writing any code:

curl -k https://<vbr-server>:9419/api/v1/serverTime


 

If this returns a JSON response with the server version and time, the API service is running and reachable. If it times out, check your firewall rules for port 9419.

3. Authentication: OAuth 2.0 Token Flow

Every API call requires a bearer token in the Authorization header. You get that token by posting credentials to the OAuth 2.0 token endpoint. The token has a default lifetime of 15 minutes. The refresh token lasts 24 hours by default regardless of the use_short_term_refresh parameter (this is a known behavior in v13.0.1 that does not match the documentation's stated formula of access token lifetime plus 15 minutes).

Getting an Access Token (curl)

TOKEN=$(curl -sk -X POST "https://<vbr-server>:9419/api/oauth2/token" \

-H "Content-Type: application/x-www-form-urlencoded" \

-H "x-api-version: 1.3-rev1" \

-d "grant_type=password&username=DOMAIN%5Cusername&password=YourPassword" \

| jq -r '.access_token')

 

echo $TOKEN


 

The response includes access_token, refresh_token, and expires_in (in seconds). Save the refresh token. When the access token expires, use the refresh token to get a new pair without re-authenticating with credentials.

Getting an Access Token (PowerShell)

$vbrServer = "vbr01.yourdomain.local"

$cred = Get-Credential -Message "VBR credentials"

 

$body = @{

grant_type = "password"

username = $cred.UserName

password = $cred.GetNetworkCredential().Password

}

 

$auth = Invoke-RestMethod -Uri "https://${vbrServer}:9419/api/oauth2/token" `

-Method Post -Body $body -SkipCertificateCheck `

-Headers @{ "x-api-version" = "1.3-rev1" }

 

$token = $auth.access_token

$refresh = $auth.refresh_token

 

$headers = @{

"Authorization" = "Bearer $token"

"x-api-version" = "1.3-rev1"

"Accept" = "application/json"

}


 

Refreshing an Expired Token

$refreshBody = @{

grant_type = "refresh_token"

refresh_token = $refresh

}

 

$newAuth = Invoke-RestMethod -Uri "https://${vbrServer}:9419/api/oauth2/token" `

-Method Post -Body $refreshBody -SkipCertificateCheck `

-Headers @{ "x-api-version" = "1.3-rev1" }

 

$token = $newAuth.access_token

$refresh = $newAuth.refresh_token

$headers["Authorization"] = "Bearer $token"


 

SECURITY NOTE

Never hardcode credentials in scripts. Use Get-Credential, environment variables, or a secrets manager. For scheduled scripts, store the refresh token in a secure vault and use it to obtain new access tokens without storing the password.


 

Authorization Code Delegation

The v13 API also supports an authorization code grant type for delegating access between clients. Client A (which has a valid token) requests a temporary authorization code from /api/oauth2/authorization_code. Client B exchanges that code for its own access token. The code expires in 60 seconds. This is useful for scenarios where a central orchestrator needs to hand off API access to a worker process without sharing the original credentials.

4. Core Endpoints: Jobs, Sessions, and Repositories

The API organizes resources into logical sections. Here are the endpoints you will use most often for monitoring and orchestration.

Endpoint

Method

What It Returns

/api/v1/jobs

GET

All configured backup, replication, and copy jobs with schedule, type, and enabled state

/api/v1/jobs/{id}

GET

Single job detail including virtual machines in the job scope

/api/v1/sessions

GET

Job sessions with status, start/end time, result, and bottleneck data

/api/v1/backups

GET

All backup chains with restore point count, size, and repository location

/api/v1/repositories

GET

Backup repositories with type, capacity, free space, and path

/api/v1/managedServers

GET

Managed infrastructure servers (vCenter, Hyper-V hosts, Linux servers)

/api/v1/credentials

GET

Credential records stored on the backup server

/api/v1/configBackup

GET

Configuration backup settings and last run status

/api/v1/encryptionPasswords

GET

Encryption password records (not the passwords themselves)

/api/v1/malwareDetection

GET

Malware detection events from SureBackup scan sessions


 

All collection endpoints support pagination with skip and limit query parameters, filtering with nameFilter (supports wildcards), and type filtering with typeFilter. For example, to get only failed job sessions:

GET /api/v1/sessions?typeFilter=Job&resultFilter=Failed&limit=50


 

5. Triggering and Managing Backup Jobs

Starting a backup job through the API is a POST to the job's start endpoint. The job runs asynchronously. The API returns a session ID that you can poll to track progress.

Start a Job

# Start a backup job by ID

$jobId = "c36824e9-0c3e-4892-8dff-44fd56968506"

 

Invoke-RestMethod -Uri "https://${vbrServer}:9419/api/v1/jobs/${jobId}/start" `

-Method Post -Headers $headers -SkipCertificateCheck


 

Stop a Running Job

Invoke-RestMethod -Uri "https://${vbrServer}:9419/api/v1/jobs/${jobId}/stop" `

-Method Post -Headers $headers -SkipCertificateCheck


 

Poll Session Status

# Get the most recent session for a specific job

$sessions = Invoke-RestMethod `

-Uri "https://${vbrServer}:9419/api/v1/sessions?jobIdFilter=${jobId}&limit=1" `

-Method Get -Headers $headers -SkipCertificateCheck

 

$latest = $sessions.data[0]

Write-Host "State: $($latest.state) | Result: $($latest.result)"


 

Session states include Working, Idle, and Stopped. Results include Success, Warning, Failed, and None (while still running).

6. Building a Health Check Script

This script authenticates, pulls all job sessions from the last 24 hours, and flags anything that did not succeed. This is the foundation for any monitoring integration.

param(

[Parameter(Mandatory)]

[string]$VBRServer,

[Parameter(Mandatory)]

[PSCredential]$Credential

)

 

# Authenticate

$authBody = @{

grant_type = "password"

username = $Credential.UserName

password = $Credential.GetNetworkCredential().Password

}

$auth = Invoke-RestMethod -Uri "https://${VBRServer}:9419/api/oauth2/token" `

-Method Post -Body $authBody -SkipCertificateCheck `

-Headers @{ "x-api-version" = "1.3-rev1" }

 

$headers = @{

"Authorization" = "Bearer $($auth.access_token)"

"x-api-version" = "1.3-rev1"

}

 

# Pull sessions from the last 24 hours

$since = (Get-Date).AddHours(-24).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")

$allSessions = @()

$skip = 0

$pageSize = 100

 

do {

$batch = Invoke-RestMethod `

-Uri "https://${VBRServer}:9419/api/v1/sessions?typeFilter=Job&limit=${pageSize}&skip=${skip}" `

-Method Get -Headers $headers -SkipCertificateCheck

$allSessions += $batch.data

$skip += $pageSize

} while ($batch.data.Count -eq $pageSize)

 

# Filter to last 24 hours

$recent = $allSessions | Where-Object {

$_.creationTime -ge $since

}

 

# Report

$failed = $recent | Where-Object { $_.result -eq "Failed" }

$warning = $recent | Where-Object { $_.result -eq "Warning" }

$success = $recent | Where-Object { $_.result -eq "Success" }

 

Write-Host "=== VBR Health Check: $VBRServer ==="

Write-Host "Period: Last 24 hours"

Write-Host "Total sessions: $($recent.Count)"

Write-Host "Success: $($success.Count) | Warning: $($warning.Count) | Failed: $($failed.Count)"

 

if ($failed.Count -gt 0) {

Write-Host "`nFailed Jobs:" -ForegroundColor Red

$failed | ForEach-Object {

Write-Host " - $($_.name) | Started: $($_.creationTime)" -ForegroundColor Red

}

}

 

if ($warning.Count -gt 0) {

Write-Host "`nWarning Jobs:" -ForegroundColor Yellow

$warning | ForEach-Object {

Write-Host " - $($_.name) | Started: $($_.creationTime)" -ForegroundColor Yellow

}

}


 

To integrate this with a monitoring platform, replace the Write-Host output with a webhook call, SNMP trap, or syslog message. The data is the same. The delivery mechanism is up to you.

7. Repository Capacity Monitoring

Repository capacity is one of the most common things you need to track programmatically. The /api/v1/repositories endpoint returns total and free space for each repository.

$repos = Invoke-RestMethod `

-Uri "https://${VBRServer}:9419/api/v1/repositories" `

-Method Get -Headers $headers -SkipCertificateCheck

 

foreach ($repo in $repos.data) {

$totalGB = [math]::Round($repo.capacityGB, 1)

$freeGB = [math]::Round($repo.freeGB, 1)

$usedPct = if ($totalGB -gt 0) {

[math]::Round((($totalGB - $freeGB) / $totalGB) * 100, 1)

} else { 0 }

 

$color = if ($usedPct -gt 90) { "Red" }

elseif ($usedPct -gt 75) { "Yellow" }

else { "Green" }

 

Write-Host "$($repo.name): ${usedPct}% used (${freeGB} GB free of ${totalGB} GB)" `

-ForegroundColor $color

}


 

For SOBR extents, the parent SOBR object in the API response includes references to its performance and capacity tier extents. Query each extent individually for granular capacity data.

8. Encryption Password Verification

This is one of the most operationally valuable endpoints added in v13.0.1. It lets you programmatically verify that an encryption password stored in VBR is still correct. If you have ever been in the position of needing to restore encrypted backups and not being certain the stored password is valid, this endpoint solves that problem before it becomes a crisis.

# List all encryption passwords

$passwords = Invoke-RestMethod `

-Uri "https://${VBRServer}:9419/api/v1/encryptionPasswords" `

-Method Get -Headers $headers -SkipCertificateCheck

 

foreach ($pw in $passwords.data) {

# Verify each password

$verifyBody = @{ password = "your-known-password" } | ConvertTo-Json

 

try {

$result = Invoke-RestMethod `

-Uri "https://${VBRServer}:9419/api/v1/encryptionPasswords/$($pw.id)/verify" `

-Method Post -Headers ($headers + @{ "Content-Type" = "application/json" }) `

-Body $verifyBody -SkipCertificateCheck

 

Write-Host "PASS: $($pw.description)" -ForegroundColor Green

}

catch {

Write-Host "FAIL: $($pw.description)" -ForegroundColor Red

}

}


 

COMPLIANCE USE CASE

Schedule this verification weekly. Export the results to a log. Auditors want proof that your encryption keys are valid and that you can actually decrypt your backups. This script provides that evidence automatically.


 

9. Malware Detection Scan Logs

When SureBackup runs a malware scan against restore points, the results are available through the /api/v1/malwareDetection endpoints. This is the API surface for building automated clean room verification reporting.

# Get malware detection events

$events = Invoke-RestMethod `

-Uri "https://${VBRServer}:9419/api/v1/malwareDetection/events" `

-Method Get -Headers $headers -SkipCertificateCheck

 

foreach ($event in $events.data) {

$status = if ($event.detectionType -eq "Clean") { "CLEAN" } else { "DETECTED" }

Write-Host "$status | $($event.machineName) | $($event.detectionTime)"

}

 

# Get detailed scan session log for a specific task

$scanLog = Invoke-RestMethod `

-Uri "https://${VBRServer}:9419/api/v1/malwareDetection/scanSessionLog/$taskSessionId" `

-Method Get -Headers $headers -SkipCertificateCheck


 

Pair this with the encryption password verification from the previous section and the health check script to build a comprehensive daily compliance report that covers job success, backup integrity, encryption key validity, and malware scan results. All from the same API surface.

10. REST API vs PowerShell: When to Use Which

The VBR PowerShell module and the REST API overlap in capability but serve different use cases. Neither replaces the other entirely.

Scenario

Best Tool

Why

Remote monitoring from a non-Windows system

REST API

No PowerShell module or Windows dependency required

Multi-server monitoring through VSPC

REST API

VSPC v9 REST API proxying routes calls through a single key

Integration with Grafana, PRTG, or n8n

REST API

HTTP calls are natively supported in every monitoring platform

Complex job creation with all options

PowerShell

PowerShell cmdlets expose every job parameter. REST API job creation is more limited.

Bulk operations on local VBR server

PowerShell

Faster iteration. No token management overhead.

Tape job management

PowerShell

Tape endpoints are not yet fully covered in the REST API as of v13.0.1

Agent job management

PowerShell

Agent job types were limited in REST API through v12.x. Coverage is expanding in v13 but PowerShell is still more complete.


 

The general rule: use the REST API when you need remote, cross-platform, or multi-server access. Use PowerShell when you need full feature coverage on a single VBR server and you are already running on Windows.

11. Operational Gotchas

The x-api-version header is mandatory. Every request to the VBR REST API must include x-api-version: 1.3-rev1 (for v13.0.1). Omit it and you get a 400 Bad Request. This catches everyone the first time.

Self-signed certificate handling. The default VBR install uses a self-signed TLS cert on port 9419. In PowerShell, use -SkipCertificateCheck. In curl, use -k. In production, replace the self-signed cert with one from your internal CA and bind it to port 9419 using netsh http add sslcert. The Veeam help center documents the exact binding command.

Token refresh behavior in v13.0.1. The documentation states that the refresh token lifetime is the access token lifetime plus 15 minutes. In practice, the refresh token consistently expires at 24 hours regardless of the use_short_term_refresh flag. This is a known community-reported behavior. Build your token refresh logic around a 24-hour window, not the documented formula.

Pagination is not optional for large environments. Collection endpoints default to returning a limited set of results. Always implement pagination with skip and limit parameters in a loop until the returned count is less than your page size. If you have 500 jobs and you pull the default page, you will miss data.

REST API coverage is still expanding. Not every VBR feature has a REST API endpoint yet. Veeam has stated they are adding coverage with every release. As of v13.0.1, the API covers vSphere backup jobs, Hyper-V backup jobs, replication jobs, VCD jobs, managed servers (VMware, Windows, Linux), repositories, sessions, credentials, encryption, malware detection, configuration backup, and the mass deployment automation endpoints. Plug-in workloads (Nutanix AHV, Proxmox, oVirt, HyperCore) and NAS backup jobs have limited or no REST API coverage yet.

Username encoding. When passing domain credentials in the token request body, backslash characters must be URL-encoded as %5C. The value DOMAIN\username becomes DOMAIN%5Cusername in the POST body.

Rate limiting. There is no documented rate limit on the VBR REST API, but hammering a VBR server with thousands of requests per minute will impact the Veeam.Backup.Service process. For monitoring scripts, a polling interval of 60 seconds or longer is sensible. For one-shot health checks, run them once and exit.

Key Takeaways

The VBR REST API runs on port 9419, separate from the Enterprise Manager API on 9398

Authentication uses OAuth 2.0 with bearer tokens. Access tokens expire in 15 minutes. Refresh tokens last 24 hours in practice.

The x-api-version header (1.3-rev1 for v13.0.1) is required on every request

Core endpoints cover jobs, sessions, repositories, credentials, encryption passwords, and malware detection events

Encryption password verification and malware scan logs are the two most operationally valuable endpoints added in v13.0.1

The Swagger UI at port 9419 is a live, interactive reference that lets you test calls directly against your VBR server

Use the REST API for remote and cross-platform monitoring. Use PowerShell when you need full feature coverage on a local Windows VBR server.

Always implement pagination for collection endpoints in environments with more than a handful of jobs


 

Published on anystackarchitect.com | Author: Eric Black | Veeam v13 Series

4 comments

Chris.Childerhose
Forum|alt.badge.img+21

Very interesting use of the API for jobs. Thanks for sharing this one.


eblack
Forum|alt.badge.img+1
  • Author
  • Influencer
  • April 1, 2026

Very interesting use of the API for jobs. Thanks for sharing this one.

I make use of 8,9 a fair amount. Thanks for reading. 


coolsport00
Forum|alt.badge.img+21
  • Veeam Legend
  • April 1, 2026

I like this Eric! I will look at putting a couple of those to use. Appreciate you sharing this content.


wolff.mateus
Forum|alt.badge.img+11
  • Veeam Vanguard
  • April 2, 2026

Its good to see API working.

I have not been in touch with this before
Tks for share ​@eblack