Forge Lifecycle Uninstalled Event

We have the installed and upgraded events, but I’m missing the uninstalled event. Especially if the app uses a remote backend, an uninstall event would be useful for cleanup.

Any change the uninstalled can be added of the list of events?

@AdamMoore including you since I saw your posts related to the install and update events.

It is a long-requested feature: [FRGE-1246] - Ecosystem Jira

Thanks @SilvreLestang for pointing me to the open ticket.

@SeanBourke @AdamMoore the request has been outstanding for a long time now, any thoughts on when we can expect the uninstalled lifecycle event?

Hey @markrekveld yes it’s definitely on the list of things we know we need to do but I don’t have an ETA to share at the moment.


Hi @AdamMoore that is good to know thanks.

Will the release of the uninstalled event also include an API that a remote can use to verify that the installations the remote has in its database ate still active, or should be cleaned up?
Or is there already an API for this? If so, a possible temporary workaround could be to schedule a daily task to verify the state of tenants.

The longer it takes for this event to be available, the dirtier the database of the remote becomes not knowing which tenants are active and which are not. This also impact being able to follow data retentions and privacy policies.

1 Like

@markrekveld is 100%right.

As we move to Forge + remotes, we really need a way to know that an app has been uninstalled, AND a way to check regularly, from outside of Forge, if the app is still installed on an instance, so we can clean up its data to be legally compliant. Also, we need the uninstallation date, because the data must be clean up 30 days after uninstallation, not before, not after.

This has been a nightmare to do properly with Connect, please please please do better with Forge.

Hey @SilvreLestang,

I’d be keen to understand more about what makes this a nightmare in Connect. Do these challenges relate to the existing uninstallation hook, or are they broader than this?

From my own experience I cannot say I agree with this statement.
I added all the possible events to the lifecycle module in the descriptor like this

  "lifecycle": {
    "installed": "/installed",
    "uninstalled": "/uninstalled",
    "enabled": "/enabled",
    "disabled": "/disabled"

This makes the app receive all lifecycle events and handle those.

Next to this I use the https://[site-name]{key} and https://[site-name] APIs in a daily task to update generic details like the instance cloudId, license data, user count, version of the app installed.

The combination of the module and the APIs give me confidence that the app can be kept clean without me doing anything manually.


Hey @SeanBourke,

The uninstallation hook is not always call, particularly when the instance is killed by Atlassian, or in the case of sandbox, where a new sandbox trigger a new installation but without uninstalling the previous one (if I remember correctly).
Also, we didn’t update our installations table with the uninstallation date for the first year, so we have a lot of installations with an unknown state.

So to ensure that we clean customers data 30 days after uninstallation with do:

  1. the uninstall hook update the installations table with an uninstallation_date
  2. a job execute everyday and clean the data when the uninstallation_date is past 30 days
  3. another job execute everyday and check the installations with the licenses data that we get from Atlassian Marketplace, base on the app_entitlement_id => if there is an evaluation_end_date, we set the installation.uninstallation_date = license.maintenance_end_date

But even with this, there are corner cases that we don’t cover. For example, some of the rows in installations are old enough to not have an app_entitlement_id => what should we do in this case ? Consider that the app has not been updated for a long time, therefore it is safe to assume it is not installed anymore ?

All of this seems way too complicated just to know if our apps are installed, or not, on some instances.

A thread on this subject where they do things differently:

Also from

There is a trick if you want to know who still has your app installed:

Publish a new micro change in your descriptor,
Atlassian picks up on it, upgrades all instances (assuming you haven’t recently made a major upgrade that customers could reject),
After 24hrs, you can unsafely assume that the remaining instances have uninstalled your app, and you have missed the uninstall hook (but this assumption is unsafe, I insist, don’t straight up delete data and don’t accuse me if it doesn’t work).

1 Like

Hey @SilvreLestang and @markrekveld,

Thanks for the feedback.

@SilvreLestang, you’ve noted that you have a lot of older installations where you do not have awareness of whether they are installed or not. Unlike the installation hook which is guaranteed on installation, if the uninstalled hook returns a non-2xx response, the app will still be uninstalled.

As @markrekveld has noted (as well as some of those threads), making a request to https://[site-name]{key} can be a good way to sense check and ensure whether the installation is still active. Once the app has been uninstalled, the app user is removed and the app will no longer be able to make requests to that instance.

Forge presents some new opportunities which otherwise would not be available in Connect. For example, Forge Remotes can be directly associated to Scheduled Trigger. This could present new opportunities to implement behaviours such as heartbeats; where the schedule trigger would no longer be emitted once an app is uninstalled.


Thanks for the schedule trigger tip, looks like a good workaround for now.

1 Like