Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vsax

A Go client library for the Kaseya VSA X REST API (v3). Provides typed access to devices, device assets, automation (workflows, tasks, scripts), notifications, webhooks, organizations, sites, groups, custom fields, scopes, patch and endpoint-protection policies, environment info, and audit logs, with a fluent OData query builder and automatic pagination.

Installation

go get github.com/scjalliance/vsax

Requires Go 1.25+ (uses iter.Seq2 range-over-func iterators).

Quick Start

client, err := vsax.NewClient(vsax.Config{
    ServerName:  "vsax.example.com", // tenant host (no scheme, no /api/v3)
    TokenID:     os.Getenv("VSAX_TOKEN_ID"),
    TokenSecret: os.Getenv("VSAX_TOKEN_SECRET"),
})
if err != nil {
    log.Fatal(err)
}

ctx := context.Background()
for dev, err := range client.Devices.All(ctx, vsax.NewQuery().Top(100)) {
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%s  %s  (group %d)\n", dev.Identifier, dev.Name, dev.GroupID)
}

Authentication

VSA X uses HTTP Basic auth over HTTPS, with a token ID as username and a token secret as password.

client, err := vsax.NewClient(vsax.Config{
    ServerName:  "vsax.example.com",
    TokenID:     "TOKEN_ID",
    TokenSecret: "TOKEN_SECRET",
})

Tokens are generated from the VSA X admin UI. Requests are rejected over plain HTTP.

Base URL

ServerName is the tenant hostname. The client targets https://<ServerName>/api/v3 automatically.

For testing or non-standard deployments, set BaseURL to override the full URL (scheme + /api/v3 path required):

cfg := vsax.Config{BaseURL: "https://staging.example.com/api/v3", TokenID: "...", TokenSecret: "..."}

Query Builder

VSA X uses OData-style list parameters ($top, $skip, $filter, $orderby, $count). The fluent Query type builds them safely:

q := vsax.NewQuery().
    Top(100).
    Skip(0).
    Filter("contains(tolower(Name),'web')").
    OrderBy("Name").
    Count(true)

For common cases, Field generates filter strings with correct quoting:

q := vsax.NewQuery().
    Filter(vsax.Field("GroupId").Eq(123))

// Boolean
q := vsax.NewQuery().
    Filter(vsax.Field("IsAgentInstalled").Eq(true))

// String contains (OData function)
q := vsax.NewQuery().
    Filter(vsax.Field("Name").Contains("web"))

// Combining
q := vsax.NewQuery().
    Filter(vsax.And(
        vsax.Field("OrganizationId").Eq(5),
        vsax.Field("IsOnline").Eq(true),
    ))

Filterable / sortable properties are endpoint-specific — see the VSA X docs per-endpoint.

Pagination

List endpoints accept $top (limit) and $skip (offset). The server emits Meta.NextQueryLink when total results exceed 5000 items. The All iterator follows it transparently:

for site, err := range client.Sites.All(ctx, nil) {
    if err != nil { log.Fatal(err) }
    process(site)
}

For page-level control:

page, err := client.Devices.List(ctx, vsax.NewQuery().Top(500).Count(true))
fmt.Printf("total: %d\n", page.Meta.TotalCount)

// Range over items in this page + follow NextQueryLink
for d, err := range page.Iter(ctx) {
    if err != nil { break }
    process(d)
}

// Collect all remaining pages into a slice
all, err := page.Collect(ctx)

Resources

Core

Service Operations
Devices List, All, Get, Publish, Move, Notifications, AllNotifications, Antivirus, CustomFields, AppliedPolicies
Assets List, All, ForDevice (with Include* section selectors)
Workflows List, All, Get, Run, Executions, AllExecutions, Execution, CancelExecutions
Tasks List, All, Get, Run, Execution, ExecutionDevices, AllExecutionDevices, ExecutionScripts, ScriptOutput
Scripts List, All, Get, Run, Executions, AllExecutions, Execution
Notifications List, All, Get, Create, Delete
NotificationWebhooks List, All, Get, Create, Update, Delete, RegenerateSecretKey

Organization Structure

Service Operations
Organizations List, All, Get, Create, Update, Delete, CustomFields
Sites List, All, Get, Create, Update, Delete, CustomFields
Groups List, All, Get, Create, Update, Delete, CustomFields, Package(id, pkgType)
CustomFields List, All, Get, Usage, AllUsage, Assign, UpdateAssignment, Unassign
Scopes List, All, Get, Usage, AllUsage

