Skip to content
Coritan Docs

Organization API: Customer Portal: Services

The 13 Organization API operations for services.

View as Markdown

Part of Customer Portal.

Method Path Summary
GET /api/v1/orgs/{org_slug}/portal/services List my services
GET /api/v1/orgs/{org_slug}/portal/services/live What the customer's servers are doing right now, in one request
GET /api/v1/orgs/{org_slug}/portal/services/{service_id} Get my service
POST /api/v1/orgs/{org_slug}/portal/services/{service_id}/cancel Cancel one of the customer's own services, now or at the end of term
POST /api/v1/orgs/{org_slug}/portal/services/{service_id}/cancel-plan-change Cancel my pending plan change
GET /api/v1/orgs/{org_slug}/portal/services/{service_id}/cancel-preview What cancelling right now would return, before committing to it
POST /api/v1/orgs/{org_slug}/portal/services/{service_id}/change-plan Move one of the customer's services to another plan
GET /api/v1/orgs/{org_slug}/portal/services/{service_id}/community-listing Get community listing
PUT /api/v1/orgs/{org_slug}/portal/services/{service_id}/community-listing Upsert community listing
PATCH /api/v1/orgs/{org_slug}/portal/services/{service_id}/gameproxy Update join-address branding (MOTD/favicon) for a service's sidecar gameproxy route
POST /api/v1/orgs/{org_slug}/portal/services/{service_id}/keep Withdraw a cancellation that is set for the end of the term, so the service keeps renewing
GET /api/v1/orgs/{org_slug}/portal/services/{service_id}/plan-preview What a plan change costs today, before committing to it
GET /api/v1/orgs/{org_slug}/portal/services/{service_id}/plans Sizes this service can move to

GET /api/v1/orgs/{org_slug}/portal/services

List the signed-in customer's services, newest first, with the servers other customers shared with them.

Each row has the service's status, plan, billing_cycle, amount, next_due_date and termination_date. termination_date is when the service is set to end, in UTC, or null. ends_at_term_end is true when the customer cancelled it for the end of the time paid for, which POST .../keep can withdraw, and false for no end date or an end date our team set. pending_plan_change is an upgrade waiting for payment, or a switch of billing period waiting for the next renewal (its applies_at is next_renewal). is_owner is false for a shared server.

Name In Type Required Description
org_slug path string yes
status_filter query string no
page query integer no Default: 1.
per_page query integer no Default: 50.
consistency query string, one of strong, eventual no strong (default): reads the primary when the request carries a Coritan-Read-After inside its window, as a client that has just written must. eventual: an idle poll that always reads a pooled replica. Either way, a page with something to heal is healed on the primary. Default: strong.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

What the customer's servers are doing right now, in one request

Section titled What the customer's servers are doing right now, in one request

GET /api/v1/orgs/{org_slug}/portal/services/live

What the customer's servers are doing right now, in one request.

Declared above /services/{service_id} deliberately: that route parses an int, so "live" would 422 rather than reach this one.

Name In Type Required Description
org_slug path string yes
refresh query boolean no Default: False.
ids query string no Comma-separated service ids to probe
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/portal/services/{service_id}

One of the customer's services, or a server shared with them, in the shape of GET /portal/services, including its termination_date (when it is set to end, or null) and ends_at_term_end (true for a cancellation the customer can take back). Another customer's service answers 404.

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

Cancel one of the customer's own services, now or at the end of term

Section titled Cancel one of the customer's own services, now or at the end of term

POST /api/v1/orgs/{org_slug}/portal/services/{service_id}/cancel

Cancel one of the customer's own services, now or at the end of term.

The sequence lives in app.services.org_service_lifecycle so staff cancelling on a customer's behalf run the very same one.

A cancellation keeps a paid container on the org's free plan when it sells one. delete_server (with immediate) is the panel's Delete Server, which deletes it regardless; without immediate it is a 422.

When the server falls back to the free plan, its add-ons end with it unless their ids are in keep_addon_ids: those stay and bill on their own from then on. A server that is deleted ends every add-on. An id that is not one of the server's add-ons is a 422.

A cancellation for the end of the term (immediate false) can be taken back until its termination_date with POST .../keep.

Name In Type Required
service_id path integer yes
org_slug path string yes

application/json

