CLI & API
May 11, 2026 ยท View on GitHub
!!! info "Prerequisites"
Ensure the server is up and running. To use dstack with AI agents, install skills.
The primary way to use dstack is the CLI. It can be used to manage
fleets, dev environments,
tasks, services,
volumes, and gateways, view logs,
and inspect events. Use the HTTP API for functionality not
available in the CLI or for integrations that need to call the server directly.
CLI
See installation on how to install the CLI.
Configuration
The CLI requires a project configuration with the project name, server URL, and user token in ~/.dstack/config.yml.
projects:
- name: main
url: http://127.0.0.1:3000
token: <user token>
default: true
- name: octocat
url: https://sky.dstack.ai
token: <user token>
Use dstack project to list,
add, delete, and set the default
project configurations. To run a command against a non-default project, pass
--project NAME, or set DSTACK_PROJECT in the current shell.
??? info "Projects" Projects enable the isolation of different teams and their resources. Users can be added to projects and assigned roles. Each user has a user token for authentication.
Manage fleets
Before submitting runs, you must create at least one fleet. Fleets act as both pools of instances and templates for how those instances are provisioned.
Use dstack fleet to
list existing fleets, their configurations, and instances (if any):
$ dstack fleet
??? info "Offers" Offers are available instance configurations that match resource requirements.
<div class="termy">
```shell
$ dstack offer --gpu H100 --max-offers 10
```
</div>
If no fleet is specified,
[`dstack offer`](../reference/cli/dstack/offer.md) shows offers from all
configured backends.
Use `--fleet NAME` to restrict offers to a fleet. Listing offers does not
create capacity.
Define a fleet configuration in a YAML file. The filename must end with
.dstack.yml, for example fleet.dstack.yml:
type: fleet
name: default
nodes: 0..1
idle_duration: 1h
resources:
gpu: 0
Pass the fleet configuration to dstack apply:
$ dstack apply -f fleet.dstack.yml
If the nodes range starts with 0, dstack creates a fleet template.
Instances are provisioned when matching runs are submitted.
Submit runs
To submit a run, define a dev environment, task, or service configuration. The example below submits a task.
type: task
name: hello
commands:
- echo hello world
Submit the run:
$ dstack apply -f .dstack.yml
!!! info "Plan and confirmation"
dstack apply shows the plan and asks for confirmation before submitting
the run. To only see the plan, answer n at the prompt:
<div class="termy">
```shell
$ echo "n" | dstack apply -f .dstack.yml
```
</div>
Use `-y` to skip confirmation.
!!! info "Attached by default"
For run configurations, dstack apply automatically attaches after
submitting the run. This configures SSH access, forwards declared ports, and
streams logs. See Attach to runs.
Use `-d` to submit in detached mode.
Attach to runs
If the run was submitted with -d, or if you need to attach to another job in
a multi-job run, use dstack attach:
$ dstack attach <run name>
!!! info "SSH"
During dstack apply in attached mode and during
dstack attach <run name>, the CLI downloads the current user's built-in
private SSH key if needed and stores it under ~/.dstack/ssh/.
While attached, the CLI updates `~/.dstack/ssh/config` and ensures this file
is included from `~/.ssh/config`. The file contains a `Host <run name>`
alias used by `ssh <run name>` to SSH into the run container:
<div editor-title="~/.dstack/ssh/config">
```ssh-config
Host <run name>
HostName <host>
Port <ssh port>
User <user>
IdentityFile <private user SSH key>
IdentitiesOnly yes
```
</div>
> For [VM-based backends](../concepts/backends.md#vm-based) and
> [SSH fleets](../concepts/fleets.md), `dstack` may add an additional alias
> `<run name>-host` and use it as a proxy jump for `ssh <run name>`.
While attached, connect to the run with:
<div class="termy">
```shell
$ ssh <run name>
```
</div>
Use --job JOB_NUMBER with dstack attach to attach to another job. Ports
declared in the run configuration are forwarded while attached.
??? info "User SSH keys" The server stores a built-in SSH key pair for each user.
Users can add custom public SSH keys via the UI or the
[users](../reference/http/users.md) API. To use a custom private key for a
particular run, pass `--ssh-identity` to `dstack apply` or `dstack attach`.
Browse logs
When dstack apply is attached, it streams logs for job 0 automatically.
Use dstack logs to view logs in detached
mode, or to view logs for a specific job:
$ dstack logs <run name>
Use --job JOB_NUMBER to select a job and --since to filter by time.
??? info "Attached logs"
Use --logs with dstack attach to stream logs while attaching:
<div class="termy">
```shell
$ dstack attach <run name> --logs
```
</div>
Commands
Other common CLI commands include dstack ps,
dstack stop, and
dstack event.
!!! info "Verbose and JSON modes"
Use -v for more details where supported. For automation, use --json,
e.g. dstack ps --json, dstack run get <run name> --json, or
dstack fleet get <fleet name> --json.
API
The dstack API is represented by the HTTP API. Use it for functionality not
available in the CLI or for integrations that need to call the server directly.
Authenticate
The HTTP API requires the Authorization header for user authentication:
Authorization: Bearer <user token>
Manage fleets
The fleets API can list existing fleets, their configurations, and instances (if any):
$ curl "<server URL>/api/project/<project name>/fleets/list" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{"include_imported": true}'
??? info "Offers"
To check available offers via the HTTP API, call
/runs/get_plan with the same lightweight
task specification used by dstack offer:
<div class="termy">
```shell
$ curl "<server URL>/api/project/<project name>/runs/get_plan" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{
"run_spec": {
"configuration": {
"type": "task",
"commands": [":"],
"image": "scratch",
"user": "root",
"resources": {
"gpu": 0
}
}
},
"max_offers": 5
}'
```
</div>
If `fleets` is not set in the run configuration, offers are returned from
all configured backends. Use `"fleets": ["default"]` to restrict offers to
a fleet.
To group offers by GPU and other fields, use the
[gpus](../reference/http/gpus.md) API.
Creating fleets uses /fleets/get_plan followed by /fleets/apply:
$ curl "<server URL>/api/project/<project name>/fleets/get_plan" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{
"spec": {
"configuration": {
"type": "fleet",
"name": "cpu-fleet",
"nodes": "0..1",
"idle_duration": "1h",
"resources": {
"gpu": 0
}
},
"profile": {}
}
}'
Then apply the fleet plan:
$ curl "<server URL>/api/project/<project name>/fleets/apply" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{
"plan": {
"spec": {
"configuration": {
"type": "fleet",
"name": "cpu-fleet",
"nodes": "0..1",
"idle_duration": "1h",
"resources": {
"gpu": 0
}
},
"profile": {}
}
},
"force": false
}'
Submit runs
Use the runs API to submit dev environments, tasks, and services. The example below submits a task:
$ curl "<server URL>/api/project/<project name>/runs/apply" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{
"plan": {
"run_spec": {
"run_name": "hello-api",
"configuration": {
"type": "task",
"commands": ["echo hello world"]
}
}
},
"force": false
}'
Set run_name if a stable run name is needed. Otherwise, the server can
generate a run name.
Poll /runs/get to check the run status:
$ curl "<server URL>/api/project/<project name>/runs/get" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{"run_name": "hello-api"}'
Poll logs
Use the logs API to poll logs. Get
job_submission_id from /runs/get, e.g. from latest_job_submission.id.
$ curl "<server URL>/api/project/<project name>/logs/poll" \
-X POST \
-H "Authorization: Bearer <user token>" \
-H 'Content-Type: application/json' \
-d '{
"run_name": "hello-api",
"job_submission_id": "<job submission id>",
"limit": 100
}'
Use next_token from the response to continue polling.
Reference
For complete details on specific CLI commands and HTTP APIs, see the
dstack server and
server references.
!!! info "OpenAPI" For complete information on the HTTP API, or to generate native clients, refer to openapi.json.
!!! info "What's next?" 1. Follow the installation guide 2. Read about projects 3. Check fleets, dev environments, tasks, and services