---
title: "Create VM"
method: POST
path: "/virtual_machines"
tags: ["Virtual machines"]
---

# Create VM

`POST /virtual_machines`

Creates a new Virtual Machine.

## Request body

- VirtualMachinePayload
  - `data` object
    - `type` 'virtual_machines'
    - `attributes` object
      - `name` string, required
      - `billing` 'hourly' | 'monthly' | 'yearly' — Billing cycle for the VM. The supported set is validated per-project (on_demand vs reserved). Defaults to the project's default billing when omitted.
      - `plan` string, nullable — The plan ID or Slug for the Virtual Machine
      - `ssh_keys` string[], nullable
      - `project` string, required
      - `operating_system` string, nullable — The operating system slug for the Virtual Machine. If not specified, defaults to ubuntu_24_04_x64_lts for CPU plans or ubuntu24_ml_in_a_box for GPU plans.
      - `user_data` union — A user data record reference (encoded id_hash, e.g. 'ud_xxx', or raw integer id) to apply as cloud-init configuration
        - integer
        - string
      - `marketplace_app` string, nullable — A marketplace app reference (slug, e.g. "openclaw", or encoded id_hash "mkapp_xxx") to preinstall on the VM via cloud-init. Cannot be combined with operating_system; the app defines its own.
      - `tags` string[], nullable — Array of tag IDs to assign to the VM.
      - `site` string, nullable — Site/region slug where the VM is provisioned (e.g. DAL, SAO). Defaults to DAL when omitted.

## Response `201`

Created

## Changes

> 29 revisions in range; 22 could not be searched.

- **2026-08-04** `018cb742936f` — 4 info
  - the request property `data/attributes/name` with a default value became required (media type: application/json)
  - the request property `data/attributes/name` with a default value became required (media type: application/vnd.api+json)
  - the request property `data/attributes/project` with a default value became required (media type: application/json)
  - the request property `data/attributes/project` with a default value became required (media type: application/vnd.api+json)
- **2026-07-26** `52c7ba2f0f3a` — 1 info
  - added the optional property `data/attributes/plan/slug` to the response with the `201` status
- **2026-07-21** `885dec47dd47` — 5 breaking, 19 info
  - the response property `data/attributes/credentials/host` became nullable for the status `201`
  - the response property `data/attributes/credentials/password` became nullable for the status `201`
  - the response property `data/attributes/credentials/ssh_keys` became nullable for the status `201`
  - the response property `data/attributes/credentials/username` became nullable for the status `201`
  - …20 more

[Change history](https://skmtc.dev/latitude/apis/latitude-sh-api/changes/virtual_machines/post.md)

---

[API](https://skmtc.dev/latitude/apis/latitude-sh-api.md) · [All operations](https://skmtc.dev/latitude/apis/latitude-sh-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/latitude/latitude-sh-api/revisions/c80535f26dd7/schema)
