Skip to content
Coritan Docs

Client API: Services

Order and manage provisioned services (lifecycle, actions, cancel, plan changes) and the add-ons on each one.

View as Markdown

Order and manage provisioned services (lifecycle, actions, cancel, plan changes) and the add-ons on each one.

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.

Method Path Summary
GET /api/v1/services/ List services
POST /api/v1/services/order Order a platform service, and any add-ons bought with it
GET /api/v1/services/{service_ref} Fetch a service by numeric id OR underlying resource UUID (instance/server/IP)
POST /api/v1/services/{service_ref}/actions Execute action
GET /api/v1/services/{service_ref}/addons The add-ons on one of your services, and the ones you can add
POST /api/v1/services/{service_ref}/addons Add a capacity add-on to one of your active services
POST /api/v1/services/{service_ref}/addons/preview What adding an add-on to one of your services would charge
DELETE /api/v1/services/{service_ref}/addons/{addon_ref} Remove a capacity add-on from one of your services
POST /api/v1/services/{service_ref}/cancel Cancel the service now or at the end of its term
POST /api/v1/services/{service_ref}/change-plan Change the service to another price, prorated
GET /api/v1/services/{service_ref}/events Get events
POST /api/v1/services/{service_ref}/keep Withdraw a cancellation set for the end of the term, so the service keeps renewing
GET /api/v1/services/{service_ref}/upgrade-preview What changing the service to another price would cost now

GET /api/v1/services/

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

Name In Type Required Description
status query string no
tag query string no Filter by resource tag
resource_type query string no Filter by product: vps (or cloud_compute), container (or container_apps), ip (or floating_ip), mail, smtp_relay or storage (Snapshot Storage). Another word answers 422 with the words it accepts.
limit query integer no Default: 100.
offset query integer no Default: 0.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

A 200 response is a list; each item has these fields:

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
[].billing_model string or null usage for a service billed by what it uses, with no plan price and no renewal. Empty for a service billed at a flat price.
[].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, …)

Order a platform service, and any add-ons bought with it

Section titled Order a platform service, and any add-ons bought with it

POST /api/v1/services/order

Order a platform service, and any add-ons bought with it.

The handler checks every add-on before it writes anything. One that the order cannot take refuses the whole order with 422 and {"errors": [<sentence>]}, and the handler creates nothing:

  • the parent decides which add-ons it takes. An instance takes Floating IP, DDoS Shield, Mail Hosting and SMTP Relay; a server takes those and Snapshot Storage; a floating IP takes DDoS Shield; a mail plan takes SMTP Relay. A server and an instance also take the capacity add-ons that fit them (more ports, databases or backup slots, automatic backups). Any other product takes none;
  • the add-on product exists and is active. It is not the free plan, and it is not a product that goes on a service the customer already has, such as an SMTP Relay dedicated IP;
  • its price belongs to it, is active and costs more than $0. Without a pricing_id the order takes the price with the parent's billing cycle, else the monthly price, else the first active price. An hourly price needs the same deposit as an hourly service;
  • an order takes one each of DDoS Shield, Mail Hosting, SMTP Relay and Snapshot Storage, up to 4 floating IPs for an instance and one /32 for a server. A floating IP with a quantity above 1 becomes one service per unit. A capacity add-on sold per unit becomes one service that holds its quantity, up to 20 units; one sold as a switch, and every other add-on, takes a quantity of 1;
  • an instance takes floating IPs only with its included IPv4 (order_ipv4), which stays its free primary address;
  • DDoS Shield needs an address in the order: the instance's included IPv4, a floating IP add-on on a server, or the floating IP being ordered. The order names those addresses itself, so its config may not set ip_service_ids;
  • each add-on's config passes the checks an order of that product on its own passes, and its config options change its price the same way. A floating IP comes from the parent's location unless it names a pool.

Each add-on becomes a pending service of the parent's owner, with addon_of_service_id in its config, and the parent's config lists them in addon_service_ids. When any of them needs a first payment, the parent, its included IP and the add-ons share one first invoice, and credit pays it once. Every service then provisions on its own job, queued when that invoice is paid, or at once when nothing is owed. Once the services are up, the floating IPs attach to the parent and the Shield profile protects the addresses. A replayed order answers with the add-ons it created the first time and creates nothing.

