Skip to content

Upload a disk image (qcow2 or raw) into the image catalog.

POST
/v1/images/upload
Code sample: Shell / cURL
curl --request POST \
--url 'https://stratum.example.com/v1/images/upload?name=example&format=qcow2&architecture=amd64&scope=global' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/octet-stream' \
--data binary

An operator’s own image, uploaded. The body is the disk image itself (Content-Type: application/octet-stream, streamed; a Content-Length is recommended but not required), and its metadata are the query parameters. Install-scope; gates on compute:ImportImage, like the URL import. The image is global or region scoped and owned by p-system, so p-system’s compute.images.count quota applies (429).

Checked before the body is read: the name (and that no live image has it), the scope, the storage class, the quota, and a Content-Length over the limit. Then the bytes are staged on the control plane that received them, their sha256 computed (and compared with sha256 when given), and qemu-img info validates them: a qcow2 or raw disk (the format is read from the bytes; format, when given, must match), with no backing file, no external data file, not encrypted, and a virtual size within the limit. A refused upload records nothing and keeps nothing.

Returns 202 with the image pending, sourceUploadNode naming the node that holds the staged bytes. That node’s storage worker imports it into the class like any import (pending -> downloading -> importing -> active; qcow2 is converted to raw) and then removes the staged copy. A failed import ends in error: delete the image and upload it again. In a per-node class (lvm-thin) only the receiving node gets a copy.

Limits: 64 GiB uploaded (STRATUM_STORAGE_IMAGE_UPLOAD_MAX_BYTES), 4 TiB virtual size.

name
required
string

The image’s name, unique among live global and region images.

displayName
string
description
string
format
string
Allowed values: qcow2 raw

The disk’s format. Left out, it is read from the bytes; given, it must match them.

sha256
string
/^[0-9a-fA-F]{64}$/

The upload’s expected sha256 (hex). A mismatch refuses it (400 CHECKSUM_MISMATCH).

architecture
string
default: amd64
Allowed values: amd64 arm64
osFamily
string
osDistribution
string
osVersion
string
scope
string
default: global
Allowed values: global region
region
string

Required when scope is region.

storageClass
string

The storage class the image is imported into. Left out, the default class.

Media typeapplication/octet-stream
string format: binary

Received and validated; the image is pending until its import finishes.

Media typeapplication/json
object
id
required
string
/^img-[a-z0-9-]+$/
projectId
required

P-system for global; owning project for scoped

string
arn

arn:stratum:compute:<region>:<owner>:image/<id>, the key a resource policy shares the image under (PUT /v1/iam/resource-policies?resourceArn=).

string
ownerProjectId

The project that owns the image (always equal to projectId): whose quota it counts against and whose editors may share, publish and delete it.

string
visibility

Who may launch the image. private: the owner project only. shared: plus every principal a resource policy on the image ARN permits compute:UseImage (a project-kind principal is what share writes). public: every project on the install. Independent of scope, which is storage placement.

string
Allowed values: private shared public
owner

The requesting project’s relation to the image: self (owned), system (the operator’s public catalog), shared (granted by a resource policy), public (another project’s public image). Filled on the project-scoped reads; absent on the admin surface.

string
Allowed values: self system shared public
sharedWith

The projects a resource policy on the image ARN grants compute:UseImage — present on the OWNER’s reads only; a grantee does not see who else was granted. Derived from the policy.

Array<string>
name
required
string
/^[a-z][a-z0-9-]{1,38}[a-z0-9]$/
displayName
required
string
>= 1 characters <= 100 characters
description
string
sizeBytes
required
integer format: int64
format
required

The source format the image was imported from (stored raw).

string
Allowed values: qcow2 raw vmdk vhdx
architecture
required
string
Allowed values: amd64 arm64
osFamily
string
osDistribution
string
osVersion
string
storageClass
required
string
driver
string
Allowed values: lvm-thin ceph-rbd
pool
string
launchableStorageClasses

The storage classes (by name) a launch of this image may name as rootStorageClass, or create-volume as storageClass: active, on the image’s storage driver, and, for a driver whose clones are pool-local (lvm-thin), on the pool the image is staged in. Any other class is refused with 409 IMAGE_POOL_MISMATCH. The server derives it from the rule it enforces, so a client offers this list rather than recomputing it. Omitting the class always launches on the image’s own storageClass. Absent when no class can be named or the classes could not be read.

Array<string>
availability

Where VMs launched from the image can run. A shared storage class (Ceph) holds one copy every node reads: scope is all-nodes and nodes is absent. A per-node class (lvm-thin) holds a copy per node, staged from the image’s source: scope is nodes and nodes lists every node with a staging row, so a VM runs only on the nodes in state ready. An image uploaded through the API into a per-node class has its bytes only on the node that received them (sourceUploadNode); every other node reports error with the reason. Import it from a URL, or upload it into a shared class, to run it everywhere. Absent while the image is not usable (not yet active) or when the nodes could not be read.

object
scope
required
string
Allowed values: all-nodes nodes
nodes

Per-node staging state, ordered by node id; only when scope is nodes.

Array<object>

One node’s staging readiness for an image.

object
nodeId
required
string
state
required

