Subscribing to App Lifecycle Webhooks
Apps can subscribe to webhooks describing their own lifecycle. This allows the app to react to its own installation, deactivation, or uninstallation — for example, to provision tenant data on install or to clean up after itself when removed.
Available in Saleor 3.23+.
Available events
The following asynchronous webhook events describe the app lifecycle:
| Event | Triggered when |
|---|---|
APP_INSTALLED | A new app finishes installation. |
APP_UPDATED | An app is updated (for example, its permissions or webhooks change). |
APP_STATUS_CHANGED | An app is activated or deactivated via appActivate or appDeactivate. |
APP_DELETED | An app is removed via appDelete. |
The corresponding GraphQL subscription payloads are AppInstalled, AppUpdated, AppStatusChanged, and AppDeleted. Each payload exposes both the app the event relates to and the recipient — the app receiving the webhook.
Subscribing from a manifest
Declare the webhook in your app manifest just like any other async webhook:
{
"webhooks": [
{
"name": "App deleted",
"asyncEvents": ["APP_DELETED"],
"query": "subscription { event { ... on AppDeleted { app { id } recipient { id } } } }",
"targetUrl": "https://my-app.example.com/api/webhooks/app-deleted"
}
]
}
No extra permissions are required. Saleor delivers an app's own lifecycle events to the app, and this app only.
Cleaning up after uninstallation
The most common use case for APP_DELETED is letting the app clean up state it keeps in external services when the merchant removes it.
There is no need to clean up data inside Saleor: the App object is removed, its privateMetadata is dropped along with it, and the app's auth token is invalidated — calls back to Saleor would fail anyway. APP_DELETED is purely a signal to clean up things Saleor cannot reach.
Typical cleanup actions include:
- Removing tenant rows from the app's own database (configuration, mappings, cached resources).
- Revoking credentials issued to third-party services on behalf of the merchant.
- Cancelling subscriptions or scheduled jobs scoped to the tenant.
- Deleting object storage entries (uploaded files, generated reports) tied to the installation.
Identifying the tenant
The webhook body is signed and includes the standard saleor-api-url header, so the app can match the event to a specific Saleor installation in its own storage. Combined with the recipient.id field in the subscription payload, this is enough to locate and remove the right records.
subscription {
event {
... on AppDeleted {
recipient {
id
}
}
}
}
Reacting to deactivation
APP_STATUS_CHANGED fires on both activation and deactivation. Treat deactivation as a pause rather than a removal — the app installation still exists and can be re-activated, so prefer disabling background work over deleting tenant data. Use APP_DELETED for destructive cleanup.