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:
| Field | Meaning |
|---|---|
priceMillicents | The price of one hour on HOURLY, or of the whole term on the other cycles, with the term's discount already taken off. |
effectiveMonthlyMillicents | The same price per month, for comparing cycles. |
termDiscount | The 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.
| Scale | Fields |
|---|---|
| Millicents, for prices and rates | Plan 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 balances | Invoice 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:
| Billing | Call | What the call does |
|---|---|---|
A term: MONTHLY, QUARTERLY, SEMI_ANNUALLY or ANNUALLY | Create order | Saves the order, raises its invoice and answers 201. Nothing is provisioned until that invoice is paid in full. |
HOURLY, one server | Create bare metal service | Provisions the server within the request and answers 201 with the new service. |
HOURLY, one IP block | Create IP block | Adds the block to a network within the request and answers 201 with the block. |
HOURLY, any number of items | Create order with cycle HOURLY | Provisions 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:
planis the plan'sid. A bare metal plan also answers to itsslug, which never changes; an IP block plan does not.datacenteris the datacenter'sidor itscode, such asams1.
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:
| Field | Left out | Accepts |
|---|---|---|
ipv4PrefixLength | 30 | 24 to 30, or null for no IPv4 |
ipv6PrefixLength | 120 | 120, or null for no IPv6 |
name | New Baremetal Server | 2 to 64 characters |
bootMode | LOCAL_DISK | LOCAL_DISK or PXE |
ipxeScript | No script | Up 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:
| Code | Field | When |
|---|---|---|
OFFERING_NOT_FOUND | items[<i>].plan | No plan has that id or, for bare metal, that slug. |
DATACENTER_NOT_FOUND | items[<i>].datacenter | No datacenter has that code, or the text is neither an id nor a code. |
BILLING_CYCLE_UNAVAILABLE | cycle | The cycle is not offered. |
PROMO_CODE_INVALID | promoCode | The code does not exist or has expired. |
IPV4_PREFIX_SIZE_UNAVAILABLE | items[<i>].ipv4PrefixLength | No IPv4 block plan of that length exists. |
IPV6_PREFIX_SIZE_UNAVAILABLE | items[<i>].ipv6PrefixLength | The length is not 120. |
OFFERING_NOT_AVAILABLE | None | The 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
stateDELETINGwhile it is powered off and torn down (Removing a service), and the subscription readsCANCELLATION_REQUESTEDuntil the server and its address blocks are gone, thenCANCELLED. - 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_REQUESTEDuntil 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:
code | When |
|---|---|
SUBSCRIPTION_NOT_ACTIVE | The subscription is already CANCELLED. |
SERVICE_LOCKED | A server it bills is locked. |
SUBSCRIPTION_SERVER_TRANSFERRED | A server it bills now belongs to another organization. |
TERMINATION_BLOCKED | One of its IP blocks has an address assigned to a service other than the subscription's own server. |
SUBSCRIPTION_CANCELLATION_INCOMPLETE | Some 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_CREDITpays 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 itPARTIALwith the paymentSUCCEEDED.STRIPEwith themethodIdof a saved card charges that card.STRIPEwithout amethodIdstarts 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:
code | When |
|---|---|
PAYMENT_FAILED | The 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_PAYMENT | The 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:
periodStartandperiodEndbound the period.accruedAmountis 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.estimatedAmountprojects the hours toperiodEnd, counting services still running as if they run until then and terminated ones at what they accrued. Traffic counts as measured so far.activeServiceCountandterminatedServiceCountcount the services behind those amounts.isPartialistruewhen 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.