promo_code takes the code's discount off the product ordered, as a credit line on the first invoice; add-ons bought with it are charged in full. A code that repeats discounts the renewals after that. A code the order cannot use refuses the whole order with 422, {"errors": [<sentence>], "promo": <reason>}, before anything is written. A first invoice the code brings to zero is paid at once.

DDoS Shield ordered on its own may name in ip_service_ids only the customer's own floating IPs that are not terminated or cancelled.

A server's name (config.name, else hostname) follows the rule a rename follows: 2–48 characters once its spaces are collapsed, letters, digits, spaces and - _ . ' ! & ( ) [ ] , : +. Any other answers 422.

A game server order may set config.start_on_install to true. We then start the server once its first install finishes. Without it, or with false, the server stays stopped until you start it. A server that waits to be restored from a snapshot stays stopped either way.

A product we no longer sell, one sold only through our sales team and one a plan includes answer 422 with a sentence that names the product. Services already on such a product renew and change plan as before. A product sold before the account plans stays on sale to an account the plans do not apply to yet. A capacity add-on that goes on a service answers 422 when ordered on its own.

An account plan answers 403, {"code": "plans_not_open"}, while plans are not open on the account, and 409 when the account already has a plan or an unpaid order for one.

Mail Hosting, SMTP Relay, Object Storage and a floating IP answer 422, {"code": "out_of_stock", "message", "errors"}, when we cannot set the order up right now: mail is not open for orders or has no capacity, the region has no storage, or no address is in stock. Nothing is charged and no invoice is made. GET /api/v1/availability lists what is available now.

org_slug orders an App Deployment for that organization (:mod:app.deployments.order_account): the caller is its owner or an admin, the service goes on the owner's account and pays from it, and the deployment is the organization's. Any other product answers 422 with "field": "org_slug"; an organization that does not exist 404; a caller who is not its owner or admin 403. Each order for it goes to its audit log as deployment.ordered, as the member who placed it.

The size is the plan's. A virtual machine or a game server gets the vCPUs, memory and disk of the plan the order names, and config may not set them: a cpu_cores, vcpu, cpu_percent, memory_mb, ram_mb, ram_gb, disk_gb or disk_mb that is not the plan's own answers 422, {"field": "<the name sent>", "errors": [...]}. Naming the plan's own figure is the same as leaving it out. Choose a larger plan for a larger size. An order staff place for a customer may size a one-off server.

Billed by use. A virtual machine (Cloud Compute), a game server or a database ordered on your own account is billed by what it uses, whichever price you name. Its service costs 0 to order, has no renewal and no monthly cap, and provisions at once: there is no first invoice. It needs Server access, which comes with its add-on, Pro, Business and Enterprise: without it the order answers 402, {"code": "paid_plan_required", "upgrade": {"addon", "plan"}}. A prepaid account must also have made the first deposit (billing.hourly_minimum_deposit) before it starts anything that runs, or the order answers 403. An account billed by invoice needs no deposit. An organization's order and an order staff place for a customer keep the flat price of the plan.

Server access with the order. A Free account can send include_paid_plan: true to buy Server access (the addon-compute-paid add-on, billed monthly at its price in the catalogue) with its first virtual machine or game server instead of meeting the 402. The add-on is an account service of its own and goes on the order's first invoice, so the invoice is the add-on's first month. The server waits for that invoice as a flat order waits for its first payment: credit pays it at once, and otherwise both services start when it is paid. An account billed by invoice gets both at once, and the add-on renews with its other services. The answer lists the add-on in addons. It answers 422 with {"code": "included_by_plan"} while the plan already includes Server access, with {"code": "already_ordered"} while the account holds it, and with a sentence for an order that is not a virtual machine or a game server billed by use.

An App Deployment of kind git, image, hybrid or static, ordered on your own account, is billed by use too and needs no plan. Leave product_id and pricing_id out (or send 0) to order it on App Deployment's own product. Naming a CX plan instead sets the memory the deployment starts with. config.billing.mode and config.billing.overage are accepted and ignored; config.billing.spend_limit still caps the month. A static deployment needs no deposit, because it runs no instance. A service billed by use refuses POST /services/{ref}/change-plan with 409, {"code": "usage_billed"}.

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

application/json (required)

