# Client API: Account plan

> Your account's plan (Free, Pro, Business or Enterprise), its limits and what the account uses.

Source: https://www.coritan.com/docs/api/reference/client/account-plan/

Your account's plan (Free, Pro, Business or Enterprise), its limits and what the account uses. Preview, order, change or cancel a plan, start the free trial, and set up the mail, SMTP Relay and Object Storage your plan includes.

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 |
| --- | --- | --- |
| GET | [`/api/v1/account/entitlements`](#op-get-api-v1-account-entitlements) | What your plan and add-ons let your account have, and what it uses |
| POST | [`/api/v1/account/included/{kind}`](#op-post-api-v1-account-included-kind) | Set up the mail, SMTP Relay or Object Storage your plan includes |
| GET | [`/api/v1/account/plan`](#op-get-api-v1-account-plan) | Your plan, the plans you can choose and your free trial |
| POST | [`/api/v1/account/plan`](#op-post-api-v1-account-plan) | Order Pro or Business, or change your plan to it |
| POST | [`/api/v1/account/plan/cancel`](#op-post-api-v1-account-plan-cancel) | Cancel your plan |
| POST | [`/api/v1/account/plan/preview`](#op-post-api-v1-account-plan-preview) | What choosing a plan would cost now, and what it would leave over the new plan's limits |
| POST | [`/api/v1/account/plan/trial`](#op-post-api-v1-account-plan-trial) | Start your account's one free trial of Pro or Business |

### What your plan and add-ons let your account have, and what it uses {#op-get-api-v1-account-entitlements}

`GET /api/v1/account/entitlements`

What your plan and add-ons let your account have, and what it uses.

The answer is ``{plan, limits, usage, over_limit, enforced}``. ``plan``
is the same object ``GET /api/v1/account/plan`` returns. ``limits`` holds
every entitlement: a number (``-1`` for unlimited), true or false for a
feature, or a word for ``support_level``. ``usage`` holds the counts we
can measure: websites, load balancers, and the mailboxes, mail domains,
messages sent this month and storage of your included services.
``over_limit`` lists each count above its limit, ``[{entitlement, limit,
used}]``: what is over keeps working, and nothing more of it can be
added. ``enforced`` is false while plans are not open on your account,
and nothing is refused for a limit until it is true.

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

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |

### Set up the mail, SMTP Relay or Object Storage your plan includes {#op-post-api-v1-account-included-kind}

`POST /api/v1/account/included/{kind}`

Set up the mail, SMTP Relay or Object Storage your plan includes.

``kind`` is ``mail``, ``sending`` or ``storage``. Each account has one
included service of each kind, at no charge, sized to its plan: on Free,
5 mailboxes of 1 GB on one domain, 3,000 messages a month and 10 GB of
storage. When the plan changes, the service moves with it.

Creating one passes the checks a free order passes: the challenge
(``turnstile_token``) and a limit on how fast free services are made.
The answer is the service, 201 when this created it and 200 when the
account already had one. Refuses with 404 for another ``kind``, 422 for
a choice the product does not take (storage needs ``location_id``), 403
when the challenge fails, 409 when the account has another free service
of the kind, 429 when free orders come too fast, and 503 when the
service is not available.

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

#### Parameters

| Name | In | Type | Required |
| --- | --- | --- | --- |
| `kind` | path | string | yes |

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `turnstile_token` | string or null | no | The Cloudflare Turnstile response, when the page shows one |
| `domain` | string or null | no | Mail and sending: the first domain. It can be added later. |
| `region` | string or null | no | Mail and sending: the region code. Left out, the default region. |
| `location_id` | integer or null | no | Storage: the location the buckets live in. Required. |
| `bucket_name` | string or null | no | Storage: a first bucket to create |

#### Responses

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

Fields of a `200` response:

| Field | Type | Description |
| --- | --- | --- |
| `id` | integer |  |
| `user_id` | integer |  |
| `product_id` | integer |  |
| `pricing_id` | integer |  |
| `hostname` | string or null |  |
| `status` | string |  |
| `billing_cycle` | string |  |
| `amount` | number |  |
| `next_due_date` | string (date-time) or null |  |
| `config` | object or null |  |
| `module_data` | object or null |  |
| `suspension_reason` | string or null |  |
| `provisioned_at` | string (date-time) or null |  |
| `created_at` | string (date-time) |  |
| `updated_at` | string (date-time) |  |
| `product_name` | string or null |  |
| `product_slug` | string or null |  |
| `module_name` | string or null |  |
| `pricing_name` | string or null |  |
| `termination_date` | string (date-time) or null |  |
| `monthly_cap` | number or null |  |
| `hourly_usage_this_month` | number or null |  |
| `hourly_cap_reached` | boolean or null |  |
| `tags` | array of string |  |
| `resource` | ServiceResourceSummary or null | Underlying VPS / Container App / Floating IP summary (DB-backed) |
| `resource.type` | string | Module resource type: vps \| container \| ip \| external_server |
| `resource.label` | string or null | Human label: hostname, server name, or IP/CIDR |
| `resource.status` | string or null | Resource-level status (not billing status) |
| `resource.address` | string or null | Primary reachability address (IP, IP:port, or CIDR) |
| `resource.detail` | Detail | Module-specific fields (uuids, node, plan, attach state, …) |

### Your plan, the plans you can choose and your free trial {#op-get-api-v1-account-plan}

`GET /api/v1/account/plan`

Your plan, the plans you can choose and your free trial.

``plan`` is ``{key, name, source, status, renews_at, ends_at,
trial_ends_at, service_id, billing_cycle}``. ``key`` is ``free``,
``plan-pro``, ``plan-business`` or ``plan-enterprise``; ``source`` is
``paid``, ``trial`` or ``free``; ``status`` is ``active``, ``cancelling``
(it ends at ``ends_at``) or ``trialing``.

``available`` lists Free and each plan on sale: ``{key, name, prices:
{monthly, annually}, popular, orderable, product_id, pricing_ids,
limits}``. A plan our sales team sells has no prices and is not
orderable. ``limits`` holds the plan's own value for every entitlement,
as ``GET /api/v1/account/entitlements`` writes them, before add-ons.

``trial`` is ``{available, plan, ends_at, status}``: whether you can
start your one trial now, and the trial you had. ``enabled`` is false
while plans are not open on your account; the plan routes that change
something then answer 403.

``pending`` is an order or a plan change waiting for payment, ``{kind,
service_id, plan, name, billing_cycle, invoice_id, amount_due}`` with
``kind`` ``order`` or ``change``; ``suspended`` is a plan held for an
unpaid invoice, ``{service_id, plan, name, invoice_id, amount_due}``.
Both are null when there is none.

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

#### Responses

| Status | Meaning |
| --- | --- |
| `200` | Success. |

### Order Pro or Business, or change your plan to it {#op-post-api-v1-account-plan}

`POST /api/v1/account/plan`

Order Pro or Business, or change your plan to it.

Without a plan, this places an order the way ``POST
/api/v1/services/order`` does: an invoice for the first period, paid
from your credit when it covers it, and the plan starts once it is paid.
``promo_code`` takes a code's discount off that invoice; a code the
order cannot use refuses it with 422, ``{"errors": [<sentence>],
"promo": <reason>}``. Ordering again while an order waits for payment
answers with that order, and an order for another plan replaces it.

With an active plan, this changes it the way ``POST
/api/v1/services/{service_ref}/change-plan`` does: an upgrade invoices
the difference for the rest of the billing period and applies once paid;
a downgrade applies now and credits the unused difference, less the last
few days. Changing the plan withdraws a cancellation, and choosing the
plan you have while it is set to end keeps it renewing.

The answer is ``{service_id, invoice_id, status, change, amount_due,
message}``. ``status`` is ``payment_required`` (pay ``invoice_id``),
``provisioning`` (the plan starts in a moment), ``changed`` or
``renewing``. A running trial ends when the paid plan starts.

Refuses with 403 while plans are not open on your account; with 422 for
Free (cancel instead), Enterprise, an unknown plan or billing, and a
promo code on a plan change; with 404 for a plan not on sale with that
billing; with 409 for the plan you already have, a plan our sales team
set, a change of billing period on an active plan, a change while the
plan is due to renew, a suspended plan and an order that is being set up.

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

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `plan` | string | yes | plan-pro or plan-business |
| `billing_cycle` | string or null | no | monthly or annually. Left out, an active plan keeps its own and a new plan is monthly. |
| `promo_code` | string or null | no | A promo code for a new plan order. A plan change takes none. |

#### Responses

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

### Cancel your plan {#op-post-api-v1-account-plan-cancel}

`POST /api/v1/account/plan/cancel`

Cancel your plan. The account moves to the Free plan.

A paid plan stays until the end of the period you paid for and then
ends; choosing it again with ``POST /api/v1/account/plan`` before then
keeps it. A suspended plan ends now and its unpaid invoice is
cancelled. A trial ends now. A plan order that was never paid is
cancelled with its invoice. Nothing is deleted: what is over the Free
plan's limits keeps working, and nothing more of it can be added.

The answer is ``{status, ends_at, message}``, with ``status``
``cancelling`` (the plan ends at ``ends_at``), ``ended``,
``trial_ended`` or ``order_cancelled``. Refuses with 409 when the plan
is already set to end, when an order is being set up, and when there is
nothing to cancel.

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

#### Request body

`application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `reason` | string or null | no | Why you are leaving, if you want to tell us |

#### Responses

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

### What choosing a plan would cost now, and what it would leave over the new plan's limits {#op-post-api-v1-account-plan-preview}

`POST /api/v1/account/plan/preview`

What choosing a plan would cost now, and what it would leave over the
new plan's limits. Nothing changes.

``plan`` is ``free``, ``plan-pro`` or ``plan-business``, and
``billing_cycle`` is ``monthly`` or ``annually``. ``promo_code`` prices a
code on a new plan order as the order would. The answer is ``{plan,
name, billing_cycle, change, due_now, discount, credit, currency,
renews_at, renewal_amount, ends_at, over_limit, trial, promo,
message}``:

* ``change`` is ``new`` (an order, paid up front), ``upgrade`` (the
  difference for the rest of this billing period is due now),
  ``downgrade`` (it applies now, and the unused difference goes to your
  credit less the last few days), ``cancel`` (to Free, at ``ends_at``),
  ``renew`` (a plan set to end keeps renewing) or ``none``;
* ``over_limit`` lists each count the new plan would leave above its
  limit, ``[{entitlement, limit, used}]``. Nothing is deleted: what is
  over keeps working, and nothing more of it can be added;
* ``renew_at_own_price`` lists the floating IPs and DDoS Shield profiles
  the plan pays for now beyond what the new plan pays for, ``[{entitlement,
  limit, used}]``. The plan keeps paying for the oldest; the newest keep
  working and renew at their own price from their next renewal;
* ``trial`` is ``converts`` when the plan is the same as a running
  trial's or higher, ``ends`` when it is lower, and null without a trial;
* ``discount`` is what the promo code takes off the first invoice, and
  ``due_now`` is what is left. ``promo`` is ``{valid, code, message,
  reason, summary, duration, cycles}``, or null without a code.
  ``renewal_amount`` is the plan's price before the code;
* ``message`` says all of it in a sentence or two.

Refuses Enterprise and unknown plans or billing (422), a plan that is not
on sale with that billing (404), and with 409: a plan whose terms our
sales team set, a change of billing period on an active plan, a change
while the plan is due to renew, and a suspended plan. A promo code on a
plan change or on Free, or one the order would refuse, answers 422
``{"errors": [<sentence>], "promo": <reason>}`` as ``POST
/api/v1/account/plan`` does. A refused code counts against the budget
``POST /api/v1/billing/promo/validate`` keeps, and while that budget is
spent a code answers 429 with ``promo`` ``rate_limited``.

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

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `plan` | string | yes | free, plan-pro or plan-business |
| `billing_cycle` | string or null | no | monthly or annually. Left out, an active plan keeps its own and a new plan is monthly. |
| `promo_code` | string or null | no | A promo code for a new plan order. A plan change takes none. |

#### Responses

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

### Start your account's one free trial of Pro or Business {#op-post-api-v1-account-plan-trial}

`POST /api/v1/account/plan/trial`

Start your account's one free trial of Pro or Business.

A trial lasts 14 days, needs no card and creates no invoice. It gives
the plan's limits at once and moves your included mail, SMTP Relay and
Object Storage up to the plan's allowance. Buying the same plan or a
higher one during the trial ends it and keeps what you have; when it
runs out, the account returns to Free. We email you 4 days and 1 day
before it ends, and when it ends. Nothing is deleted.

The answer (201) is ``{plan, trial, message}``, with ``plan`` as ``GET
/api/v1/account/plan`` returns it. Refuses with 403 while plans are not
open on your account or when the challenge fails, 422 for a plan other
than Pro or Business, 409 when the account has had its trial or has a
paid plan, and 429 after five tries in an hour.

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

#### Request body

`application/json` (required)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `plan` | string | yes | plan-pro or plan-business |
| `turnstile_token` | string or null | no | The Cloudflare Turnstile response, when the page shows one |

#### Responses

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