Skip to content
Coritan Docs

Client API: Billing

Invoices and their PDFs, credit balance, top-ups, refund requests and hourly billing controls, and how each deployment is billed: its metered use, its cost this month, pay as you go or a commit, overa

View as Markdown

Invoices and their PDFs, credit balance, top-ups, refund requests and hourly billing controls, and how each deployment is billed: its metered use, its cost this month, pay as you go or a commit, overage, and the deployment's and the account's spend limits. For Object Storage: the month so far against the free amounts, a monthly budget that sends alerts, and the month's use by bucket and day as CSV.

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/billing/credit Your credit balance and your 20 newest credit entries
GET /api/v1/billing/crypto/address This user's permanent deposit address for the network's chain family
GET /api/v1/billing/crypto/assets Assets we can accept right now
POST /api/v1/billing/crypto/check Look for this customer's payment now, and say where it stands
GET /api/v1/billing/crypto/deposits Deposit history, including transfers still confirming
GET /api/v1/billing/crypto/deposits/{deposit_id} One deposit, for polling while it confirms
GET /api/v1/billing/crypto/plan Every way to pay this amount in crypto, cheapest first
GET /api/v1/billing/crypto/quote How much to send for a target USD credit, itemised
GET /api/v1/billing/deployments/{app_uuid} How a deployment is billed and what it has cost this month
PATCH /api/v1/billing/deployments/{app_uuid} Change deployment billing
PUT /api/v1/billing/deployments/{app_uuid}/spend-limit Set a deployment's monthly spend limit, or change it
DELETE /api/v1/billing/deployments/{app_uuid}/spend-limit Remove a deployment's monthly spend limit, and lift what it held
POST /api/v1/billing/deployments/{app_uuid}/switch Move a deployment from pay as you go or a commit to usage billing
GET /api/v1/billing/hourly-eligibility Check hourly eligibility
GET /api/v1/billing/invoices Newest first, ties by id so a page boundary never repeats or skips a row
GET /api/v1/billing/invoices/{invoice_id} Get invoice
POST /api/v1/billing/invoices/{invoice_id}/apply-credit Apply account credit to an unpaid invoice (unlocks provision / plan change when paid)
GET /api/v1/billing/invoices/{invoice_id}/pdf The invoice as a PDF to keep, for the account it belongs to
GET /api/v1/billing/object-storage/{service_id} Object storage billing
PUT /api/v1/billing/object-storage/{service_id}/budget Set the service's monthly budget, or change it
DELETE /api/v1/billing/object-storage/{service_id}/budget Remove the service's monthly budget, and with it the alerts
GET /api/v1/billing/object-storage/{service_id}/usage.csv Object storage usage CSV
GET /api/v1/billing/refund-requests The account's refund requests, newest first
POST /api/v1/billing/refund-requests Ask for money back on a paid invoice: all of it, or amount
POST /api/v1/billing/refund-requests/{request_id}/withdraw Withdraw a request staff have not decided yet
POST /api/v1/billing/services/{service_id}/switch Switch service to usage
GET /api/v1/billing/spend-limit Get account spend limit
PUT /api/v1/billing/spend-limit Set the account's own monthly spend limit, across all its deployments
DELETE /api/v1/billing/spend-limit Remove the account's own monthly spend limit, and lift what it held
POST /api/v1/billing/topup/checkout Hosted checkout to buy account credit without a saved payment method
GET /api/v1/billing/topup/config Get topup config
PUT /api/v1/billing/topup/config Update topup config
POST /api/v1/billing/topup/confirm-payment Add credit for a card payment the customer finished in the page
POST /api/v1/billing/topup/manual Add credit by charging a saved payment method
POST /api/v1/billing/topup/pay-intent Create a Stripe PaymentIntent to add credit in the page
GET /api/v1/billing/topup/pay-quote What a card payment to add credit charges, and which card form to draw
POST /api/v1/billing/topup/paypal-capture Capture an approved PayPal order and credit the platform user balance
POST /api/v1/billing/topup/square-pay Add credit with a Square card token
GET /api/v1/billing/transactions As listinvoices: newest first, ties by id, withtotal for a TransactionPage
GET /api/v1/billing/usage Deployment usage

Your credit balance and your 20 newest credit entries

Section titled Your credit balance and your 20 newest credit entries

GET /api/v1/billing/credit

