Reference companion to AGENTS.md. Use this file when an LLM needs to answer "how do I do X with this library" quickly, without reading every source file.
client, err := vsax.NewClient(vsax.Config{
ServerName: "vsax.example.com",
TokenID: os.Getenv("VSAX_TOKEN_ID"),
TokenSecret: os.Getenv("VSAX_TOKEN_SECRET"),
})Everything else hangs off client.<Service>.<Method>.
- List pages: every list endpoint exposes both
List(ctx, *Query) (*PagedResult[T], error)andAll(ctx, *Query) iter.Seq2[T, error]. PreferAllunless you need access toMeta.TotalCountor manual page control. - Single-item get:
Get(ctx, id)— device IDs arestringGUIDs; org/site/group IDs areint64. - Create:
Create(ctx, *XRequest) (*X, error)— always pass a typed*XRequestbody. - Run-style endpoints (workflows, tasks, scripts):
Run(ctx, id, *RunXRequest); passnilwhen no parameters are needed. - Sub-resource lists (e.g.
Devices.Notifications): mirror the sameList/AllFoopair.
vsax.NewQuery().Top(100) // $top=100
vsax.NewQuery().Skip(100) // $skip=100
vsax.NewQuery().Count(true) // $count=true
vsax.NewQuery().OrderBy("Name desc") // $orderby=Name desc
vsax.NewQuery().Filter("GroupId eq 5") // raw $filter
vsax.NewQuery().Filter(vsax.Field("Name").Contains("web"))
vsax.NewQuery().ScopeID(42) // scopeId=42 (devices only)
vsax.NewQuery().Include(vsax.IncludeSecurity) // assets only
vsax.NewQuery().Set("deviceId", "guid") // escape hatch for arbitrary paramsField(name) methods: Eq, Ne, Gt, Ge, Lt, Le, Contains, StartsWith, EndsWith. Compose with vsax.And(a, b), vsax.Or(a, b), vsax.Not(a).
| Sentinel | Typical cause |
|---|---|
vsax.ErrUnauthorized |
invalid/expired token (401) |
vsax.ErrForbidden |
authenticated but lacks permissions (403) |
vsax.ErrNotFound |
resource doesn't exist (404) |
vsax.ErrBadRequest |
validation failure (400) |
vsax.ErrServer |
500/502/503/504 |
if errors.Is(err, vsax.ErrNotFound) { /* ... */ }
var ve *vsax.ValidationError
if errors.As(err, &ve) {
log.Printf("bad request: %s", ve.Base.Message)
}These return flexible JSON payloads that vary by tenant config:
| Endpoint | Wrapper | Unwrap |
|---|---|---|
/patchmanagement/policies/{id} |
PolicyDocument |
doc.As(&myPolicy) |
/patchmanagement/globalrules |
PolicyDocument |
doc.As(&rules) |
/endpointprotection/policies/{id} |
PolicyDocument |
doc.As(&policy) |
/environment |
Environment (typed; License is json.RawMessage) |
env.DecodeLicense(&lic) |
/groups/{id}/package/{type} |
GroupPackage (typed Name, Url) |
direct |
/customfields/{id}/usage |
paged []CustomFieldUsageEntry |
direct |
/scopes/{id}/usage |
paged []ScopeUsageEntry |
direct |
PolicyDocument wraps raw JSON via Raw json.RawMessage. Round-trip safely — if you re-marshal the wrapper, you get the original JSON back.
The VSA X surface has a few path shapes worth knowing:
- Automation lives under
/automation/:/automation/workflows,/automation/tasks,/automation/scripts. - Workflow executions are addressed by execution ID alone (no workflow ID in the path):
/automation/workflows/executions/{id}.Workflows.Executions()lists executions across all workflows — filter byWorkflowIdto scope to one. - Workflow cancellation is a bulk POST:
POST /automation/workflows/executions/cancelwith{ "ExecutionIds": [...] }. UseWorkflows.CancelExecutions(ids...). - Task executions are addressed by execution ID only:
/automation/tasks/executions/{id}. Sub-resources:/devices,/devices/{deviceId}/scripts,/devices/{deviceId}/scripts/{scriptId}. - Script executions live under a script + device + execution tuple:
/automation/scripts/{scriptId}/device/{deviceId}/executions[/{executionId}]. - Notification webhooks are under
/notifications/webhooks(note the/— not a single/notificationwebhooksword). - Custom fields use camelCase in the path:
/customFields,/customFields/{id}/assign,/customFields/{id}/updateAssigned,/customFields/{id}/unassign. - Audit logs are under
/auditlogs(plural).
DeviceService.Publish registers or updates a device and can populate the "details" view with tabs of labels and webhook commands:
client.Devices.Publish(ctx, &vsax.PublishDevice{
InstanceID: "my-instance-123",
GroupID: 42,
Name: "Widget",
Contents: []vsax.PublishDeviceTab{{
Name: "Status",
Contents: []vsax.PublishDeviceEntry{
{Type: "label", Title: "State", Subtitle: "Running", Icon: "information"},
{Type: "webhook_command", Title: "Restart", CallbackURL: "https://my.app/restart"},
},
}},
NextRefreshIntervalMinutes: 15,
})Valid Type values: "label", "webhook_command". Valid Icon: "information", "warning", "error".
The test suite uses httptest.NewServer and disables retries (MaxRetries: &zero) so tests run fast. When adding tests for new endpoints, mirror that pattern.
- The VSA X docs HTML is the only spec. No OpenAPI/Swagger.
- Rate-limit behaviour is undocumented — client does exponential backoff for 5xx, but no token-bucket throttling.
- Patch-management and endpoint-protection response shapes are tenant/OS dependent. Prefer
As(dst)with a struct you've verified against real responses; fall back toRawwhen structure is unknown.