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

# Creating Servers

> Create, reinstall, resize and delete servers: payment and password rules.

`POST /servers` needs a `read_write` token. It charges the first billing period to your default card, else your first saved card, then builds the server.

## Before You Start

* A verified email address, else `403 email_not_verified`.
* A saved card, else `402 no_payment_method`.
* SSH keys added with `POST /ssh-keys`.
* `GET /locations`, then `GET /plans?location=fra` and `GET /images?location=fra`.

## Create a Server

```bash theme={null}
curl -X POST https://api.arct.cloud/v1/servers \
  -H "Authorization: Bearer $ARCT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "hostname": "web-1",
    "location": "fra",
    "plan": "vm.small",
    "image_id": "IMAGE_ID",
    "ssh_key_ids": ["SSH_KEY_ID"]
  }'
```

| Field | Required | Rules |
| - | - | - |
| `hostname` | Yes | 1 to 63 letters, digits, hyphens; no hyphen at either end. |
| `location` | Yes | Location `code` from `GET /locations`, any case. |
| `plan` | Yes | Plan `slug` from `GET /plans`. |
| `image_id` | Yes | Image ID from `GET /images` for the same location. |
| `billing_period` | No | `monthly` (default), `quarterly`, `semi_annual`, `yearly`. Pre-order locations: `semi_annual` or `yearly`. |
| `ssh_key_ids` | No | Up to 20 of your SSH key IDs. See [Login Password](#login-password). |
| `coupon_code` | No | Promo code, up to 64 characters. See [Promo Codes](#promo-codes). |
| `enable_backups` | No | `true` adds automatic backups for 20% of the plan price, where `backups_available` is `true`. |

There is no card field. To charge another card, make it the default in the dashboard.

Returns `201`:

```json theme={null}
{
  "order": {
    "id": "9b1e3d5f-7a2c-4e6b-8d0f-1c3e5a7b9d2f",
    "order_number": "ORD-20261013-1A2B3C",
    "status": "paid",
    "payment_method": "card",
    "amount": 5.99,
    "server_id": "4f6c2a8e-1d3b-4c5a-9e7f-0b2d4c6e8a1f"
  },
  "server": {"id": "4f6c2a8e-1d3b-4c5a-9e7f-0b2d4c6e8a1f", "hostname": "web-1", "status": "provisioning"},
  "password": null
}
```

`server` can be `null` until it is recorded; find it with `GET /servers`. At a pre-order location, `status` is `pre_order` until deployed.

## Login Password

`password` is the login for `server.login_user`:

| Image | `ssh_key_ids` | `password` |
| - | - | - |
| Windows | Ignored | Set (user `Administrator`) |
| Linux | `[]` | Set |
| Linux | Omitted, no saved keys | Set; keys saved later aren't installed |
| Linux | Omitted, saved keys | `null`; all saved keys installed |
| Linux | Your key IDs | `null`; those keys installed |

* Shown only in this response and the server-ready email. Sent with `Cache-Control: no-store`.
* `null` at pre-order locations or for a delayed build; it is emailed once built.
* A build retried by support gets a new password by email.
* If Windows password setup fails, the email says so; set one in the [VNC Console](/compute/virtual-machines/manage.md#vnc-console).

Connect with [SSH](/compute/virtual-machines/connect-ssh.md) or [RDP](/compute/virtual-machines/connect-rdp.md) once `status` is `running`. Reset a lost password in the dashboard.

## Promo Codes

Send the code as `coupon_code`.

* Checked before any charge. A discount lowers today's charge.
* A code that makes the first payment free sets `payment_method` to `promo`.
* A recurring code also discounts renewals.

## Create Errors

Only `409 payment_pending` and `500` with `details.order_intent_id` may have charged your card: don't retry, contact support with that ID.

| Response | Action |
| - | - |
| `400 bad_request` | Fix the request; see `message`. |
| `400 invalid_promo_code` | Fix or remove `coupon_code`. |
| `402 authentication_required` | Deploy from the dashboard. |
| `402 card_declined` | Make another card the default. |
| `402 no_payment_method` | Add a card in the dashboard. |
| `402 payment_failed` | Check the card, or retry later. |
| `403 email_not_verified` | Verify your email, then retry. |
| `403 orders_disabled`, `503 service_unavailable` | Retry later. |
| `404 not_found` | Send only your own SSH key IDs. |
| `409 hostname_taken` | See [Safe Retries](#safe-retries). |
| `409 out_of_stock` | Choose another plan or location. |
| `409 promo_changed` | Resend the request as is. |
| `409 payment_pending` | Don't retry. Contact support. |
| `500 internal_error` | Retry unless `details.order_intent_id` is set. |

## Follow Provisioning

Poll `GET /servers/{server_id}` every 5 to 10 seconds until `status` is `running`; `ipv4` is set by then.

```bash theme={null}
curl https://api.arct.cloud/v1/servers/$SERVER_ID \
  -H "Authorization: Bearer $ARCT_TOKEN"
```

## Safe Retries

Retry `POST /servers` with the same `hostname`; it can't create a second server.

* A live server or open order with that hostname (any case) returns `409 hostname_taken`.
* After `402`, `409 out_of_stock` or `503` nothing is reserved, so a retry can create the server.
* A deleted server frees its hostname.

## Reinstall a Server

`POST /servers/{server_id}/reinstall` wipes the disk and installs `image_id` from the server's location. The server must be running or stopped. Returns `202` with a new `password` ([same rules](#login-password)); the old one stops working.

```bash theme={null}
curl -X POST https://api.arct.cloud/v1/servers/$SERVER_ID/reinstall \
  -H "Authorization: Bearer $ARCT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"image_id": "IMAGE_ID", "ssh_key_ids": []}'
```

## Resize a Server

A resize moves a stopped server to a bigger plan. The API charges the prorated difference for the rest of the period to the server's billing card, else your default card. A recurring promo carries over.

1. Stop the server; wait until `status` is `stopped`.
2. Call `GET /servers/{server_id}/resize-options`. Check each plan's `eligible` and `amount_due_today`, or `blocked_code` when `can_resize` is `false`.
3. Send `POST /servers/{server_id}/resize` with `plan` and, optionally, `expected_amount` set to the quoted `amount_due_today`.
4. Start the server.

```bash theme={null}
curl -X POST https://api.arct.cloud/v1/servers/$SERVER_ID/resize \
  -H "Authorization: Bearer $ARCT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"plan": "vm.medium", "expected_amount": 4.12}'
```

### Resize Outcomes

| Response | Meaning |
| - | - |
| `200` | Paid. `status` is `applied`. |
| `202` | `status` is `pending_payment`; applies once the payment clears. |
| `400 invalid_plan`, `ineligible` | Not a plan this server can move to. |
| `402 authentication_required` | Pay `details.hosted_invoice_url` within 1 hour; applies once paid. |
| `402 card_declined` | Bank declined the charge. |
| `402 no_payment_method` | No saved card. |
| `409 price_changed` | New quote in `details.amount`. |
| `409 vm_state` | Server isn't stopped, or is suspended. |
| `409 conflict` | Server is a pre-order. |
| `409 pending` | Another resize awaits payment. |
| `409 unpaid_invoice`, `subscription_not_active` | Pay the server's open invoice first. |
| `409 cancel_scheduled` | Undo cancel at period end first. |
| `409 cancelled` | Another session cancelled this resize. |
| `409 refund_pending` | Charged, but the server was deleted; support refunds `details.invoice_id`. |
| `403 billing_mismatch`, `409 unsupported_subscription`, `unknown_plan`, `unknown_price`, `no_billing_period` | Contact support. |
| `503 service_unavailable`, `billing_unavailable` | Retry later. |

`402`, `409 price_changed` and `409 cancelled` charge nothing.

## Delete a Server

`DELETE /servers/{server_id}` deletes the server and wipes its disk at once. Returns `204`. Can't be undone.

```bash theme={null}
curl -X DELETE https://api.arct.cloud/v1/servers/$SERVER_ID \
  -H "Authorization: Bearer $ARCT_TOKEN"
```

* Renewals stop; an unstarted renewal invoice is cancelled.
* Paid time isn't refunded.
* Backups are deleted (used backup days are billed); snapshots are kept.

Returns `409 conflict` when:

* Delete protection is on. Turn it off with `PATCH /servers/{server_id}` and `{"delete_protection": false}`.
* A backup, snapshot or restore is running.
* The server is a pre-order.
* The server is already being deleted.

### Delete at Period End

`DELETE /servers/{server_id}?at_period_end=true` keeps the server until its paid period ends, then deletes it. Nothing renews. Returns `200` with the server; `cancel_at` is the deletion date. Calling it again changes nothing.

```bash theme={null}
curl -X DELETE "https://api.arct.cloud/v1/servers/$SERVER_ID?at_period_end=true" \
  -H "Authorization: Bearer $ARCT_TOKEN"
```

Also returns `409 conflict` when an invoice is unpaid, a resize is pending, a renewal is in progress, or no paid time is left. `503 service_unavailable` means billing is unreachable; retry later.

### Cancel a Scheduled Deletion

`POST /servers/{server_id}/cancel-deletion` keeps the server; it renews as before. Returns `200` with the server and `cancel_at: null`. A server with nothing scheduled is returned unchanged.

```bash theme={null}
curl -X POST https://api.arct.cloud/v1/servers/$SERVER_ID/cancel-deletion \
  -H "Authorization: Bearer $ARCT_TOKEN"
```

Returns `409 conflict` when the server is already being deleted or its period has ended.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.