Lifecycle action specifications
If you haven't already, read about scopes' main concepts.
Also, keep these references handy:
- Scope Service Action Specification API
- Schemas
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:
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)
See the UI schema reference section 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 or API.
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.
Use the type field on the action specification to distinguish between create, update, and custom actions.
Create scope
- CLI
- cURL
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": {}
}
}'
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": {}
}
}'
Start initial
- CLI
- cURL
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": {}
}
}'
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": {}
}
}'
Start blue green
- CLI
- cURL
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": {}
}
}'
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": {}
}
}'
Finalize blue green
- CLI
- cURL
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": {}
}
}'
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": {}
}
}'
Rollback deployment
- CLI
- cURL
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": {}
}
}'
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": {}
}
}'
Delete deployment
- CLI
- cURL
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": {}
}
}'
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": {}
}
}'
Update scope
- CLI
- cURL
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": {}
}
}'
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": {}
}
}'
Delete scope
- CLI
- cURL
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": {}
}
}'
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": {}
}
}'
Wait for instances
- CLI
- cURL
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": {}
}
}'
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": {}
}
}'
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 trafficorrollback 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:
{
"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 for more info.
Configure the maximum wait time for deployment start actions
When a deployment of an agent-backed scope starts, nullplatform waits for its instances while the start action runs. By default, it waits up to 600 seconds (10 minutes).
If the limit is exceeded, nullplatform marks the running action as failed, adds the deployment message Instances didn't become healthy within the 10m limit (with your limit in place of 10m), and cancels the deployment. Then it runs Rollback deployment for blue-green deployments, or Delete deployment for initial ones.
Start actions that run long jobs, such as Terraform, may need more time. To raise (or lower) the limit, declare a max_wait_seconds integer property with a default value in the parameters.schema of the start action specification. It's a regular parameter, so you don't need to configure anything else.
| Property | Type | Effective range | Used when absent |
|---|---|---|---|
max_wait_seconds | integer | 60 – 3600 seconds | 600 seconds |
- Declare it in the Start initial (
start-initial) action specification for initial deployments, in the Start blue green (start-blue-green) action specification for blue-green deployments, or in both. It isn't read from any other action specification. - Only the property's
defaultis used, and it must be a number. If the property or itsdefaultis missing, or thedefaultisn't a number (for example, the string"1500"), the wait is 600 seconds. Values outside the 60 – 3600 range are clamped to the nearest limit. - The limit is the total time of the "waiting for instances" phase, counted from when the start action is triggered. If your scope also defines a Wait for instances (
wait-for-instances) action, all of its runs count against the same limit: a run that returnsready: falsedoesn't reset it. The value is still read from the start action specification. - Your agent also receives
max_wait_secondsin the action payload, as declared and without clamping. Your script can ignore it, since nullplatform enforces the wait itself. - The wait is read from the start action specification while the deployment waits, so changing the
defaultalso affects deployments that are already waiting.
Example
Allow up to 25 minutes (1500 seconds) for the initial deployment of a scope whose start action runs Terraform:
{
"name": "Start initial",
"type": "custom",
"parameters": {
"schema": {
"type": "object",
"required": ["scope_id", "deployment_id"],
"properties": {
"scope_id": {
"type": "string"
},
"deployment_id": {
"type": "string"
},
"max_wait_seconds": {
"type": "integer",
"default": 1500,
"minimum": 60,
"maximum": 3600
}
}
},
"values": {}
},
"results": {
"schema": {
"type": "object",
"properties": {}
},
"values": {}
}
}
💡 Tip: Adding
minimumandmaximumto the property is optional, but it documents the supported range. Regardless of the schema, nullplatform clamps the wait to 60 – 3600 seconds.
To apply the same limit to blue-green deployments, add the same max_wait_seconds property to the parameters.schema of the start-blue-green action specification.