Create a launch template with its version 1.
curl --request POST \ --url https://stratum.example.com/v1/projects/example/asg/launch-templates \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "name": "example", "description": "example", "tags": { "additionalProperty": "example" }, "version": { "description": "example", "imageId": "example", "instanceType": "example", "subnetIdStrategy": "static", "subnetId": "example", "securityGroupIds": [ "example" ], "floatingIpPool": "example", "rootVolumeSizeBytes": 1, "rootStorageClass": "example", "placementGroupName": "example", "keyPairName": "example", "userData": "example", "iamInstanceProfileId": "example", "metadataOptions": { "httpEndpoint": "enabled", "httpTokens": "optional", "httpPutResponseHopLimit": 1, "instanceMetadataTags": "enabled" }, "blockDeviceMappings": [ { "deviceIndex": 1, "sizeBytes": 1, "deleteOnTermination": true } ], "agentEnabled": true, "tagsAtLaunch": { "additionalProperty": "example" } } }'The template and its first version are created in one
transaction; $LATEST and $DEFAULT both point at version 1. Every
reference in the version (image, instance type, subnet, security groups,
key pair, placement group, instance profile, storage class) is validated
against the owning service: an absent or inactive one is 400 VALIDATION_FAILED. The name is unique per project (409). Counted
against asg.launch_templates.count (429). Cedar-gated on
asg:CreateLaunchTemplate.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Bodyrequired
Section titled “Request Bodyrequired”object
Unique per project.
object
The launch blueprint one version freezes (amended 2026-09-15). Every field maps onto the Compute instance create request; at 2.0 a version describes one NIC (security groups + optional floating-IP pool) and the root volume. Every reference is validated at create against the service that owns it, so a group never discovers a bad blueprint at launch.
object
An active image visible to the project.
Instance type name (m1.medium), as Compute takes it.
static launches into subnetId; inherited lets the group pick a subnet by AZ balance. Defaults to static when subnetId is given, else inherited.
Required with static; forbidden with inherited.
Allocate a floating IP from this pool at launch.
0 = the image’s size.
Storage class (by name) for each instance’s root volume; omitted =
the image’s own class. Must be one of the image’s
launchableStorageClasses: checked when the version is saved, 409
IMAGE_POOL_MISMATCH otherwise.
placement group — the only spread mechanism inside one AZ.
Raw cloud-config / Ignition (NOT base64). Returned on describe; the audit trail carries only its SHA-256.
An active instance profile in the same project.
Per-instance AWS-shape IMDS options. Returned on
the Instance and settable at launch (CreateInstanceRequest) or via the
modify-metadata-options action. httpEndpoint is enforced: when
disabled the whole IMDS surface (including the Stratum SSH-CA agent
plane) is off for the instance. httpTokens + httpPutResponseHopLimit
are recorded for AWS parity only — Stratum’s IMDS always requires a
session token (effectively IMDSv2-only), so optional does not relax
that in v1. Omitted fields default to enabled / required / 1.
object
Whether IMDS is reachable for the instance. Default enabled.
IMDSv2 token requirement (recorded; Stratum is always v2). Default required.
Recorded for AWS parity. Default 1.
When enabled the guest can read its own tags at /latest/meta-data/tags/instance/. Default disabled; the image builder enables it on a build instance.
Per-device overrides for a multi-volume image; every data device the image carries is launched (cloned from its snapshot and attached before first boot) whether or not it is named here. 400 for a device the image does not have or a size below the snapshot’s.
A per-device override for one of the data devices a
multi-volume image carries. deviceIndex must be one the image has
(>= 1; device 0 is the root, sized by rootVolumeSizeBytes);
sizeBytes must be at or above the snapshot’s; absent fields keep the
image’s values. Devices not named are launched as the image mapped them.
object
false launches without the instance agent; the group’s instance health mode then rides lifecycle state alone.
Tags stamped on every launched instance (reserved prefixes refused).
object
Responses
Section titled “Responses”Created — the template with its version 1 embedded.
object
lt-…
arn:stratum:asg:<region>:<projectId>:launch-template/<id>
What $LATEST resolves to; moves on every new version.
What $DEFAULT resolves to; moves only by set-default-version.
object
object
An active image visible to the project.
Instance type name (m1.medium), as Compute takes it.
static launches into subnetId; inherited lets the group pick a subnet by AZ balance. Defaults to static when subnetId is given, else inherited.
Required with static; forbidden with inherited.
Allocate a floating IP from this pool at launch.
0 = the image’s size.
Storage class (by name) for each instance’s root volume; omitted =
the image’s own class. Must be one of the image’s
launchableStorageClasses: checked when the version is saved, 409
IMAGE_POOL_MISMATCH otherwise.
placement group — the only spread mechanism inside one AZ.
Raw cloud-config / Ignition (NOT base64). Returned on describe; the audit trail carries only its SHA-256.
An active instance profile in the same project.
Per-instance AWS-shape IMDS options. Returned on
the Instance and settable at launch (CreateInstanceRequest) or via the
modify-metadata-options action. httpEndpoint is enforced: when
disabled the whole IMDS surface (including the Stratum SSH-CA agent
plane) is off for the instance. httpTokens + httpPutResponseHopLimit
are recorded for AWS parity only — Stratum’s IMDS always requires a
session token (effectively IMDSv2-only), so optional does not relax
that in v1. Omitted fields default to enabled / required / 1.
object
Whether IMDS is reachable for the instance. Default enabled.
IMDSv2 token requirement (recorded; Stratum is always v2). Default required.
Recorded for AWS parity. Default 1.
When enabled the guest can read its own tags at /latest/meta-data/tags/instance/. Default disabled; the image builder enables it on a build instance.
Per-device overrides for a multi-volume image; every data device the image carries is launched (cloned from its snapshot and attached before first boot) whether or not it is named here. 400 for a device the image does not have or a size below the snapshot’s.
A per-device override for one of the data devices a
multi-volume image carries. deviceIndex must be one the image has
(>= 1; device 0 is the root, sized by rootVolumeSizeBytes);
sizeBytes must be at or above the snapshot’s; absent fields keep the
image’s values. Devices not named are launched as the image mapped them.
object
false launches without the instance agent; the group’s instance health mode then rides lifecycle state alone.
Tags stamped on every launched instance (reserved prefixes refused).
object
ltv-…
Monotonic from 1; immutable.
Example
{ "version": { "subnetIdStrategy": "static", "metadataOptions": { "httpEndpoint": "enabled", "httpTokens": "optional", "instanceMetadataTags": "enabled" }, "agentEnabled": true }}Bad request.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
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.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
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
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Authenticated but not authorized.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
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.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
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
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}IMAGE_POOL_MISMATCH — rootStorageClass cannot hold a clone of
the image: it is not one of the image’s
launchableStorageClasses, so every launch from this version would
be refused with the same code. Nothing is saved. details is an
ImagePoolMismatchDetails. IMAGE_DISABLED — the image is disabled.
CONFLICT — the name is taken in this project.
A 409 on a route that can answer IMAGE_POOL_MISMATCH: a
Problem whose details, for that code, is an ImagePoolMismatchDetails.
The route’s other conflict codes carry no details.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
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.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
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
details of a 409 IMAGE_POOL_MISMATCH problem,
the same on POST /v1/projects/{projectId}/compute/instances and the
image create-volume action: the storage class asked for cannot hold a
clone of the image.
object
The storage driver the image is stored on.
The pools the image’s base lives in.
The storage class asked for, by name.
The driver that class puts volumes on.
The pool that class puts volumes in.
The classes, by name, that can launch the image (equal to the image’s
launchableStorageClasses). Omitting the class always can.
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.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
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.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
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
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Headers
Section titled “Headers”Seconds to wait before retrying.
Upstream temporarily unavailable (driver / scheduler / dependency).
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
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.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
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
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}