# Onboarding: zero to running VM

Setup is split between your human and you. **Signup, the authenticator, the
first API key, and anything involving money are human-only** — they happen in
the dashboard, and an API key sent to those endpoints is rejected with
`403 human_required`. Everything else you do yourself, with your key.

All paths below are relative to `https://api.agidock.cloud`, and every one of
them already carries its `/v1` prefix. Requests are shown as method, path and
JSON body; the `Authorization: Bearer agd_...` header is assumed on all of
them, and every POST also needs an `Idempotency-Key`
(see [API conventions](api.md)).

## What the human does first (in the dashboard)

At [dashboard.agidock.cloud](https://dashboard.agidock.cloud), roughly five
minutes:

1. **Sign up** with an email, accept the
   [Terms of Service](https://agidock.cloud/legal/tos.html) and
   [AUP](https://agidock.cloud/legal/aup.html), optionally enter a signup code
   for starter credits, a bonus on every top-up, or both.
2. **Enroll an authenticator** (TOTP). Required before a key can be minted,
   and the credential they will need again to move money or lift a freeze.
3. **Mint an API key** and hand it to you: `agd_...`.
4. **Add a payment method and credits.**

What that leaves you with:

- **No call you make will ask for an authenticator code.** Everything that
  needs one happens before you get the key.
- **Roles**: `read`, `write` or `admin`. Most agents are given `write`, which
  covers every call for VMs, volumes, email and tickets. What each role can
  do: [API conventions](api.md#authentication).
- **Money endpoints will always reject you** — topup, refill, payment method.
  `403 human_required` is not retryable: ask your human.
- **Email sending stays locked until one real payment clears**, regardless of
  granted credits.

Missing a key, missing credits, or `403 human_required`: tell your human.
None of it is fixable from the API.

**Make the requests below yourself; do not hand them to your human.** Then
tell your human what exists and what it costs.

## 1. Create the first VM

```
POST /v1/vms
Authorization: Bearer agd_...
Idempotency-Key: first-vm
Content-Type: application/json

{"name":"web1","ram_mb":4096,"disk_gb":40,
 "image":"ubuntu-lts","ssh_keys":["ssh-ed25519 AAAA..."]}
```

**You choose two sizes, RAM and root disk; the vCPU count follows from RAM.**
`disk_gb` **can never be resized after creation**, so oversize it and put
bulk data on volumes rather than the root.
Minimums, step sizes and the vCPU formula:
[VMs](vm.md#sizing); which disk holds what:
[two kinds of disk](vm.md#two-kinds-of-disk).

`image` comes from `GET /v1/images` — stock images only, no custom upload.

**The create returns a stopped machine, and starting it is a second call.**
Attach whatever the machine should have at first boot, then start it:

```
# optional: give it a data disk before it ever boots.
# Volumes are created detached; attaching is the second call.
POST /v1/volumes                       {"name":"data1","size_gb":500}
POST /v1/volumes/vol_01H.../actions    {"type":"attach","vm_id":"vm_01H..."}
POST /v1/vms/vm_01H.../actions         {"type":"start"}
```

The create response already carries the public IPv4 — ssh in as `ubuntu` with
your key once the machine is running — and that address stays with this VM
for its whole life ([why](vm.md#the-ip-is-fixed-to-the-vm)). If provisioning
goes wrong, the reasons are in `GET /v1/vms/{id}/events`.

Before you change the firewall or sshd: [Harden a
VM](best-practices/harden-your-vm.md).

## 2. Email credentials (optional, needs a real payment)

```
POST /v1/email/domains                 {"domain":"example.com"}
POST /v1/email/credentials             {"domain":"example.com"}
```

The domain comes first. Add the domain, publish the two records it
returns — the DKIM key and a DMARC policy, both checked before the domain will
send — then create a credential against it. There is no shared sending
domain. The credential response carries the submission host and port, and
`GET /v1/email/credentials` carries them again — the password is the only part
you cannot ask for a second time. Daily limits and spam scoring:
[Email relay](email.md). Why a VM cannot deliver mail itself:
[Firewall](vm.md#firewall).

## Default quotas (per project)

RAM, root disk and volume storage are capped per project; nothing else is. The
numbers, and what happens when you reach one, are in
[Running the account](account.md#default-quotas).
