Getting started
What you will build¶
- Authenticate to the shared Sophos Fusion GraphQL endpoint.
- List the AI activity that AI Defense observed in your tenant since Monday.
- Request the next page with a cursor.
Prerequisites¶
- A service principal (API credentials) for your tenant.
- Read the guide for your account type before you continue:
- Sophos Partners: Getting started as a Partner
- Enterprise customers managing multiple tenants: Getting started as an Organization
- Other customers: Getting started as a Tenant
Get credentials¶
Follow the audience guide above to create a service principal. Exchange it for a bearer token with the client_credentials grant.
Queries need permission to read AI Defense data. updateSecureAITenantSettings needs permission to write it.
First authenticated call¶
Send a POST request to the GraphQL endpoint. Put the token in the Authorization header and your tenant ID in X-Tenant-ID.
The activities query returns activity that matches its filter. This call asks for the 10 most recent activities since 00:00 UTC on Monday of the current week.
curl -X POST "https://api.taegis.sophos.com/graphql" \
-H "Authorization: Bearer <jwt>" \
-H "X-Tenant-ID: <tenant-id>" \
-H "Content-Type: application/json" \
-d '{
"query": "query ListActivities($filter: SecureAiActivityFilter, $sort: SortInput, $first: Int64, $after: String) { activities(filter: $filter, sort: $sort, first: $first, after: $after) { totalCount pageInfo { hasNextPage endCursor } activities { id timestamp { startTime endTime } action risk policy actor { id name } application { id name } device { id name } } } }",
"variables": {
"filter": {
"timeRange": { "relative": "SINCE_BEGINNING_OF_WEEK_MONDAY" }
},
"sort": { "field": "TIMESTAMP", "order": "DESC" },
"first": 10
}
}'
A successful response looks like this:
{
"data": {
"activities": {
"totalCount": 348,
"pageInfo": {
"hasNextPage": true,
"endCursor": "<cursor>"
},
"activities": [
{
"id": "<activity-id>",
"timestamp": {
"startTime": "2026-10-15T14:02:11Z",
"endTime": "2026-10-15T14:05:40Z"
},
"action": "BLOCKED",
"risk": "HIGH",
"policy": "Block unsanctioned AI chat apps",
"actor": { "id": "<actor-id>", "name": "<user-name>" },
"application": { "id": "<application-id>", "name": "<application-name>" },
"device": { "id": "<device-id>", "name": "<device-name>" }
}
]
}
}
}
Verify it worked¶
Check data.activities.totalCount in the response. It is the number of activities that match your filter on all pages.
If you do not set filter.timeRange, the query returns activity since the start of the current day. Set either relative or startTime and endTime, not both.
A request that fails at the GraphQL layer returns HTTP 200 with an errors array. An expired token or a rate limit returns a non-2xx status before the query reaches the GraphQL layer.
What to do next¶
- Browse the AI Defense Activity GraphQL API reference for every query and mutation, or go to its types.
- Use
activitywith an activity ID to get one activity and its enrichment data. - Use
appInventoryanduserInventoryto list the AI applications and users in your tenant. UseuserAppsto list the applications that one user used. - Use
inventorySummaryto get the total number of AI applications and users. - Use
secureAITenantSettingsto read your AI Defense settings. UseupdateSecureAITenantSettingsto change them. The mutation changes only the sections that you send.
Get the next page¶
The activities query uses cursor pagination. The default page size is 20.
To get the next page, send the same query again. Set after to the endCursor value from the previous page. Stop when pageInfo.hasNextPage is false.
The inventory queries use offset pagination. Set limit and offset, and use hasNextPage in the response to find out if more entries exist.
Selection-set cost¶
Request only the fields you need. Keep each page small to control the response size.
- The
activitiesquery always returns an emptyadditionalDataobject. To get enrichment data, such as source IP addresses, use theactivityquery for one activity.
The AI Defense services do not set their own query depth or complexity limit. This guide cannot confirm the limits that the federated GraphQL endpoint applies. Keep nested selections narrow, and request only the pages you need.