Concepts

Billing

Billing cycles, the units the API uses for money, orders and subscriptions, invoices and payments, current usage, account credit and payment methods.

Billing cycles

A service is billed on one of five cycles. MONTHLY, QUARTERLY, SEMI_ANNUALLY and ANNUALLY are terms of 1, 3, 6 and 12 months, paid in advance: each new term is invoiced ahead of time and falls due on the subscription's nextRenewal date. HOURLY is paid afterwards. Its billing period is the calendar month in UTC, and once a month closes, a usage invoice bills every hourly service's hours in it, with any traffic over a plan's allowance, due seven days after it is raised.

Each plan prices its cycles under pricing.rates, an object keyed by cycle. Every rate has three fields:

FieldMeaning
priceMillicentsThe price of one hour on HOURLY, or of the whole term on the other cycles, with the term's discount already taken off.
effectiveMonthlyMillicentsThe same price per month, for comparing cycles.
termDiscountThe discount the term carries, as a fraction between 0 and 1. It is 0 on HOURLY.

Units of money

Every amount is a whole number in the currency of its record, or of the record that contains it, and the field's name gives the scale. A name ending in Millicents counts thousandths of a cent, so 150000 is 1.50. Every other money field counts cents: 12999 is 129.99.

ScaleFields
Millicents, for prices and ratesPlan priceMillicents and effectiveMonthlyMillicents; subtotalMillicents on an order, on each of its items and on each item's lines; subtotalMillicents on a subscription item
Cents, for charges and balancesInvoice subtotal, discount, taxes, total and amountDue, and an invoice item's subtotal, discount, taxAmount and total; transaction amount; usage accruedAmount and estimatedAmount; account credit creditBalance, minPurchaseAmount, maxPurchaseAmount, entry amount and the purchase amount

Millicents let an hourly rate keep its sub-cent part, while a term price is always a whole number of cents. An order carries only its price. Tax, discounts and the amount due appear on its invoice.

The currency is an ISO 4217 code, sent as currency on plan pricing, orders, subscriptions and their items, invoices and their transactions, the credit balance and its entries, and the usage summary. Plans are priced in US dollars and converted into the currency the organization is billed in, which cannot change once the organization has an order, an invoice, a subscription or a credit entry.

Ordering services

How you buy a new server or IP block depends on its billing cycle:

BillingCallWhat the call does
A term: MONTHLY, QUARTERLY, SEMI_ANNUALLY or ANNUALLYCreate orderSaves the order, raises its invoice and answers 201. Nothing is provisioned until that invoice is paid in full.
HOURLY, one serverCreate bare metal serviceProvisions the server within the request and answers 201 with the new service.
HOURLY, one IP blockCreate IP blockAdds the block to a network within the request and answers 201 with the block.
HOURLY, any number of itemsCreate order with cycle HOURLYProvisions every item within the request and answers 201. No invoice is raised.

Create order requires cycle and takes all five. The two single-item calls are shorthands for an hourly order of one item: they take that item's fields at the top level of the body, with no type and no cycle, place the same order and run the same checks. All three accept an Idempotency-Key (Idempotency).

Hourly billing needs a usage-based entitlement that a new organization does not have. For now it is granted on request through support in the cloud console. Get entitlements shows it as billing.isUsageBased, and an hourly order or shorthand sent without it answers 422 USAGE_BILLING_DISABLED.

Order items

items holds one entry per server or IP block, since an item has no quantity field. Each entry names its kind in type, BAREMETAL or IP_BLOCK in exactly that case; anything else, or no type at all, is refused with 400 VALIDATION_ERROR. Every item names a plan and a datacenter:

  • plan is the plan's id. A bare metal plan also answers to its slug, which never changes; an IP block plan does not.
  • datacenter is the datacenter's id or its code, such as ams1.

List bare metal plans and List IP block plans return each plan's id, a bare metal plan's slug, and an availability entry per datacenter with its id, its code and the quantity in stock.

A BAREMETAL item also takes the new server's addresses and boot settings:

FieldLeft outAccepts
ipv4PrefixLength3024 to 30, or null for no IPv4
ipv6PrefixLength120120, or null for no IPv6
nameNew Baremetal Server2 to 64 characters
bootModeLOCAL_DISKLOCAL_DISK or PXE
ipxeScriptNo scriptUp to 65,536 characters

With bootMode PXE and a script, the server boots once into that script after it is provisioned (Custom iPXE scripts). The operating system is not part of the order: it is chosen when the server is deployed.

The /30 and the /120 are included in the plan's price. A larger IPv4 block, a length from 24 to 29, adds an IPv4 /<length> line to the order item's lines and to the invoice, priced as the difference between the IPv4 IP block plan of that length and the /30 one.

IPv6 ordered with IPv4 is left out when the datacenter has no IPv6 space, and the server comes up without it; ordered alone, it fails the item instead. A server with both lengths null gets no network and no address, and cannot be deployed until you attach a network of your own and assign it a primary IPv4 address (Networking). Otherwise its prefixes sit on an internet access network created for that server and are billed on the server's own subscription, which is why a BAREMETAL item has no network field.