Field Type Required Description
product_id integer or null no The product to order. An App Deployment of kind git, image, hybrid or static, ordered on your own account, may leave it out or send 0: it is then ordered on App Deployment's usage terms. Naming a CX plan on such an order sets the memory the deployment starts with. Every other order names the product.
pricing_id integer or null no The price of the product. Leave it out only when product_id is also left out, or names App Deployment's own product, which has one price. Virtual machines and game servers are billed by use whichever price you name.
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. App Deployment takes Floating IP, DDoS Shield, Snapshot Storage, Mail Hosting and SMTP Relay. Floating IP takes DDoS Shield. Mail Hosting takes SMTP Relay. App Deployment also takes extra backup slots, extra ports, extra databases, extra CPU, automatic backups and Server Management. Cloud Compute also takes automatic backups. Floating IP, DDoS Shield and Snapshot Storage go on a server, so of the App Deployment kinds only a template takes them. 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.
include_paid_plan boolean no Buy Server access with this order. A virtual machine or a game server needs it, and a Free account has none, so without this the order answers 402 paid_plan_required. With true the order adds Server access (the addon-compute-paid add-on, billed monthly at its current price) to the same first invoice. The server starts when that invoice is paid, at once when your credit covers it. The order answers 422 with included_by_plan when your plan already includes Server access, with already_ordered when your account already holds it, and with a sentence when the order is not a virtual machine or a game server billed by use.
org_slug string or null no Order an App Deployment for this organization instead of your own account. You must be the organization's owner or an admin. The deployment belongs to the organization, and the service goes on the owner's account, which pays for it. Only an App Deployment can be ordered this way.
Status Meaning
201 Success.
422 The request is not valid. detail lists each problem.

Fields of a 201 response:

Field Type Description
service ServiceResponse
service.id integer
service.user_id integer
service.product_id integer
service.pricing_id integer
service.hostname string or null
service.status string
service.billing_cycle string
service.amount number
service.next_due_date string (date-time) or null
service.config object or null
service.module_data object or null
service.suspension_reason string or null
service.provisioned_at string (date-time) or null
service.created_at string (date-time)
service.updated_at string (date-time)
service.product_name string or null
service.product_slug string or null
service.module_name string or null
service.pricing_name string or null
service.termination_date string (date-time) or null
service.billing_model string or null usage for a service billed by what it uses, with no plan price and no renewal. Empty for a service billed at a flat price.
service.monthly_cap number or null
service.hourly_usage_this_month number or null
service.hourly_cap_reached boolean or null
service.tags array of string
service.resource ServiceResourceSummary or null Underlying VPS / Container App / Floating IP summary (DB-backed)
invoice_id integer or null
requires_payment boolean
checkout_available boolean
amount_due string or null
message string or null
addons array of ServiceResponse The services created for the order's add-ons, in the order the client listed them: one per floating IP, and one for each other add-on, which holds its quantity. A replayed order lists the add-ons it created the first time.
addons[].id integer
addons[].user_id integer
addons[].product_id integer
addons[].pricing_id integer
addons[].hostname string or null
addons[].status string
addons[].billing_cycle string
addons[].amount number
addons[].next_due_date string (date-time) or null
addons[].config object or null
addons[].module_data object or null
addons[].suspension_reason string or null
addons[].provisioned_at string (date-time) or null
addons[].created_at string (date-time)
addons[].updated_at string (date-time)
addons[].product_name string or null
addons[].product_slug string or null
addons[].module_name string or null
addons[].pricing_name string or null
addons[].termination_date string (date-time) or null
addons[].billing_model string or null usage for a service billed by what it uses, with no plan price and no renewal. Empty for a service billed at a flat price.
addons[].monthly_cap number or null
addons[].hourly_usage_this_month number or null
addons[].hourly_cap_reached boolean or null
addons[].tags array of string
addons[].resource ServiceResourceSummary or null Underlying VPS / Container App / Floating IP summary (DB-backed)

Fetch a service by numeric id OR underlying resource UUID (instance/server/IP)

Section titled Fetch a service by numeric id OR underlying resource UUID (instance/server/IP)

GET /api/v1/services/{service_ref}

Fetch a service by numeric id OR underlying resource UUID (instance/server/IP).

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

Name In Type Required
service_ref path string yes
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
billing_model string or null usage for a service billed by what it uses, with no plan price and no renewal. Empty for a service billed at a flat price.
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, …)

POST /api/v1/services/{service_ref}/actions

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

Name In Type Required
service_ref path string yes

application/json (required)

Field Type Required
action string yes
params object or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

The add-ons on one of your services, and the ones you can add

Section titled The add-ons on one of your services, and the ones you can add

GET /api/v1/services/{service_ref}/addons

The add-ons on one of your services, and the ones you can add.

