Setup: Exalate on both sides of a Jira Cloud ↔ Jira Cloud connection, script-based (Groovy) sync rules.
Context: When an issue is under sync, our outgoing/incoming scripts maintain a few custom fields on the issue (ex: remote reference fields).
Problem: When a user manually Unexalates an issue (via the Exalate panel or bulk Unexalate), those fields become stale they still show the issue as synced. Exalate does not seem to offer any native trigger, event, or script hook that fires on Unexalate, so we have no way to clean up / update those fields at that moment.
Question: Is there any way to detect that an issue has been unexalated so we can update fields on it? For example:
An “onUnexalate” hook or event in the sync rules?
A webhook or notification fired by Exalate when a twin trace is removed?
A supported way to query Exalate (REST API) for the sync status of issues, so we could poll periodically (e.g., scheduled Jira automation + Exalate API) and detect issues whose twin trace no longer exists?
Any recommended pattern others use for this (marker fields, entity properties, scheduled reconciliation jobs)?
Any pointers or workarounds would be much appreciated. Thanks!
You’ve outlined the challenge really well—currently, Exalate doesn’t provide a direct “onUnexalate” event or script hook that fires when an issue is unexalated, so there’s no native way to trigger cleanup actions in your sync rules at that exact moment. However, there are some practical workarounds and patterns you can use:
Polling the Exalate REST API for Sync Status
You can use the Exalate REST API to periodically check which issues are still exalated. Specifically, you can query for the existence of a sync connection (twin trace) for each issue. If your custom fields indicate an issue is synced, but the API shows no active sync, you know it’s been unexalated and can trigger cleanup via Jira automation or a scheduled job.
See the Exalate REST API documentation for endpoints like /issue/{issueKey}/connections to check sync status.
Scheduled Jira Automation
Combine the above with Jira Automation:
Schedule a rule to run periodically.
For each issue with your custom “synced” marker, call the Exalate API to check if it’s still exalated.
If not, clear or update your custom fields.
Marker Fields or Entity Properties
Since Exalate doesn’t remove custom fields or properties on unexalate, using a scheduled reconciliation job (as above) is the most reliable way to keep them accurate.
Webhooks
Currently, Exalate does not fire a webhook specifically for unexalate events. You can see more about available webhooks here: Webhooks in Exalate.
Summary:
There is no direct “onUnexalate” hook or event.
Polling the Exalate REST API and reconciling with your marker fields is the recommended workaround.
No native webhook is fired on unexalate.
Scheduled reconciliation jobs are a common pattern for this scenario.
Thanks for flagging the broken links — and I’ve got a better answer than the polling route mentioned before.
First, to confirm the core point: Exalate has no “onUnexalate” script hook. Internally, unexalate is a cleanup event — it removes the sync/twin-trace and deliberately does not run your incoming/outgoing sync rules, so there’s no way to reset your marker fields from within the sync rules at that moment.
This lets you trigger unexalate from a workflow transition instead of the manual button. Because it’s a transition, you can attach your own cleanup to the same transition — a standard “Update/Clear field value” post function, or a ScriptRunner scripted post function ordered right after the Unexalate Now one. The result is a single atomic action:
one transition → Unexalate Now post function + your field-reset post function
That gives you the immediate, event-driven “on-unexalate” hook you were after, rather than an eventually-consistent job.
One boundary to be aware of: this only fires for unexalates that go through that transition. It won’t cover the manual Unexalate button on the sync panel, bulk unexalate via a trigger, or a remote-initiated unexalate from the other side. If you can make this transition the sanctioned “stop syncing” path, that’s fully covered.
Backstop for the ad-hoc paths (optional): a reconciliation job.
So: use the workflow post function as the primary, immediate hook, and keep the reconciliation job only as a safety net for out-of-band unexalates.
Let me know if you need a sample post-function/script setup or the polling loop if useful.
Helli @Sonal_Otwani
I had actually considered this approach already, but since I have multiple synchronized tickets and users may need to unsync only one of them rather than all of them, I think it would either be complicated to implement or not very user-friendly.
I’ll keep it as a fallback option and explore it further if no better solution is available.
Regarding the reconciliation job, is there any documentation available on how it works?