EDR Integrations
Breeze integrates with leading Endpoint Detection and Response (EDR) platforms to give you a unified view of endpoint security across your managed fleet. Instead of switching between your RMM and EDR consoles, you can view threat data, agent coverage, and incident details directly in Breeze.
Currently supported EDR vendors:
| Vendor | Data Synced | Actions Available |
|---|---|---|
| Huntress | Agents, incidents | Webhook ingestion, manual sync |
| SentinelOne | Agents, threats, site mappings | Device isolation, threat actions (kill, quarantine, rollback), manual sync |
Both integrations follow the same pattern: you provide API credentials, Breeze syncs agent and threat data on a schedule, and the synced data is automatically mapped to your existing Breeze devices.
Auto-Linking: How EDR Agents Map to Breeze Devices
Section titled “Auto-Linking: How EDR Agents Map to Breeze Devices”During each sync, Breeze automatically attempts to match imported EDR agents to enrolled Breeze devices. The matching logic differs slightly by vendor:
Huntress: Agents are matched by hostname (case-insensitive, trimmed). Breeze compares the Huntress agent’s hostname against both the hostname and displayName of every enrolled device in the organization. If a match is found, the Huntress agent and any associated incidents are linked to that Breeze device.
SentinelOne: Agents are matched first by hostname (the computerName field), then by IP address as a fallback. If the SentinelOne agent’s computer name matches a Breeze device hostname (case-insensitive), the match is made. If no hostname match exists, Breeze checks the agent’s network interfaces against known device IP addresses.
Agents that cannot be matched appear as “unmapped” in the integration status dashboard. To resolve unmapped agents, either enroll the missing device in Breeze or verify that the hostname in the EDR system matches the hostname reported by the Breeze agent.
Huntress
Section titled “Huntress”Overview
Section titled “Overview”The Huntress integration syncs agent inventory and incident reports from your Huntress account into Breeze. It supports both pull-based syncing (via the Huntress API) and push-based updates (via webhooks). Huntress agents are automatically matched to Breeze devices, and incidents are linked to the affected device when a mapping exists.
Setting Up Huntress
Section titled “Setting Up Huntress”- In the Breeze dashboard, navigate to Settings > Integrations > Huntress.
- Provide a name for the integration (e.g., “Production Huntress”).
- Enter your Huntress API key. This is encrypted at rest using AES before being stored.
- Optionally provide your Huntress account ID and API base URL (defaults to
https://api.huntress.io/v1). - Optionally provide a webhook secret for signature verification on incoming webhook payloads.
- Click Save. An initial sync is automatically scheduled.
Webhook Configuration
Section titled “Webhook Configuration”Huntress can push event notifications to Breeze in real time via webhooks. Configure the webhook URL in your Huntress dashboard:
POST https://your-breeze-instance.com/api/v1/huntress/webhookWebhook payloads are verified using HMAC-SHA256 signature validation:
- Breeze reads the signature from the
x-huntress-signatureheader (fallback:x-signature). - Breeze reads the timestamp from the
x-huntress-timestampheader (fallback:x-timestamp). - Breeze computes
HMAC-SHA256(secret, "{timestamp}.{body}")and compares the result to the provided signature using a timing-safe comparison. - The timestamp must be within 10 minutes of the current server time, or the webhook is rejected as a potential replay.
The expected signature format is sha256={hex_digest}.
Webhook Routing
Section titled “Webhook Routing”When Breeze receives a Huntress webhook, it needs to determine which integration the event belongs to. The integration is resolved using (in order of priority):
integrationIdquery parameter orx-huntress-integration-idheaderintegrationIdfield in the JSON payload bodyx-huntress-account-idheader or account ID extracted from the payload
If multiple active integrations match the same account and no explicit integration ID is provided, the webhook returns a 409 conflict.
Data Model (For Integrators)
Section titled “Data Model (For Integrators)”Huntress Agents
Section titled “Huntress Agents”| Field | Type | Description |
|---|---|---|
huntressAgentId | String | Unique agent identifier from Huntress |
deviceId | UUID | Mapped Breeze device (nullable if unmapped) |
hostname | String | Agent hostname |
platform | String | Operating system platform |
status | String | Agent status (e.g., online, offline) |
lastSeenAt | Timestamp | Last time the agent checked in with Huntress |
metadata | JSON | Additional agent metadata from Huntress |
Huntress Incidents
Section titled “Huntress Incidents”| Field | Type | Description |
|---|---|---|
huntressIncidentId | String | Unique incident identifier from Huntress |
deviceId | UUID | Affected Breeze device (nullable if unmapped) |
severity | String | Incident severity level |
category | String | Incident category (max 60 chars) |
title | String | Incident title |
description | Text | Detailed incident description |
recommendation | Text | Recommended remediation steps |
status | String | Current incident status |
reportedAt | Timestamp | When the incident was first reported |
resolvedAt | Timestamp | When the incident was resolved (nullable) |
details | JSON | Full incident details from Huntress |
Status Dashboard
Section titled “Status Dashboard”The Huntress status endpoint provides a summary of your integration health:
| Metric | Description |
|---|---|
totalAgents | Total Huntress agents synced |
mappedAgents | Agents matched to Breeze devices |
unmappedAgents | Agents without a Breeze device match |
offlineAgents | Agents with an offline status |
open | Count of unresolved incidents |
bySeverity | Incident counts grouped by severity |
byStatus | Incident counts grouped by status |
Listing Incidents
Section titled “Listing Incidents”Incidents can be filtered by multiple criteria:
| Filter | Type | Description |
|---|---|---|
orgId | UUID | Filter by organization |
integrationId | UUID | Filter by specific integration |
status | String | Filter by incident status |
severity | String | Filter by severity level |
deviceId | UUID | Filter by affected Breeze device |
search | String | Search incident titles (case-insensitive) |
limit | Number | Results per page (1-500, default 100) |
offset | Number | Pagination offset |
SentinelOne
Section titled “SentinelOne”Overview
Section titled “Overview”The SentinelOne integration provides deeper operational capabilities beyond data sync. In addition to importing agent and threat data, you can isolate devices and take threat actions (kill, quarantine, rollback) directly from the Breeze dashboard — commands are dispatched to the SentinelOne management console via API.
Setting Up SentinelOne
Section titled “Setting Up SentinelOne”- In the Breeze dashboard, navigate to Settings > Integrations > SentinelOne.
- Provide a name for the integration.
- Enter your SentinelOne management console URL (e.g.,
https://usea1.sentinelone.net). - Enter your SentinelOne API token. This is encrypted at rest before being stored.
- Click Save. An initial sync is automatically scheduled.
MFA Requirements by Operation
Section titled “MFA Requirements by Operation”The following SentinelOne operations require MFA verification before they can be executed:
| Operation | MFA Required |
|---|---|
| Create or update integration | Yes |
| Isolate / unisolate devices | Yes |
| Execute threat actions (kill, quarantine, rollback) | Yes |
| Trigger manual sync | No |
| View status, threats, or sites | No |
Data Model (For Integrators)
Section titled “Data Model (For Integrators)”SentinelOne Agents
Section titled “SentinelOne Agents”| Field | Type | Description |
|---|---|---|
s1AgentId | String | Unique agent identifier from SentinelOne |
deviceId | UUID | Mapped Breeze device (nullable if unmapped) |
status | String | Agent connection status |
infected | Boolean | Whether the agent has active threats |
threatCount | Integer | Number of threats detected on this agent |
policyName | String | Applied SentinelOne policy name |
lastSeenAt | Timestamp | Last check-in time |
metadata | JSON | Additional agent metadata including site name |
SentinelOne Threats
Section titled “SentinelOne Threats”| Field | Type | Description |
|---|---|---|
s1ThreatId | String | Unique threat identifier from SentinelOne |
deviceId | UUID | Affected Breeze device (nullable if unmapped) |
classification | String | Threat classification (e.g., Malware, PUP) |
severity | String | Severity level (low, medium, high, critical) |
threatName | String | Name of the detected threat |
processName | String | Process that triggered the detection |
filePath | String | File path of the threat |
mitreTactics | JSON | MITRE ATT&CK tactic mappings |
status | String | Current threat status (active, in_progress, resolved, etc.) |
detectedAt | Timestamp | When the threat was first detected |
resolvedAt | Timestamp | When the threat was resolved (nullable) |
details | JSON | Full threat details from SentinelOne |
SentinelOne Actions
Section titled “SentinelOne Actions”| Field | Type | Description |
|---|---|---|
action | String | Action type (isolate, unisolate, kill, quarantine, rollback) |
status | String | Action status: queued, in_progress, completed, failed |
providerActionId | String | Action ID from SentinelOne API |
requestedBy | UUID | User who initiated the action |
requestedAt | Timestamp | When the action was requested |
completedAt | Timestamp | When the action finished (nullable) |
error | Text | Error message if the action failed |
Site Mappings
Section titled “Site Mappings”SentinelOne organizes agents into “Sites.” Breeze lets you map SentinelOne sites to Breeze organizations, enabling multi-tenant EDR management from a single SentinelOne console.
- Navigate to Settings > Integrations > SentinelOne > Sites.
- View the list of SentinelOne sites with their agent counts.
- For each site, select the Breeze organization it should map to.
- Click Save to apply the mapping.
To remove a mapping, set the target organization to null.
Device Isolation
Section titled “Device Isolation”You can isolate compromised devices directly from Breeze. The isolation command is sent to SentinelOne, which enforces network isolation at the endpoint level.
- Select one or more devices in the Breeze dashboard.
- Click Isolate (or Unisolate to restore connectivity).
- Breeze identifies the corresponding SentinelOne agents and dispatches the isolation command.
- The action status is tracked and reported back.
Threat Actions
Section titled “Threat Actions”Take direct action on detected threats without leaving Breeze:
| Action | Description |
|---|---|
kill | Terminate the malicious process |
quarantine | Move the threat file to quarantine |
rollback | Roll back changes made by the threat (Windows only) |
- Navigate to the Threats view and find the threat(s) to act on.
- Select the threat action (kill, quarantine, or rollback).
- Confirm the action. Up to 200 threats can be acted on in a single request.
- The action is dispatched to SentinelOne and the status is tracked.
Status Dashboard
Section titled “Status Dashboard”The SentinelOne status endpoint provides a comprehensive summary:
| Metric | Description |
|---|---|
totalAgents | Total SentinelOne agents synced |
mappedDevices | Agents matched to Breeze devices |
infectedAgents | Agents with active infections |
activeThreats | Threats with active or in_progress status |
highOrCriticalThreats | Threats with high or critical severity |
pendingActions | Actions with queued or in_progress status |
reportedThreatCount | Sum of threat counts across all agents |
Listing Threats
Section titled “Listing Threats”Threats can be filtered by multiple criteria:
| Filter | Type | Description |
|---|---|---|
orgId | UUID | Filter by organization |
integrationId | UUID | Filter by specific integration |
deviceId | UUID | Filter by affected Breeze device |
status | String | Filter by threat status |
severity | String | Filter by severity level |
search | String | Search by threat name, process name, or file path |
start | ISO datetime | Threats detected on or after this time |
end | ISO datetime | Threats detected on or before this time |
limit | Number | Results per page (1-500, default 100) |
offset | Number | Pagination offset |
Syncing
Section titled “Syncing”Both integrations support manual and automatic syncing.
Manual Sync
Section titled “Manual Sync”Trigger a sync from the Breeze dashboard or API. The sync job is queued via the background queue and processes in the background.
| Vendor | Requirements |
|---|---|
| Huntress | orgs:write permission, MFA, active integration |
| SentinelOne | orgs:write permission, active integration |
Sync Status
Section titled “Sync Status”Each integration tracks its last sync result:
| Field | Description |
|---|---|
lastSyncAt | Timestamp of the most recent sync |
lastSyncStatus | Result: success or failure indicator |
lastSyncError | Error message from the last failed sync (nullable) |
Sync Error Handling and Retries
Section titled “Sync Error Handling and Retries”Sync jobs are processed through a background queue. If a sync fails (for example, due to a network timeout or an API rate limit from the EDR vendor), the following happens:
- SentinelOne syncs automatically retry up to 3 times with exponential backoff (starting at 2 seconds, then 4 seconds, then 8 seconds).
- Huntress syncs do not have built-in retries. If a Huntress sync fails, trigger another manual sync or wait for the next scheduled sync cycle.
- The
lastSyncErrorfield on the integration record is updated with the error message from the most recent failure. Check this field in the dashboard or API to diagnose sync issues. - If the initial sync scheduled on integration creation fails, a warning is returned in the API response: “Initial sync could not be scheduled. Data will sync on the next scheduled cycle.”
API Reference
Section titled “API Reference”Huntress
Section titled “Huntress”All authenticated endpoints require organization, partner, or system scope. Mounted at /api/v1/huntress.
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /webhook | No (signature verified) | Receive Huntress webhook events |
GET | /integration | Yes | Get the Huntress integration for the current org |
POST | /integration | Yes + MFA | Create or update a Huntress integration |
POST | /sync | Yes + MFA | Trigger a manual Huntress sync |
GET | /status | Yes | Get integration status and coverage summary |
GET | /incidents | Yes | List Huntress incidents with filters |
SentinelOne
Section titled “SentinelOne”All endpoints require authentication with organization, partner, or system scope. Mounted at /api/v1/sentinel-one.
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /integration | Yes | Get the SentinelOne integration for the current org |
POST | /integration | Yes + MFA | Create or update a SentinelOne integration |
GET | /status | Yes | Get integration status and threat summary |
GET | /threats | Yes | List threats with filters |
POST | /isolate | Yes + MFA | Isolate or unisolate devices |
POST | /threat-action | Yes + MFA | Execute a threat action (kill, quarantine, rollback) |
POST | /sync | Yes | Trigger a manual SentinelOne sync |
GET | /sites | Yes | List SentinelOne sites with agent counts and org mappings |
POST | /sites/map | Yes | Map or unmap a SentinelOne site to a Breeze organization |
Security
Section titled “Security”Credential Storage
Section titled “Credential Storage”API keys and tokens for both Huntress and SentinelOne are encrypted at rest using AES encryption before being stored in the database. The apiKeyEncrypted and apiTokenEncrypted fields are never returned in API responses — only a boolean hasApiKey or similar flag is exposed.
Webhook Verification
Section titled “Webhook Verification”Huntress webhooks use HMAC signature verification. The webhook secret is encrypted at rest and decrypted only at verification time. Webhooks without a configured secret or with an invalid signature are rejected.
Permission Requirements
Section titled “Permission Requirements”| Operation | Required Permission | MFA Required |
|---|---|---|
| View integration status | organization, partner, or system scope | No |
| Create/update integration | orgs:write | Yes |
| Trigger manual sync | orgs:write | Huntress: Yes, SentinelOne: No |
| Isolate devices | devices:execute | Yes |
| Execute threat actions | devices:execute | Yes |
Troubleshooting
Section titled “Troubleshooting”Sync shows “Integration is inactive”
Section titled “Sync shows “Integration is inactive””Activate the integration by updating it with isActive: true before triggering a sync.
Huntress webhook returns 403 “Webhook secret not configured”
Section titled “Huntress webhook returns 403 “Webhook secret not configured””You must configure a webhook secret on the integration before Breeze will accept webhook payloads. Update the integration with a webhookSecret value that matches what you configured in your Huntress dashboard.
Huntress webhook returns 409 “Multiple active integrations match”
Section titled “Huntress webhook returns 409 “Multiple active integrations match””When multiple Huntress integrations share the same account ID, Breeze cannot determine which one to route the webhook to. Include the integrationId as a query parameter on your webhook URL or in the x-huntress-integration-id header.
SentinelOne isolation returns 502
Section titled “SentinelOne isolation returns 502”A 502 response means the isolation command was sent to SentinelOne but the provider returned an error. Check the warning field in the response for details and verify the target devices have active SentinelOne agents.
Unmapped agents
Section titled “Unmapped agents”After syncing, some EDR agents may not be matched to Breeze devices. This happens when the hostname or identifier in the EDR system does not correspond to any enrolled Breeze device. Enroll the missing devices in Breeze or verify the hostname matches.
”API token is required for new integrations”
Section titled “”API token is required for new integrations””When creating a new SentinelOne integration, the API token is mandatory. For updates to existing integrations, the token is optional (the existing encrypted token is preserved).