Client API: Services
Order and manage provisioned services (lifecycle, actions, cancel, plan changes).
Order and manage provisioned services (lifecycle, actions, cancel, plan changes).
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.
Operations
Section titled Operations| 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 |
| POST | /api/v1/services/{service_ref}/cancel |
Cancel service |
| POST | /api/v1/services/{service_ref}/change-plan |
Change plan |
| GET | /api/v1/services/{service_ref}/events |
Get events |
| GET | /api/v1/services/{service_ref}/upgrade-preview |
Preview plan change |
List services
Section titled List servicesGET /api/v1/services/
Authentication: an access token, sent as Authorization: Bearer <token>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
status |
query | string | no | |
tag |
query | string | no | Filter by resource tag |
resource_type |
query | string | no | Filter by underlying product module. Aliases: cloud_compute→vps, container_apps→container, floating_ip→ip |
limit |
query | integer | no | Default: 100. |
offset |
query | integer | no | Default: 0. |
Responses
Section titled Responses| 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 | |
[].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 itPOST /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. 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_idthe 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. Only a floating IP takes a quantity above 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.
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.
Authentication: an access token, sent as Authorization: Bearer <token>.
Request body
Section titled Request bodyapplication/json (required)
| Field | Type | Required | Description |
|---|---|---|---|
product_id |
integer | yes | |
pricing_id |
integer | yes | |
hostname |
string or null | no | |
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. 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. Only a floating IP may be more than 1, and each one becomes its own service. |
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. |
Responses
Section titled Responses| 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.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 unit of 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[].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>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
service_ref |
path | string | yes |
Responses
Section titled 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, …) |
Execute action
Section titled Execute actionPOST /api/v1/services/{service_ref}/actions
Authentication: an access token, sent as Authorization: Bearer <token>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
service_ref |
path | string | yes |
Request body
Section titled Request bodyapplication/json (required)
| Field | Type | Required |
|---|---|---|
action |
string | yes |
params |
object or null | no |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Cancel service
Section titled Cancel servicePOST /api/v1/services/{service_ref}/cancel
Authentication: an access token, sent as Authorization: Bearer <token>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
service_ref |
path | string | yes |
Request body
Section titled Request bodyapplication/json (required)
| Field | Type | Required |
|---|---|---|
reason |
string or null | no |
immediate |
boolean | no |
keep_snapshot |
boolean | no |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Change plan
Section titled Change planPOST /api/v1/services/{service_ref}/change-plan
Authentication: an access token, sent as Authorization: Bearer <token>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
service_ref |
path | string | yes |
Request body
Section titled Request bodyapplication/json (required)
| Field | Type | Required |
|---|---|---|
new_pricing_id |
integer | yes |
Responses
Section titled Responses| 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 events
Section titled Get eventsGET /api/v1/services/{service_ref}/events
Authentication: an access token, sent as Authorization: Bearer <token>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
service_ref |
path | string | yes | |
page |
query | integer | no | Default: 1. |
limit |
query | integer | no | Default: 50. |
Responses
Section titled Responses| 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) |
Preview plan change
Section titled Preview plan changeGET /api/v1/services/{service_ref}/upgrade-preview
Authentication: an access token, sent as Authorization: Bearer <token>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
service_ref |
path | string | yes |
new_pricing_id |
query | integer | yes |
Responses
Section titled Responses| 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 |