An IP_BLOCK item takes networkId, the network the block is added to. A network that does not exist or belongs to another organization answers 404 ENTITY_NOT_FOUND. List service virtual networks gives a server's networks with their ids, so a block for a new server's network is ordered once that server exists.

promoCode is optional. Its discount comes off a term order's first invoice; renewals and hourly orders are not discounted, and a blank code counts as none.

The order is checked when it is placed, and a refusal is a 422. OFFERING_NOT_AVAILABLE arrives as the code itself. Every other refusal is a detail under VALIDATION_FAILED on the field it names, which on the shorthands has no items[<i>]. prefix:

CodeFieldWhen
OFFERING_NOT_FOUNDitems[<i>].planNo plan has that id or, for bare metal, that slug.
DATACENTER_NOT_FOUNDitems[<i>].datacenterNo datacenter has that code, or the text is neither an id nor a code.
BILLING_CYCLE_UNAVAILABLEcycleThe cycle is not offered.
PROMO_CODE_INVALIDpromoCodeThe code does not exist or has expired.
IPV4_PREFIX_SIZE_UNAVAILABLEitems[<i>].ipv4PrefixLengthNo IPv4 block plan of that length exists.
IPV6_PREFIX_SIZE_UNAVAILABLEitems[<i>].ipv6PrefixLengthThe length is not 120.
OFFERING_NOT_AVAILABLENoneThe plan is out of stock in that datacenter, the datacenter has no room for the requested prefix, the IP block plan is no longer sold, or no datacenter has that id.

Paying for a term order

A term order's answer holds data.order, whose status is UNPAID, and data.invoiceId. The invoice is due on the day it is raised. It bills each server at its plan's priceMillicents for the cycle, any priced IPv4 prefix on a line of its own, tax for the organization's billing address, and the promo discount. An organization with no billing address gets 422 BILLING_ADDRESS_REQUIRED after the order has been saved; set the address in the cloud console, then send the same request with the same Idempotency-Key to raise the invoice for that saved order.

Nothing pays this invoice for you. Renewal and usage invoices are charged on their due date, from account credit first and then the default card, but an order's first invoice waits until a payment covers it. From a script, Pay invoice with providerType ACCOUNT_CREDIT pays it from the organization's credit, as in the Quickstart.

An order left unpaid is cancelled within 24 hours. Until then it holds no server: stock is checked when the order is placed and again when the paid order is provisioned.