Per-node staging lifecycle. ready means a VM can clone its root volume from the local base LV here.

string
Allowed values: pending staging ready error
message

Failure detail when state is error; absent otherwise.

string
sizeBytes

Size of the staged base LV in bytes; absent until known.

integer format: int64
updatedAt
required
string format: date-time
region
string
scope
required
string
Allowed values: global region project
sourceSnapshotId
string
sourceUrl
string format: uri
sourceUrlSha256
string
sourceBucket

The bucket a bucket import read from.

string
sourceKey

The object key a bucket import read.

string
sourceUploadNode

An uploaded image (POST /v1/images/upload): the node whose control plane received the bytes. They stay staged there until the import has written them into the storage class.

string
exports

Every export job requested on the image.

Array<object>

One export job on an image.

object
id
required
string
bucket
required
string
key
required
string
format
required
string
Allowed values: qcow2 raw
state
required
string
Allowed values: pending running succeeded failed
sha256

Hex-encoded SHA256 of the uploaded object (succeeded only).

string
sizeBytes
integer format: int64
reason

Why the job failed (failed only).

string
requestedBy
required
string
requestedAt
required
string format: date-time
finishedAt
string format: date-time
sourceInstanceId

The instance a create-image was taken from.

string
sourceImageId

The image that instance booted (lineage).

string
consistency

How a create-from-instance snapshot was taken: the instance was stopped, the guest agent quiesced its filesystems, or neither answered and the image is crash-consistent. Absent on imported and promoted images.

string
Allowed values: stopped quiesced crash
blockDeviceMappings

The volumes the image carries; device 0 is the root snapshot, higher indexes are data volumes cloned at launch. Empty for single-volume images.

Array<object>

One volume an image carries. Device 0 is the root (also sourceSnapshotId); higher indexes are data volumes cloned at launch. A launch may override sizeBytes upward.

object
deviceIndex
required
integer
snapshotId
required
string
sizeBytes
required
integer format: int64
deleteOnTermination
boolean
createPhase

Where a create-from-instance is while the image is pending: requested → stopping | freezing → snapshotting → thawing | starting → promoting → done, or failed (the image is then error with stateReason). Absent on every other image.

string
Allowed values: requested stopping freezing snapshotting thawing starting promoting done failed
state
required
string
Allowed values: pending downloading importing creating active disabled deprecated deleting deleted error
stateReason

Human-readable cause. Set when state is error, and while deleting when the delete is BLOCKED: a volume still CoW-cloned from this image, the backing store still held open, or a transient backend error. A blocked delete is not a failure — the image stays deleting and the worker re-attempts it about once a minute until the blocker clears (a clone you delete, a watcher that goes); nothing needs re-issuing. Cleared on any other transition.

Read this before acting on an image that is not gone yet: it names the volume to delete, or tells you an operator is needed.

string
publishedAt

When the image became public: stamped by publish and by the operator catalog’s activation, cleared by unpublish. A private or shared image has none — this is a visibility stamp, not “became available” (createdAt / state say that).

string format: date-time
nullable
deprecatedAt
string format: date-time
nullable
disabledAt

Set while the image is disabled.

string format: date-time
nullable
lastLaunchedAt

The last launch from the image, stamped at most once an hour.

string format: date-time
nullable
deprecateAt

A scheduled deprecation not yet applied.

string format: date-time
nullable
inUseBy

What references the image, on the owner’s reads: the launch templates whose $Default or $Latest version names it. A deregister without force is refused while this is non-empty.

object
launchTemplates
Array<string>
tags

AWS-shape resource tags. Freeform UTF-8 keys (1-128 bytes, no leading/trailing whitespace) mapped to freeform UTF-8 values (0-256 bytes). Max 50 tags per resource. Reserved prefixes (stratum.dev/, stratum.platform_health., stratum:, aws:) return 400 RESERVED_NAMESPACE on customer input. PATCH replaces the whole map..

object
<= 50 properties
key
additional properties
string
<= 256 characters
createdAt
required
string format: date-time
updatedAt
required
string format: date-time
createdBy
required
string

Example

{
"visibility": "private",
"owner": "self",
"format": "qcow2",
"architecture": "amd64",
"driver": "lvm-thin",
"availability": {
"scope": "all-nodes",
"nodes": [
{
"nodeId": "n-msst0001",
"state": "pending"
}
]
},
"scope": "global",
"exports": [
{
"format": "qcow2",
"state": "pending"
}
],
"consistency": "stopped",
"createPhase": "requested",
"state": "pending"
}

INVALID_INPUT (name, scope, region, storage class, format value), CHECKSUM_MISMATCH, or INVALID_IMAGE: qemu-img cannot read it, it is not qcow2 or raw (or not the format given), it names a backing file or an external data file, or it is encrypted.

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"
}
]
}

IMAGE_TOO_LARGE: the upload, or the virtual size it describes, is over the limit.

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"
}
]
}

UNSUPPORTED_MEDIA_TYPE: the body is not application/octet-stream.

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"
}
]
}

QUOTA_EXCEEDED: p-system’s compute.images.count is at its limit.

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"
}
]
}

INSUFFICIENT_STORAGE: the staging filesystem cannot hold an upload of that length.

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"
}
]
}