attached lists every add-on that has not ended: the products bought with the service (a floating IP, DDoS Shield, Snapshot Storage), the capacity add-ons added since and an SMTP Relay's dedicated IPs. Each carries addon, which says what it adds and whether DELETE takes it. available lists every capacity add-on for this kind of service, with its price on the service's billing cycle. When one cannot be added now, addable is false and reason_unavailable says why. Answers 404 for a service that does not exist and 403 for one that is not yours.

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

Name In Type Required
service_ref path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type Description
parent AddonParent
parent.id integer
parent.product_name string or null
parent.module_name string
parent.status string
parent.billing_cycle string The cycle the service renews on. Its add-ons renew with it. A service billed by use is hourly: each add-on then renews every month on its own, from the day you add it.
parent.amount string The service's own price each cycle. A service billed by use has none.
parent.next_due_date string or null The service's next renewal. An add-on bought now is charged up to this date.
attached array of AttachedAddon
attached[].id integer
attached[].user_id integer
attached[].product_id integer
attached[].pricing_id integer
attached[].hostname string or null
attached[].status string
attached[].billing_cycle string
attached[].amount number
attached[].next_due_date string (date-time) or null
attached[].config object or null
attached[].module_data object or null
attached[].suspension_reason string or null
attached[].provisioned_at string (date-time) or null
attached[].created_at string (date-time)
attached[].updated_at string (date-time)
attached[].product_name string or null
attached[].product_slug string or null
attached[].module_name string or null
attached[].pricing_name string or null
attached[].termination_date string (date-time) or null
attached[].billing_model string or null usage for a service billed by what it uses, with no plan price and no renewal. Empty for a service billed at a flat price.
attached[].monthly_cap number or null
attached[].hourly_usage_this_month number or null
attached[].hourly_cap_reached boolean or null
attached[].tags array of string
attached[].resource ServiceResourceSummary or null Underlying VPS / Container App / Floating IP summary (DB-backed)
attached[].addon AddonBlock
available array of AvailableAddon
available[].product AddonProduct
available[].kind string
available[].label string
available[].adds string What one unit adds.
available[].unit integer How many of the limit one unit adds.
available[].unit_label string
available[].fits array of string
available[].price AddonPrice
available[].max_quantity integer The largest quantity POST takes now. 0 when it cannot be added.
available[].addable boolean
available[].included_by_plan boolean
available[].reason_unavailable string or null Why it cannot be added now, in a sentence.

Add a capacity add-on to one of your active services

Section titled Add a capacity add-on to one of your active services

POST /api/v1/services/{service_ref}/addons

Add a capacity add-on to one of your active services.

The add-on renews with the service, on its billing cycle and date. The first invoice charges the rest of the current period, plus any setup fee, and we take it from your credit balance when that covers it. The add-on applies once the invoice is paid: until then requires_payment is true and invoice_id names the invoice to pay. A service billed by the hour pays a full hour.

Answers 422 with {"errors": [<sentence>]} when the add-on cannot go on this service, such as a product that is not an add-on for it, a quantity above what the service still takes, or automatic backups on a plan that already includes them. A promo code it cannot use also answers 422, with promo naming the reason. Answers 429, with Retry-After, when the account changes add-ons too often.

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

Name In Type Required
service_ref path string yes

application/json (required)

Field Type Required Description
product_id integer yes An add-on from this service's available list.
quantity integer or null no How many units, for an add-on sold per unit. Leave it out for 1. The most a service takes of one kind, across its add-ons, is 20.
billing_cycle string or null no An add-on renews with its service. Leave it out, or send the service's own cycle. A service billed by use has none, so its add-ons renew monthly: send monthly or leave it out.
promo_code string or null no A promo code for the add-on. A code it cannot use refuses the request with 422.
Status Meaning
201 Success.
422 The request is not valid. detail lists each problem.

Fields of a 201 response:

