# Let customers run Cloud Compute instances

> The portal API your storefront uses to show a customer's Cloud Compute instances, and to power, reach, snapshot and back them up.

Source: https://docs.coritan.com/organizations/storefront/portal-cloud-compute/

Your storefront's instance panel runs on the portal API. Every route on this page is under `/portal/vps/{uuid}/` and takes the customer's token as `Authorization: Bearer $CUSTOMER_TOKEN`. Only the customer who owns an instance can use it: instances cannot be shared, and any other customer gets `404` with `Cloud Compute instance not found`.

The routes work like the platform's `/api/v1/client/vps/{uuid}/` routes that the [Cloud Compute](/cloud-compute/) guides describe, and those guides explain each feature in more depth.

## Before you begin

- Get a customer token as [Sign customers in to your storefront](/organizations/storefront/customer-sign-in/) describes.
- Find the instance's `uuid`. It is `resource.uuid` on the customer's service; see [Show the customer's services](/organizations/storefront/customer-portal/#show-the-customer-s-services).
- The portal has no routes to rebuild an instance, replace its SSH keys, rename it or set its reverse DNS. Plan your panel without them.

## Show an instance

```bash
curl "https://api.coritan.com/api/v1/orgs/acme/portal/vps/$INSTANCE_UUID" \
  -H "Authorization: Bearer $CUSTOMER_TOKEN"
```

The answer is the instance with its `status`, its plan's size, and the image it runs as `template_name`, `os_family` and `os_version`. `username` is the account to sign in with, and `migration` describes a move to another host while one is under way.

| Route | What it returns |
| --- | --- |
| `GET /status` | The live state from the instance's host. |
| `GET /ips` | The instance's addresses, each with its `address`, `gateway` and whether it `is_primary`. |
| `GET /graphs` | Processor, memory, disk and network samples. `timeframe` is `hour` by default, or `day`, `week`, `month` or `year`. |
| `GET /bandwidth` | Traffic this period: `bytes_in`, `bytes_out`, `bytes_used`, the plan's `limit_tb`, `remaining_tb`, `percent_used` and `over_quota`. [How instance traffic is counted](/cloud-compute/traffic/) explains the period. |

## Power an instance

```bash
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/portal/vps/$INSTANCE_UUID/power" \
  -H "Authorization: Bearer $CUSTOMER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action": "shutdown"}'
```

`action` is `start`, `reboot`, `shutdown` (a clean shutdown) or `stop` (power off at once), as [Start, stop and restart an instance](/cloud-compute/power/) describes. The answer is `{"status": "ok", "action": "shutdown"}`.

## Open the console

`GET /console` starts a console session on the instance's host. It answers `vnc_ws`, `vnc_session`, `vnc_password`, `expires_in` and `display`, as [Use an instance's console](/cloud-compute/console/) shows, and the customer's token as `token`. Within `expires_in` seconds, connect a VNC client that speaks WebSocket, such as noVNC, and answer its password prompt with `vnc_password`:

```text
wss://api.coritan.com/ws/vps/vnc/<instance uuid>?token=<customer token>&session=<vnc_session>
```

Ask for a new session for every connection. The socket closes with the codes that guide lists when it cannot connect.

## Passwords and the hostname

- `GET /credentials` returns the `username`, whether we hold a password (`password_stored`) and `updated_at`, without the password.
- `POST /reset-password` sets a new random password on a running instance and returns it once, as `{"password": "…"}`. Show it to the customer straight away, because it cannot be read again.
- `PATCH /hostname` with `hostname` (up to 63 characters) sets the hostname. `reboot` set to `true` restarts the instance so the name takes effect at once.

```bash
curl -X PATCH "https://api.coritan.com/api/v1/orgs/acme/portal/vps/$INSTANCE_UUID/hostname" \
  -H "Authorization: Bearer $CUSTOMER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hostname": "web-2", "reboot": true}'
```

[Manage an instance's password, SSH keys and hostname](/cloud-compute/access/) gives the hostname rules.

## Snapshots

A snapshot saves the instance's disk on its host so the customer can roll back to it. [Take and roll back instance snapshots](/cloud-compute/snapshots/) explains how many an instance keeps.

| Route | What it does |
| --- | --- |
| `GET /snapshots` | Lists the instance's snapshots. |
| `POST /snapshots` | Takes one. `name` is 1–40 characters (default `snapshot`), `description` is optional, and `vmstate` set to `true` saves the memory too. |
| `POST /snapshots/{snapshot_id}/rollback` | Returns the instance to the snapshot, losing every change since. |
| `DELETE /snapshots/{snapshot_id}` | Deletes the snapshot. |

## Backups

A backup is a full copy of the instance's disk, saved as an archive apart from the disk. [Back up and restore an instance](/cloud-compute/backups/) explains how many an instance keeps.

- `GET /backups` lists them.
- `POST /backups` starts one and answers `{"backup_id": 812, "status": "creating"}`.
- `POST /backups/{backup_id}/restore` answers `{"status": "restore_queued"}`, and `DELETE /backups/{backup_id}` answers `{"status": "delete_queued"}`. Read `GET /backups` to follow them.

## Rescue mode

Rescue mode restarts the instance from a rescue image so the customer can repair its disk, as [Repair an instance in rescue mode](/cloud-compute/rescue-mode/) describes.

1. List the images with `GET /rescue/media`. Each has a `volid`.
2. Enter rescue mode with `POST /rescue/enter`, and the image's `volid` as `iso_volid`. With no `iso_volid`, the first image in the list is used.
3. When the repair is done, `POST /rescue/exit` restarts the instance from its disk.

## Result

Customers see each instance they bought from you, with its state, traffic and graphs, and can power it, reach its console, reset its password, and take snapshots and backups without contacting your staff.

## Troubleshooting

`Cloud Compute instance not found`
: The instance is not this customer's, or its service has ended. Check the `uuid` against their services.

`Instance is migrating`
: We are moving the instance to another host. Power actions and new backups are refused until the move ends.

`Cannot perform power actions on a suspended instance`
: The instance is suspended. The service's `status` says so too; see [Service statuses](/organizations/customer-services/#service-statuses).

`Invalid action. Must be: start, stop, shutdown, reboot`
: Send one of those words as `action`.

`Instance must be running to reset password`
: Start the instance, wait for it to boot, then reset the password.

`Monthly traffic quota exceeded; backups are blocked until the next period`
: The instance has used its traffic for this period. Backups work again when the next period starts.

`iso_volid required`
: The host has no rescue image to fall back on. Pick a `volid` from `GET /rescue/media`.

## Related

- [Build the customer account area](/organizations/storefront/customer-portal/)
- [Let customers run their servers](/organizations/storefront/portal-servers/)
- [Cloud Compute](/cloud-compute/)

## API

- `GET /api/v1/orgs/{org_slug}/portal/vps/{uuid}`: Get instance (https://docs.coritan.com/api/reference/organizations/customer-portal/vps/#op-get-api-v1-orgs-org-slug-portal-vps-uuid)
- `GET /api/v1/orgs/{org_slug}/portal/vps/{uuid}/backups`: List backups (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-backups/#op-get-api-v1-orgs-org-slug-portal-vps-uuid-backups)
- `POST /api/v1/orgs/{org_slug}/portal/vps/{uuid}/backups`: Create backup (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-backups/#op-post-api-v1-orgs-org-slug-portal-vps-uuid-backups)
- `DELETE /api/v1/orgs/{org_slug}/portal/vps/{uuid}/backups/{backup_id}`: Delete backup (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-backups/#op-delete-api-v1-orgs-org-slug-portal-vps-uuid-backups-backup-id)
- `POST /api/v1/orgs/{org_slug}/portal/vps/{uuid}/backups/{backup_id}/restore`: Restore backup (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-backups/#op-post-api-v1-orgs-org-slug-portal-vps-uuid-backups-backup-id-restore)
- `GET /api/v1/orgs/{org_slug}/portal/vps/{uuid}/bandwidth`: Get bandwidth (https://docs.coritan.com/api/reference/organizations/customer-portal/vps/#op-get-api-v1-orgs-org-slug-portal-vps-uuid-bandwidth)
- `GET /api/v1/orgs/{org_slug}/portal/vps/{uuid}/console`: Console info (https://docs.coritan.com/api/reference/organizations/customer-portal/vps/#op-get-api-v1-orgs-org-slug-portal-vps-uuid-console)
- `GET /api/v1/orgs/{org_slug}/portal/vps/{uuid}/credentials`: Credentials (https://docs.coritan.com/api/reference/organizations/customer-portal/vps/#op-get-api-v1-orgs-org-slug-portal-vps-uuid-credentials)
- `GET /api/v1/orgs/{org_slug}/portal/vps/{uuid}/graphs`: Get graphs (https://docs.coritan.com/api/reference/organizations/customer-portal/vps/#op-get-api-v1-orgs-org-slug-portal-vps-uuid-graphs)
- `PATCH /api/v1/orgs/{org_slug}/portal/vps/{uuid}/hostname`: Patch hostname (https://docs.coritan.com/api/reference/organizations/customer-portal/vps/#op-patch-api-v1-orgs-org-slug-portal-vps-uuid-hostname)
- `GET /api/v1/orgs/{org_slug}/portal/vps/{uuid}/ips`: List IPs (https://docs.coritan.com/api/reference/organizations/customer-portal/vps/#op-get-api-v1-orgs-org-slug-portal-vps-uuid-ips)
- `POST /api/v1/orgs/{org_slug}/portal/vps/{uuid}/power`: Power (https://docs.coritan.com/api/reference/organizations/customer-portal/vps/#op-post-api-v1-orgs-org-slug-portal-vps-uuid-power)
- `POST /api/v1/orgs/{org_slug}/portal/vps/{uuid}/rescue/enter`: Rescue enter (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-rescue/#op-post-api-v1-orgs-org-slug-portal-vps-uuid-rescue-enter)
- `POST /api/v1/orgs/{org_slug}/portal/vps/{uuid}/rescue/exit`: Rescue exit (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-rescue/#op-post-api-v1-orgs-org-slug-portal-vps-uuid-rescue-exit)
- `GET /api/v1/orgs/{org_slug}/portal/vps/{uuid}/rescue/media`: Rescue media (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-rescue/#op-get-api-v1-orgs-org-slug-portal-vps-uuid-rescue-media)
- `POST /api/v1/orgs/{org_slug}/portal/vps/{uuid}/reset-password`: Reset password (https://docs.coritan.com/api/reference/organizations/customer-portal/vps/#op-post-api-v1-orgs-org-slug-portal-vps-uuid-reset-password)
- `GET /api/v1/orgs/{org_slug}/portal/vps/{uuid}/snapshots`: List snapshots (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-snapshots/#op-get-api-v1-orgs-org-slug-portal-vps-uuid-snapshots)
- `POST /api/v1/orgs/{org_slug}/portal/vps/{uuid}/snapshots`: Create snapshot (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-snapshots/#op-post-api-v1-orgs-org-slug-portal-vps-uuid-snapshots)
- `DELETE /api/v1/orgs/{org_slug}/portal/vps/{uuid}/snapshots/{snapshot_id}`: Delete snapshot (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-snapshots/#op-delete-api-v1-orgs-org-slug-portal-vps-uuid-snapshots-snapshot-id)
- `POST /api/v1/orgs/{org_slug}/portal/vps/{uuid}/snapshots/{snapshot_id}/rollback`: Rollback snapshot (https://docs.coritan.com/api/reference/organizations/customer-portal/vps-snapshots/#op-post-api-v1-orgs-org-slug-portal-vps-uuid-snapshots-snapshot-id-rollback)
- `GET /api/v1/orgs/{org_slug}/portal/vps/{uuid}/status`: Get status (https://docs.coritan.com/api/reference/organizations/customer-portal/vps/#op-get-api-v1-orgs-org-slug-portal-vps-uuid-status)
