---
title: Lifecycle
slug: data-platform/connect-platform/ocpcoreconcepts-lifecycle
docTags: 
createdAt: 2026-08-05T20:06:36.783Z
---

## The basics

The Lifecycle is how you manage all the stages of an app:

- Install
- Settings
- Form submission
- Upgrades
- Uninstalls

App template generated by `ocp app init` contains a skeleton of lifecycle methods. Add any logic your application needs there.

## Settings form submission

One of the core components in creating your app is interacting with the [settings.yml](docId\:GWRZD0rP4MVXA78SMqQul). Handling the actions and being able to validate keys or communicate toasts back into the Connect Platform for Optimizely Data Platform (ODP) application.

Here is a sample `settings.yml` and the associated `onSettingsForm` from the Lifecycle that handles the interactions from it.

### settings.yml

```yaml
sections:
  - key: auth
    label: Authenticate
    properties:
      - authConfirmed
    elements:
    - type: secret
      key: client_id
      label: Client ID
      help: Get your Client ID from Vendor
    - type: secret
      key: client_secret
      label: Client Secret
      help: Get your Client Secret from Vendor
    - type: button
      label: Authorize
      style: primary
      action: authorize #<-- action passed in
      disabled:
        key: client_id
        empty: true
  - key: config
    label: Configuration
    properties:
      - canImport
    disabled:
      key: auth.authConfirmed
      equals: false
    elements:
    - type: toggle
      key: winback
      defaultValue: true
      label: Winback
      help: Toggle to send Winback segment to Vendor (engaged, winback, churned)
    - type: toggle
      key: order_likelihood
      defaultValue: true
      label: Order Likelihood
      help: Toggle to send Order Likelihood segment to Vendor (Extremely Likely, Very Likely, Likely, Unlikely)
    - type: toggle
      key: discount_affinity
      defaultValue: true
      label: Discount Affinity
      help: Toggle to send Discount Affinity segment to Vendor (Always, Sometimes, Never)
    - type: button
      label: Save
      action: save #<-- action passed in
      style: primary
    - type: button
      label: Start Initial Import
      action: import #<-- action passed in
      disabled:
        key: canImport
        equals: false
```

### `onSettingsForm`

Each time the form is submitted you can handle interactions with the form and also set variables for use in the forms for enabling new sections.

```typescript
import {Vendor} from '../lib/Vendor';
  
  ...

  public async onSettingsForm(
          section: string, action: string, formData: App.SubmittedFormData
  ): Promise<App.LifecycleSettingsResult> {
    const result = new App.LifecycleSettingsResult();
    const vendor = new Vendor();
    try {
      switch (action) {
      case 'authorize': // <-- switching on the action from above
        try {
          await vendor.validateAuth(formData);
          formData.authConfirmed = true; // <-- setting a variable for use in settings.yml
          await storage.settings.put(section, formData); // <-- saving form data
          result.addToast('success', 'Authorized');
        } catch (e) {
          logger.error('issue authenticating', e);
          result.addToast('warning', 'Could not Authenticate, please validate your information is correct');
        }
        break;
      case 'save':
        try {
          await vendor.createObjects(formData);
          formData.canImport = true;
          await storage.settings.put(section, formData);
          result.addToast('success', 'Ready to Import');
        } catch (e) {
          logger.error('Issue creating objects', e);
          result.addToast('warning', 'Could not create audiences');
        }
        break;
      case 'import':
        logger.info('Starting Job');
        await App.jobs.trigger('nightly_export', {}); // <-- starting a Job
        result.addToast('info', 'Sync Started');
        break;
      }
      return result;
    } catch (e) {
      logger.error('Issue:', e);
      return result.addToast('danger', 'Sorry, an unexpected error occurred. Please try again in a moment.');
    }
  }
```

## App installation

When an app is installed to an ODP account, the `onInstall` method is called.
The method should contain any logic that is required to initialize the app, for example:

- initialization of KV storage
- registering webhooks in third-party services
- performing dynamic ODP schema amendments via API (declarative schema changes are performed automatically by Connect Platform for ODP before the method is called)
- etc.

## App upgrades

When an app is upgraded to a new version, either by an auto-upgrade or a manual upgrade, Connect Platform for ODP calls three lifecycle methods:

- `onUpgrade` - this method is called after declarative schema changes are performed by Connect Platform for ODP. It can be used to perform dynamic schema changes via API.
- `onFinalizeUpgrade` - this method is called after webhook URLs are created for all new functions in the version. Use it to register webhooks in a third-party service if needed.
- `onAfterUpgrade` - this method is called after the upgrade is completed. It can be used to trigger any required one-off jobs.

Keep in mind the upgrade is not necessarily from the previous most recent version.
The previous version of the app is provided in 'onUpgrade' method attribute.

## Authentication

`onAuthorizationRequest` and `onAuthorizationGrant` are called as part of the authorization process initialized by
clicking on [OAuth Button](docId\:V5iqIFcSz3Zl7fFExP8mL) element type in app settings form.
Refer to [authentication doc](docId\:fS7u929rUh_eCow3L6o3M) for more details.

## Uninstalling an app

When an app gets uninstalled from an ODP account, Connect Platform for ODP calls `onUninstall` lifecycle method.
The method should contain the logic to clean up after the app is uninstalled.
This might include invalidating authentication tokens in third-party services,
removing resources from third-party services, etc.