Your credit balance and your 20 newest credit entries.

balance and every entry's amount are in credit_currency, always USD. currency is the currency we charge you in. It is your preferred pay currency and does not label the balance.

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

Status Meaning
200 Success.

Fields of a 200 response:

Field Type Description
balance number Your credit balance, in credit_currency.
currency string The currency we charge you in (your preferred pay currency). It never labels balance.
credit_currency string The currency balance and every ledger amount are held in. Always USD.
recent_transactions array of CreditLedgerEntry
recent_transactions[].id integer
recent_transactions[].amount number
recent_transactions[].balance_after number
recent_transactions[].description string
recent_transactions[].created_at string (date-time)

This user's permanent deposit address for the network's chain family

Section titled This user's permanent deposit address for the network's chain family

GET /api/v1/billing/crypto/address

This user's permanent deposit address for the network's chain family.

Uses the write session because a first call issues an address. Repeat calls return the same one.

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

Name In Type Required Description
network query string yes Network key, e.g. base or bitcoin
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Assets we can accept right now

Section titled Assets we can accept right now

GET /api/v1/billing/crypto/assets

Assets we can accept right now.

Excludes anything enabled but unpriced, since a deposit to it would be held rather than credited.

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

Status Meaning
200 Success.

Look for this customer's payment now, and say where it stands

Section titled Look for this customer's payment now, and say where it stands

POST /api/v1/billing/crypto/check

Look for this customer's payment now, and say where it stands.

What the refresh button calls, and what the wallet and invoice panels poll while they are open. Before this the panels could only re-read the database and wait for the background scan to notice. A customer who had just paid had no way to ask, and the honest answer to "is it there yet" was "wait".

Rate limited because it reads the chain, which is spending money on the customer's behalf. The chain read is separately throttled inside, so several tabs polling on their own timers cost one read rather than one each; below that threshold this still answers with current deposit state, which is what was actually being asked for.

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

application/json

Type: object or null.

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

Deposit history, including transfers still confirming

Section titled Deposit history, including transfers still confirming

GET /api/v1/billing/crypto/deposits

Deposit history, including transfers still confirming.

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

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

One deposit, for polling while it confirms

Section titled One deposit, for polling while it confirms

GET /api/v1/billing/crypto/deposits/{deposit_id}

One deposit, for polling while it confirms.

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

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

Every way to pay this amount in crypto, cheapest first

Section titled Every way to pay this amount in crypto, cheapest first

GET /api/v1/billing/crypto/plan

Every way to pay this amount in crypto, cheapest first.

Answers the question a customer has ("how much do I send to end up with $X?") instead of showing a rate and a spread and leaving the arithmetic to them. Each option states what it credits, which is never below the target, and says outright when a chain's fee would eat the deposit.

invoice_id targets the invoice's outstanding balance instead of a bare amount, so the figure shown is the one that settles it.

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

Name In Type Required
amount query number or string yes
invoice_id query integer or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

How much to send for a target USD credit, itemised

Section titled How much to send for a target USD credit, itemised

GET /api/v1/billing/crypto/quote

How much to send for a target USD credit, itemised.

Quoting records an intent, which is what lets the deposit be credited at the rate shown here and applied to invoice_id when it lands, instead of arriving as a balance the customer then has to spend by hand.

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

Name In Type Required
network query string yes
asset query string yes
amount query number or string yes
invoice_id query integer or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

How a deployment is billed and what it has cost this month

Section titled How a deployment is billed and what it has cost this month

GET /api/v1/billing/deployments/{app_uuid}

How a deployment is billed and what it has cost this month.

billing_mode is usage (rated by the second on memory, CPU, requests and data out, with no price of its own), payg (each instance-hour at payg.hourly_price) or commit (commit.instances paid for by the commit.cycle at commit.price, renewing at commit.renews_at). It is null for a deployment billed by its own service's plan (service), and for one not billed yet, which shows the hourly price pay as you go would start at. sponsored is true for a deployment Coritan runs at no charge. spend_limit and account_spend_limit are the deployment's and the account's monthly limits with what counts against each; held says whether a reached limit (its policy) or a used-up allowance is holding the deployment back, and held.allowances lists each used-up allowance as {meter, entitlement, addon}, where addon is the slug of the add-on pack that raises it, or null. usage is this month's metered use by meter and month_to_date what the deployment has cost this month, a commit's share of its base included.

