---
sidebar_label: Lifecycle action specifications
doc_id: ed0da4fb-04db-4c59-a776-0135d1d5287d
description: >-
  Guide to designing and implementing lifecycle action specifications for scope
  management in nullplatform.
keywords:
  - lifecycle actions
  - scope specifications
  - nullplatform
  - deployment strategies
  - API integration
  - parallel execution
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Lifecycle action specifications

:::note Before you start

If you haven't already, read about [scopes' main concepts](/docs/agent-backed-scopes/overview).

Also, keep these references handy:

- **Scope Service Action Specification API**
  * [Our API reference](/docs/service-action-specification-api-index)
- **Schemas**  
  - [JSON Schema (external link)](https://json-schema.org/learn/getting-started-step-by-step)  
  - [Additional keywords supported by nullplatform](/docs/json-ui-schema/json-schema)  
  - [UI Schema (external link)](https://jsonforms.io/docs/uischema/)  
  - [How UI schema is integrated in nullplatform](/docs/json-ui-schema/overview)

:::

## Design your action specifications

Now that you have a scope specification, bring it to life by designing actions that nullplatform will invoke at
different points in the scope's lifecycle.

Here are some key design questions:

| Question                                                 | Guidance                                                                                                               |
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Which input parameters are required to create the scope? | This defines the contents of the JSON schema under the `attributes` field.                                             |
| What optional actions should be available?               | Think about actions that support specific operations, like adjusting traffic percentage during blue-green deployments. |


### Lifecycle: execution flow

The execution flow for lifecycle actions is illustrated below:

```mermaid
graph TB;
    Step1["Create scope"] -.-> Step0["The first deployment uses initial strategy"]:::note -.-> Initial;


    subgraph Initial["<b>Initial deployment process</b>"]
        direction LR
        Step20["Start initial"]

        note1["No switch traffic nor rollback here, as there is no old version running"]
    end

    subgraph BlueGreen["<b>Blue green deployment process</b>"]
        direction TB
       
        note4["After a blue green is finalized or roll-backed,<br> new ones can be created"]~~~blank1[" "]~~~blank2[" "]
        Step30["Start blue green"]-->Step31["Switch traffic"];
        Step31["Switch traffic"]-->Step32["Finalize blue green"];
        Step31["Switch traffic"]-->Step33["Roll back deployment"];
        note3["Switch traffic is executed<br> with different `desired_traffic` values "]~~~blank4[" "]~~~blank5[" "] 
       
    end

    Initial -.-> note2["Further deployments use the blue green strategy"]

    note2 -.-> BlueGreen

    
    classDef box fill:#cbd5e1,stroke:#94a3b8,stroke-width:1.4px,color:#0f172a;
    classDef note fill:#111827,stroke:#475569,color:#e2e8f0;
    classDef invisible fill:none,stroke:none;

    class note1,note2,note3,note4,note5 note
    class Initial,BlueGreen box
    classDef blank fill:none,stroke:none;
    class blank1,blank2,blank3,blank4,blank5 blank

```


## Define all required actions

Most scopes require at least these actions:

- **create** or **delete** the scope  
- Handle deployments, like triggering initial deployments or finalizing blue-green ones

In addition, you can define **optional** custom actions to extend your scope’s functionality. This means that you'll
likely have to design and create several actions for a scope.

Your actions should use one of the following types: `create`, `update`, or `custom`.

### Action specification reference

| Name                    | Action type | Parameters                                     | Description                                                                                          | Required |
| ----------------------- | ----------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -------- |
| **Create scope**        | `create`    | `scope_id`                                     | Triggered during scope creation to provision infrastructure independent of app versions (e.g., DNS). | Yes      |
| **Start initial**       | `custom`    | `scope_id`, `deployment_id`                    | Starts an initial deployment, typically the first or one after a scope restart.                      | Yes      |
| **Start blue green**    | `custom`    | `scope_id`, `deployment_id`                    | Initiates a blue-green deployment.                                                                   | Yes      |
| **Switch traffic**      | `custom`    | `scope_id`, `deployment_id`, `desired_traffic` | Adjusts traffic percentage during blue-green deployments.                                            | No       |
| **Finalize blue green** | `custom`    | `scope_id`, `deployment_id`                    | Cleans up old infrastructure after blue-green deployment completion.                                 | Yes      |
| **Rollback deployment** | `custom`    | `scope_id`, `deployment_id`                    | Reverts to the previous deployment and removes the new infrastructure.                               | Yes      |
| **Delete deployment**   | `custom`    | `scope_id`, `deployment_id`                    | Deletes deployment infrastructure when the active scope is stopped.                                  | No       |
| **Wait for instances**  | `custom`    | `scope_id`, `deployment_id`, `ready`           | Waits for instances to be ready before proceeding with deployment operations.                        | No       |
| **Update scope**        | `update`    | `scope_id`                                     | Updates the scope’s infrastructure if changes are required.                                          | No       |
| **Delete scope**        | `custom`    | `scope_id`                                     | Deletes app-version-independent infrastructure during scope deletion.                                | Yes      |

## Parameters

Each action must define the following:

- **`parameters`**: inputs required to execute the action (as a JSON schema)

:::note UI Schema
See the [UI schema reference section](/docs/json-ui-schema/overview) for more information on how to control
the fields in the UI.
:::


## Creating action specifications

To define the actions for your scope, use the [CLI](/docs/cli/) or [API](/docs/service-action-specification-api-index). 

While not strictly required, most scopes rely on actions to create, update, or delete the scope and to manage
scope workflows.

When using the UI, nullplatform automatically looks up the corresponding action specifications and creates instances as
needed. If you're integrating programmatically, you’ll need to trigger these actions explicitly.

:::info Action types
Use the `type` field on the action specification to distinguish between `create`, `update`, and `custom` actions.
:::


### Create scope

<Tabs
defaultValue="create-scope-cli"
values={[
{ label: 'CLI', value: 'create-scope-cli' },
{ label: 'cURL', value: 'create-scope-curl' },
]}>
  <TabItem value="create-scope-curl">
    ```bash
    curl -L -X POST "https://api.nullplatform.com/service_specification/$service-spec/action_specification" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Create scope",
        "type": "create",           
        "parameters": {       // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id"],    // Required parameter to create a scope
            "properties": {
              "scope_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {      
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
  <TabItem value="create-scope-cli">
    ```bash
    np service specification action specification create \ 
     --serviceSpecificationId $service-spec-id \
     --body '{
        "name": "Create scope",
        "type": "create",               
        "parameters": {           // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id"],    // required parameter to create a scope
            "properties": {
              "scope_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {              
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
</Tabs>


### Start initial

<Tabs
defaultValue="start-initial-cli"
values={[
{ label: 'CLI', value: 'start-initial-cli' },
{ label: 'cURL', value: 'start-initial-curl' },
]}>
  <TabItem value="start-initial-curl">
    ```bash
    curl -L -X POST "https://api.nullplatform.com/service_specification/$service-spec/action_specification" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Start initial",
        "type": "custom",
        "parameters": {         // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to start initial
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {        
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
      ```
  </TabItem>
  <TabItem value="start-initial-cli">
    ```bash
    np service specification action specification create \
      --serviceSpecificationId $service-spec-id \
      --body '{
        "name": "Start initial",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to start initial
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
</Tabs>

### Start blue green

<Tabs
defaultValue="start-blue-green-cli"
values={[
{ label: 'CLI', value: 'start-blue-green-cli' },
{ label: 'cURL', value: 'start-blue-green-curl' },
]}>
  <TabItem value="start-blue-green-curl">
    ```bash
    curl -L -X POST "https://api.nullplatform.com/service_specification/$service-spec/action_specification" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Start blue green",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to start blue green
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
  <TabItem value="start-blue-green-cli">
    ```bash
    np service specification action specification create \
      --serviceSpecificationId $service-spec-id \
      --body '{
        "name": "Start blue green",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to start blue green
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {      
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
      ```
  </TabItem>
</Tabs>


### Finalize blue green

<Tabs
defaultValue="finalize-blue-green-cli"
values={[
{ label: 'CLI', value: 'finalize-blue-green-cli' },
{ label: 'cURL', value: 'finalize-blue-green-curl' },
]}>
  <TabItem value="finalize-blue-green-curl">
    ```bash
    curl -L -X POST "https://api.nullplatform.com/service_specification/$service-spec/action_specification" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Finalize blue green",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to finalize blue green
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {      
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
  <TabItem value="finalize-blue-green-cli">
    ```bash
    np service specification action specification create \
      --serviceSpecificationId $service-spec-id \
      --body '{
        "name": "Finalize blue green",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],    // required parameters to finalize blue green
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {      
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
</Tabs>

### Rollback deployment

<Tabs
defaultValue="rollback-cli"
values={[
{ label: 'CLI', value: 'rollback-cli' },
{ label: 'cURL', value: 'rollback-curl' },
]}>
  <TabItem value="rollback-curl">
    ```bash
    curl -L -X POST "https://api.nullplatform.com/service_specification/$service-spec/action_specification" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Roll back deployment",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to roll back deployment
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
  <TabItem value="rollback-cli">
    ```bash
    np service specification action specification create \
      --serviceSpecificationId $service-spec-id \
      --body '{
        "name": "Roll back deployment",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to roll back deployment
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
      ```
  </TabItem>
</Tabs>

### Delete deployment

<Tabs
defaultValue="delete-cli"
values={[
{ label: 'CLI', value: 'delete-cli' },
{ label: 'cURL', value: 'delete-curl' },
]}>
  <TabItem value="delete-curl">
    ```bash
    curl -L -X POST "https://api.nullplatform.com/service_specification/$service-spec/action_specification" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Delete deployment",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to delete deployment
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
  <TabItem value="delete-cli">
    ```bash
    np service specification action specification create \
      --serviceSpecificationId $service-spec-id \
      --body '{
        "name": "Delete deployment",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to roll back deployment
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
</Tabs>

### Update scope

<Tabs
defaultValue="update-scope-cli"
values={[
{ label: 'CLI', value: 'update-scope-cli' },
{ label: 'cURL', value: 'update-scope-curl' },
]}>
  <TabItem value="update-scope-curl">
    ```bash
    curl -L -X POST "https://api.nullplatform.com/service_specification/$service-spec/action_specification" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Update scope",
        "type": "update",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id"],     // required parameters to update deployment
            "properties": {
              "scope_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
  <TabItem value="update-scope-cli">
    ```bash
    np service specification action specification create \
      --serviceSpecificationId $service-spec-id \
      --body '{
        "name": "Update scope",
        "type": "update",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id"],     // required parameters to update deployment
            "properties": {
              "scope_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
</Tabs>

### Delete scope

<Tabs
defaultValue="delete-scope-cli"
values={[
{ label: 'CLI', value: 'delete-scope-cli' },
{ label: 'cURL', value: 'delete-scope-curl' },
]}>
  <TabItem value="delete-scope-curl">
    ```bash
    curl -L -X POST "https://api.nullplatform.com/service_specification/$service-spec/action_specification" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Delete scope",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id"],     // required parameters to delete deployment
            "properties": {
              "scope_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
  <TabItem value="delete-scope-cli">
    ```bash
    np service specification action specification create \
      --serviceSpecificationId $service-spec-id \
      --body '{
        "name": "Delete scope",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id"],     // required parameters to delete deployment
            "properties": {
              "scope_id": {
                "type": "string"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
</Tabs>

### Wait for instances

<Tabs
defaultValue="wait-for-instances-cli"
values={[
{ label: 'CLI', value: 'wait-for-instances-cli' },
{ label: 'cURL', value: 'wait-for-instances-curl' },
]}>
  <TabItem value="wait-for-instances-curl">
    ```bash
    curl -L -X POST "https://api.nullplatform.com/service_specification/$service-spec/action_specification" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Wait for instances",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to wait for instances
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              },
              "ready": {
                "type": "boolean",
                "description": "Indicates whether instances should be ready"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
  <TabItem value="wait-for-instances-cli">
    ```bash
    np service specification action specification create \
      --serviceSpecificationId $service-spec-id \
      --body '{
        "name": "Wait for instances",
        "type": "custom",
        "parameters": {          // defines the input requirements for the action
          "schema": {
            "type": "object",
            "required": ["scope_id", "deployment_id"],     // required parameters to wait for instances
            "properties": {
              "scope_id": {
                "type": "string"
              },
              "deployment_id": {
                "type": "string"
              },
              "ready": {
                "type": "boolean",
                "description": "Indicates whether instances should be ready"
              }
            }
          },
          "values": {}
        },
        "results": {       
          "schema": {
            "type": "object",
            "properties": {}
          },
          "values": {}
        }
      }'
    ```
  </TabItem>
</Tabs>


## Run scope actions in parallel

By default, scope lifecycle actions are executed sequentially to ensure safety and predictability. However, some lifecycle operations can safely run in parallel.

With the `parallelize` flag, you can configure certain **custom scope actions** to run concurrently, improving deployment speed and throughput when actions don’t depend on each other.

**When to use parallel execution**

Parallel execution is valuable when lifecycle actions are independent and don’t modify the same resource at the same time. Typical use cases include:

- **Blue-green deployments:** Triggering multiple rollout steps or health checks simultaneously.
- **Traffic management:** Adjusting traffic for multiple services or endpoints in parallel.
- **Infrastructure operations:** Running instance readiness checks (`wait-for-instances`) concurrently across deployments.

> ℹ️ **Best practice:** Only parallelize lifecycle actions that are **idempotent** or operate on **isolated** resources. Keep sequential execution for steps like `switch traffic` or `rollback deployment`, where order and consistency matter.

### How to enable parallel execution

To mark a lifecycle action as parallelizable, set `"parallelize": true` in its action specification:

```json
{
  "actions": {
    "wait-for-instances": { "parallelize": true },
    "switch-traffic": { "parallelize": false }
  }
}
```
- `parallelize: true` → the action can run alongside other actions.
- `parallelize: false` → the action must complete before others start.

This gives you fine-grained control over which lifecycle steps can safely overlap.

> 📖 See our [API reference](/docs/api/service-specification-actions-create) for more info. 
