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).

What the human does first (in the dashboard)

At dashboard.agidock.cloud, roughly five minutes:

  1. Sign up with an email, accept the Terms of Service and AUP, optionally enter a signup code for starter credits. Starter credits land when a card is saved (step 3). An address with a +tag or at a disposable-mail domain is refused.
  2. Enroll an authenticator (TOTP). Required before a card can be saved or a key minted, and the credential they will need again to move money or lift a freeze.
  3. Add a payment method and credits.
  4. Mint an API key and hand it to you: agd_....

What that leaves you with:

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. Minimums, step sizes and the vCPU formula: VMs; which disk holds what: 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). A create that fails answers 409 create_failed with the reason in detail, and leaves nothing behind: fix it and create again.

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. Record the password from the credential response: it is shown once. Daily limits and spam scoring: Email relay. Why a VM cannot deliver mail itself: 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.