currency is always USD: the currency of month_to_date, usage, rates and both spend limits, whatever currency the account pays in. price_currency is the currency of the prices read from a pricing row (commit, payg and service.amount). It is USD unless the plan has a price in the account's own currency.

rates is set only for a deployment billed by use. It lists each web meter with its rate per unit, the included amount the account gets each month (the three data out meters share one allowance, egress_gb) and used, how much of that amount every deployment of the account has used this month. used is null for anyone but the account that pays.

Answers 404 for a deployment this account does not pay for.

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

Name In Type Required Description
app_uuid path string yes The deployment's uuid
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

PATCH /api/v1/billing/deployments/{app_uuid}

Change how a deployment is billed: pay as you go or a commit, how many instances a commit pays for, and whether use past an allowance is blocked or billed per unit.

With ?preview=1 nothing is written and the answer is the price. due_now: a new commit pays its first whole period from now, and more instances pay the rest of the period. credit: fewer instances, or leaving a commit, return the unused rest less the holdback days. payment says how due_now would be paid: credit when the credit balance covers it, invoice for an account that pays by invoice, short when neither does. refusal is what the change would be refused with. Without preview the change is made at once and the answer is the deployment's billing with change: what was charged or credited, and the invoice. A deployment not billed yet starts pay as you go first (starts_billing).

due_now, credit, commit and payg are in price_currency, the currency of the plan's pricing row (USD unless the plan has a price in the account's own currency). credit_balance and currency are always USD, the currency of the credit balance.

Answers 402 when a prepaid account's credit does not cover what is due now (nothing changes), 404 for a deployment this account does not pay for, 409 when the deployment is billed by its own service's plan or by use (usage_billed), is sponsored, its service is not active or is set to end, its plan is not offered with the billing mode, or a part-paid renewal invoice stands in the way, and 422 for an empty change, commit_instances without a commit, or pay as you go for an account billed by invoice (prepaid_only), which needs a commit.

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

Name In Type Required Description
app_uuid path string yes The deployment's uuid
preview query boolean no Price the change and write nothing Default: False.

application/json (required)

Field Type Required Description
billing_mode string or null no payg bills each instance-hour; commit pays for a number of instances by the month
commit_instances integer or null no The instances a commit pays for; a new commit takes its locations' minimum when left out
overage_mode string or null no block stops use past an allowance; allow bills it per unit, up to the spend limit
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Set a deployment's monthly spend limit, or change it

Section titled Set a deployment's monthly spend limit, or change it

PUT /api/v1/billing/deployments/{app_uuid}/spend-limit

Set a deployment's monthly spend limit, or change it.

What counts against it is the deployment's metered use this month and its commit's share of the month. Alerts go to the account at 80% and 100%, and at 50% while the deployment is pay as you go. At 100% policy applies: block sleeps its previews and stops bursts, builds and overage; pause stops every instance until the limit is raised or the month turns. Setting a limit above what is spent lifts what it held.

Answers 404 for a deployment this account does not pay for, 409 for one billed by its own service's plan, and 422 for an amount that is not more than 0 and at most 1000000 with two decimal places.

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

Name In Type Required Description
app_uuid path string yes The deployment's uuid

application/json (required)

Field Type Required Description
monthly_limit number or string yes An amount in US dollars, the currency of your credit, e.g. "50.00"
policy string no At 100%: block sleeps previews and stops bursts, builds and overage; pause stops every instance
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Remove a deployment's monthly spend limit, and lift what it held

Section titled Remove a deployment's monthly spend limit, and lift what it held

DELETE /api/v1/billing/deployments/{app_uuid}/spend-limit

Remove a deployment's monthly spend limit, and lift what it held. Answers 204 whether or not it had one, and 404 for a deployment this account does not pay for.

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

Name In Type Required Description
app_uuid path string yes The deployment's uuid
Status Meaning
204 Success.
422 The request is not valid. detail lists each problem.

Move a deployment from pay as you go or a commit to usage billing

Section titled Move a deployment from pay as you go or a commit to usage billing

POST /api/v1/billing/deployments/{app_uuid}/switch

Move a deployment from pay as you go or a commit to usage billing.

Usage billing rates what the deployment uses by the second (memory, CPU, requests, data out, builds and logs) after the account's included monthly amounts, and has no price of its own. The move is one way. Spend limits and add-ons stay as they are, and open renewal invoices are voided.

