← Blog

Update,

Apps Can Now Subscribe to Their Own Lifecycle

Łukasz Ostrowski

Apps can now reliably react to their own installation, activation, and removal — making clean uninstallation a first-class pattern in Saleor 3.23.

When a merchant uninstalls your app,

your app should know.

Until now, apps couldn't reliably observe their own lifecycle. Events like APP_DELETED were silently dropped unless the receiving app held the MANAGE_APPS permission — and even then, an already-deactivated or soft-deleted app would never receive them. The net effect: apps had no dependable signal that they had been removed.

Starting with Saleor 3.23, the four app lifecycle events — APP_INSTALLED, APP_UPDATED, APP_STATUS_CHANGED, and APP_DELETED — are delivered reliably to the app they relate to. No permission gate, no edge cases where the event quietly disappears.

Clean uninstallation, finally

The most useful pattern this unlocks is letting an app clean up after itself when a merchant removes it. Subscribe to APP_DELETED and use it to tidy up state Saleor cannot reach on your behalf:

  • Remove tenant rows from the app's own database.
  • Revoke credentials issued to third-party services for the merchant.
  • Cancel subscriptions or scheduled jobs scoped to the tenant.
  • Delete uploaded files or generated reports tied to the installation.

There's no need to clean up data inside Saleor — the App object, its privateMetadata, and its auth token are already gone. APP_DELETED is purely a signal for everything outside.

Subscribing from the manifest

Declare the webhook like any other async event. No extra permissions required:

JSON
1{
2 "webhooks": [
3 {
4 "name": "App deleted",
5 "asyncEvents": ["APP_DELETED"],
6 "query": "subscription { event { ... on AppDeleted { recipient { id } } } }",
7 "targetUrl": "https://my-app.example.com/api/webhooks/app-deleted"
8 }
9 ]
10}

The payload exposes both the app the event relates to and the recipient receiving the webhook, and the request carries the standard saleor-api-url header — enough to match the event back to a specific installation in your own storage.

A note on deactivation

APP_STATUS_CHANGED fires on both activation and deactivation. Treat deactivation as a pause, not a removal — the installation still exists and can be re-enabled. Disable background work, but reserve destructive cleanup for APP_DELETED.

Documentation

For the full guide — including subscription payloads and tenant identification — see the new docs page.

Subscribing to App Lifecycle Webhooks

    Get more useful guides, tech insights, and free learning materials by subscribing to our list.
    All human-written!

    By registering you agree to our Privacy Policy.
    The form is protected by reCAPTCHA - Privacy Policy and Terms of Service.