Skip to main content

PSA integration (HaloPSA)

dotMARC can open a HaloPSA ticket when an alert fires, close it automatically when the alert resolves, and resolve the alert back when a tech closes the ticket directly in Halo. See Alerts for how alerting itself works - this page covers wiring it to HaloPSA specifically.

Set up the Halo API application

In HaloPSA, go to Configuration → Integrations → HaloPSA API and create an application with these scopes: edit:tickets, read:tickets, read:customers, read:teams. Note its account name, auth server URL, resource server URL, client ID, and client secret.

Configure dotMARC

From Alert settings, in the PSA integration (HaloPSA) section: enable it, fill in the account name/URLs/client ID, and paste in the client secret (it's write-only - once saved, you won't see it again, only whether one is configured). Click Load ticket types / priorities / statuses from Halo to populate the three dropdowns, pick the ticket type new tickets should use, the default priority, and which Halo status counts as "closed" for resolving the alert back.

Click Generate new webhook secret, click Save PSA settings, then copy the shown webhook URL into HaloPSA's own outbound webhook configuration, triggered on ticket status change. Save first - the secret only takes effect once it's persisted, so a URL copied before saving 404s until you do. This is what lets a ticket closed directly in Halo resolve the dotMARC alert.

Where the client secret itself is stored (Postgres, encrypted, or Azure Key Vault) depends on your deployment, see Deploy to Azure if you're running on Azure and want it in Key Vault.

Route tickets to the right client

Tickets need to land against the right Halo client (company). From Manage groups, each Group gets a Halo Client picker - set once per Group (typically once per MSP client), every domain in that Group routes there. If a Group's name matches a Halo client's name, a suggested match appears; review and click Use it rather than it being applied automatically. A domain that needs to route differently than its Group can be overridden individually from Manage domains.

A domain with no mapping (no Group, or a Group with none set) simply doesn't get a ticket, same as leaving the generic webhook URL blank, it isn't an error.

What syncs, and what doesn't

  • Alert fires → ticket created, using the alert's title/message as the ticket's summary/details, filed under the configured ticket type and default priority.
  • Alert resolves in dotMARC (the report comes back, or a later TLSRPT report has no failures) → ticket closed in Halo automatically.
  • Ticket closed in Halo → alert resolved in dotMARC automatically, via the webhook above.
  • Nothing else syncs: no comments, and no changes made directly in Halo (priority, reassignment, notes) flow back to dotMARC - only a status change to the configured "closed" status is read. If the underlying condition is still active after a ticket's closed early in Halo, the very next monitor cycle (not the cooldown window) re-opens the alert, since the cooldown only gates re-creation while an alert is still unresolved - once resolved, the next cycle sees no unresolved alert and creates a fresh one immediately. A new ticket for that fresh alert is opened too, unless another ticket for the same domain and alert type is already open, in which case ticket creation is skipped for that occurrence (dotMARC's own alert history still gets the new row either way) - this is expected, not a sync bug.

Two other things worth knowing:

  • The Halo Client column on Manage Groups/Manage Domains only appears once HaloPSA is both enabled and has a saved client secret - enabling it alone isn't enough to see the column.
  • Ticket priority syncs from dotMARC to Halo once, on ticket creation (the configured default priority). It does not sync afterwards in either direction: a priority change made later, in dotMARC or in Halo, doesn't propagate to the other side.