With ?preview=1 (or {"preview": true}) nothing is written and the answer is {"preview": true, "current": {"billing", "cycle", "price", "paid", "renews_at"}, "usage": {"total", "currency", "lines"}, "basis", "sources", "window", "difference", "effective", "switches_at", "credit", "credit_now", "scheduled", "currency", "price_currency", "paid_plan", "refusal", "notes"}. usage.total is what the last 30 days (or the days since the deployment was made) would have cost on usage billing and current.paid what it paid. currency is always USD, the currency of the usage and of the credit balance. current.price is in price_currency, the currency of the service's pricing row. basis is measured when the estimate comes from the deployment's own meters and run history, and assumed when nothing was measured and the estimate takes it as always on with CPU at 10%. refusal carries what would stop the move now (a deposit not made, a part-paid renewal) as {code, message} and leaves the estimate in place.

A deployment billed by the hour moves at once (effective now). One billed by the month or longer moves when its paid period ends (effective at renewal, the default, when renewal), or at once with {"when": "now"}, which credits the unused days less the holdback days to the credit balance (credit). Without preview the answer is the deployment's billing, as GET /api/v1/billing/deployments/{uuid} answers, with switch (effective, switched, switches_at, credited, from). Audited deployment.billing_switched.

Answers 403 deposit_required to a prepaid account that has not made the deposit that unlocks hourly billing, 404 for a deployment this account does not pay for, 409 for a deployment that is already billed by use (already_usage), sponsored, not billed yet (not_billed), billed to an organization's customer (organization_customer) or kept at a Coritan brand's price (brand_service), whose service is not active or is set to end, that already moves at its renewal (switch_scheduled) or has a part-paid renewal invoice (renewal_part_paid), and 429 past 20 changes or 240 previews an hour.

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

Name In Type Required Description
app_uuid path string yes The deployment's uuid
preview query boolean no Price the move and write nothing Default: False.

application/json

Field Type Required Description
preview boolean no Price the move and write nothing, as ?preview=1 does
when string or null no For a service billed by the month or longer: renewal (the default) moves it when its paid period ends, now moves it at once and credits the unused days. A service billed by the hour always moves now.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/billing/hourly-eligibility

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

Status Meaning
200 Success.

Newest first, ties by id so a page boundary never repeats or skips a row

Section titled Newest first, ties by id so a page boundary never repeats or skips a row

GET /api/v1/billing/invoices

Newest first, ties by id so a page boundary never repeats or skips a row.

The bare list is the answer every existing caller reads; with_total wraps the same page in InvoicePage.

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

Name In Type Required Description
page query integer no Default: 1.
limit query integer no Default: 50.
status_filter query string or null no
with_total query boolean no Default: False.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/billing/invoices/{invoice_id}

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

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

Fields of a 200 response:

Field Type
id integer
invoice_number string
user_id integer
subtotal number
tax number
total number
amount_paid number
currency string
status string
due_date string (date-time)
paid_at string (date-time) or null
notes string or null
items array of InvoiceItemResponse
items[].id integer
items[].service_id integer or null
items[].description string
items[].item_type string
items[].quantity number
items[].unit_price number
items[].total number
created_at string (date-time)

Apply account credit to an unpaid invoice (unlocks provision / plan change when paid)

Section titled Apply account credit to an unpaid invoice (unlocks provision / plan change when paid)

POST /api/v1/billing/invoices/{invoice_id}/apply-credit

Apply account credit to an unpaid invoice (unlocks provision / plan change when paid).

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

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

The invoice as a PDF to keep, for the account it belongs to

Section titled The invoice as a PDF to keep, for the account it belongs to

GET /api/v1/billing/invoices/{invoice_id}/pdf

The invoice as a PDF to keep, for the account it belongs to. It is made out to the account's billing profile as it is when the PDF is made (/api/v1/auth/me/billing-profile), else to the account's name.

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

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

GET /api/v1/billing/object-storage/{service_id}

This month so far for one Object Storage service: its rates, the free amounts it draws on, each meter's use (quantity, what the free amounts or the plan included, what is billable and its amount), egress, the charges so far (month_to_date), the month's estimate (projected) and its budget.

