# Client API: Checkout

> Price an order before you place it: the first invoice's lines, a promo code's discount, what is due now and what renews.

Source: https://www.coritan.com/docs/api/reference/client/checkout/

Price an order before you place it: the first invoice's lines, a promo code's discount, what is due now and what renews. Nothing is written.

Base URL: `https://api.coritan.com/api/v1`. Paths below are complete.

To try these requests in the browser, open the [interactive Client API reference](https://api.coritan.com/docs).

## Operations

| Method | Path | Summary |
| --- | --- | --- |
| POST | [`/api/v1/checkout/quote`](#op-post-api-v1-checkout-quote) | What an order would cost, without placing it |

### What an order would cost, without placing it {#op-post-api-v1-checkout-quote}

`POST /api/v1/checkout/quote`

What an order would cost, without placing it.

Send the body you would send to ``POST /api/v1/services/order``,
``addons`` and ``promo_code`` included. The answer lists the lines of the
order's first invoice, what the promo code takes off, what is due before
the order starts and what renews at what price. An order that would be
refused is refused here with the same status and the same sentence, so
a checkout can show it before anyone pays. The quote writes nothing, and
the order checks everything again.

A promo code the order cannot use does not refuse the quote: ``promo``
says why, with ``valid`` false. A refused code counts against the same
budget as ``POST /api/v1/billing/promo/validate``.

Authentication: an access token, sent as `Authorization: Bearer <token>`.

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `product_id` | integer | yes |  |
| `pricing_id` | integer | yes |  |
| `hostname` | string or null | no | The service's name. A Cloud Compute order uses it as the guest hostname: one name of up to 63 letters, digits and hyphens, with no dots and no hyphen at either end. Any other hostname answers 422. |
| `config` | object or null | no |  |
| `idempotency_key` | string or null | no | Replay key for IP orders (double-submit / multi-tab) |
| `turnstile_token` | string or null | no |  |
| `addons` | array of ServiceOrderAddon | no | Up to 8 products bought with this one. Cloud Compute takes Floating IP, DDoS Shield, Mail Hosting and SMTP Relay. Container Apps takes Floating IP, DDoS Shield, Snapshot Storage, Mail Hosting and SMTP Relay. Floating IP takes DDoS Shield. Mail Hosting takes SMTP Relay. Container Apps also takes extra backup slots, extra ports, extra databases and automatic backups. Cloud Compute also takes automatic backups. When the API cannot take one add-on, it refuses the whole order and creates nothing. |
| `addons[].product_id` | integer | yes | The add-on product. |
| `addons[].pricing_id` | integer or null | no | One of the add-on's active prices. Leave it out to take the price with the parent's billing cycle, else the monthly price, else the first active price. |
| `addons[].quantity` | integer | no | How many to order. Each floating IP becomes its own service. A capacity add-on sold per unit, such as Extra Port, becomes one service that holds its quantity, up to 20 units. Every other add-on takes 1. |
| `addons[].config` | object or null | no | The add-on's own config, as an order for that product on its own takes it. A floating IP comes from the parent's location unless config.pool_id names a pool. A DDoS Shield add-on takes profile_name (up to 40 characters), protection_mode, default_action, per_source_pps and aggregate_pps. The order sets the addresses it protects, so the API refuses ip_service_ids. |
| `promo_code` | string or null | no | A promo code. Its discount comes off the product ordered on the first invoice, and off later invoices when the code repeats. A code the order cannot use refuses the order with 422. |

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |
| `422` | The request is not valid. `detail` lists each problem. |

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `lines` | array of QuoteLine | The lines of the order's first invoice. |
| `lines[].label` | string |  |
| `lines[].amount` | string | What the first invoice charges for this line. |
| `lines[].cycle` | string | The billing cycle it renews on, or one_time for a setup fee. |
| `lines[].kind` | string | recurring for the product ordered, setup for its setup fee, addon for the rest. |
| `subtotal` | string |  |
| `discount` | string | What the promo code takes off the first invoice. |
| `due_now` | string | What the order asks you to pay before it starts: the subtotal less the discount, or 0.00 when the order is billed at its first renewal instead. |
| `requires_payment` | boolean | Whether the order waits for its first invoice to be paid. |
| `currency` | string |  |
| `renews` | array of QuoteRenewal | What renews, and at what price. |
| `renews[].label` | string |  |
| `renews[].amount` | string | What each renewal charges, after a promo code that repeats. |
| `renews[].cycle` | string |  |
| `promo` | QuotePromo or null | Null when the order names no promo code. |
| `promo.valid` | boolean |  |
| `promo.code` | string or null |  |
| `promo.message` | string |  |
| `promo.reason` | string or null | Why the code was refused: unknown, inactive, not_yet, expired, exhausted, already_used, first_order, wrong_product, nothing_off, rate_limited or unavailable. |
| `promo.summary` | string or null |  |
| `promo.duration` | string or null |  |
| `promo.cycles` | integer or null | How many invoices the code discounts, when it repeats a set number of times. |
