Skip to content

Create an auto scaling group.

POST
/v1/projects/{projectId}/asg/groups
Code sample: Shell / cURL
curl --request POST \
--url https://stratum.example.com/v1/projects/example/asg/groups \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "name": "example", "description": "example", "subnetIds": [ "example" ], "launchTemplateId": "example", "launchTemplateVersion": "$LATEST", "minSize": 1, "maxSize": 1, "desiredSize": 1, "healthCheckType": "instance", "healthCheckGracePeriodSeconds": 300, "targetGroupIds": [ "example" ], "loadBalancer": { "create": true, "scheme": "internet-facing", "port": 80, "protocol": "HTTP", "healthCheck": { "enabled": true, "protocol": "http", "path": "example", "interval_ms": 1, "timeout_ms": 1, "healthy_threshold": 1, "unhealthy_threshold": 1, "expect_status": "example" }, "listener": { "port": 1, "protocol": "HTTP", "certificateId": "example" } }, "defaultCooldownSeconds": 300, "terminationPolicies": [ "example" ], "tags": { "additionalProperty": "example" } }'

Records the desired state; the asg reconciler (ScopeLeader, every 30 s) launches instances from the resolved launch template version toward desiredSize, tracks them to InService as Compute reports running + healthy, and replaces the unhealthy after the grace period. Subnets must be on one VPC (the AZ set is derived); the template/version must resolve; maxSize is bounded by asg.max_instances_per_asg. Counted against asg.auto_scaling_groups.count. Cedar-gated on asg:CreateAutoScalingGroup.

projectId
required
string
/^p-[a-z0-9-]+$/
Media typeapplication/json
object
name
required
string
/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/
description
string
subnetIds
required

One or more subnets of ONE VPC; the AZ set is derived from them.

Array<string>
>= 1 items
launchTemplateId
required
string
launchTemplateVersion
string
default: $LATEST
minSize
required
integer
maxSize
required

Bounded by the project’s asg.max_instances_per_asg quota.

integer
desiredSize

Defaults to minSize.

integer
healthCheckType
string
default: instance
Allowed values: instance load_balancer
healthCheckGracePeriodSeconds
integer
default: 300 <= 7200
targetGroupIds

Target groups (targetType ip or auto-scaling-group) on the same VPC; required with healthCheckType=load_balancer unless the group owns its front door (loadBalancer). Exclusive with loadBalancer.

Array<string>
loadBalancer

Ask the group to OWN its front door (as amended,): the asg service creates a target group (targetType: ip, the group’s port and protocol, the health check), a load balancer on the group’s subnets with the requested scheme, and a listener default-forwarding to the target group — as desired state, converged by the reconciler, bound to the group, and torn down after the drain when the group goes. The owned rows are ordinary load-balancer / target-group / listener rows in the project; a resource-policy forbid keeps their update and deletion to the service. Exclusive with targetGroupIds (one owner per binding); sets healthCheckType: load_balancer unless given. The caller needs lb:CreateTargetGroup, lb:CreateLoadBalancer and lb:CreateListener in the project; the lb.* quotas apply.

object
create

On PATCH, false tears the owned set down (the group keeps running, its health falls back to instance when nothing else is bound). Omit or true with a spec to create or change it.

boolean
scheme
string
default: internet-facing
Allowed values: internet-facing internal
port

The port the members serve on (the target group’s).

integer
default: 80 >= 1 <= 65535
protocol

The target group’s protocol.

string
default: HTTP
Allowed values: HTTP HTTPS TCP
healthCheck

Prober config, passed through to the axlbd data plane. Property names are the data-plane JSONB contract (snake_case). The prober only runs when enabled; disabled or empty means every target is treated healthy and no probing happens.

object
enabled
boolean
protocol
string
Allowed values: http tcp
path

HTTP health-check path, e.g. /healthz

string
interval_ms
integer
timeout_ms
integer
healthy_threshold
integer
unhealthy_threshold
integer
expect_status

Accepted status codes, e.g. “200”, “200,302”, “200-299”

string
listener

The listener on the load balancer; defaults to the target port over HTTP. An HTTPS listener names its certificateId and defaults to port 443. A change of port, protocol or certificate replaces the listener.

object
port

The listener’s port; the target port for HTTP, 443 for HTTPS when omitted.

integer
>= 1 <= 65535
protocol
string
Allowed values: HTTP HTTPS
certificateId

The SSL certificate (cert-…) the HTTPS listener terminates with: a certificate of the SAME project, bound as the listener’s default certificate. Required when protocol is HTTPS, refused (400) otherwise; a certificate that is not in the project is a 400. Changing it replaces the listener, like a port change.

string
/^cert-[a-z0-9]+$/
defaultCooldownSeconds
integer
default: 300 <= 86400
terminationPolicies
Array<string>
tags
object
key
additional properties
string

Created.

Media typeapplication/json
object
id
required

asg-…

string
arn
required

arn:stratum:asg:<region>:<projectId>:auto-scaling-group/<id>

string
projectId
required
string
name
required
string
description
string
region
required
string
subnetIds
required
Array<string>
vpcId
required

The VPC every subnet is on; immutable.

string
availabilityZones
required

Derived from the subnets (amended 2026-09-15), never stored.

Array<string>
launchTemplateId
required
string
launchTemplateVersion
required