usage covers the hours rated so far (rated_through); the last two hours are not in yet. projected adds the current storage for the rest of the month and the operations at this month's pace. On a pay as you go service the free amounts are the account's, and free.shared is true when more than one of its services draws on them; -1 is unlimited. A fixed plan has one storage line, its rate above the included GB as rates.storage_gb_month and its included GB as free.storage_gb_month. A service that moved from a fixed plan to pay as you go this month is shown from the move, which since names (null otherwise); its earlier hours go on the invoice at the fixed plan's terms. Money is a string with two places; budget.spent_pct is a fraction (0.31 is 31%), and budget is null without one.

Answers 404 for a service that is not this account's Object Storage.

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

Name In Type Required Description
service_id path integer yes The Object Storage service's id
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Set the service's monthly budget, or change it

Section titled Set the service's monthly budget, or change it

PUT /api/v1/billing/object-storage/{service_id}/budget

Set the service's monthly budget, or change it. A budget stops nothing: when this month's charges reach 50%, 80% and 100% of it, we email the account's owner and its team members with the Billing or Admin role, once per threshold per month. A changed amount starts the alerts over. Answers the budget as GET writes it.

Answers 404 for a service that is not this account's Object Storage, and 422 when monthly_amount is not a number of US dollars from 1 to 1,000,000.

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

Name In Type Required Description
service_id path integer yes The Object Storage service's id

application/json (required)

Field Type Required Description
monthly_amount number or string no US dollars a month, from 1 to 1000000, as a number or a string such as "25.00"
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Remove the service's monthly budget, and with it the alerts

Section titled Remove the service's monthly budget, and with it the alerts

DELETE /api/v1/billing/object-storage/{service_id}/budget

Remove the service's monthly budget, and with it the alerts. Answers {"ok": true} whether or not it had one, and 404 for a service that is not this account's Object Storage.

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

Name In Type Required Description
service_id path integer yes The Object Storage service's id
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/billing/object-storage/{service_id}/usage.csv

A month's use of one Object Storage service as a CSV file, for finance teams and their tools: one row per bucket and day with use, oldest first, with the columns date,bucket,region,gb_months,class_a,class_b,bytes_out. gb_months is the share of the month the bucket's storage came to that day. Requests that named no bucket (listing the buckets) have an empty bucket and region. It covers the hours rated so far, so this month's file grows each hour.

Answers 404 for a service that is not this account's Object Storage, and 422 for a month that is not YYYY-MM.

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

Name In Type Required Description
service_id path integer yes The Object Storage service's id
month query string or null no YYYY-MM; this month when left out
Status Meaning
200 One row per bucket and day
422 The request is not valid. detail lists each problem.

The account's refund requests, newest first

Section titled The account's refund requests, newest first

GET /api/v1/billing/refund-requests

The account's refund requests, newest first.

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

Status Meaning
200 Success.

Ask for money back on a paid invoice: all of it, or amount

Section titled Ask for money back on a paid invoice: all of it, or amount

POST /api/v1/billing/refund-requests

Ask for money back on a paid invoice: all of it, or amount. Staff decide, and we email the answer. One open request per invoice.

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

application/json (required)

Field Type Required
invoice_id integer yes
amount number or string or null no
reason string yes
Status Meaning
201 Success.
422 The request is not valid. detail lists each problem.

Withdraw a request staff have not decided yet

Section titled Withdraw a request staff have not decided yet

POST /api/v1/billing/refund-requests/{request_id}/withdraw

Withdraw a request staff have not decided yet.

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

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

POST /api/v1/billing/services/{service_id}/switch

Move a VM, game server or database that keeps a flat price to usage billing: memory while it runs, disk while it exists, CPU it uses and data out, after the included amounts of Server access (the Performance line costs 1.5 times on memory, CPU and disk). The move is one way.