Field Type Description
service AttachedAddon
service.id integer
service.user_id integer
service.product_id integer
service.pricing_id integer
service.hostname string or null
service.status string
service.billing_cycle string
service.amount number
service.next_due_date string (date-time) or null
service.config object or null
service.module_data object or null
service.suspension_reason string or null
service.provisioned_at string (date-time) or null
service.created_at string (date-time)
service.updated_at string (date-time)
service.product_name string or null
service.product_slug string or null
service.module_name string or null
service.pricing_name string or null
service.termination_date string (date-time) or null
service.billing_model string or null usage for a service billed by what it uses, with no plan price and no renewal. Empty for a service billed at a flat price.
service.monthly_cap number or null
service.hourly_usage_this_month number or null
service.hourly_cap_reached boolean or null
service.tags array of string
service.resource ServiceResourceSummary or null Underlying VPS / Container App / Floating IP summary (DB-backed)
service.addon AddonBlock
invoice_id integer or null
requires_payment boolean
charge string The first charge: the rest of this period, plus any setup fee.
discount string
amount_due string What is left to pay on the invoice.
renews_at string or null
renewal_amount string What the add-on costs each cycle from its first renewal.
billing_cycle string
message string

What adding an add-on to one of your services would charge

Section titled What adding an add-on to one of your services would charge

POST /api/v1/services/{service_ref}/addons/preview

What adding an add-on to one of your services would charge. Nothing is added or charged.

The body is the one POST /api/v1/services/{service_ref}/addons takes. The answer is {due_now, currency, lines, renews, promo}: due_now is what the first invoice charges, lines are its parts (the add-on, any setup fee and a promo code as a negative amount), and renews is {amount, cycle, date} for the next renewal. An add-on bought after its service is charged up to the service's next renewal and renews with it. A service billed by use has no renewal, so its add-on charges a full month and renews every month from today.

promo is {valid, message} when you send promo_code and null otherwise. A code the add-on cannot use does not refuse the preview: it answers valid false with the reason, and a refused code counts against the budget POST /api/v1/billing/promo/validate keeps. Refuses what adding the add-on would refuse, with the same answer: 403 for a service that is not yours, 404 for a service or product that does not exist and 422 for an add-on the service cannot take, a quantity it cannot take or another billing cycle.

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

Name In Type Required
service_ref path string yes

application/json (required)

Field Type Required Description
product_id integer yes An add-on from this service's available list.
quantity integer or null no How many units, for an add-on sold per unit. Leave it out for 1. The most a service takes of one kind, across its add-ons, is 20.
billing_cycle string or null no An add-on renews with its service. Leave it out, or send the service's own cycle. A service billed by use has none, so its add-ons renew monthly: send monthly or leave it out.
promo_code string or null no A promo code for the add-on. A code it cannot use refuses the request with 422.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type Description
due_now string What the first invoice charges, after a promo code.
currency string
lines array of PreviewLine
lines[].label string
lines[].amount string What the line costs now. A promo code is a line with a negative amount.
renews PreviewRenewal
renews.amount string What the add-on costs at each renewal, after a promo code that repeats.
renews.cycle string
renews.date string When it renews next, as an ISO 8601 time in UTC.
promo PreviewPromo or null Null when the request names no promo code.
promo.valid boolean
promo.message string

Remove a capacity add-on from one of your services

Section titled Remove a capacity add-on from one of your services

DELETE /api/v1/services/{service_ref}/addons/{addon_ref}

Remove a capacity add-on from one of your services.

addon_ref is the add-on's service id, from the list. The limit it added comes off when it ends. Nothing you already have is deleted, but you cannot add more until you are under the limit again. An add-on whose first invoice was never paid ends at once and its invoice is cancelled. Extra mailboxes or storage in use cannot be removed: delete what is over the limit first (409). An add-on that is being applied cannot be removed until it is on (409). A product bought with the service, such as a floating IP, is cancelled from its own page (422). Answers 429, with Retry-After, when the account changes add-ons too often.

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

Name In Type Required Description
service_ref path string yes
addon_ref path string yes
when query string no end_of_term keeps the add-on until the service renews, and nothing more is charged for it. now removes it at once and refunds nothing. Default: end_of_term.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type Description
service_id integer
when string now or end_of_term, as it was applied.
status string
termination_date string or null
message string

Cancel the service now or at the end of its term

Section titled Cancel the service now or at the end of its term

POST /api/v1/services/{service_ref}/cancel

Cancel the service now or at the end of its term.

immediate queues the terminate job, and a service that was never built ends at once. Otherwise it stays active until its next due date, when the daily sweep ends it. Its unpaid invoices are voided either way. The capacity add-ons on it end with it, on the same day; a failure there is logged and never stops the cancellation. Answers 400 when the service has already ended or is already set to end.

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

Name In Type Required
service_ref path string yes

application/json (required)

Field Type Required
reason string or null no
immediate boolean no
keep_snapshot boolean no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Change the service to another price, prorated

Section titled Change the service to another price, prorated