Field Type Required Description
immediate boolean no
reason string or null no
keep_ipv4 boolean no
keep_snapshot boolean no
delete_server boolean no
keep_addon_ids array of integer no Server add-ons (the org_service_id values in the cancel preview's addons) that stay with the server when it falls back to the free plan. Each one bills on its own from then on. The server's other add-ons end with it. Only used when the server falls back to the free plan: a server that is deleted ends every add-on and the ids do nothing. An id that is not one of this server's add-ons answers 422.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/orgs/{org_slug}/portal/services/{service_id}/cancel-plan-change

Cancel an unpaid upgrade so a different plan can be chosen, or call off a switch of billing period that is waiting for the next renewal (the answer then has invoice_id null and applies_at next_renewal).

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

What cancelling right now would return, before committing to it

Section titled What cancelling right now would return, before committing to it

GET /api/v1/orgs/{org_slug}/portal/services/{service_id}/cancel-preview

What cancelling right now would return, before committing to it.

For a server, falls_back_to_free says whether it stays on the free plan, and addons lists its add-ons that are pending, active or suspended (org_service_id, kind, name, quantity, amount, billing_cycle, next_due_date). When the server falls back, send the ids you want to keep as keep_addon_ids on the cancel.

Name In Type Required Description
service_id path integer yes
org_slug path string yes
immediate query boolean no Default: True.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Move one of the customer's services to another plan

Section titled Move one of the customer's services to another plan

POST /api/v1/orgs/{org_slug}/portal/services/{service_id}/change-plan

Move one of the customer's services to another plan.

Send an Idempotency-Key so a retry does not ask twice. An upgrade answers requires_payment: true with the invoice_id of the invoice to pay, and applies once it is paid. A downgrade or a move at the same price applies at once.

A free server may move onto a plan of any billing period, such as a weekly one. When that period is not the free plan's own, the invoice is one whole period of the new plan, and the period starts on the day the invoice is paid. Every other service keeps its billing period: a plan of another period answers 400.

A service on a Standalone product, such as a rank, can also take another billing period of the same product (monthly to annually, or back). That change costs nothing today and applies at the next renewal: the answer has pending: true, scheduled: true, applies_at next_renewal, effective_at and the new_* fields of the plan that is waiting, and no invoice_id. The renewal invoice, the service's amount and its billing cycle then use the new plan. Asking for another period replaces the one waiting, and POST .../cancel-plan-change calls it off. It answers 409 while the service is set to end or an upgrade is waiting for payment.

A server add-on cannot be moved to another plan or billing period: it answers 409. Cancel the add-on and order the one you want.

Name In Type Required
service_id path integer yes
org_slug path string yes
Idempotency-Key header string or null no

application/json (required)

Field Type Required Description
org_pricing_id integer yes
coupon_code string or null no A coupon code of the organization for an upgrade, checked as an order checks it. It comes off the upgrade invoice, and its use is counted when the invoice is paid. A code that does not apply answers 422 with errors and coupon (the reason's word, such as unknown or wrong_product).
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/portal/services/{service_id}/community-listing

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

PUT /api/v1/orgs/{org_slug}/portal/services/{service_id}/community-listing

Name In Type Required
service_id path integer yes
org_slug path string yes

application/json (required)

Field Type Required
display_name string or null no
slug string or null no
tagline string or null no
description string or null no
category string or null no
tags array of string or null no
website_url string or null no
discord_url string or null no
icon_data_uri string or null no
banner_data_uri string or null no
gallery array of string or null no
seo_title string or null no
seo_description string or null no
show_player_count boolean or null no
published boolean or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Update join-address branding (MOTD/favicon) for a service's sidecar gameproxy route

Section titled Update join-address branding (MOTD/favicon) for a service's sidecar gameproxy route

PATCH /api/v1/orgs/{org_slug}/portal/services/{service_id}/gameproxy

Update join-address branding (MOTD/favicon) for a service's sidecar gameproxy route.

Name In Type Required
service_id path integer yes
org_slug path string yes

application/json (required)

Type: Body.

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

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

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

POST /api/v1/orgs/{org_slug}/portal/services/{service_id}/keep

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

Send no body (or {}). It works on the customer's own service while it is active and has an end date in the future: the termination_date goes back to null, a server that would have moved to the free plan on that date stays on its paid plan, and the organization's webhooks receive service.cancellation_withdrawn. The answer is the service, as GET /portal/services/{service_id} returns it.

Unpaid invoices that the cancellation cancelled stay cancelled, and so does a plan change it cleared. The next renewal is invoiced as usual, on the plan the service is on now.

It answers 409 with {"error", "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 customer's service answers 404. A support session can use it only where it can cancel.

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

What a plan change costs today, before committing to it

Section titled What a plan change costs today, before committing to it

GET /api/v1/orgs/{org_slug}/portal/services/{service_id}/plan-preview

What a plan change costs today, before committing to it.

Charged on the days left in the current cycle, not the full price difference: moving up on the last day of the month should cost a day.

For a service on a Standalone product, such as a rank, a plan of another billing period (monthly to annually, or back) costs nothing today and applies at the next renewal. The answer has the same fields, with change_type period, applies_at next_renewal, due_today 0, effective_at (when the first renewal at the new period falls due), renewal_invoice_open (true when the next renewal is already invoiced, so the switch lands on the one after) and current_billing_cycle.

A free server may move onto a plan of any billing period. When the period is not the free plan's own, the upgrade buys one whole period of the new plan from the day it is paid: first_period is true, due_today and charge_amount are the plan's price for that period, days_remaining and days_in_cycle are the period's length, and next_due_date is when it would end if paid now. Every other answer has first_period false.

Name In Type Required Description
service_id path integer yes
org_slug path string yes
org_pricing_id query integer yes
coupon_code query string or null no A coupon code to price an upgrade with. The answer's coupon is {code, discount} and due_today is what is left to pay. A code that does not apply answers 422 with errors and coupon, as change-plan does. Ignored for a downgrade, a move at the same price and a switch of period.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Sizes this service can move to

Section titled Sizes this service can move to

GET /api/v1/orgs/{org_slug}/portal/services/{service_id}/plans

Sizes this service can move to.

Constrained to the same game, the same hardware tier and the same billing cycle, so the list is genuinely "the same thing, bigger or smaller". Without the game filter a Minecraft server was offered Terraria and Rust plans, and without the cycle filter the same size appeared once per billing period.

A service on a Standalone product, such as a rank, has no sizes. Its list is the product's own pricing rows, one per billing period (monthly, annually), so the customer can switch between them. Each row says when it would apply in applies_at: now for the service's own billing cycle, next_renewal for another one, which the service takes when its next renewal is invoiced. scheduled is true on the row a switch is waiting for.

A server add-on (extra CPU, automatic backups, Server Management) has no plans to move to, so its list is empty.

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