It takes the same body and answers as POST /api/v1/billing/deployments/{uuid}/switch does, with service (the service's billing) in place of the deployment's. A service billed by the hour moves at once; a service billed by the month or longer moves when its paid period ends, or at once with {"when": "now"}, which credits the unused days less the holdback days. Audited service.billing_switched.

Answers 402 paid_plan_required (with upgrade) to an account that has not got Server access, 403 deposit_required to a prepaid account that has not made the deposit that unlocks hourly billing, 404 for a service this account does not pay for, and 409 for the free server (free_server), a service of an organization or its customer (organization_service, organization_customer), one that is already billed by use or is not a server or deployment, and the refusals of the deployment route.

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

Name In Type Required Description
service_id path integer yes The service's id
preview query boolean no Price the move and write nothing Default: False.

application/json

Field Type Required Description
preview boolean no Price the move and write nothing, as ?preview=1 does
when string or null no For a service billed by the month or longer: renewal (the default) moves it when its paid period ends, now moves it at once and credits the unused days. A service billed by the hour always moves now.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/billing/spend-limit

The account's own monthly spend limit across all its deployments (spend_limit, null when it has none) and what its deployments have cost this month (month_to_date), commits' shares of their base included. currency is always USD, the currency of your credit, whatever currency the account pays in.

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

Status Meaning
200 Success.

Set the account's own monthly spend limit, across all its deployments

Section titled Set the account's own monthly spend limit, across all its deployments

PUT /api/v1/billing/spend-limit

Set the account's own monthly spend limit, across all its deployments.

It works as a deployment's limit does (alerts at 80% and 100%, and at 50% while any deployment is pay as you go), and at 100% its policy applies to every deployment of the account. Setting it above what is spent lifts what it held. Answers 422 for an amount that is not more than 0 and at most 1000000 with two decimal places.

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

application/json (required)

Field Type Required Description
monthly_limit number or string yes An amount in US dollars, the currency of your credit, e.g. "50.00"
policy string no At 100%: block sleeps previews and stops bursts, builds and overage; pause stops every instance
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Remove the account's own monthly spend limit, and lift what it held

Section titled Remove the account's own monthly spend limit, and lift what it held

DELETE /api/v1/billing/spend-limit

Remove the account's own monthly spend limit, and lift what it held. Answers 204 whether or not it had one.

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

Status Meaning
204 Success.

Hosted checkout to buy account credit without a saved payment method

Section titled Hosted checkout to buy account credit without a saved payment method

POST /api/v1/billing/topup/checkout

Hosted checkout to buy account credit without a saved payment method.

amount is the credit to add, in US dollars. The checkout charges currency (the code your page showed the customer) at the exchange rate GET /payments/rates shows, or the account's preferred pay currency when you send none. The answer holds currency, charge_amount in that currency's smallest unit, base_amount and fx_rate. For a PayPal account, session_id is the order id, made in that currency: load PayPal's buttons with the same currency. Answers 400 for a currency no payment account takes.

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

application/json (required)

Field Type Required
amount number or string yes
currency string or null no
gateway_name string or null no
return_url string or null no
cancel_url string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/billing/topup/config

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

Status Meaning
200 Success.

Fields of a 200 response:

Field Type
auto_topup_enabled boolean
auto_topup_threshold string
auto_topup_amount string
credit_balance string
total_deposited string
hourly_billing_unlocked boolean

PUT /api/v1/billing/topup/config

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

application/json (required)

Field Type Required
enabled boolean yes
threshold number or string or null no
amount number or string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Add credit for a card payment the customer finished in the page

Section titled Add credit for a card payment the customer finished in the page

POST /api/v1/billing/topup/confirm-payment

Add credit for a card payment the customer finished in the page.

Send payment_intent_id, the gateway_reference that POST /billing/topup/pay-intent answered, and the gateway_name it was made on. We read the payment from the card processor and add the US dollars it was made for to the balance, once: sending it again answers succeeded and adds nothing. amount is optional. When you send it, it must be within two cents of that amount, or we answer 400 amount does not match the completed payment. Answers requires_action with a client_secret while the customer must still authenticate, pending with a message while the payment is still being processed (a bank debit takes days, and the credit is added by itself once it clears), and 402 when the payment did not complete.

We add nothing and refuse a payment that you did not make to add credit. Answers 400 for a payment made for an invoice, 403 for a payment another account made, 409 This payment has already been applied for a payment that already settled something else, and 409 Your payment is being processed when the payment does not name its top-up yet (the credit appears by itself once the processor confirms it).

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

Name In Type Required
gateway_name query string yes
payment_intent_id query string yes
amount query number or string or null no
currency query string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Add credit by charging a saved payment method

Section titled Add credit by charging a saved payment method

POST /api/v1/billing/topup/manual

Add credit by charging a saved payment method.

amount is the credit to add, in US dollars (1 to 10,000), and the balance grows by exactly that. We charge the payment method in currency at the exchange rate GET /payments/rates shows, or in the account's preferred pay currency when you send none. Answers 404 for a payment method that is not the caller's, 400 for a currency you cannot pay in, 400 with This card cannot pay in <code>. Choose another card or pay with a new card. when currency is sent and the payment account that holds the card does not take it (a Square card takes US dollars only), 409 while an earlier top-up is still being processed (a bank debit that has not cleared, or a payment the card processor has not answered), and 402 when the charge is declined. We write nothing and charge nothing when we refuse.

The answer's status is succeeded when the credit was added, requires_action with a client_secret while the customer must authenticate, and pending with a message while the payment is on its way (a bank debit takes days). A pending payment adds the credit by itself once it clears, so do not charge again.

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

application/json (required)

Field Type Required Description
amount number or string yes
payment_method_id integer yes
currency string or null no The currency to charge the payment method in. Send the code your page showed the customer. Without it we charge in the account's preferred pay currency.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Create a Stripe PaymentIntent to add credit in the page

Section titled Create a Stripe PaymentIntent to add credit in the page

POST /api/v1/billing/topup/pay-intent

Create a Stripe PaymentIntent to add credit in the page.

Complete it with Stripe.js confirmPayment and the client_secret, then call POST /billing/topup/confirm-payment, which adds the credit. Without gateway_name we pick the Stripe account as GET /billing/topup/pay-quote does.

Send expected_amount (the quote's charge_amount) from a wallet button. When the amount has changed since the quote, for example because the exchange rate moved, we answer 412 with detail.code amount_changed and a new quote in detail.quote, and create nothing.

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

application/json (required)

Field Type Required Description
amount number or string yes
currency string or null no
gateway_name string or null no
save_method boolean no
expected_amount integer or null no The charge_amount from the top-up's pay quote, in minor units. When the amount has changed since, we answer 412 with a new quote and create nothing.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

What a card payment to add credit charges, and which card form to draw

Section titled What a card payment to add credit charges, and which card form to draw

GET /api/v1/billing/topup/pay-quote

What a card payment to add credit charges, and which card form to draw.

Ask for it before you show the card form or the wallet buttons. adapter says which processor takes the payment, and public holds the keys its form needs.

For stripe, create Stripe's Express Checkout Element with its publishable_key, charge_amount, currency, save_method and payment_method_configuration. Once the customer approves, create the payment with POST /billing/topup/pay-intent with the same amount, currency, gateway_name and save_method, and the charge_amount as expected_amount. renewal is always null for a top-up.

For square, draw Square's card form with public.application_id and public.location_id, tokenize the card in the browser, and send the token to POST /billing/topup/square-pay with amount_usd set to this amount, the same gateway_name, and the charge_amount as expected_amount. Square takes US dollars only. When the account offers saved cards, ask for save_method and send it to square-pay to keep the card.

We pick Square only when card_adapters lists it and the routing rules prefer it for this payment, and not with save_method true while Square cannot keep cards. A quote creates nothing and does not contact the processor. Answers 422 for an amount outside 1 to 10,000 US dollars, 400 for a currency that is not enabled or that the account does not take, and 503 when no card account takes the currency.

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

Name In Type Required Description
amount query number or string yes US dollars of credit to add, from 1 to 10,000.
currency query string or null no Currency to charge in. Defaults to the account's preferred pay currency.
gateway_name query string or null no Card account to charge through. Leave it out and we pick the account the payment picks.
save_method query boolean no Keep the payment method for later charges. A top-up does not keep it unless you ask. A Square payment keeps the card only while the account offers saved cards, and the quote answers save_method false otherwise. Default: False.
card_adapters query string or null no The card processors your page can draw a card form for, as a comma list: stripe, square or stripe,square. Defaults to stripe. We pick Square only when it is listed, so a page written before Square keeps getting Stripe.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Capture an approved PayPal order and credit the platform user balance

Section titled Capture an approved PayPal order and credit the platform user balance

POST /api/v1/billing/topup/paypal-capture

Capture an approved PayPal order and credit the platform user balance.

USD credit is derived from the order (custom_id=topup:<usd>), not the client amount alone. Optional amount may assert within $0.02.

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

Name In Type Required
order_id query string yes
gateway_name query string yes
amount query number or string or null no
currency query string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Add credit with a Square card token

Section titled Add credit with a Square card token

POST /api/v1/billing/topup/square-pay

Add credit with a Square card token.

Draw Square's card form, tokenize the card in the browser and send the token as source_id, with amount_usd set to the US dollars of credit to add (1 to 10,000). We charge the card in this request and add the credit when Square takes the payment, so there is no second step. Without gateway_name we pick the Square account as GET /billing/topup/pay-quote?card_adapters=square does. Square takes US dollars only, so currency defaults to USD and any other currency is refused. Send save_method true to keep the card for later charges such as auto top-up. We honor it only while the account offers saved cards, and when a save was asked for and the payment succeeds, the answer holds saved_method: true when we saved the card, false with a plain message when we could not. A card that fails to save never changes the payment. Only a card can be saved: a payment made with Apple Pay, Google Pay, Cash App Pay, Afterpay or a bank account (ACH) answers saved_method false.

Send source_kind (card, apple_pay, google_pay, ach, cash_app or afterpay) to say which Web Payments SDK method made the token. Leave it out for a card. We answer 400 and charge nothing when the account has not switched that method on (public in the quote) or the token is not that kind of token. The answer holds method ({kind, label, brand, source_type}). An ach payment answers pending and the credit is added 2 to 3 business days later, when the bank confirms it.

Send expected_amount (the quote's charge_amount). When the amount has changed since the quote, we answer 412 with detail.code amount_changed and a new quote in detail.quote, and charge nothing.

Answers 200 with status succeeded when the credit is added, failed with a message to show when the payment was declined (ask for another token, which works once), and pending when Square has not finished: do not send the customer to pay again, because the credit appears when Square confirms. A token you send twice charges once. Answers 409 with Retry-After while the same payment still waits for Square, and 400 for an amount outside 1 to 10,000 US dollars, for a currency other than USD, for an account that is not Square's and for a source_kind the account refuses or the token does not fit.

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

application/json (required)

Field Type Required Description
gateway_name string or null no The Square account to charge through. Leave it out and we pick the account the pay quote picks.
source_id string yes The payment token the Web Payments SDK returned from tokenize().
source_kind string, one of card, apple_pay, google_pay, ach, cash_app, afterpay or null no The way of paying the token came from: card, apple_pay, google_pay, ach (a US bank account), cash_app or afterpay. Leave it out for a card. We refuse a way the account has not switched on, and a token that is not that kind of token, before we charge anything. Only a card can be saved: a save_method sent with any other kind is refused with saved_method false. An ach payment answers pending and settles 2 to 3 business days later.
expected_amount integer or null no The quote's charge_amount in the smallest currency unit. When the amount due has moved since, we answer 412 and create nothing.
save_method boolean no Keep the card for renewals. Honored only while the account offers saved cards (public.can_save_cards).
verification_token string or null no The buyer verification token tokenize() returned, when it returned one.
buyer_email string or null no Where Square sends its receipt, when you want one.
billing SquareBilling or null no
billing.given_name string or null no
billing.family_name string or null no
billing.email string or null no
billing.phone string or null no
billing.address_lines array of string or null no
billing.city string or null no
billing.state string or null no
billing.postal_code string or null no
billing.country_code string or null no
currency string or null no The currency of the quote. Defaults to the account's pay currency.
amount_usd number or string or null no US dollars to pay now, for part of an invoice. Defaults to everything still owed.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

As listinvoices: newest first, ties by id, withtotal for a TransactionPage

Section titled As listinvoices: newest first, ties by id, withtotal for a TransactionPage

GET /api/v1/billing/transactions

As list_invoices: newest first, ties by id, with_total for a TransactionPage. type_filter=credit is credit added or used.

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

Name In Type Required Description
page query integer no Default: 1.
limit query integer no Default: 50.
type_filter query string or null no
with_total query boolean no Default: False.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/billing/usage

A month's metered use of the account's deployments, by deployment and meter: the quantity in the meter's unit, what the allowances included, what was billable and what it cost. A deployment deleted since is listed with deleted. A virtual machine, game server or database billed by use has no deployment: its entry has a null uuid and its own service_id. Meters read memory, CPU, disk, requests, data out by region, builds and logs for a service billed by use, each with its unit. Commit bases are billed by their renewal invoices and are not in total. Every amount is in currency, always USD, whatever currency the account pays in. Answers 422 for a month that is not YYYY-MM.

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

Name In Type Required Description
month query string or null no YYYY-MM; this month when left out
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.