Once the invoice reads PAID, provisioning runs in the background. Each item gets a subscription of its own on the order's cycle, and Get order shows the outcome: the item moves from PENDING to COMPLETED, its provisionedId holds the new server's id (the new block's id for an IP_BLOCK item), and the order moves from UNPAID to COMPLETE. List invoices gives each order invoice's orderId.

An item that cannot be provisioned reads FAILED; a server whose plan sold out between the order and the payment is one example. The order reads FAILED once provisioning has ended with at least one failed item, even when the others completed. The order does not say why an item failed, nothing retries it on its own, a paid invoice stays paid and nothing is refunded automatically, so contact support with the order's id.

Hourly requests

The id in a shorthand's answer is the new server's or block's id. Create order on HOURLY answers with invoiceId null, the subscriptions it opened, and provisionedItems: one entry per item with its orderItemId, its provisionedId and isProvisioned, plus an errorMessage when isProvisioned is false.

A request in which nothing could be provisioned answers 409 PROVISIONING_FAILED, and the order it placed is kept with status FAILED. With several items an order can succeed in part; the answer is then a 201 whose provisionedItems show which items came up. Sending the request again with the same Idempotency-Key places no second order. It answers 200, with isReplayed true on Create order, returns what the first request provisioned and tries any failed item again.

Subscriptions

Each billed service belongs to a subscription, which keeps its cycle, status, lastRenewal and nextRenewal, a terminatedAt once it has ended, and the items it bills, ended ones included. A server's subscription holds the server and one IP_BLOCK item for each address family it was ordered with. An item's provisionedId is the id of the server or block it bills, and its subtotalMillicents is its price per cycle, or per hour on HOURLY. Its details carry includedEgressGb for a server (null for unlimited), or ipVersion and prefixLength for a block.

Get service subscription and Get IP block subscription return the subscription that bills one server or block. A subscription's status is ACTIVE, CANCELLATION_REQUESTED or CANCELLED.

Cancel subscription answers 204. From that moment the subscription raises no renewal invoice and an hourly one stops accruing usage. What happens next depends on what it bills:

  • A bare metal server is deleted. It reads state DELETING while it is powered off and torn down (Removing a service), and the subscription reads CANCELLATION_REQUESTED until the server and its address blocks are gone, then CANCELLED.
  • An IP block ordered on its own is released at once, and its subscription goes straight to CANCELLED.
  • A cloud server, or a subscription with no live item left, goes to our support staff as a ticket for manual review. The subscription reads CANCELLATION_REQUESTED until they finish.

Delete bare metal service on a subscription's only server starts the same cancellation, and Delete IP block does the same for a block ordered on its own. A block that came with a server is refused with 422 BUNDLED_ITEM_CANCELLATION_BLOCKED: delete the server, and the block is released after it.

Asking again while the cancellation is pending answers 204 again. A refusal is a 422, and only SUBSCRIPTION_CANCELLATION_INCOMPLETE comes after a partial change:

codeWhen
SUBSCRIPTION_NOT_ACTIVEThe subscription is already CANCELLED.
SERVICE_LOCKEDA server it bills is locked.
SUBSCRIPTION_SERVER_TRANSFERREDA server it bills now belongs to another organization.
TERMINATION_BLOCKEDOne of its IP blocks has an address assigned to a service other than the subscription's own server.
SUBSCRIPTION_CANCELLATION_INCOMPLETESome items ended before one failed. Sending the request again is safe and does not repeat the finished ones.

Invoices

List invoices takes unpaidOnly=true for the ones still open: UNPAID, PARTIAL and OVERDUE. An invoice's status is one of those three, PAID, COLLECTIONS, CANCELLED or REFUNDED, and its type is STANDARD or, for a credit top-up, CREDIT_PURCHASE. Download invoice PDF returns the PDF itself rather than JSON.

Pay invoice takes a JSON body whose providerType is ACCOUNT_CREDIT or STRIPE; MANUAL, which the enum also lists, is refused with 400. It answers 200 with the payment's status (PENDING, SUCCEEDED, FAILED or CANCELLED), the transactionId it recorded on the invoice, a clientSecret and a declineCode.

  • ACCOUNT_CREDIT pays from the organization's credit, which is the way a script holding a key pays. It takes what the balance holds, up to the amount due, so a balance smaller than the invoice leaves it PARTIAL with the payment SUCCEEDED.
  • STRIPE with the methodId of a saved card charges that card.
  • STRIPE without a methodId starts a card payment for a card form to complete.

A card payment that needs the cardholder, either a new card or a saved one asking for 3-D Secure, answers PENDING with a clientSecret. Stripe.js completes it in a browser with our publishable key, which the API does not hand out, and Confirm invoice payment then records the outcome from providerType STRIPE and the providerTransactionId Stripe gave the payment. Card payments are therefore made in the cloud console.

A refused payment is a 422 whose data holds the same payment view:

codeWhen
PAYMENT_FAILEDThe card was declined, the organization has no account credit, a CREDIT_PURCHASE invoice was sent to be paid from credit, no usable saved card is on file, or Confirm invoice payment could not verify the payment against this invoice.
INVOICE_CANNOT_ACCEPT_PAYMENTThe invoice is already paid, cancelled or refunded, has nothing due, or already has a payment awaiting confirmation. No money was taken. Confirm invoice payment never answers this code.

declineCode is set only for a card decline, for example INSUFFICIENT_FUNDS or EXPIRED_CARD. A generic decline reads GENERIC_DECLINE, and so does a card the network flags as fraudulent, lost or stolen; a decline the platform does not recognise reads UNKNOWN.

Usage in the current period

Get current usage covers the hourly services in the billing period in progress, with amounts in cents:

  • periodStart and periodEnd bound the period.
  • accruedAmount is what those services have run up so far: each one's billable hours at its hourly rate, less any item discount, plus traffic over a plan's allowance.
  • estimatedAmount projects the hours to periodEnd, counting services still running as if they run until then and terminated ones at what they accrued. Traffic counts as measured so far.
  • activeServiceCount and terminatedServiceCount count the services behind those amounts.
  • isPartial is true when part of the usage could not be read, and the amounts then leave that part out.

Account credit

Get credit balance returns the organization's creditBalance and the smallest and largest amount one purchase accepts, minPurchaseAmount and maxPurchaseAmount, all in cents. Purchase credit takes an amount in cents and answers 201 with a CREDIT_PURCHASE invoice; an amount outside the limits is a 422 VALIDATION_FAILED with a CREDIT_AMOUNT_INVALID detail on amount. That invoice carries no tax, is never charged automatically and is paid by card in the cloud console. The credit is added once it is paid.

The balance is the sum of a ledger. List credit entries pages it newest first, and Get credit entry reads one entry: its amount in cents, type, description, createdAt and, when an invoice is involved, invoiceId. A paid credit purchase adds an ADDITION, and credit spent on an invoice is a negative INVOICE_PAYMENT. The other types are PROMOTION, MANUAL_ADJUSTMENT for credit our staff add or remove, and REFUND for credit given back when a credit payment is reversed.

Payment methods

Cards are added in the cloud console, through Stripe, so the card number never passes through this API. Add a card takes no body and answers 201 with provider STRIPE and the clientSecret of the Stripe setup behind the console's card form, which Stripe.js finishes in a browser as it does a card payment. Without a billing address on the organization, the first card setup answers 422 BILLING_ADDRESS_REQUIRED.

Make default payment method answers 204 and makes a saved card the one renewal and usage invoices are charged to. Delete payment method answers 204 and removes a card from the organization and from Stripe. No call lists the saved cards: their ids sit on the organization record, which only a console session reads, so a key cannot find the id these two calls and Pay invoice's methodId take.