Integrations
Integrations connect Breeze to the tools your team already uses – PSA platforms for ticketing, communication channels for alerting, and monitoring endpoints for telemetry forwarding. Most integrations are scoped to an organization and configured independently, so MSPs can tailor connections per customer without cross-tenant interference; PSA connections can also be owned partner-wide, so one connection serves every organization under the partner (see PSA Integrations). PSA credentials are encrypted at rest using AES-256-GCM, and every configuration change is recorded in the audit log.
Integration Types
Section titled “Integration Types”Breeze supports three categories of integrations, each served by a dedicated set of API routes.
| Category | Providers | Purpose |
|---|---|---|
| Communication | Slack, Microsoft Teams, Discord | Alert notifications, status updates, and on-call messaging |
| PSA / Ticketing | Jira, ServiceNow, ConnectWise, Autotask, Freshservice, Zendesk | Connection management and credential storage today; ticket sync is not implemented yet (see PSA Integrations) |
| Monitoring | External monitoring endpoints | Forward device telemetry and health data to third-party observability platforms (see Monitoring & Observability Integrations) |
| Accounting | QuickBooks Online | Connect your accounting platform (see Accounting Integrations) |
| Distributors | Pax8, TD SYNNEX | Sync licenses and pull live distributor pricing into your Product Catalog – see Distributor Integrations |
| Network | UniFi (Ubiquiti Site Manager cloud, or a self-hosted controller) | Discover UniFi fleet inventory and WAN health via the cloud, or connect a self-hosted controller directly through a Breeze agent – with optional agent-collected deep telemetry either way (see UniFi Network Integration) |
Communication Integrations
Section titled “Communication Integrations”Communication integrations push notifications from Breeze into your team’s messaging platform. Each provider is configured with a POST request containing the webhook URL and any provider-specific settings.
Setting Up a Provider
Section titled “Setting Up a Provider”POST /integrations/slackContent-Type: application/json
{ "webhookUrl": "https://hooks.slack.com/services/T00/B00/xxxx", "channel": "#breeze-alerts", "username": "Breeze RMM", "notifyOn": ["alert.critical", "alert.warning", "device.offline"]}POST /integrations/teamsContent-Type: application/json
{ "webhookUrl": "https://outlook.office.com/webhook/...", "notifyOn": ["alert.critical", "device.offline"]}POST /integrations/discordContent-Type: application/json
{ "webhookUrl": "https://discord.com/api/webhooks/...", "notifyOn": ["alert.critical", "alert.warning"]}Each provider endpoint accepts an optional "test": true flag in the request body. When present, the API queues a test notification to the configured webhook. Note that the configuration is saved to the in-memory store before the test is executed, so sending "test": true does persist the settings for the lifetime of the current API process.
POST /integrations/slack{ "webhookUrl": "https://hooks.slack.com/services/T00/B00/xxxx", "test": true}Response:
{ "success": true, "message": "slack test notification queued." }Retrieving Communication Settings
Section titled “Retrieving Communication Settings”Fetch the current communication configuration for an organization:
GET /integrations/communication?orgId=<uuid>The response contains all configured providers in a single object:
{ "data": { "slack": { "webhookUrl": "...", "channel": "#breeze-alerts" }, "teams": { "webhookUrl": "..." } }}If no communication settings exist for the organization, the endpoint returns 404.
Monitoring Integration
Section titled “Monitoring Integration”The monitoring integration forwards device telemetry to an external observability platform. Configuration is stored as a freeform JSON object, so you can include whatever fields your monitoring endpoint requires.
Saving Monitoring Settings
Section titled “Saving Monitoring Settings”PUT /integrations/monitoringContent-Type: application/json
{ "orgId": "<uuid>", "endpoint": "https://monitoring.example.com/ingest", "apiKey": "mon_xxxxxxxxxxxx", "metricsEnabled": true, "forwardEvents": ["cpu", "memory", "disk", "network"]}Retrieving Monitoring Settings
Section titled “Retrieving Monitoring Settings”GET /integrations/monitoring?orgId=<uuid>Returns the stored configuration object, or an empty object {} if nothing has been configured.
Testing Monitoring Connectivity
Section titled “Testing Monitoring Connectivity”POST /integrations/monitoring/testReturns { "success": true, "message": "Connection successful." } when the monitoring endpoint is reachable.
Ticketing Integration
Section titled “Ticketing Integration”The ticketing integration provides a lightweight configuration store for generic ticketing systems that are not covered by the dedicated PSA routes.
Saving Ticketing Settings
Section titled “Saving Ticketing Settings”POST /integrations/ticketingContent-Type: application/json
{ "orgId": "<uuid>", "provider": "custom", "apiUrl": "https://tickets.example.com/api", "apiKey": "tk_xxxxxxxxxxxx", "projectKey": "BREEZE", "autoCreate": true}Retrieving Ticketing Settings
Section titled “Retrieving Ticketing Settings”GET /integrations/ticketing?orgId=<uuid>Testing Ticketing Connectivity
Section titled “Testing Ticketing Connectivity”POST /integrations/ticketing/testReturns { "success": true, "message": "Connection successful. Credentials validated." }.
PSA Integrations
Section titled “PSA Integrations”PSA (Professional Services Automation) integrations are the most fully featured integration type. They are backed by a dedicated database table (psa_connections) with encrypted credential storage, sync tracking, and ticket mapping. Use the /psa routes for all PSA operations.
Supported PSA Providers
Section titled “Supported PSA Providers”| Provider | Enum Value | Typical Credentials |
|---|---|---|
| ConnectWise Manage | connectwise |
Company ID, public key, private key, site URL |
| Datto Autotask | autotask |
Username, secret, integration code |
| Jira | jira |
Email, API token, site URL, project key |
| ServiceNow | servicenow |
Instance URL, username, password or OAuth token |
| Freshservice | freshservice |
Domain, API key |
| Zendesk | zendesk |
Subdomain, email, API token |
Creating a PSA Connection
Section titled “Creating a PSA Connection”-
Choose a provider from the supported list above.
-
Send a POST request with the connection name, provider, and credentials:
Terminal window POST /psa/connectionsContent-Type: application/json{"orgId": "<uuid>","provider": "connectwise","name": "ConnectWise — Contoso","credentials": {"companyId": "contoso","publicKey": "pk_xxxx","privateKey": "sk_xxxx","siteUrl": "https://na.myconnectwise.net"},"settings": {"defaultBoard": "Service Board","defaultStatus": "New"}} -
The API encrypts the credentials and returns the new connection (without credentials in the response):
{"id": "uuid","orgId": "uuid","provider": "connectwise","name": "ConnectWise — Contoso","settings": { "defaultBoard": "Service Board", "defaultStatus": "New" },"createdAt": "2026-02-18T...","updatedAt": "2026-02-18T...","lastTestedAt": null,"lastSyncedAt": null,"hasCredentials": true} -
Test the connection to verify credentials are valid (see Testing Connections below).
Updating a PSA Connection
Section titled “Updating a PSA Connection”Update the name, credentials, or settings of an existing connection. Only the fields you include will be changed.
PATCH /psa/connections/:idContent-Type: application/json
{ "name": "ConnectWise — Contoso (Production)", "settings": { "defaultBoard": "MSP Board", "defaultStatus": "New", "autoSync": true }}Credential Handling
Section titled “Credential Handling”PSA credentials follow a strict security model:
| Behavior | Detail |
|---|---|
| Encryption | All credentials are encrypted with AES-256-GCM using the APP_ENCRYPTION_KEY before being written to the database |
| Response redaction | List and detail endpoints never return raw credentials. The hasCredentials boolean indicates whether credentials are stored |
| Rotation | Update credentials via PATCH /psa/connections/:id with a new credentials object. The old encrypted value is replaced atomically |
| Deletion | Deleting a connection removes the encrypted credentials and all associated ticket mappings from the database |
Accounting Integrations
Section titled “Accounting Integrations”Connect Breeze to your accounting platform from the Accounting tab on the Integrations page. Accounting integrations are a partner-level feature – they’re set up once for your practice, not per customer.
QuickBooks Online
Section titled “QuickBooks Online”QuickBooks Online connects through Intuit’s standard OAuth consent flow:
- Open Integrations → Accounting and click Connect to QuickBooks.
- You’re taken to Intuit’s consent screen to authorize Breeze; approving it returns you to Breeze with the connection established.
- The tab then shows the connection status, the connected environment, and a Disconnect option. You can also choose whether issued invoices push to QuickBooks automatically or manually.
Importing customers
Section titled “Importing customers”Once QuickBooks is connected, you can bring your existing QuickBooks customers into Breeze as organizations – no re-typing. Each imported customer becomes one Breeze organization (customer type) with a default site, carrying over the billing contact and address.
- On the connected QuickBooks Online panel, open the Import customers section and click Load customers.
- Tick the customers you want to import. Customers you’ve already imported show an Already imported badge and are skipped automatically (select-all excludes them).
- Click Import selected. Breeze reports how many were imported, skipped, and failed, with an inline list of any failures.
The import is idempotent – it keys off the QuickBooks customer id, so re-running it never creates duplicates. It requires partner scope, and one QuickBooks company (realm) is connected per partner.
Distributor Integrations
Section titled “Distributor Integrations”Distributor integrations live on the Distributors tab of the Integrations page and let you bring vendor licenses and pricing into Breeze. They’re partner-scoped.
Pax8 syncs your clients and their subscription/license quantities, which you can map to organizations and link to recurring contract lines. After connecting your Pax8 account and mapping companies to Breeze organizations, open the Subscriptions tab to manage how each subscription connects to a contract line.
Each subscription row offers these actions:
| Action | Description | Requires MFA |
|---|---|---|
| Link for observation | Connect the subscription to an existing contract line, or create a new manual line on the spot, so Pax8-reported quantities can be compared with Breeze billing | Yes |
| Change | Re-point the subscription to a different contract line | Yes |
| Pause observations | Stop recording new Pax8 quantity observations while keeping the link intact | Yes |
| Resume observations | Resume recording Pax8 quantity observations and surfacing drift | Yes |
| Unlink | Remove the connection between the subscription and the contract line | Yes |
When Track Pax8 reported quantity for drift is enabled on a link, each Pax8 sync records the latest known quantity as an observation and surfaces any difference from the linked manual contract-line quantity. Breeze’s order ledger and linked manual quantity remain authoritative for billing; observation sync never overwrites that billing quantity. Pausing stops new observations and drift updates while leaving the link and billing quantity intact.
Beyond subscription sync, you can also search the Pax8 catalog and import individual products into your Product Catalog – see Product Catalog for that workflow.
TD SYNNEX
Section titled “TD SYNNEX”TD SYNNEX provides live product price and availability you can import straight into your catalog. The end-to-end workflow – including EC Express live pricing – is documented under Product Catalog → Importing from distributor catalogs.
UniFi Network
Section titled “UniFi Network”UniFi is a partner-level, strictly read-only integration that discovers your Ubiquiti network fleet across every customer site and reconciles it into Breeze’s unified network view, so gateways, switches, and access points show up alongside your agent-discovered assets without duplicating them. Configure it on the UniFi tab of the Integrations page, either through Ubiquiti’s cloud (Site Manager), optionally paired with on-site deep telemetry agents, or fully self-hosted with a Breeze agent talking directly to your on-prem controller and no Ubiquiti cloud account at all.
The full connection walkthrough for both modes, deep telemetry, and what Breeze pulls from UniFi is documented on its own page: see UniFi Network Integration.
Testing Connections
Section titled “Testing Connections”Every integration type provides a test endpoint. Testing verifies that the configured credentials and endpoint are reachable.
Communication Test
Section titled “Communication Test”Pass "test": true in the provider configuration body:
POST /integrations/slack{ "webhookUrl": "https://hooks.slack.com/...", "test": true }Monitoring Test
Section titled “Monitoring Test”POST /integrations/monitoring/testTicketing Test
Section titled “Ticketing Test”POST /integrations/ticketing/testPSA Connection Test
Section titled “PSA Connection Test”Test a specific saved PSA connection by ID:
POST /psa/connections/:id/testOn success, the API updates the connection’s syncSettings with a lastTestedAt timestamp and sets the status to verified. The response confirms the result:
{ "success": true, "message": "Credentials verified" }This endpoint also writes an audit log entry with action psa.connection.test.
Managing Integrations
Section titled “Managing Integrations”Listing PSA Connections
Section titled “Listing PSA Connections”GET /psa/connections?orgId=<uuid>&provider=connectwise&page=1&limit=50All query parameters are optional. Results are paginated and ordered by most recently updated.
| Parameter | Type | Description |
|---|---|---|
orgId |
UUID | Filter to a specific organization |
provider |
string | Filter by PSA provider (jira, connectwise, etc.) |
page |
integer | Page number (default: 1) |
limit |
integer | Results per page (default: 50, max: 100) |
Viewing a Single Connection
Section titled “Viewing a Single Connection”GET /psa/connections/:idReturns the connection detail including settings, sync timestamps, and hasCredentials flag. Credentials themselves are not included.
Deleting a PSA Connection
Section titled “Deleting a PSA Connection”DELETE /psa/connections/:idTriggering a Sync
Section titled “Triggering a Sync”POST /psa/connections/:id/syncUpdating Connection Status
Section titled “Updating Connection Status”Set a custom status on a connection (e.g., active, paused, error):
POST /psa/connections/:id/statusContent-Type: application/json
{ "status": "paused" }Ticket Mappings
Section titled “Ticket Mappings”PSA connections can map Breeze alerts and devices to external tickets. Ticket mappings track the relationship between internal entities and their corresponding tickets in the PSA platform.
Listing All Tickets
Section titled “Listing All Tickets”GET /psa/tickets?page=1&limit=50Returns all ticket mappings across connections accessible to the authenticated user. Results include:
| Field | Description |
|---|---|
id |
Internal mapping ID |
psaId |
The PSA connection this ticket belongs to |
title |
Display title derived from the external ticket ID |
status |
Current ticket status |
syncedAt |
Last sync timestamp |
raw.externalTicketId |
The ticket ID in the external PSA system |
raw.externalTicketUrl |
Direct URL to the ticket in the PSA platform |
raw.alertId |
Associated Breeze alert ID (if any) |
raw.deviceId |
Associated Breeze device ID (if any) |
Listing Tickets for a Connection
Section titled “Listing Tickets for a Connection”GET /psa/connections/:id/tickets?page=1&limit=50Returns only ticket mappings associated with the specified PSA connection.
API Reference
Section titled “API Reference”Integration Routes (/integrations)
Section titled “Integration Routes (/integrations)”| Method | Path | Description |
|---|---|---|
| GET | /integrations/communication |
Retrieve communication integration settings for an organization |
| POST | /integrations/slack |
Configure or test Slack integration |
| POST | /integrations/teams |
Configure or test Microsoft Teams integration |
| POST | /integrations/discord |
Configure or test Discord integration |
| GET | /integrations/monitoring |
Retrieve monitoring integration settings |
| PUT | /integrations/monitoring |
Save monitoring integration settings |
| POST | /integrations/monitoring/test |
Test monitoring endpoint connectivity |
| GET | /integrations/ticketing |
Retrieve ticketing integration settings |
| POST | /integrations/ticketing |
Save ticketing integration settings |
| POST | /integrations/ticketing/test |
Test ticketing endpoint connectivity |
| GET | /integrations/psa |
Retrieve legacy PSA settings (use /psa routes instead) |
| POST | /integrations/psa |
Save legacy PSA settings |
| PUT | /integrations/psa |
Update legacy PSA settings |
| POST | /integrations/psa/test |
Test legacy PSA connection |
PSA Routes (/psa)
Section titled “PSA Routes (/psa)”| Method | Path | Description |
|---|---|---|
| GET | /psa/connections |
List PSA connections (filterable by orgId, provider) |
| POST | /psa/connections |
Create a new PSA connection with encrypted credentials |
| GET | /psa/connections/:id |
Get a single PSA connection detail |
| PATCH | /psa/connections/:id |
Update connection name, credentials, or settings |
| DELETE | /psa/connections/:id |
Delete a connection and its ticket mappings |
| POST | /psa/connections/:id/test |
Test connection credentials |
| POST | /psa/connections/:id/sync |
Trigger a manual data sync |
| POST | /psa/connections/:id/status |
Update connection status |
| GET | /psa/connections/:id/tickets |
List ticket mappings for a connection |
| GET | /psa/tickets |
List all ticket mappings across accessible connections |
Database Schema
Section titled “Database Schema”PSA connections and ticket mappings are stored in two tables defined in the integrations schema.
psa_connections
Section titled “psa_connections”| Column | Type | Description |
|---|---|---|
id |
UUID | Primary key |
org_id |
UUID | Organization this connection belongs to |
provider |
enum | PSA provider (connectwise, autotask, jira, servicenow, freshservice, zendesk) |
name |
varchar(255) | Display name for the connection |
credentials |
JSONB | Encrypted credential payload (AES-256-GCM) |
settings |
JSONB | Provider-specific configuration (board, project, defaults) |
sync_settings |
JSONB | Internal sync metadata including lastTestedAt and status |
enabled |
boolean | Whether the connection is active (default: true) |
last_sync_at |
timestamp | Last successful sync time |
last_sync_status |
varchar(50) | Status of the most recent sync (queued, running, completed, failed) |
last_sync_error |
text | Error message from the last failed sync |
created_by |
UUID | User who created the connection |
created_at |
timestamp | Creation timestamp |
updated_at |
timestamp | Last modification timestamp |
psa_ticket_mappings
Section titled “psa_ticket_mappings”| Column | Type | Description |
|---|---|---|
id |
UUID | Primary key |
connection_id |
UUID | Foreign key to psa_connections |
alert_id |
UUID | Associated Breeze alert (nullable) |
device_id |
UUID | Associated Breeze device (nullable) |
external_ticket_id |
varchar(100) | Ticket ID in the external PSA system |
external_ticket_url |
text | Direct URL to the external ticket |
status |
varchar(50) | Current ticket status |
last_sync_at |
timestamp | Last sync timestamp for this mapping |
created_at |
timestamp | Creation timestamp |
updated_at |
timestamp | Last modification timestamp |
Troubleshooting
Section titled “Troubleshooting”Communication webhook not receiving notifications.
Verify the webhook URL is correct and publicly reachable. Use the "test": true flag to send a test notification. Check that your messaging platform has not revoked or rotated the webhook token.
PSA connection test fails.
Confirm that the credentials are correct and the PSA platform’s API is accessible from your Breeze API server. Some providers require IP allowlisting or VPN access. Check the lastTestedAt and sync status fields on the connection for additional context.
“Failed to encrypt credentials” error on PSA connection creation.
The APP_ENCRYPTION_KEY environment variable is not set or is invalid. It’s required in every environment – the API will not start without it.
Ticket mappings not appearing. This is expected today – PSA ticket sync is not implemented yet (see PSA Integrations), so no ticket mappings are ever created.
“Organization context required” error.
Integration routes require an organization scope. If you are authenticated with a partner or system scope, pass the orgId query parameter or include it in the request body to specify which organization’s integrations you are managing.
Deleted connection – can I recover ticket mappings? No. Deleting a PSA connection removes all associated ticket mappings from the database. This action is irreversible. Export or back up ticket data before deleting a connection if you need to retain it.