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
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.
Operations
Section titled Operations| 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 entriesGET /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>.
Responses
Section titled Responses| 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 familyGET /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>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
network |
query | string | yes | Network key, e.g. base or bitcoin |
Responses
Section titled Responses| 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 nowGET /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>.
Responses
Section titled Responses| 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 standsPOST /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>.
Request body
Section titled Request bodyapplication/json
Type: object or null.
Responses
Section titled Responses| 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 confirmingGET /api/v1/billing/crypto/deposits
Deposit history, including transfers still confirming.
Authentication: an access token, sent as Authorization: Bearer <token>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit |
query | integer | no | Default: 50. |
Responses
Section titled Responses| 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 confirmsGET /api/v1/billing/crypto/deposits/{deposit_id}
One deposit, for polling while it confirms.
Authentication: an access token, sent as Authorization: Bearer <token>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
deposit_id |
path | integer | yes |
Responses
Section titled Responses| 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 firstGET /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>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
amount |
query | number or string | yes |
invoice_id |
query | integer or null | no |
Responses
Section titled Responses| 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, itemisedGET /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>.
Parameters
Section titled Parameters| 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 |
Responses
Section titled Responses| 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 monthGET /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>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
app_uuid |
path | string | yes | The deployment's uuid |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Change deployment billing
Section titled Change deployment billingPATCH /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>.
Parameters
Section titled Parameters| 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. |
Request body
Section titled Request bodyapplication/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 |
Responses
Section titled Responses| 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 itPUT /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>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
app_uuid |
path | string | yes | The deployment's uuid |
Request body
Section titled Request bodyapplication/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 |
Responses
Section titled Responses| 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 heldDELETE /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>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
app_uuid |
path | string | yes | The deployment's uuid |
Responses
Section titled Responses| 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 billingPOST /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>.
Parameters
Section titled Parameters| 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. |
Request body
Section titled Request bodyapplication/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. |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Check hourly eligibility
Section titled Check hourly eligibilityGET /api/v1/billing/hourly-eligibility
Authentication: an access token, sent as Authorization: Bearer <token>.
Responses
Section titled Responses| 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 rowGET /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>.
Parameters
Section titled Parameters| 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. |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Get invoice
Section titled Get invoiceGET /api/v1/billing/invoices/{invoice_id}
Authentication: an access token, sent as Authorization: Bearer <token>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
invoice_id |
path | integer | yes |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Fields of a 200 response:
| Field | Type |
|---|---|
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>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
invoice_id |
path | integer | yes |
Responses
Section titled Responses| 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 toGET /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>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
invoice_id |
path | integer | yes |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Object storage billing
Section titled Object storage billingGET /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>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
service_id |
path | integer | yes | The Object Storage service's id |
Responses
Section titled Responses| 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 itPUT /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>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
service_id |
path | integer | yes | The Object Storage service's id |
Request body
Section titled Request bodyapplication/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" |
Responses
Section titled Responses| 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 alertsDELETE /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>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
service_id |
path | integer | yes | The Object Storage service's id |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Object storage usage CSV
Section titled Object storage usage CSVGET /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>.
Parameters
Section titled Parameters| 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 |
Responses
Section titled Responses| 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 firstGET /api/v1/billing/refund-requests
The account's refund requests, newest first.
Authentication: an access token, sent as Authorization: Bearer <token>.
Responses
Section titled Responses| 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 amountPOST /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>.
Request body
Section titled Request bodyapplication/json (required)
| Field | Type | Required |
|---|---|---|
invoice_id |
integer | yes |
amount |
number or string or null | no |
reason |
string | yes |
Responses
Section titled Responses| 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 yetPOST /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>.
Parameters
Section titled Parameters| Name | In | Type | Required |
|---|---|---|---|
request_id |
path | integer | yes |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Switch service to usage
Section titled Switch service to usagePOST /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>.
Parameters
Section titled Parameters| 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. |
Request body
Section titled Request bodyapplication/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. |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Get account spend limit
Section titled Get account spend limitGET /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>.
Responses
Section titled Responses| 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 deploymentsPUT /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>.
Request body
Section titled Request bodyapplication/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 |
Responses
Section titled Responses| 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 heldDELETE /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>.
Responses
Section titled Responses| 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 methodPOST /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>.
Request body
Section titled Request bodyapplication/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 |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Get topup config
Section titled Get topup configGET /api/v1/billing/topup/config
Authentication: an access token, sent as Authorization: Bearer <token>.
Responses
Section titled Responses| 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 |
Update topup config
Section titled Update topup configPUT /api/v1/billing/topup/config
Authentication: an access token, sent as Authorization: Bearer <token>.
Request body
Section titled Request bodyapplication/json (required)
| Field | Type | Required |
|---|---|---|
enabled |
boolean | yes |
threshold |
number or string or null | no |
amount |
number or string or null | no |
Responses
Section titled Responses| 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 pagePOST /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>.
Parameters
Section titled Parameters| 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 |
Responses
Section titled Responses| 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 methodPOST /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>.
Request body
Section titled Request bodyapplication/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. |
Responses
Section titled Responses| 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 pagePOST /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>.
Request body
Section titled Request bodyapplication/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. |
Responses
Section titled Responses| 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 drawGET /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>.
Parameters
Section titled Parameters| 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. |
Responses
Section titled Responses| 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 balancePOST /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>.
Parameters
Section titled Parameters| 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 |
Responses
Section titled Responses| 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 tokenPOST /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>.
Request body
Section titled Request bodyapplication/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. |
Responses
Section titled Responses| 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 TransactionPageGET /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>.
Parameters
Section titled Parameters| 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. |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Deployment usage
Section titled Deployment usageGET /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>.
Parameters
Section titled Parameters| Name | In | Type | Required | Description |
|---|---|---|---|---|
month |
query | string or null | no | YYYY-MM; this month when left out |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |