SentinelOne API Reference Console
A self-contained developer portal and API reference tool for SentinelOne integrations. Provides endpoint documentation, code samples, authentication guidance, rate limit reference, a mock API explorer, and GraphQL playground — all in a single offline-capable HTML file.
What Is This Tool
The SentinelOne API Reference Console is a static, single-file developer portal for engineers building or maintaining SentinelOne integrations. Unlike the operational dashboards in this suite (Keeper, FortiGate), this console does not fetch live data from any vendor API. It is a reference and learning tool — an offline-capable developer portal that replaces the need to navigate multiple documentation pages.
It is part of the KrawTech Stack Dashboard Suite and shares the suite's design system and code conventions, with a special distinction: instead of live data polling, it provides the documentation and tooling needed to build the integrations that drive other dashboards.
This is the only tool in the KrawTech suite that is purely static. No real API calls are made under any configuration. The "live stats" on the home page are animated demo counters only.
Console Type
This is a static API reference portal. It does not poll any API for operational data. The suite-pattern functions (loadDashboard(), startAutoRefresh(30000), refreshAll()) are present for suite consistency and govern the home page animated stat counters only — they do not call SentinelOne endpoints in any mode.
Architecture
The console is a single-file static HTML application — no server, no build step, no external dependencies beyond Google Fonts. It can be opened directly from disk or served from any static host. All 30+ documentation pages are sections within a single file, shown/hidden by the go(id) navigation function.
All 30+ pages are <section class="page"> elements. Only one has class="page on" at a time. The sidebar calls go(id) which adds/removes the on class and scrolls the main container to top. Page IDs follow the pattern p-{name}; sidebar nav IDs follow n-{name}.
Top Bar
Fixed header at 56px height. Contains brand identity, a global search field, version badge, and avatar.
| Element | Behavior | Notes |
|---|---|---|
| S1 Logo block | Static — gradient purple box with "S1" | Shine animation loops every 4s |
| Brand name + subtitle | Static HTML — "SentinelOne / API Reference Console" | — |
| Search field (⌘K) | Keyword routing — Enter key triggers go() for matched section | Maps ~20 keywords to page IDs. No real search index. |
| v2.1 chip | Static version badge | Update manually when API version changes |
| Avatar (T1) | Static decorative — no click action | "Technician" tooltip on hover |
Home Page / Live Stats
The landing page of the console. Contains a scrolling threat feed ticker, four animated stat cards, navigation shortcut tiles, and a quick endpoint reference panel. All data displayed is simulated — no SentinelOne API calls are made.
The "Active Threats", "Agents Online", "API Calls/min", and "Events Today" counters animate from mock starting values and drift every 4 seconds. They are not sourced from GET /threats or GET /agents. See the Proxy Activation section for wiring instructions to make these live.
| Component | Type | Data Source | Live Activates? |
|---|---|---|---|
| Threat feed ticker | Animated string cycler | 10 hardcoded FEED_ITEMS strings, 3.5s interval | No — always demo |
| Active Threats (red) | Animated counter | Starts at 47, drifts +0–1 every 4s | Yes — wire to GET /threats pagination.totalItems |
| Agents Online (green) | Animated counter | Starts at 1284, drifts ±1 every 4s | Yes — wire to GET /agents pagination.totalItems |
| API Calls/min (cyan) | Session counter | Random init 820–1020, increments on explorer sends | No — tracks simulator clicks only |
| Events Today (yellow) | Animated counter | Random init 14200–17200, drifts +12–42 every 4s | No — requires activities endpoint polling |
| Quick endpoint reference | Static list with go() links | Hardcoded endpoint rows | N/A — static reference |
| Section index grid | Navigation shortcuts | All call go(id) | N/A — navigation only |
| Base URL panel | Static code block | Hardcoded tenant URL patterns | N/A — reference text |
API Explorer
The API Explorer provides a request-builder interface with method selector, URL field, headers/body/params tabs, and a SEND button. It serves two purposes: (1) building cURL commands for copy-paste execution, and (2) simulating demo API responses with syntax-highlighted JSON.
SentinelOne enforces strict CORS headers. Real API calls from a browser context will be blocked regardless of token validity. The explorer intentionally does not attempt live fetch() calls. Use the built cURL output in your terminal, Postman, or integration code.
URLs matching /threats, /agents, /activities, or /sites return realistic demo payloads. All other URLs return the default generic response.
| Template | Method | Path Loaded |
|---|---|---|
| Open threat triage queue | GET | threats?resolved=false&limit=100 |
| Bulk quarantine | POST | threats/mitigate/quarantine |
| Infected endpoints | GET | agents?isActive=true&isInfected=true |
| Recent activity log | GET | activities?limit=50 |
GraphQL Playground
A split-pane GraphQL editor showing query templates and example response shapes. The RUN button instructs users to copy the query into Postman — no live GraphQL execution occurs in the browser.
API Reference Pages
The core of the console. The API Reference section shows the endpoint catalog in tabbed groups. All paths shown are relative to https://<tenant>.sentinelone.net/web/api/v2.1/.
| Method | Path | Description |
|---|---|---|
| GET | /threats | List threats. Params: resolved, siteIds, limit, cursor |
| POST | /threats/mitigate/{action} | kill / quarantine / remediate / rollback / disconnect |
| POST | /threats/analyst-verdict | Bulk set analyst verdict (true_positive / false_positive / undefined) |
| GET | /threats/{id}/timeline | Threat timeline events for a specific threat ID |
| GET | /threats/{id}/forensics | Download forensic artifacts (NEW badge in UI) |
| POST | /threats/mark-as-benign | Bulk mark threats as benign |
| POST | /threats/fetch-file | Fetch file from endpoint for analysis |
| POST | /threats/mark-as-resolved | Mark threats resolved. Corrected from DEL /threats — no bulk delete API exists. |
| Method | Path | Description |
|---|---|---|
| POST | /dv/init-query | Start a Deep Visibility query. Body: {query, fromDate, toDate, siteIds} |
| GET | /dv/query-status | Poll query execution status. Param: queryId |
| GET | /dv/events | Fetch query results. Params: queryId, limit, cursor |
| POST | /dv/cancel-query | Cancel running query. Corrected from GET — requires POST with queryId in body. |
| Method | Path | Description |
|---|---|---|
| GET | /notification-schema/connections | List webhook subscriptions. Corrected from /webhook-schema/ — path does not exist in v2.1. |
| POST | /notification-schema/connections | Create webhook subscription |
| PUT | /notification-schema/connections/{id} | Update subscription |
| DEL | /notification-schema/connections/{id} | Delete subscription |
| POST | /notification-schema/connections/{id}/test | Send test payload to webhook endpoint |
| Method | Path | Description |
|---|---|---|
| GET | /threat-intelligence/iocs | List custom IOC entries |
| POST | /threat-intelligence/iocs | Create custom IOC. Body: type, value, name, description, externalId, source, validUntil |
| PUT | /threat-intelligence/iocs/{id} | Update IOC entry |
| DEL | /threat-intelligence/iocs/{id} | Delete IOC entry |
All Other Pages
The console contains 30+ pages. The table below summarises all sections not covered in detail above.
| Page ID | Title | Content Summary |
|---|---|---|
| home | Overview | Live stats, threat feed ticker, quick nav cards, endpoint shortcut list |
| docs | Developer Docs | Python + PowerShell quick-start code samples, documentation section index |
| base | Base Endpoint | URL structure table, region variants (US/EU/APAC), tenant lookup guide |
| free | Free Dev Account | Sandbox feature comparison table, signup CTA |
| auth | Authentication | Auth flow diagram, header format, cURL example, token scope reference table |
| identity | Identity Protocols | Supported protocols table (ApiToken, OAuth 2.0, SAML, OIDC, LDAP), OAuth flows |
| sso | SSO / Social Login | 8-provider SSO grid (Okta, Azure AD, SAML, LDAP, Google, Ping, OneLogin, GitHub) |
| oauth | OAuth Playground | Authorization Code flow steps, Client Credentials M2M example, token response shape |
| apiref | API Reference | Tabbed endpoint catalog: Threats, Agents, Policies, Activities, Exclusions, Groups |
| graphqlep | GraphQL Endpoint | Endpoint URL, request format, header requirements |
| pagination | Pagination Style | Cursor pattern, breaking change notice (v2.1.2), Python fetch-all sample |
| customobj | Custom Object Support | IOC CRUD endpoints, IOC schema JSON example |
| querylang | Query Language | Deep Visibility API endpoints, DNS exfil + lateral movement hunt examples |
| webhooks | Webhooks | Event types list, delivery guarantees table, THREATS_ALERT payload example |
| whmgmt | Webhook Mgmt API | Notification Center CRUD endpoints, create webhook request body example |
| explorer | API Explorer | Interactive request builder + mock response simulation |
| graphql | GraphQL Playground | Split-pane query editor with 3 template tabs, response shape preview |
| sandbox | Sandbox Environment | Sandbox URL, credentials guide, sandbox vs production comparison table |
| postman | Postman / Insomnia | Collection import instructions, environment variable setup |
| openapi | OpenAPI / Swagger | OpenAPI spec download link, Swagger UI integration notes |
| cli | CLI | s1cli tool usage reference and install instructions |
| ide | IDE Extensions | VS Code, IntelliJ extension links for S1 API development |
| integrations | Integrations | Certified integration cards: Splunk, SIEM tools, ServiceNow, Jira, PagerDuty, Okta, Tenable, AWS |
| ecosystem | Ecosystem | Partner stats (340+ apps, 120+ tech partners, 600+ MSSPs, 48 open-source projects) |
| applist | App Listing Requirements | 8-item marketplace submission checklist |
| pricing | API Pricing | 3-tier pricing cards: Developer (free), Included (with license), Enterprise Add-on |
| ratelimits | API Rate Limits | 6 rate limit cards with animated bars, response headers reference, Python backoff code |
| community | Community | Links grid: GitHub, StackOverflow, Forum, Slack, Tutorials, Samples |
| github | GitHub | Key repositories: Python SDK, Go SDK, CLI, api-examples, Splunk TA |
| stackoverflow | StackOverflow Tags | Recommended tags: [sentinelone], [sentinelone-api], [s1-edr], [edr-api] |
| tutorials | Tutorials | 6 featured tutorials: Getting Started, Auth, Webhooks, Auto-Triage, ServiceNow, GraphQL |
| samples | Samples & Examples | Bulk triage Python + Go samples, agent isolation, IOC upload examples |
| changelog | API Changelog | Version history with breaking change notices and feature additions |
| status | Status Page | Static service status rows (hardcoded Operational) + UTC clock |
| metrics | Dev Metrics | Developer engagement stats panel |
API Endpoints
All endpoints shown in the console have been verified against SentinelOne Management API v2.1 documentation. Three endpoint errors were found and corrected during the Directive 1 audit. See Section 12 for the full corrections log.
All paths in this console are relative to: https://<tenant>.sentinelone.net/web/api/v2.1/
Sandbox base: https://usea1-012.sentinelone.net/web/api/v2.1/
Auth header: Authorization: ApiToken <YOUR_TOKEN>
Audit Corrections
Three endpoint errors were identified and corrected during the Directive 1 audit. All corrections are also documented in inline code comments in the dashboard file.
DEL /threats — "Delete resolved threats"Fixed to:
POST /threats/mark-as-resolvedReason: SentinelOne does not expose a bulk delete endpoint for threats. Threats are resolved or marked benign — they are not deleted via the API. A DELETE method on
/threats does not exist in v2.1 and would return 405 Method Not Allowed.GET /dv/cancel-queryFixed to:
POST /dv/cancel-queryReason: The Deep Visibility cancel-query operation requires a POST request with the
queryId in the request body. A GET request to this path is not documented and would not function correctly as GET requests do not carry a body payload./webhook-schema/connections (all 5 CRUD + test endpoints)Fixed to:
/notification-schema/connectionsReason: The
/webhook-schema/ path does not exist in the SentinelOne v2.1 REST API. Webhook subscription management is handled through the Notification Center API at /notification-schema/. All five webhook management endpoint rows (GET, POST, PUT, DEL, POST test) and the code sample header were corrected.Vendor Limitations
These are genuine SentinelOne API constraints documented in code comments in the dashboard file. They affect what can realistically be made "live" if this console is extended to real data fetching.
resolved=false filter on GET /threats.status.sentinelone.net is a static Atlassian Statuspage instance. The Status page section in this console uses hardcoded "Operational" values — there is no API to populate it with live status. For real-time monitoring, scrape the Statuspage JSON feed (unofficial) or subscribe to email/webhook alerts from the status page directly./web/api/v2.1/graphql supports read queries only in v2.1. Write mutations (creating/modifying threats, agents, policies) are planned for v2.2. Current GraphQL queries are limited to threats, agents, and activities objects. Use the REST endpoints for all write operations until v2.2 GraphQL mutations are available.Authorization: ApiToken <token>) for all production integrations. OAuth is suitable for third-party app authorization flows where user consent is required, but it is not yet GA-stable.Config Fields
All configuration lives at the top of the <script> block in stack-sentinelone.html. This is a reference console, so the config governs the live stats wiring only — it does not affect the documentation content.
| Variable | Default | Effect |
|---|---|---|
| DEMO_MODE | true | When true, refreshAll() calls initLiveStats() (animated counters). When false, refreshAll() attempts real GET /threats and GET /agents calls for the home page counters. |
| S1_BASE_URL | '' (empty) | Base URL for live fetch calls. Set to your tenant URL or local proxy URL. Used only when DEMO_MODE=false. |
| S1_API_TOKEN | '' (empty) | ApiToken value for Authorization header. Only used when DEMO_MODE=false and you are not injecting the header via a proxy. |
Even in live mode, only the home page stat counters (Active Threats, Agents Online) fetch real data. All documentation pages, code samples, endpoint lists, rate limit figures, and other reference content remain static regardless of DEMO_MODE setting.
Proxy Activation
The console can optionally be wired to pull live threat and agent counts for the home page stat counters. This is optional — the console is fully functional as a reference tool without any live data. Complete these steps only if you want the home page counters to reflect real tenant data.
In the SentinelOne Management Console: Settings → Users → Service Users → Create Service User. Assign a role with
threats:read and agents:read scope minimum. Copy the generated token — shown once only.Test:
curl -H "Authorization: ApiToken YOUR_TOKEN" https://acme.sentinelone.net/web/api/v2.1/threats?limit=1Expect a JSON response with
"pagination": {"totalItems": N}. A 401 means wrong token; a 403 means insufficient scope on the service user role.SentinelOne enforces CORS — direct browser fetch calls will fail. Run a local proxy on port 8080 that forwards to your tenant and injects the auth header. Example nginx config:
location /api/ { proxy_pass https://acme.sentinelone.net/web/api/v2.1/; proxy_set_header Authorization "ApiToken YOUR_TOKEN"; }Set
DEMO_MODE = false. Set S1_BASE_URL to your proxy base URL (e.g., http://localhost:8080/api). Optionally set S1_API_TOKEN if the proxy does not inject the header.Find the
// ── LIVE path (uncomment when proxy is ready) ── comment inside refreshAll(). Uncomment the try/catch block. The function will then call GET /threats?resolved=false&limit=1 and GET /agents?isActive=true&limit=1 to populate the stat counters with real pagination.totalItems values.API Calls/min, Events Today, and the live threat ticker are hardcoded demo animations and will not change in live mode. The explorer SEND button will still return mock responses — this is by design (CORS limitation). Only Active Threats and Agents Online activate from live data.
Throughout the console, code samples use
acme.sentinelone.net as the example tenant. Optionally do a find-replace to use your actual tenant subdomain so copy-pasted samples work immediately for your engineers.Troubleshooting
refreshAll(). Setting DEMO_MODE=false only changes which branch runs — if the live path is still commented out, initLiveStats() still fires and you get demo counters. Also verify your proxy is running and S1_BASE_URL points to the proxy correctly, not directly to sentinelone.net (CORS will block that).go(id) function looks for elements with IDs p-{id} (page) and n-{id} (nav item). If the page doesn't appear, verify the page section element exists with the correct ID in the HTML. Check the browser console for any JS errors. The window.go override (wrapping the original go()) must not have syntax errors — any error in the override block can silently break navigation.animateRateBars() which is triggered in the window.go override when id === 'ratelimits'. The bars use data-pct attributes or inline style.width as the animation target. If bars show at 0%, ensure the rl-fill elements have either a data-pct attribute or an initial style.width value set. The 100ms timeout on navigation should be sufficient; if bars still don't animate, increase the timeout to 250ms.keydown listener uses partial string matching (q.includes(k)). If your search term matches multiple keywords, the first match wins. The map is processed in object insertion order — put more specific keywords first if you need to override. Common issue: searching "webhook" works, searching "webhooks management" still lands on "webhooks" because "webhook" matches first. Type "whmgmt" or "mgmt" to navigate directly to the management page — add it to the map if needed.toast('Copied!') only — they do not execute navigator.clipboard.writeText(). This was an intentional simplification in the demo version. To add real clipboard copy: wrap each code block content in a named element, then call navigator.clipboard.writeText(document.getElementById('code-id').textContent) from the copy button's onclick. Note: navigator.clipboard requires HTTPS or localhost.GET /web/api/v2.1/threats/actions which returns the list of available threat action endpoints for your version. If mark-as-resolved is not listed, use POST /threats/mark-as-resolved with body {"filter": {"ids": [...]}, "data": {}} — the endpoint exists in all v2.1 deployments.