Connect HaloPSA
Create an API Application in HaloPSA, then paste four fields into DarkBird.
DarkBird connects to HaloPSA using OAuth 2.0 Client Credentials (no user login required). You will create a dedicated API Application inside HaloPSA, then paste its credentials into Settings → Integrations → HaloPSA.
Step 1 — Create an API Application
- Configuration → Integrations → HaloPSA API
Click View Applications, then New.
- Name and authentication
Set the Application Name to DarkBird and Authentication Method to Client ID and Secret (Services) — the option marked "for backend non user-facing applications only" (not Username & Password, Implicit Flow, or Authorisation Code).
- Login type and agent
Set Login Type to Agent, then pick an Agent to log in as — this field is required. Use a dedicated, non-human agent (e.g. named DarkBird Integration) rather than a real technician's own login: that keeps the sync's actions attributable to DarkBird in Halo's own audit trail instead of to a person, and the integration keeps working if that person leaves or their access changes. This agent does not need to be a Halo Admin or Superuser — it only needs functional access to the areas DarkBird actually touches (Projects, Tickets, Customers, Items, Quotes, Timesheets — see the table below). Whatever this agent can see in Halo is the ceiling for what DarkBird can sync, no matter what you grant on the Permissions tab in the next step.
- Set permissions
On the Permissions tab, check exactly the scopes in the table below — least privilege, nothing broader. Don't check all or all:standard; DarkBird doesn't need them.
- Save and copy credentials
Back on the Details tab, copy the Client ID, then click Generate and Copy next to Client secret. Copy both immediately — the secret is shown only once, and generating a new one invalidates the old one.
Step 2 — Permissions to grant
Check these boxes on the Permissions tab — DarkBird touches these areas and nothing else, so this is the least-privilege set. Missing any one of them will make that piece of the sync fail (silently, until you notice the symptom), so check every row, not a subset.
| Area | Scopes to check | Used for |
|---|---|---|
| Projects | read:projects | Linking the won Halo project |
| Tickets | read:tickets, edit:tickets | Reading opportunities; pushing the WBS as phase/task tickets |
| Sales | read:sales | Listing opportunities — check it if your opportunity list comes back empty |
| Customers | read:customers | Client and site lookup when linking an opportunity |
| Items | read:items | Syncing the Halo product catalog |
| Quotes | read:quotes, edit:quotes | Pushing a quote with BOM lines onto the linked opportunity |
| Timesheets | read:timesheets | Pulling time entries back as actuals |
DarkBird's server always requests the OAuth `all` scope when it authenticates (it never asks for a named subset) — but the token Halo actually grants is capped by what this Application is configured for, so checking only the rows above still keeps the connection to least privilege. If a sync fails with a permission error after connecting, it means one of those boxes got missed — recheck the table above before reaching for the broader `all:standard` / `all` scopes.
On the Security tab, leave the CORS Whitelist blank. It only matters for an integration calling the Halo API from inside a browser — DarkBird's calls all originate server-side.
Step 3 — Enter credentials in DarkBird
Go to Settings → Integrations → HaloPSA and click Connect. Fill in all four fields:
| Field | Where to find it |
|---|---|
| Client ID | Shown on the API Application page in HaloPSA after saving |
| Client Secret | Shown once when the application is first created — copy before closing |
| Tenant Name | The subdomain of your HaloPSA URL, e.g. yourcompany from yourcompany.halopsa.com |
| API URL | Your full HaloPSA domain, e.g. https://yourcompany.halopsa.com |
On first connect, DarkBird automatically imports your HaloPSA product/item catalog. This may take a moment for large catalogs.
Step 4 — Tell DarkBird which ticket types and statuses mean what
HaloPSA ticket types and statuses are fully customizable per account, so DarkBird cannot guess which ones to use. Right after you connect, it fetches your account's actual ticket types and statuses and asks you to choose:
- Opportunity ticket types (required) — the types your team uses for sales opportunities, usually Opportunity. A HaloPSA opportunity is a ticket of one of these types; the list also contains Leads and Quick Quotes, which DarkBird leaves out unless you tick them.
- Project ticket types (required) — the types for delivery projects, usually Project. Not the tasks inside them: a Project Task is not a project.
- Won and lost statuses (optional) — which statuses mean an opportunity was won or lost. Every other status counts as open, and won or lost opportunities are hidden when you link one.
- Ticket type for pushed project plans — the type DarkBird uses for the phase and task tickets it pushes. Some ticket types enforce required fields through a workflow, so pick the one your team uses for project work.
- Status that means "completed" (optional) — used to find completed projects for Concierge import.
The opportunity and project types are pre-selected by name when your ticket types are called Opportunity and Project — check them and save; nothing is stored until you do. You can skip this and finish later from Settings → Integrations → HaloPSA (a Finish HaloPSA setup banner reminds you) or with the gear icon on the connected card.
Linking an opportunity or the won project will refuse (with a clear message) until those types are chosen, and Sync Plan will refuse until a plan ticket type is chosen — DarkBird never guesses a type or pushes tickets into a default one.
What DarkBird does in HaloPSA
- Link the opportunity — In the Estimate phase strip, click Link opportunity and pick the existing HaloPSA opportunity (a ticket of your Opportunity type). The opportunity is the hub for the project. DarkBird never creates opportunities in HaloPSA — create it there first if it does not exist. When you start a new project from the HaloPSA tab, the same picker applies and the client name and site data pull in automatically.
- Push the quote — When Settings → Integrations → Quoting is set to HaloPSA, Push to HaloPSA quote creates a new quotation tied to the linked opportunity, with all BOM line items and a total labor hours summary. Products synced from HaloPSA are matched by catalog ID; manually-entered products appear as description-only lines. Each push creates a new quote.
- Sync Plan to HaloPSA — On the Deliver tab, push the WBS to the linked project. Each DarkBird phase becomes a parent ticket; each task becomes a child ticket with budget hours, using the ticket type configured in Step 4. If the DarkBird project is still linked to the opportunity, use Link won project in the Deliver strip first — it lists only your Project-type tickets.
- Pull actuals from HaloPSA — in the Review phase, pull time entries logged against the project. Hours are matched to DarkBird tasks by name and populate the Actuals column for calibration; a ticket renamed on the HaloPSA side after DarkBird created it will not match — its time is skipped rather than mis-attributed.
- Product Catalog Sync — Automatically runs on first connect and can be re-run from Settings → Integrations → HaloPSA → Sync Products.
DarkBird never deletes records in HaloPSA. Sync operations only create or read.