> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rafftechnologies.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Your First VM

> Step-by-step guide to deploying a virtual machine on Raff

<sub>Updated May 8, 2026</sub>

This guide walks you through creating a virtual machine, connecting via SSH, and managing its lifecycle.

## Prerequisites

* A Raff account with billing set up
* An API key (Dashboard → **API Keys** → Create API Key)
* A project ID (Dashboard → **Projects**)
* An SSH key pair (optional but recommended)

## Step 1: Authenticate

Set your API key and project ID as environment variables for convenience:

```bash theme={null}
export RAFF_API_KEY="YOUR_API_KEY"
export RAFF_PROJECT_ID="YOUR_PROJECT_ID"
```

Verify your access:

```bash theme={null}
curl -H "X-API-Key: $RAFF_API_KEY" \
  https://api.rafftechnologies.com/api/v1/vms
```

## Step 2: Create a VM

Create an Ubuntu VM with 2 vCPUs, 4 GB RAM:

```bash theme={null}
curl -X POST https://api.rafftechnologies.com/api/v1/vms \
  -H "X-API-Key: $RAFF_API_KEY" \
  -H "X-Project-ID: $RAFF_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-ubuntu-server",
    "template_id": "<template-uuid>",
    "pricing_id": 3,
    "region": "us-east",
    "ssh_keys": ["ssh-ed25519 AAAA... user@laptop"],
    "backup_type": "weekly",
    "backup_time": "8am",
    "backup_date": "Saturday"
  }'
```

<Note>
  Replace `<template-uuid>` with your OS template ID — get one from [List Templates](/api-reference/catalog/list-templates) (no auth required; filter with `?category=os`).

  The `pricing_id` selects a plan that determines vCPU, RAM, storage, and bandwidth — list plans with [List VM Pricing](/api-reference/catalog/list-vm-pricing).
</Note>

The response includes your new VM details:

```json theme={null}
{
  "success": true,
  "data": {
    "id": "69590a15-9f68-4b6f-8232-b07781218852",
    "name": "my-ubuntu-server",
    "status": "provisioning",
    "cpu": 2,
    "ram": 4,
    "storage": 80,
    "pricing_id": 3,
    "price_per_hour": "0.027764",
    "billing_type": "payg",
    "public_ipv4_address": "15.204.178.3",
    "region": "us-east"
  }
}
```

## Step 3: Wait for VM to Become Active

Poll the VM status until it becomes `active`:

```bash theme={null}
curl -H "X-API-Key: $RAFF_API_KEY" \
  https://api.rafftechnologies.com/api/v1/vms/69590a15-9f68-4b6f-8232-b07781218852
```

The VM transitions through these states in order:

| Status         | Description                               |
| -------------- | ----------------------------------------- |
| `initiating`   | Queued, initial setup before provisioning |
| `provisioning` | VM being created in the hypervisor        |
| `booting`      | VM starting up                            |
| `active`       | Running and reachable                     |

## Step 4: Connect via SSH

Once the VM is `active`, connect using the public IPv4 address:

```bash theme={null}
ssh root@15.204.178.3
```

If you provided a password instead of SSH keys during creation:

```bash theme={null}
ssh root@15.204.178.3
# Enter the password you set
```

## Step 5: Manage Your VM

### Stop the VM

```bash theme={null}
curl -X POST -H "X-API-Key: $RAFF_API_KEY" -H "X-Project-ID: $RAFF_PROJECT_ID" \
  https://api.rafftechnologies.com/api/v1/vms/69590a15-9f68-4b6f-8232-b07781218852/stop
```

<Info>
  Stopped VMs retain their resources and IP address. You are still billed for reserved resources.
</Info>

### Resize the VM

Resize requires the VM to be stopped first. Pass a new `pricing_id` — the plan determines the new vCPU, RAM, storage, and bandwidth. Get plan IDs from [List VM Pricing](/api-reference/catalog/list-vm-pricing).

```bash theme={null}
curl -X POST https://api.rafftechnologies.com/api/v1/vms/69590a15-9f68-4b6f-8232-b07781218852/resize \
  -H "X-API-Key: $RAFF_API_KEY" \
  -H "X-Project-ID: $RAFF_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{"pricing_id": 5}'
```

### Start the VM

```bash theme={null}
curl -X POST -H "X-API-Key: $RAFF_API_KEY" -H "X-Project-ID: $RAFF_PROJECT_ID" \
  https://api.rafftechnologies.com/api/v1/vms/69590a15-9f68-4b6f-8232-b07781218852/start
```

### Delete the VM

```bash theme={null}
curl -X DELETE -H "X-API-Key: $RAFF_API_KEY" -H "X-Project-ID: $RAFF_PROJECT_ID" \
  https://api.rafftechnologies.com/api/v1/vms/69590a15-9f68-4b6f-8232-b07781218852
```

<Warning>
  Deleting a VM is permanent. All data on the VM will be lost. Make sure to back up any important data first.
</Warning>

## VPC Networking

By default every VM gets a VPC. You can opt out, or share a VPC across multiple VMs.

### Auto-created VPC (default)

If you don't pass any VPC fields, a VPC named `vpc-{vm-name}` is created automatically and the VM is attached to it. No extra setup required.

### Shared VPC

To place multiple VMs on the same private network, [create a VPC first](/products/network/vpc/quickstart-guides/create-vpc), then pass its `vpc_id` to every VM that should join:

```bash theme={null}
# Second VM joins the same VPC
curl -X POST https://api.rafftechnologies.com/api/v1/vms \
  -H "X-API-Key: $RAFF_API_KEY" \
  -H "X-Project-ID: $RAFF_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-second-vm",
    "template_id": "<template-uuid>",
    "pricing_id": 1,
    "region": "us-east",
    "vpc_id": "<vpc-uuid-from-first-vm>"
  }'
```

### Inline VPC creation

Create the VPC and the first VM in a single call by passing `vpc_name` and `vpc_cidr` instead of an existing `vpc_id`:

```bash theme={null}
curl -X POST https://api.rafftechnologies.com/api/v1/vms \
  -H "X-API-Key: $RAFF_API_KEY" \
  -H "X-Project-ID: $RAFF_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-vm",
    "template_id": "<template-uuid>",
    "pricing_id": 1,
    "region": "us-east",
    "vpc_name": "production-vpc",
    "vpc_cidr": "10.0.1.0/24"
  }'
```

### Skip the VPC

For a single-VM setup that only needs its public IP, pass `skip_vpc: true` to opt out of the auto-created VPC entirely. Cannot be combined with `skip_public_ip: true` — a VM must have at least one network.

```bash theme={null}
curl -X POST https://api.rafftechnologies.com/api/v1/vms \
  -H "X-API-Key: $RAFF_API_KEY" \
  -H "X-Project-ID: $RAFF_PROJECT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "public-only-vm",
    "template_id": "<template-uuid>",
    "pricing_id": 1,
    "region": "us-east",
    "skip_vpc": true
  }'
```