Policies / Environment / Audit

Service Operations
PatchManagement Policy(id), GlobalRules()
EndpointProtection Policy(id)
Environment Get()
AuditLog List, All

Policy endpoints (PatchManagement.Policy, PatchManagement.GlobalRules, EndpointProtection.Policy) return a PolicyDocument wrapping raw JSON because the schema varies by policy kind. Use doc.As(&myStruct) to decode it.

Environment.Get returns a typed Environment for the common fields (ProductVersion, CustomerId, CustomerName, ServerType, Language) and keeps the License block as json.RawMessage. Call env.DecodeLicense(&myLicense) to decode it into a tenant-specific struct.

Include Parameter (Assets)

GET /assets supports a comma-separated include selector. Use the Include* constants with Query.Include:

q := vsax.NewQuery().Top(100).Include(
    vsax.IncludeAvailableUpdates,
    vsax.IncludeSecurity,
    vsax.IncludeAssetInfo,
    vsax.IncludeLocalIPAddresses,
)
page, err := client.Assets.List(ctx, q)

The constants for the available sections:

Constant Section
IncludeTags Tags
IncludeUpdates Updates
IncludeAvailableUpdates AvailableUpdates
IncludeSecurity Security
IncludeAssetInfo AssetInfo
IncludeIPAddresses IpAddresses
IncludeLocalIPAddresses LocalIpAddresses
IncludeDisks Disks
IncludeInstalledSoftware InstalledSoftware
IncludeNone (no optional sections)

When include is not set, VSA X defaults to Tags, Updates, AssetInfo, IpAddresses, LocalIpAddresses, Disks, InstalledSoftware.

Error Handling

4xx and 5xx responses return typed errors. Callers can either switch on type or use errors.Is against sentinel errors.

_, err := client.Devices.Get(ctx, "missing-guid")
if err != nil {
    switch {
    case errors.Is(err, vsax.ErrUnauthorized):
        log.Fatal("invalid or expired token")
    case errors.Is(err, vsax.ErrForbidden):
        log.Printf("permission denied")
    case errors.Is(err, vsax.ErrNotFound):
        var nfe *vsax.NotFoundError
        errors.As(err, &nfe)
        log.Printf("%s %q missing", nfe.ResourceType, nfe.ResourceID)
    case errors.Is(err, vsax.ErrBadRequest):
        log.Printf("validation failed: %v", err)
    default:
        log.Printf("api error: %v", err)
    }
}

Transient errors (5xx, network) are retried with exponential backoff up to Config.MaxRetries times (default: 3).

Configuration

client, err := vsax.NewClient(vsax.Config{
    ServerName:     "vsax.example.com",    // tenant host
    TokenID:        "TOKEN_ID",            // required
    TokenSecret:    "TOKEN_SECRET",        // required
    BaseURL:        "",                    // optional: override full base URL (scheme + /api/v3)
    HTTPClient:     nil,                   // optional: custom http.Client
    MaxRetries:     nil,                   // optional: retry count (nil → 3; set to &zero to disable)
    DefaultTimeout: 30 * time.Second,      // optional: timeout applied when HTTPClient is nil
    UserAgent:      "my-app/1.0",          // optional: override User-Agent
})

CLI

cmd/vsa is a read-only CLI that wraps the client library. Useful for exploring a tenant and validating credentials without writing any code.

envwith -f .secrets/.env -- go run ./cmd/vsa whoami
envwith -f .secrets/.env -- go run ./cmd/vsa devices -org 123 -limit 100
envwith -f .secrets/.env -- go run ./cmd/vsa device <GUID>
envwith -f .secrets/.env -- go run ./cmd/vsa find web01
envwith -f .secrets/.env -- go run ./cmd/vsa audit -limit 20
envwith -f .secrets/.env -- go run ./cmd/vsa env

Required environment variables:

Variable Purpose
VSAX_SERVER Tenant hostname (e.g. tenant.vsax.net)
VSAX_TOKEN_ID API token ID
VSAX_TOKEN_SECRET API token secret

Run go run ./cmd/vsa with no args for the full command list.

Documentation

License

MIT.

About

Go client library for the Kaseya VSA X REST API (v3)

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages