---
title: "Create a new order"
method: POST
path: "/orders"
tags: ["Orders"]
---

# Create a new order

`POST /orders`

## Request

- Base URL: `https://api.imprezahost.com/v1`
- URL: `https://api.imprezahost.com/v1/orders`
- Auth: API key in header `X-API-Key` and API key in header `X-API-Secret`

Creates a new order and pays from account credit balance. The balance must cover
the whole price, configurable options included; otherwise `409 INSUFFICIENT_BALANCE`
returns what is required, what is available and the top-up needed. Nothing is
ordered or charged on any error.

**The VPS** is one configurable product. Choose its `location`, `os`, `cpu_cores`,
`memory_gb` and `disk_gb` from `GET /products/vps` and leave `product_id` out; price
the same body first with `GET /products/vps/quote` if you like. Every choice is
checked against the product: an unknown or hidden location or OS, a size outside
its range or not a whole number, a cycle the product does not sell, or raw
`config_options`/`custom_fields`/`domain` on the VPS returns `400`. A location with
no server that can take the VPS right now returns `409 LOCATION_UNAVAILABLE` before
anything is charged.

**Fixed plans** (Tor Hosting, dedicated servers, e-mail) take their `product_id`
from `GET /products`. Use `GET /products/{id}` to discover their `config_options`
(e.g. number of email accounts) and `custom_fields`. Each option must belong to the
product; the ones you leave out take the default the cart shows.

**Repeats are not charged twice.** An order identical to one placed in the last
24 hours — for the VPS, the same location, OS, sizes, app, cycle and, when given,
hostname — returns that order instead of creating another. To order a second
identical VPS, give it a different `hostname`.

`max_amount` refuses the order with `409 PRICE_ABOVE_LIMIT` if it would cost more.
The REST call answers `202` with `status: provisioning` once every check has
passed, and the order is placed right after; poll `GET /platform/servers` or
`GET /account/services`.

**VPS orders default to a bare OS.** If `app` is omitted, it defaults to
`none`: no Impreza agent is installed, matching the clientarea cart.
Choose `app: "@agent"` explicitly to install the agent at first boot,
`@agent-mcp` for the agent with MCP setup, or a catalog app for first-boot
installation. The customer can request the agent later through the AI
with `impreza_install_agent` and confirmation. Bare VPS services appear
in `GET /account/services`; only an installed, online agent registers
under `GET /platform/servers` and can receive app deployments.

### Examples

**VPS — 2 vCPU, 4 GB, 40 GB in Romania on Ubuntu 24.04 (24.00 USD a month):**
```json
{
  "billing_cycle": "monthly",
  "location": "romania",
  "os": "ubuntu-24.04",
  "cpu_cores": 2,
  "memory_gb": 4,
  "disk_gb": 40,
  "hostname": "web-1"
}
```

**VPS that auto-installs an app on first boot (born deployable):**
```json
{
  "billing_cycle": "annually",
  "location": "switzerland",
  "os": "debian-12",
  "cpu_cores": 2,
  "memory_gb": 4,
  "disk_gb": 60,
  "app": "memos"
}
```

**Tor Hosting (a fixed plan):**
```json
{
  "product_id": 682,
  "billing_cycle": "monthly"
}
```

**Titan Email with 5 accounts:**
```json
{
  "product_id": 20,
  "billing_cycle": "annually",
  "domain": "example.com",
  "config_options": { "8": "5" }
}
```

**Google Workspace with 3 seats:**
```json
{
  "product_id": 25,
  "billing_cycle": "annually",
  "domain": "example.com",
  "config_options": { "12": "3" }
}
```

## Request body

- object
  - `billing_cycle` 'monthly' | 'quarterly' | 'semiannually' | 'annually' | 'biennially' | 'triennially', required
  - `location` union: **VPS.** A location `id`, `slug` or `name` from `GET /products/vps`.
    - string
    - integer
  - `os` union: **VPS.** An operating system `id`, `slug` or `name` from `GET /products/vps`.
    - string
    - integer
  - `cpu_cores` integer: **VPS.** vCPU count, inside the range `GET /products/vps` lists.
  - `memory_gb` integer: **VPS.** Memory in GB, inside the range `GET /products/vps` lists.
  - `disk_gb` integer: **VPS.** SSD disk in GB, inside the range `GET /products/vps` lists.
  - `hostname` string: Server hostname: a DNS name of letters, digits and hyphens in dot-separated labels (stored lowercase). Omitted, the VPS gets a generated one.
  - `max_amount` string: The most this order may cost, in the account currency; a higher price is refused with `409 PRICE_ABOVE_LIMIT`.
  - `product_id` integer: A fixed plan from `GET /products` (Tor Hosting, dedicated, e-mail). Omit it for the VPS, or pass the `product_id` of `GET /products/vps`.
  - `domain` string: Fixed plans only — domain for the service (if applicable).
  - `config_options` object: Fixed plans only. Configurable options: object keys are option IDs, values are the selected sub-option IDs (a number for a quantity, 1/0 for a yes/no). Get the available options from `GET /products/{id}`; each must belong to the product.
  - `custom_fields` object: Fixed plans only. Custom field values: object keys are field IDs, values are the field values. Get available fields from `GET /products/{id}`.
  - `app` string: **VPS only.** What to install on first boot: - `@agent` — install just the Impreza agent. The VPS becomes a **deployable server**: it appears in `GET /platform/servers` and can receive apps via `POST /platform/deployments`. This is an explicit opt-in; the customer can also request it later via `impreza_install_agent` with confirmation. - `@agent-mcp` — the agent, pre-wired for MCP clients (Claude, Cursor, …). - `none` — the default: a bare VPS (OS only, no agent). - an app name from `GET /platform/apps` (e.g. `memos`) — installs the agent **and** that app, served at a free `imprezaapps.com` subdomain with automatic TLS. - on the VPS, a `@panel-*` choice from `GET /products/vps` makes it a control-panel server; an OS the panel cannot run returns `400 INCOMPATIBLE_OS`. Ignored for non-VPS products. An unknown value returns `400`.

## Response `200`

A repeat of an order already placed and paid — that order, not a new one (`repeat` is true)

## Other responses

- `201`: Order created and paid (MCP / in-process callers)
- `202`: Every check passed; the order is being placed and paid, and the VPS provisions (REST)
- `400`: Invalid request — a field names something this product does not offer
- `409`: Not placed, nothing charged: `INSUFFICIENT_BALANCE`, `DUPLICATE_ORDER` (an identical order was accepted in the last 24 hours), `LOCATION_UNAVAILABLE`, `PRICE_ABOVE_LIMIT` or `ORDER_IN_PROGRESS` (another order for the same product is being placed on the account; retry in a few seconds).

---

[API](https://skmtc.dev/imprezahost/apis/impreza-host-public-api.md) · [All operations](https://skmtc.dev/imprezahost/apis/impreza-host-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/imprezahost/apis/impreza-host-public-api/revisions/db86511f604f?raw)
