What Current writes back to HaloPSA (and when)
Current pulls a lot from HaloPSA, but it also writes back — task schedules, status changes, comments, time (as Halo actions), and CRM activity all flow the other direction once you allow them. This page lists exactly what triggers a push, the gates in front of every write, how a Halo write physically works, and the hard boundaries Current never crosses. For the full pull-side field reference, see "HaloPSA sync: the complete field-mapping reference".
The gates, in order
- 1Only HaloPSA-synced projects ever pushA Current-native project makes no Halo calls at all, and a project synced to a since-disconnected PSA is frozen — the engine refuses cross-provider operations outright (a job that reaches the wrong engine fails closed rather than writing to the wrong PSA).
- 2The two-way sync switch governs task fieldsIntegrations → HaloPSA → Manage. It controls the task-field pushes and field-by-field conflict resolution. Its position is per workspace — check it deliberately as part of your go-live plan.
- 3CRM write mode governs every CRM writeOff by default — no CRM writes at all. Test mode allows writes only against companies whose Halo name starts with "ZZ-Current Test" (older "ZZ-Cascade Test" names still count); live mode is an explicit admin action, taken after test writes have landed correctly.
What triggers a push, by entity
| Your action in Current | What's written to HaloPSA |
|---|---|
| Drag a task to a new date on the Timeline or Schedule | The child ticket's new start and end dates |
| Change a task's status (Kanban or task drawer) | The child ticket's status, through your status mapping |
| Edit a task's synced fields (with two-way sync on) | That field's new value, if your edit is newer than Halo's last change to it |
| Comment on a task | A note (action) on the ticket |
| Save a time entry | A new Halo action on the ticket with the hours, the charge rate, the contract, and the billable flag you picked |
| Create or edit a CRM company, add a contact, or log a note | The matching Halo record (gated by CRM write mode); a company push also writes its account manager back as Halo's account-manager agent |
| A new lead arrives (website form or added by hand) | A new Halo client plus its contact — created without a client type, because Halo has no prospect field Current can set (see the note below). A lead that matched a company you already have is linked instead, and a lead imported from a saved list is never pushed |
| Create a deal or move it to a new pipeline stage | A new or updated opportunity, through your stage mapping |
| Convert a won quote | The project build and product charges in Halo, and the quote/opportunity moved to your converted state |
| Click "Build in HaloPSA" on a Current-native project or playbook | A brand-new Halo project, with its milestones (phases) and child tickets |
How Current writes: array upsert keyed on the Halo id
Halo has no separate update call — you write a record by POSTing it, and Halo decides create-vs-update from whether the record carries its id. That makes the id the safety property: every update Current sends carries the mirrored Halo id it stored when the record was first created or pulled, so Halo updates the existing record instead of quietly creating a duplicate. A create returns the new record, and Current stores that id immediately, so a retry can never make a second copy.
Verify-after-write: no silent successes
After every push, Current reads the record back from Halo and compares what landed against what it sent. A write that Halo accepted but quietly adjusted — a clamped date, a defaulted field — is reported as a residual, not swallowed. And if a push fails, the error surfaces Halo's real message, never a generic "sync failed."
Time entries, billing, and prepay
- +Time is logged as a Halo action on the ticket. Current writes a new action and never edits or deletes one that already exists in Halo — every push is claimed once and confirmed by Halo's response, so a retry can't create a duplicate.
- +An invoiced action is untouchable. Once a Halo action is attached to an invoice, Current treats it as final — it will not edit, delete, or retry it, because no write can succeed on invoiced time.
- +Prepay is protected. Logging billable time against a Pre-Pay contract draws down the client's prepaid balance in Halo, so Current's claim-once, confirm-by-response rule is exactly what stops a retry from double-charging or over-drawing prepaid hours.
- +After a push, the action's billed hours and invoice status are read back on a cycle — and Current only ever promotes an entry toward billed and invoiced, never demotes one. Billed hours can differ from logged hours because Halo's rate engine applies its own minimums, increments, and multipliers; that's Halo working, not an error.
Retry and dead-letter behavior
- +Retryable failures — Halo's rate limit (429), timeouts, temporary Halo errors — retry automatically with increasing delays, and a write is never blindly re-sent (see the time-entry rule above).
- +After repeated failed attempts, a job is marked dead-letter and stops retrying on its own — it needs a person to look at it.
- +Validation errors and permission errors are never auto-retried — these need a fix, not a delay.
- +CRM pushes notify your sales leadership once a push has dead-lettered, so it doesn't sit silently.
What a push can never touch
- +Contracts, recurring invoices, and anything else in your billing structures — read-only in every direction.
- +Invoiced actions, and hours already billed and posted.
- +The product catalog — charges reference catalog items; they never create or reprice them.
- +Halo's own computed rollups — project completion percentage and the like are read for display, never written back.
- +Records outside your API application's permission scope — Halo's own permissions are the final gate.
- +Anything at all while the relevant gate (two-way sync, CRM write mode) is closed.
This boundary is intentional: billing accuracy depends on Halo staying the single source of truth for anything that touches an invoice. See "Reading the sync health dashboard (and fixing a stale sync)" for where failures surface.
