Securely automate the Sophos Fusion Endpoint API
The Sophos Fusion Endpoint API is the tenant API for endpoint and server resources. It inventories devices and, depending on the endpoint and permission, can manage scans, isolation, groups, policies, exclusions, tags and software assignments. Write access affects protection operations; a read-only identity is sufficient for inventory queries.
The safe short path is: use an API Credential with the minimum role, obtain a token through the OAuth2 client credentials flow, discover the tenant ID and regional host, test GET /endpoint/v1/endpoints first, and process every page and error.
Boundary with Sophos Fusion Admin and other APIs
Creating, storing, rotating and deleting service principals is a shared Sophos Fusion Admin task. The complete process is therefore covered centrally in Manage Sophos Fusion API credentials securely rather than duplicated here.
Partner and organization tenant lists, alerts, Audit Events, Account Health, cases and Live Discover also do not automatically belong to the Endpoint API. Sophos Fusion (formerly Sophos Central) provides separate APIs for these areas, with their own roles and limits. This article covers only requests below the regional /endpoint/v1 base path.
Authentication and request context
The linked owner article exclusively defines the token request and response contract, whoami, partner and Enterprise tenant lists, host validation, and secret handling. Carry SOPHOS_ACCESS_TOKEN, SOPHOS_TENANT_ID, and SOPHOS_API_HOST from that process without alteration. scope=token does not replace authorization: the service principal role, tenant access, licence, and selected Endpoint permission also apply; Partner Assistance or Enterprise Admin Management must permit the target tenant.
Make a harmless read request
This example invents neither a token nor tenant data. It expects three values from your own credential and discovery process and writes the first page to a local file:
: "${SOPHOS_ACCESS_TOKEN:?Bearer token is missing}"
: "${SOPHOS_TENANT_ID:?Tenant ID is missing}"
: "${SOPHOS_API_HOST:?Regional API host is missing}"
umask 077
curl --fail-with-body --silent --show-error --get \
"${SOPHOS_API_HOST}/endpoint/v1/endpoints" \
--header "X-Tenant-ID: ${SOPHOS_TENANT_ID}" \
--data-urlencode "pageSize=50" \
--output endpoints-page.json \
--config - <<EOF
header = "Authorization: Bearer ${SOPHOS_ACCESS_TOKEN}"
EOF
Take SOPHOS_API_HOST unchanged from whoami or the tenant list. Supply the token to the process from a secret store; do not put it in the script, shell history, command arguments, tickets or debug logs. The standard-input config keeps the expanded bearer header out of curl’s argument list, while umask 077 restricts permissions on the new output file. --fail-with-body exposes an HTTP error, but the saved response must still be protected as potentially sensitive inventory data.
A successful HTTP status confirms only the request. Next confirm that the file contains valid JSON, the expected tenant was queried, and the required devices are present. No sample response is shown here that could be mistaken for an observed response.
Choose Endpoint paths deliberately
Endpoint v1 includes these paths:
GET /endpoint/v1/endpointsandGET /endpoint/v1/endpoints/{endpointId}for inventory and details;POST /endpoint/v1/endpoints/{endpointId}/scansto request a scan;POST /endpoint/v1/endpoints/tamper-protectionfor targeted Tamper Protection changes on up to 200 devices;POST /endpoint/v1/endpoints/reset-healthfor a health/alert reset on up to 500 supported devices;/endpoint/v1/endpoint-groupsfor computer and server groups;/endpoint/v1/policiesfor endpoint, server and Device Encryption policies;POST /endpoint/v1/tags/assignmentfor tag assignments;- endpoints for isolation, allowed or blocked items, exclusions, Web Control, software packages and endpoint migrations.
Use the HTTP method and complete path shown above; do not substitute similar-looking legacy paths. Before writing, check the request schema, required role and permission, platform and licence boundary, status codes, and operation-specific rate limit on the selected endpoint.
Change Tamper Protection and health selectively with bulk requests
The two bulk operations supplement existing Endpoint v1 calls; they do not require a migration. Both use the discovered regional host, bearer token, the target tenant’s X-Tenant-ID and Content-Type: application/json. Each requires the endpoint-state:update permission. A read-only identity is insufficient; first check that the service principal’s role includes this permission in the target tenant.
Tamper Protection: The JSON body for POST /endpoint/v1/endpoints/tamper-protection contains ids with 1–200 unique endpoint UUIDs and at least one of the boolean fields enabled or regeneratePassword. enabled: true requests enablement; enabled: false requests disablement. regeneratePassword: true requests new device passwords. The schema uses anyOf, not oneOf: both fields can therefore be supplied together. For traceable maintenance changes, nevertheless plan state changes and password regeneration separately and send only the intended fields. Password regeneration is neither a local four-hour override nor a shared password for all devices.
Before disabling protection: Use only the approved set of IDs and record each device’s initial state, maintenance end time and responsible person. API disablement has no documented automatic four-hour return path. After maintenance, request enablement for exactly the devices you disabled and verify its effect. The local and per-device maintenance methods often remain the better choice for individual devices.
First read GET /endpoint/v1/endpoints/{endpointId}?view=full and include only devices with confirmed tamperProtectionSupported: true; a missing value is not approval. The health reset’s Windows/Linux boundary does not establish platform support for Tamper Protection. Check the global switch with GET /endpoint/v1/settings/tamper-protection: if it is off, enabling individual devices does not restore protection. GET /endpoint/v1/endpoints/{endpointId}/tamper-protection returns the intended enabled state, but also password and, where applicable, previousPasswords. Do not log this response in full. Passwords belong neither in tickets nor in debug logs; rotation cannot be undone by writing the old password back.
Reset Health: POST /endpoint/v1/endpoints/reset-health expects a JSON body with the required ids field: 1–500 unique endpoint UUIDs. Windows computers, Windows servers and Linux are supported, but macOS is not.
Before resetting: The operation sets health status to green and deletes all alerts for the affected endpoints. First preserve relevant findings, alert details and audit evidence outside the view that will be cleared, and obtain explicit approval for deletion. The reset does not remove malware or repair a faulty protection service. A green status after this intervention is not proof that the underlying cause has been resolved; the reset contract provides no undo operation to restore deleted alerts.
After an approved pilot request, read the device details again, check health status and alerts in Sophos Fusion, and verify actual protection functionality separately. Investigate new alerts rather than hiding them with repeated resets.
Accepted does not mean completed
For both bulk operations, HTTP 202 means only that the request was processed and acceptance assessed per ID. items contains accepted requests with id, status: requested and requestedAt; errors contains rejected requests with id, errorCode and errorMessage. requestedAt is not a completion timestamp. Reconcile every submitted ID with these results; missing or contradictory mappings remain unresolved even if the HTTP status indicates success.
The error codes are notFound, notSupported, conflict, permissionDenied and internalError. For the first four, correct the ID/tenant, device support, state or permission first, as applicable. Even internalError is not permission to resend the entire batch. For HTTP errors, evaluate the error response; a 202 can contain both accepted and rejected IDs.
Then confirm the effect separately: after successful device contact, read endpoint details with view=full and, for Tamper Protection, the settings as well, then check protection locally. Evaluate lastSeenAt, tamperProtectionEnabled or health.overall, health.threats and health.services, as appropriate. Reading back an intended state alone does not confirm implementation on an offline device. Set a bounded polling interval and an overall timeout for checks; without confirmation, document the run as open and investigate device connectivity or errors.
A write request may already have been accepted after a timeout or lost connection. Do not retry blindly: first reconcile state and available evidence per ID. Otherwise, another password rotation or alert reset could change states that have arisen in the meantime. Authorize another attempt only for subsets demonstrably rejected and safe to repeat after correction; set unresolved IDs aside for manual review.
Groups, tags, software and policies
Groups control policy assignment and remain within the tenant hierarchy. Tags complement inventory and search. A tag key is 1–40 characters and a value 0–40 characters, with no colon in either. An endpoint can have at most 15 tags, and one key can have only one value on an endpoint. One assignment request accepts at most 1,000 endpoint UUIDs and can return per-endpoint partial failures, so the client must evaluate every returned endpoint status.
For Device Software, Protection, Encryption and ZTNA are separate categories. Computers support all three; servers support Protection only in this workflow. A request accepts at most 1,000 IDs in each computer or server block. Valid software IDs depend on the specific endpoint, catalogue and licence. Use only IDs returned by a prior read request for that exact endpoint; do not apply All, None or guessed IDs without validation.
For policies, preserve the type, settings, assignments and priority before changing anything. Base Policies and additional policies do not support the same operations. Change only fields that the current tenant object exposes as writable and unlocked. A PATCH contains only deliberately reviewed keys; an old complete object must not overwrite settings added later.
Pagination, limits and error handling
Endpoint lists use key-based pagination: load the first page without pageFromKey, then pass the previous response’s pages.nextKey for each following page. Other Endpoint resources use page-based pagination. pageSize has a different maximum by operation; endpoints default to 50, while Endpoint Groups document a maximum of 500. Follow the selected endpoint’s schema and stop only when there is no next key or page.
The global Sophos Fusion API limits are:
- 10 calls per second: recommended;
- 100 per minute: enforced, with short bursts up to 300 allowed;
- 1,000 per hour: recommended;
- 200,000 per day: enforced.
Stricter operation-specific limits take precedence. Sophos applies the first three limits separately to the credentials, account and originating IP; the daily quota applies to the account and credentials, not the originating IP. Do not use multiple credentials or IPs to circumvent a limit.
For read requests that are safe to repeat, handle 429 Too Many Requests and 5xx with bounded exponential backoff and random jitter. This does not apply to writes across the board: if acceptance is unclear, check the effect per object first. For 400, 401, 403, 404 and 409, correct the request, token, role, ID or state first. Bulk endpoints can return error lists despite HTTP 200 or 202, so evaluate success and failure per object and retry only failed parts that are safe to repeat.
Roll out write access safely
- Verify tenant, regional host, pagination and filters with a read-only credential.
- Select the smallest documented role and permission for the exact operation.
- Read and preserve the current state and affected IDs as change evidence.
- Make exactly one change to a pilot group or test device.
- Evaluate the complete API response and verify the effect on the device or in Central.
- Expand only afterwards; handle rollback, credential expiry,
429and partial failures in advance.
The specific operational rules for Endpoint groups and device inventory, policy order and Live Discover still apply. The supported process for moving already protected endpoints to another tenant is covered separately and must not be inferred from a generic API example.
Frequently asked questions
Is scope=token sufficient for every Endpoint request?
scope=token belongs to the OAuth token request. The role, tenant access, licence and operation-specific permissions additionally determine whether Sophos permits an Endpoint request.Why are devices missing although the first request succeeded?
pages.nextKey, filters, tenant ID and regional host, then read every page.