Introduction
Instance creation on Vast.ai follows a two-step process: first find an offer (an available machine), then accept that offer to create an instance. You can configure instances in two ways:- Directly: Pass all configuration (image, environment variables, launch mode, etc.) in the instance creation request
- From a template: Reference a pre-configured template by its
hash_id, optionally overriding specific values
PUT /api/v0/asks/{offer_id}/.
For information about creating and managing templates, see Creating and Using Templates with API.
Instance Creation Fields Reference
When creating an instance, the following fields can be configured:| Field | Type | Required | Description |
|---|---|---|---|
image | string | Yes* | Docker image path (e.g., vllm/vllm-openai). *Optional when using a template |
template_hash_id | string | No | Template hash ID to use as base configuration |
label | string | No | Custom name for the instance |
disk | number | No | Local disk partition size in GB (default: 8) |
runtype | string | No | Launch mode. SSH/Jupyter runtypes replace the image entrypoint with Vast’s entrypoint; args preserves it. See Runtype and Connection Options |
target_state | string | No | Initial state: running (default) or stopped |
price | number | No | Bid price in $/hour (for interruptible instances only) |
env | object | No | Environment variables and port mappings as a JSON object (e.g., {"VAR": "val", "-p 8000:8000": "1"}) |
onstart | string | No | Shell commands to run after Vast’s entrypoint initializes. Used with SSH/Jupyter runtypes to start your application |
args_str | string | No | Replaces the image’s Docker CMD. If the image defines an ENTRYPOINT, args_str is passed as arguments to it. Only used with runtype: "args" |
use_jupyter_lab | boolean | No | Use JupyterLab instead of Jupyter Notebook |
jupyter_dir | string | No | Directory to launch Jupyter from |
python_utf8 | boolean | No | Set Python locale to C.UTF-8 |
lang_utf8 | boolean | No | Set locale to C.UTF-8 |
image_login | string | No | Docker registry credentials for private images (eg., -u username -p access_token docker.io) |
cancel_unavail | boolean | No | Cancel if instance cannot start immediately |
vm | boolean | No | Create a VM instance instead of a container |
volume_info | object | No | Volume creation or linking configuration |
Step 1: Find an Offer
Before creating an instance, search for available machines that match your requirements.The offer
id returned from search is the value you pass as {offer_id} in the instance creation endpoint.Step 2: Create the Instance
Option A: Create Instance Directly (No Template)
Pass all configuration parameters directly in the request. At minimum, you must provide theimage field.
Simple example — create an SSH instance with Ubuntu:
Option B: Create Instance from a Template
Reference a template by itshash_id. The template provides default values for all configuration fields, so you don’t need to specify image or other parameters unless you want to override them.
Basic template usage — all configuration comes from the template:
Runtype and Connection Options
Theruntype field controls how you connect to your instance:
| Runtype | Auto-provisioned Ports | Description |
|---|---|---|
ssh_direct | 22 (SSH) | Direct SSH connection. Port 22 is provisioned on the instance |
ssh_proxy | None | SSH via Vast.ai proxy. No ports provisioned on the instance |
ssh | None | Alias for ssh_proxy |
jupyter_direct | 8080 (Jupyter) + 22 (SSH) | Recommended. Direct Jupyter and SSH access. Ports 8080 and 22 are provisioned on the instance |
jupyter_proxy | None | Jupyter and SSH via Vast.ai proxy. No ports provisioned on the instance |
jupyter | None | Alias for jupyter_proxy |
args | None | Container runs with the original entrypoint and args_str appended. No SSH/Jupyter |
All Jupyter runtypes implicitly include SSH access. Only the
_direct runtypes provision ports on the instance itself — jupyter_direct provisions ports 8080 and 22, while ssh_direct provisions port 22. Proxy runtypes route connections through Vast.ai’s infrastructure without opening ports on the instance.runtype: "jupyter_direct" for the most flexibility — you get both direct Jupyter and direct SSH access with ports provisioned on the instance. Use runtype: "ssh_direct" if you only need SSH.
Entrypoint Behavior
How the container starts depends on the runtype:- SSH and Jupyter runtypes: The image’s original entrypoint is replaced by Vast’s own entrypoint, which sets up SSH/Jupyter access. Use the
onstartfield to run your own startup commands (e.g., launching a server). Youronstartscript runs after the Vast entrypoint has initialized. argsruntype: The image’s originalENTRYPOINTis preserved. Theargs_strvalue replaces the image’s DockerCMD— if the image defines anENTRYPOINT,args_stris passed as arguments to it. If the image has noENTRYPOINT(onlyCMD),args_strreplaces the command entirely. No SSH or Jupyter access is provisioned.
Runtype Examples
Jupyter Lab with SSH (recommended) — useonstart to start your application:
onstart:
args_str replaces the image’s CMD and is passed to its ENTRYPOINT:
Environment Variables and Ports
When creating instances, theenv field is a JSON object (dict). Environment variables are key-value pairs, and port mappings use the Docker -p syntax as keys with "1" as the value.
env dict from your request is merged with the template’s env:
- Existing keys from the template are retained
- New keys from the request are added
- Conflicting keys use the request value
Instance Pricing
On-Demand Instances
On-demand instances use fixed pricing. Simply omit theprice field:
Interruptible (Bid) Instances
For lower-cost interruptible instances, set a bid price. Search withtype: "bid" to find interruptible offers, then provide the price field:
Attaching Volumes
Attach persistent storage to your instance using thevolume_info field. The volume must already exist — you can create volumes separately via the API or CLI before attaching them to an instance.
You can list your existing volumes with
vastai show volumes or the equivalent API call to find the volume_id to use.Using Private Docker Images
If your Docker image is hosted in a private registry, provide credentials via theimage_login field:
When using a template with private registry credentials (
docker_login_repo, docker_login_user, docker_login_pass), those credentials carry over to the instance automatically.End-to-End Example
This example shows the complete workflow: searching for a machine, creating an instance, and checking its status.CLI Reference
The Vast.ai CLI provides equivalent commands for instance creation:| Command | Description |
|---|---|
vastai search offers '<filters>' | Search for available machines |
vastai create instance <offer_id> <image> [options] | Create an instance directly |
vastai create instance <offer_id> --template_hash <hash> | Create an instance from a template |
--image IMAGE- Docker image--template_hash HASH- Template hash ID--disk GB- Disk space in GB--ssh- Launch as SSH instance--direct- Use direct connections--jupyter- Launch as Jupyter instance--jupyter-lab- Use JupyterLab--env ENV- Docker options (env vars and ports)--onstart-cmd CMD- Onstart script--label LABEL- Instance name--price PRICE- Bid price for interruptible instances--link-volume ID- Attach an existing volume--mount-path PATH- Volume mount path
Common Pitfalls
My instance was created but I can't connect via SSH
My instance was created but I can't connect via SSH
Ensure you set the correct
runtype. For SSH access, use runtype: "ssh_direct" for best results. Also verify that:- You have an SSH key registered with Vast.ai (
vastai create ssh-key) - The machine supports direct connections (most verified machines do)
- The instance has finished loading (check
actual_statusisrunning)
My environment variables aren't taking effect
My environment variables aren't taking effect
For instance creation, the This exports all environment variables so they persist across SSH logins.
env field must be a JSON object (dict), not a Docker flag string:- Correct:
{"VAR1": "value1", "VAR2": "value2"} - Wrong:
"-e VAR1=value1 -e VAR2=value2"
-p syntax as keys with "1" as the value: {"-p 8000:8000": "1"}Note: Template creation still uses the Docker flag string format.Also note that environment variables set via env are not automatically visible in SSH sessions. To make them available when you SSH in, add the following to your onstart script:Offer not found or no longer available
Offer not found or no longer available
Offers are dynamic — machines can be rented by others between your search and creation request. Handle this by:
- Searching for multiple offers and trying the next one if creation fails
- Using
cancel_unavail: trueto fail fast if the offer is no longer available - Retrying the search to find fresh offers
My bid instance keeps getting interrupted
My bid instance keeps getting interrupted
Interruptible instances can be stopped when someone outbids you. To reduce interruptions:
- Increase your bid
price - Choose machines with lower demand
- Consider on-demand instances for critical workloads (omit
pricefield)
Volume didn't mount to my instance
Volume didn't mount to my instance
The Where
volume_info field must be included in the instance creation request, not just the template. Template volume_info is a UI hint only.The volume must already exist before you can attach it. Ensure you provide the correct structure:volume_id is the ID of an existing volume from vastai show volumes.