Finalizing the skill to "done, no errors, all skill rules": - errorlog compliance: gz.py no longer logs EXPECTED API responses (validation, method-not-found, not-configured, rate-limit, expected state) or `raw`/selftest runs to errorlog.md. Per CLAUDE.md "do not log expected/handled conditions". Verified: selftest + probes leave errorlog unchanged. - moveCustomGroup: param is `parentId`, not `newParentId` (6th doc-vs-live fix caught by a full param-shape audit). - ASCII-clean code: removed all non-ASCII (em-dashes, U+21D2 arrow) from scripts (avoids cp1252 encode errors; aligns with the ASCII-markers rule). - api-reference updated. Verified: 18/18 read commands rc=0 live; selftest 75/75; parser builds; ASCII markers + vault load + errorlog helper present. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
19 KiB
Bitdefender GravityZone Cloud Public API Reference
Authoritative product + API docs: GravityZone Support Center — https://www.bitdefender.com/business/support/en/77211-79436-welcome-to-gravityzone.html (everything about the product and the Public API). Use it to confirm any UNVERIFIED method/param below before relying on it.
Verified spec for the methods used by this skill. Sourced from Bitdefender's
archived Public API documentation. Methods are flagged VERIFIED (signature
confirmed and exposed in the CLI) or UNVERIFIED (signature not confirmed —
callable only via the generic raw subcommand, never exposed as a dedicated CLI
command).
Connection
- Base URL:
https://cloud.gravityzone.bitdefender.com/api/v1.0/jsonrpc - Module endpoint:
<base>/<module>(e.g..../jsonrpc/network) - Auth: HTTP Basic. Username = API key, password = empty string
"". - Transport: HTTPS POST,
Content-Type: application/json.
JSON-RPC envelope (request)
{
"id": "1",
"jsonrpc": "2.0",
"method": "<methodName>",
"params": { ...method params... }
}
Response
- Success: body has a
resultfield. The skill returnsbody["result"]. - Error: body has an
errorobject. The skill surfaceserror.data.detailsif present, elseerror.message.
{ "error": { "code": -32602, "message": "...", "data": { "details": "..." } } }
ACG tenant IDs (hardcoded, partner root)
| Constant | Value | Meaning |
|---|---|---|
ACG_ROOT_COMPANY_ID |
5c4280716c0318f3478b456a |
ACG partner company root |
ACG_COMPANIES_CONTAINER_ID |
5c4280716c0318f3478b456e |
Container holding all client companies |
In getNetworkInventoryItems results, type == 1 denotes a company node.
general (/general)
| Method | Params | Status | Notes |
|---|---|---|---|
getApiKeyDetails |
{} |
VERIFIED | Key scopes / rights. |
licensing (/licensing)
| Method | Params | Status | Notes |
|---|---|---|---|
getLicenseInfo |
{} |
VERIFIED | Seats, expiry, usage. CLI status. |
getMonthlyUsage |
{} |
VERIFIED LIVE | endpoint/encryption/email/mobile monthly usage. CLI monthly-usage. |
getMonthlyUsagePerCompany |
— | DOES NOT EXIST | "method not found". |
integrations (/integrations)
| Method | Params | Status | Notes |
|---|---|---|---|
getConfiguredIntegrations |
page?, perPage? |
VERIFIED LIVE | Configured third-party integrations (empty live). CLI integrations. |
getPSAIntegrationList / getIntegrationsList |
— | DOES NOT EXIST | wrong names; "method not found". |
packages (detail)
| Method | Params | Status | Notes |
|---|---|---|---|
getPackageDetails |
packageId (req) |
VERIFIED (probe) | Installation package detail. CLI package-details. |
companies (/companies) — COMPLETE (6 methods; no updateCompany/getCompaniesList)
updateCompanyandgetCompaniesListreturn "method not found" — they do NOT exist. Enumerate companies vianetwork.getNetworkInventoryItems(thecompaniesCLI cmd).type: 0=Partner, 1=Customer.
| Method | Params | Status | Notes |
|---|---|---|---|
getCompanyDetails |
{} or {companyId} |
VERIFIED LIVE | Own company when no arg. CLI company [id]. |
getCompanyDetailsByUser |
username |
VERIFIED LIVE | Company that owns a user. CLI company-by-user. |
createCompany |
type (req), name (req), parentId?, address?, country?, state?, phone?, industry?, canBeManagedByAbove?, assignedProductType?, licenseSubscription{type,reservedSlots,endSubscription,autoRenewPeriod,...} |
VERIFIED (docs + probe) | CLI company-create, gated. STATE-CHANGING. Docs: 77211-126236-createcompany.html |
suspendCompany |
companyId |
VERIFIED (probe) | CLI company-suspend, gated. STATE-CHANGING. |
activateCompany |
companyId |
VERIFIED (probe) | CLI company-activate, gated. STATE-CHANGING. |
deleteCompany |
companyId |
VERIFIED (probe) | CLI company-delete, gated. STATE-CHANGING. |
network (/network)
| Method | Params | Status | Notes |
|---|---|---|---|
getNetworkInventoryItems |
parentId?, page?, perPage?, filters? |
VERIFIED | Inventory tree: companies/groups/endpoints. type==1 = company. |
getEndpointsList |
parentId?, page?, perPage<=100, filters?, options? |
VERIFIED | Endpoint list under a parent. filters supports name / OS / security status / policy. |
getManagedEndpointDetails |
endpointId, options? |
VERIFIED | Full detail: malwareStatus, agent{productVersion,engineVersion,signatureOutdated,productOutdated,lastUpdate}, modules, state, policy, companyId, lastSeen. |
getScanTasksList |
name?, status?, page?, perPage? |
VERIFIED | List scan tasks. |
createScanTask |
targetIds[], type, name?, customScanSettings? |
VERIFIED | Start a scan. type: 1=Quick, 2=Full, 3=Memory, 4=Custom (verify against console). |
moveEndpoints |
endpointIds[], groupId |
VERIFIED | Move endpoints into a group. |
createCustomGroup |
name, parentId? |
VERIFIED | Create a custom group; returns new group id. |
deleteEndpoint |
endpointId |
VERIFIED (destructive) | Remove an endpoint from inventory. CLI-gated behind --confirm. |
deleteCustomGroup |
groupId |
VERIFIED (destructive) | Delete a custom group. CLI-gated behind --confirm. |
moveCustomGroup |
groupId, parentId (NOT newParentId — verified live) |
VERIFIED | Re-parent a custom group. |
assignPolicy |
policyId, targetIds[], forcePolicyInheritance?, inheritFromAbove? |
VERIFIED (docs+probe) | CLI assign-policy, gated. See policies section. |
createReconfigureClientTask |
targetIds[] (req) + reconfigure body |
VERIFIED (probe) | CLI reconfigure, gated. STATE-CHANGING. |
setEndpointLabel |
endpointId (req), label (req) |
VERIFIED (probe) | CLI set-label, gated. STATE-CHANGING. |
getEndpointTags |
{} |
VERIFIED LIVE | List endpoint tags (returns a list). CLI endpoint-tags. |
createUninstallTask + variants |
— | DOES NOT EXIST | No uninstall-task method under /network in this API version (createUninstallTask / createUninstallClientTask / createUninstallRoleTask / uninstallClientTask all "method not found"). Uninstall via the console. |
getEndpointsByPolicy, getManagedEndpointDetailsByIp, createScanTaskByMailboxes |
— | DOES NOT EXIST | "method not found" on this tenant/version. |
packages (/packages)
| Method | Params | Status | Notes |
|---|---|---|---|
getPackagesList |
page?, perPage<=100 |
VERIFIED | List installation packages. |
createPackage |
packageName, companyId?, description?, language?, modules?, scanMode?, settings?, roles?, deploymentOptions? |
VERIFIED | Create an installer package. Returns the new package id. |
getInstallationLinks |
packageName, companyId? |
VERIFIED | Returns Windows / Mac / Linux installer download URLs for a package. |
deletePackage |
packageName, companyId? |
VERIFIED (destructive) | Delete a package. CLI-gated behind --confirm. |
policies (/policies) — FULL READ + ASSIGN (authoring is console-only)
Corrected 2026-06-21: the earlier "shallow only" claim was WRONG.
getPolicyDetailsreturns the COMPLETE granular module configuration (general/antimalware/firewall/content-control/etc.), confirmed live on a real policy. You CAN: list policies, read the full config, and assign an existing policy to endpoints/groups (network.assignPolicy, param shape now verified). You still CANNOT create / edit / clone a policy body via the Public API — authoring stays in the GravityZone console.
| Method | Params | Status | Notes |
|---|---|---|---|
getPoliciesList |
page?, perPage? |
VERIFIED | List policies (id, name). |
getPolicyDetails |
policyId |
VERIFIED | Full granular config (not shallow). |
assignPolicy (/network) |
policyId, targetIds[], inheritFromAbove:false (REQUIRED w/ policyId), forcePolicyInheritance? |
VERIFIED LIVE 2026-06-21 | Assigning a policyId REQUIRES inheritFromAbove:false in the same call or the API rejects with a misleading "inheritFromAbove should not be used" error. {targetIds, inheritFromAbove:true} (no policyId) = make target inherit. CLI assign-policy, gated. |
reports (/reports) — COMPLETE
| Method | Params | Status | Notes |
|---|---|---|---|
getReportsList |
page?, perPage? |
VERIFIED LIVE | List saved reports. CLI reports. |
createReport |
name (req), type, targetIds, recurrence/format... |
VERIFIED (probe) | CLI report-create --name [--extra-json], gated. STATE-CHANGING. |
getDownloadLinks |
reportId (req) |
VERIFIED (probe) | Report download links. CLI report-links --id. |
deleteReport |
reportId (req) |
VERIFIED (probe) | CLI report-delete --id, gated. STATE-CHANGING. |
getReportConfiguration |
— | DOES NOT EXIST | "method not found". |
accounts (/accounts) — COMPLETE (all 7 methods wrapped)
| Method | Params | Status | Notes |
|---|---|---|---|
getAccountsList |
page?, perPage? |
VERIFIED LIVE | List console accounts/users. CLI accounts. |
getAccountDetails |
accountId? |
VERIFIED LIVE | No id ⇒ the API key's own account. CLI account [id]. |
getNotificationsSettings |
{} |
VERIFIED LIVE | Notification config. CLI notif-settings. |
createAccount |
email (req), userName, password, role, profile{fullName,language,timezone}, phoneNumber{countryCode,subscriberNumber}, rights{manageInventory,managePoliciesRead/Write,...} |
VERIFIED (docs + probe) | CLI account-create, gated. STATE-CHANGING. Docs: 77212-125284-createaccount.html |
updateAccount |
accountId (req) + fields |
VERIFIED (probe) | CLI account-update --id --set-json, gated. STATE-CHANGING. |
deleteAccount |
accountId (req) |
VERIFIED (probe) | CLI account-delete --id, gated. STATE-CHANGING. |
configureNotificationsSettings |
settings object (NO required field — empty payload is accepted) | VERIFIED (probe) | CLI notif-configure --settings-json, gated. STATE-CHANGING. ⚠ never probe with {} on a live tenant — it is a setter. |
push (/push) — event push service (VERIFIED reachable)
Powers event-driven alerting (GravityZone POSTs security events to a receiver you specify) instead of polling
sweep.get/statserror with "…were not set" until configured — that is an EXPECTED unconfigured state, handled cleanly by the CLI (rc0 + INFO), NOT a failure.
| Method | Params | Status | Notes |
|---|---|---|---|
getPushEventSettings |
{} |
VERIFIED LIVE | Current settings. CLI push-settings. |
getPushEventStats |
{} |
VERIFIED LIVE | Delivery stats. CLI push-stats. |
sendTestPushEvent |
eventType (req) |
VERIFIED (probe) | Fire a test event to the configured receiver. CLI push-test --event-type, gated. |
setPushEventSettings |
status (req), serviceType, serviceSettings{url,requireValidSslCertificate,authorization}, subscribeToEventTypes{<event flags>} |
VERIFIED (official docs + probe) | Configure the service. serviceType ∈ splunk/cef/jsonRPC. Receiver MUST support TLS 1.2+. subscribeToEventTypes is a map of event flags (av, fw, aph, registration, task-status, modules, network-sandboxing, antiexploit, dp, uc, …) set true to subscribe. Returns bool. CLI push-set, gated. STATE-CHANGING. Needs a receiver URL. Docs: 77209-135319-setpusheventsettings.html |
Receiver pattern for the webhook (Phase-2): stand up an HTTPS endpoint (TLS 1.2+, valid cert) that accepts GravityZone's event POSTs — a coord-API route or an RMM ingest route — then
push-set --status 1 --url <that-endpoint> --confirm.serviceType jsonRPCposts JSON-RPC event batches.
quarantine (/quarantine)
| Method | Params | Status | Notes |
|---|---|---|---|
getQuarantineItemsList |
companyId, page, perPage, filters? |
VERIFIED LIVE | Service-scoped path quarantine/computers. CLI quarantine --company. |
createRemoveQuarantineItemTask |
quarantineItemsIds (req) |
VERIFIED (probe) | Path quarantine/computers. CLI quarantine-remove --items, gated. STATE-CHANGING. |
createRestoreQuarantineItemTask |
quarantineItemsIds (req), addExclusionInPolicy? |
VERIFIED (probe) | CLI quarantine-restore --items [--extra-json], gated. STATE-CHANGING. |
incidents (/incidents) — EDR / incident response
The incidents module backs the EDR controls: endpoint isolation, the hash blocklist, and the incident list. READ methods are safe; the state-changing methods (isolate / restore / blocklist add+remove) are CLI-gated behind
--confirm.isolateandaddToBlocklist/removeFromBlocklistare NEW destructive verbs — therawsubcommand also gates any method whose name containsisolat,addtoblocklist, orremovefromblocklist.
| Method | Params | Status | Notes |
|---|---|---|---|
getBlocklistItems |
companyId?, page?, perPage? |
VERIFIED LIVE | Returns {total, page, perPage, pagesCount, items:[{id, source, sourceInfo, hashType, hash, companyId}]}. Returned 26 items live. perPage defaults to 100 in the CLI. companyId scopes to one company; omit for the whole tenant. |
getIncidentsList |
parentId, page?, perPage (500-10000), filters? |
UNVERIFIED / possibly unavailable | parentId = a company/group id and is REQUIRED. perPage must be 500-10000 (the API rejected 100 with "Invalid value for 'perPage' parameter. The value should be between 500 and 10000"); the CLI defaults it to 500. However, live re-testing on 2026-05-30 returned Method not found for this method on the /incidents module, while getBlocklistItems on the SAME module succeeds in the same request — so this is NOT rate-limiting or a bad key. The method is likely gated behind an EDR/incidents license feature that is OFF on this tenant, or is named differently in this API version. The CLI incidents subcommand is wired up but will surface Method not found until the feature is enabled / the correct name is confirmed. |
createIsolateEndpointTask |
endpointId (SINGLE) |
VERIFIED LIVE 2026-06-21 | Takes ONE endpointId per call (NOT an endpointIds array — that errors "not expected"). Client loops for multiple. Cuts endpoint off network (BD mgmt link preserved). CLI isolate, gated. |
createRestoreEndpointFromIsolationTask |
endpointId (SINGLE) |
VERIFIED LIVE 2026-06-21 | One endpointId per call. FAILS if the isolation task is still in progress ("cannot be restored") — wait + retry. CLI unisolate, gated. |
addToBlocklist |
companyId, hashType, hashList[], sourceInfo, operatingSystems? |
VERIFIED (destructive) | hashType is an int (1 is the common value seen live; see the console / API docs for the full mapping). hashList is an array of hash strings. sourceInfo is a free-text description. CLI-gated behind --confirm. |
removeFromBlocklist |
hashItemId (UNVERIFIED param name) |
VERIFIED method, UNVERIFIED param | Removes one blocklist entry. The param name hashItemId is UNVERIFIED — the id field from getBlocklistItems is the candidate. Confirm against the official API reference before relying on it. CLI-gated behind --confirm; the CLI --id value comes from blocklist output. |
getCustomRulesList |
page?, perPage? |
VERIFIED LIVE | EDR custom rules (returned 1 live). CLI custom-rules. |
createCustomRule |
name (req), settings/companyId/tags via extra |
VERIFIED (probe) | CLI custom-rule-create, gated. STATE-CHANGING. |
deleteCustomRule |
ruleId (req) |
VERIFIED (probe) | CLI custom-rule-delete --id, gated. STATE-CHANGING. |
changeIncidentStatus |
type (req) + id/status |
VERIFIED (probe) | CLI incident-status --type --set-json, gated. STATE-CHANGING. |
updateIncidentNote |
type (req) + id/note |
VERIFIED (probe) | CLI incident-note --type --set-json, gated. STATE-CHANGING. |
EDR custom rules + incident status/note ARE available on this tenant even though
getIncidentsListis not (that one method is feature-gated/renamed).
Dead / unavailable modules on this tenant (probed 2026-06-21)
In the API-key scope but NOT usable — calls return "not available" / "method not found". Do not build against these without a license/feature change:
patchmanagement— license OFF (managePatchManagement: false). "not available".phasr— license/feature OFF.getStatus→ method not found.maintenancewindows—getMaintenanceWindows(List)→ "not available".integrations— PARTLY ALIVE:getConfiguredIntegrationsworks (wrapped);getPSAIntegrationList/getIntegrationsListare wrong names (not found).incidents.getIncidentsList— "Method not found" (yetgetBlocklistItemsand the isolate tasks on the SAME module work — likely an EDR sub-feature gate).
Verified vs Unverified summary
VERIFIED (CLI-exposed):
general.getApiKeyDetails, licensing.getLicenseInfo, companies.getCompanyDetails,
network.getNetworkInventoryItems, network.getEndpointsList,
network.getManagedEndpointDetails, network.getScanTasksList,
network.createScanTask, network.createCustomGroup, network.moveEndpoints,
network.moveCustomGroup, network.deleteEndpoint (gated),
network.deleteCustomGroup (gated), packages.getPackagesList,
packages.createPackage, packages.getInstallationLinks, packages.deletePackage
(gated), policies.getPoliciesList, policies.getPolicyDetails,
quarantine.getQuarantineItemsList, incidents.getBlocklistItems,
incidents.createIsolateEndpointTask (gated),
incidents.createRestoreEndpointFromIsolationTask (gated),
incidents.addToBlocklist (gated), incidents.removeFromBlocklist (gated;
param name UNVERIFIED), network.getScanTasksList, network.assignPolicy (gated;
param shape verified 2026-06-21), reports.getReportsList, accounts.getAccountsList,
accounts.getNotificationsSettings, push.getPushEventSettings,
push.getPushEventStats, push.setPushEventSettings (gated; status verified,
nested shape UNVERIFIED).
NOTE:
incidents.getIncidentsListis wired into the CLI (incidentssubcommand) but returnedMethod not foundon live re-test (2026-05-30) — see the incidents module table. Likely a license-gated EDR feature that is OFF on this tenant. Not counted as VERIFIED LIVE.
UNVERIFIED (raw subcommand only — do NOT trust the param shape): network.assignPolicy, network.createReconfigureClientTask, network.createUninstallTask, network.setEndpointLabel, companies.getCompanyDetailsByUser, quarantine.createRemoveQuarantineItemTask, quarantine.createRestoreQuarantineItemTask, incidents.changeIncidentStatus, incidents.updateIncidentNote, incidents.createCustomRule, incidents.getCustomRulesList, incidents.deleteCustomRule (destructive). Whole modules raw-only/UNVERIFIED: patchmanagement (license OFF), integrations, maintenancewindows.
Confirm any UNVERIFIED signature against the official Bitdefender API reference
before relying on it. The generic raw --module M --method m --params '<json>'
subcommand can call any method once you know the correct params.