$LATEST, $DEFAULT or an ltv-… id; resolved at every launch.

string
minSize
required
integer
maxSize
required
integer
desiredSize
required
integer
healthCheckType
required
string
Allowed values: instance load_balancer
healthCheckGracePeriodSeconds
required
integer
targetGroupIds
required
Array<string>
defaultCooldownSeconds
required

Holds back policy-driven scaling after a scaling action; customer set-desired, replace-unhealthy and delete are immediate.

integer
terminationPolicies
required
Array<string>
Allowed values: Default OldestInstance NewestInstance OldestLaunchTemplate ClosestToNextInstanceHour
suspendedProcesses
required
Array<string>
Allowed values: Launch Terminate HealthCheck ReplaceUnhealthy AZRebalance AlarmNotification ScheduledActions AddToLoadBalancer InstanceRefresh
lastScalingActionAt
string format: date-time
lastScalingReason

api, policy:<id> or scheduled:<id> — what last moved desiredSize.

string
lastLaunchError

Why the controller’s most recent launch was refused (capacity, quota, a bad launch template); absent once a launch goes through. The group’s audit trail (asg.group.instance_launch_failed) has the history.

string
lastLaunchErrorAt
string format: date-time
state
required

deleting while the reconciler drains the instances; the group disappears once drained.

string
Allowed values: active deleting
tags
required
object
key
additional properties
string
createdBy
required
string
createdAt
required
string format: date-time
updatedAt
required
string format: date-time
loadBalancer

The group’s owned front door: the spec as asked, what the reconciler has made of it, and the ids of the owned rows. status moves creating → active; updating while a spec change is applied (a scheme change replaces the load balancer, a listener change replaces the listener, a health-check change is applied in place); deleting while the set is torn down; error with reason when the last pass failed — it is retried every tick. Each id is recorded the moment its row exists, so a restart resumes rather than creating twice.

object
scheme
required
string
Allowed values: internet-facing internal
port
required
integer
protocol
required
string
healthCheck

Prober config, passed through to the axlbd data plane. Property names are the data-plane JSONB contract (snake_case). The prober only runs when enabled; disabled or empty means every target is treated healthy and no probing happens.

object
enabled
boolean
protocol
string
Allowed values: http tcp
path

HTTP health-check path, e.g. /healthz

string
interval_ms
integer
timeout_ms
integer
healthy_threshold
integer
unhealthy_threshold
integer
expect_status

Accepted status codes, e.g. “200”, “200,302”, “200-299”

string
listener
required
object
port
required
integer
protocol
required
string
certificateId

The HTTPS listener’s certificate; absent for HTTP.

string
status
required
string
Allowed values: creating active updating deleting error
reason
string
loadBalancerId
string
targetGroupId
string
listenerId
string
dnsName

The load balancer’s DNS name, once it exists.

string
internalIp

The load balancer’s VPC-internal address, once it exists.

string
deletingAt
string format: date-time

Example

{
"healthCheckType": "instance",
"terminationPolicies": [
"Default"
],
"suspendedProcesses": [
"Launch"
],
"state": "active",
"loadBalancer": {
"scheme": "internet-facing",
"healthCheck": {
"protocol": "http"
},
"status": "creating"
}
}

Bad request.

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

Field errors, for codes that carry them: each problem at its field (see FieldError). Documented on the responses that set it, e.g. approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED. Absent otherwise.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

Structured facts about the refusal, for codes that carry them. The shape is fixed per code and documented on the response that answers it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and IMAGE_IN_USE. Absent for codes that carry none.

object
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}

Authenticated but not authorized.

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

Field errors, for codes that carry them: each problem at its field (see FieldError). Documented on the responses that set it, e.g. approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED. Absent otherwise.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

Structured facts about the refusal, for codes that carry them. The shape is fixed per code and documented on the response that answers it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and IMAGE_IN_USE. Absent for codes that carry none.

object
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}

Conflicting state.

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

Field errors, for codes that carry them: each problem at its field (see FieldError). Documented on the responses that set it, e.g. approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED. Absent otherwise.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

Structured facts about the refusal, for codes that carry them. The shape is fixed per code and documented on the response that answers it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and IMAGE_IN_USE. Absent for codes that carry none.

object
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}

Request rate limit exceeded. The API-boundary throttle caps request throughput per principal and per project; code is RATE_LIMITED (distinct from the quota engine’s QUOTA_EXCEEDED). The Retry-After header carries the seconds to wait. Applies to any authenticated endpoint — it is enforced by middleware, not per-path.

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

Field errors, for codes that carry them: each problem at its field (see FieldError). Documented on the responses that set it, e.g. approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED. Absent otherwise.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

Structured facts about the refusal, for codes that carry them. The shape is fixed per code and documented on the response that answers it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and IMAGE_IN_USE. Absent for codes that carry none.

object
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}
Retry-After
integer

Seconds to wait before retrying.

Upstream temporarily unavailable (driver / scheduler / dependency).

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

Field errors, for codes that carry them: each problem at its field (see FieldError). Documented on the responses that set it, e.g. approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED. Absent otherwise.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

Structured facts about the refusal, for codes that carry them. The shape is fixed per code and documented on the response that answers it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and IMAGE_IN_USE. Absent for codes that carry none.

object
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}