POST /api/v1/services/{service_ref}/change-plan

Change the service to another price, prorated.

new_pricing_id must be a price of the service's own product, except that an account plan may move between the Pro and Business plans, and Object Storage on a plan we no longer sell may move to pay as you go; the service moves with it. An upgrade creates an invoice for the rest of the cycle and applies once it is paid, at once when your credit covers it. When no whole day is left to prorate, or the new plan costs less per day, that invoice is for a whole period of the new plan instead: the period runs from the renewal date (from now when a period from that date would already be over), the renewal date moves to its end, and the open renewal invoice for that period is voided. A downgrade applies now and credits the unused remainder less the holdback days. The service is then resized. Refuses a service that is not active or already on that price (400), an add-on (422), a price of another product (400), a plan we no longer sell or sell only through our sales team (422), a price that is no longer on sale (422, {"code": "price_not_on_sale"}), a plan whose terms our sales team set (409), a floating IP or DDoS Shield profile the account plan pays for (409), and a whole period while the renewal invoice it would replace is part paid (409). A capacity add-on changes with its service, and an account add-on is cancelled and ordered again. An included service follows the account plan and is not changed on its own. A service billed by what it uses has no price to change and answers 409, {"code": "usage_billed"}. An account plan changes its billing period on the Plan page, or with POST /api/v1/account/plan, and a price on another billing period answers 409.

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

Name In Type Required
service_ref path string yes

application/json (required)

Field Type Required
new_pricing_id integer yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
change_type string
net_amount number
credit_amount number
charge_amount number
credit_issued number
days_remaining integer
invoice_id integer or null
status string or null
message string or null

GET /api/v1/services/{service_ref}/events

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

Name In Type Required Description
service_ref path string yes
page query integer no Default: 1.
limit query integer no Default: 50.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

A 200 response is a list; each item has these fields:

Field Type
[].id integer
[].event_type string
[].actor_type string
[].actor_id integer or null
[].description string or null
[].metadata object or null
[].created_at string (date-time)

Withdraw a cancellation set for the end of the term, so the service keeps renewing

Section titled Withdraw a cancellation set for the end of the term, so the service keeps renewing

POST /api/v1/services/{service_ref}/keep

Withdraw a cancellation set for the end of the term, so the service keeps renewing.

Send no body. It works on your own service while it is active and has an end date in the future: the end date goes back to empty, and the capacity add-ons that were set to end with the service stay too. The answer is the service, as GET /api/v1/services/{service_ref} returns it. The event goes to the service's history and to your account's activity log.

What the cancellation already did is not undone. An unpaid invoice it voided stays void, and a plan change it cleared stays cleared. The next renewal is invoiced as usual, on the plan the service is on now.

Answers 409 with {"code", "message"} when it cannot keep the service: not_cancelled when nothing is scheduled, already_ended when the service has ended or its end date has passed, not_active for a service that is suspended or not running, and scheduled_by_support for an end date our team set. Another account's service answers 403. Organization portals keep their own route for their customers' services.

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

Name In Type Required
service_ref path string yes
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
billing_model string or null usage for a service billed by what it uses, with no plan price and no renewal. Empty for a service billed at a flat price.
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, …)

What changing the service to another price would cost now

Section titled What changing the service to another price would cost now

GET /api/v1/services/{service_ref}/upgrade-preview

What changing the service to another price would cost now.

new_pricing_id must be a price of the service's own product, with two exceptions: an account plan may move between the Pro and Business plans, and Object Storage on a plan we no longer sell may move to pay as you go. The answer is the prorated charge or credit for the rest of the current cycle; credit_estimate is what a downgrade returns after the holdback days. Refuses a service that is not active (400), an add-on (422), a price of another product (400), a plan we no longer sell or sell only through our sales team (422), a price that is no longer on sale (422, {"code": "price_not_on_sale"}), a plan whose terms our sales team set (409), a floating IP or DDoS Shield profile the account plan pays for (409), and a service billed by what it uses (409, {"code": "usage_billed"}). A capacity add-on changes with its service, and an account add-on is cancelled and ordered again. An account plan changes its billing period on the Plan page, or with POST /api/v1/account/plan, and a price on another billing period answers 409.

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

Name In Type Required
service_ref path string yes
new_pricing_id query integer yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
credit_amount number
charge_amount number
net_amount number
credit_estimate number
creditable_days integer
days_remaining integer
days_in_cycle integer
change_type string