---
schema_version: "1"
id: 41079447c36c4f8e976fa0b8aa58cfc44750f3d8a7793362d864c4c597b21995
title: Run Apex on Package Install/Upgrade
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/platform-pkg-exchange/managed_packaging/guides/first-generation/pd-apex-post-install-script.md
canonical_url: https://developer.salesforce.com/docs/platform/pkg2-dev/guide/pd-apex-post-install-script.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 2ac14ede513538db9efca7e1f26fb9919efaf4e90686c01e0f7a50505e3e2185
products:
  - Second-Generation Managed Packaging Developer Guide
  - merged-docs
---

# Run Apex on Package Install/Upgrade

App developers can specify an Apex script to run automatically after a subscriber installs or upgrades a managed package. This script makes it possible to customize the package install or upgrade, based on details of the subscriber’s organization. For instance, you can use the script to populate custom settings, create sample data, send an email to the installer, notify an external system, or kick off a batch operation to populate a new field across a large set of data. For simplicity, you can only specify one post install script. It must be an Apex class that is a member of the package.

The post install script is invoked after tests have been run, and is subject to default governor limits. It runs as a special system user that represents your package, so all operations performed by the script appear to be done by your package. You can access this user by using UserInfo. You can only see this user at runtime, not while running tests.

If the script fails, the install/upgrade is aborted. Any errors in the script are emailed to the user specified in the **Notify on Apex Error** field of the package. If no user is specified, the install/upgrade details are unavailable.

The post install script has the following additional properties.

- It can initiate batch, scheduled, and future jobs.
- It can’t access Session IDs.
- It can only perform callouts using an async operation. The callout occurs after the script is run and the install is complete and committed.
- It can’t call another Apex class in the package if that Apex class uses the `with sharing` or `inherit sharing` keyword. These keywords can prevent the package from successfully installing. To learn more, see the [Apex Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_keywords_sharing.htm).

**note:** You can’t run a post install script in a new trial organization provisioned using Trialforce. The script only runs when a subscriber installs your package in an existing organization.

- **[How Does a Post Install Script Work?](https://developer.salesforce.com/docs/platform/pkg2-dev/guide/apex-post-install-script-intro.md)**


    A post install script is an Apex class that implements the `InstallHandler` interface.

- **[Example of a Post Install Script](https://developer.salesforce.com/docs/platform/pkg2-dev/guide/apex-post-install-script-create.md)**

- **[Specifying a Post Install Script](https://developer.salesforce.com/docs/platform/pkg2-dev/guide/pd-apex-post-install-script-specify.md)**


    After you’ve created and tested the post install script, you can specify it in the **Post Install Script** lookup field on the Package Detail page. In subsequent patch releases, you can change the contents of the script but not the Apex class.
