Client API: Billing
Invoices, credit balance, top-ups, and hourly billing controls.
Invoices, credit balance, top-ups, and hourly billing controls.
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 |
Get credit |
| 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/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) |
| POST | /api/v1/billing/topup/checkout |
Hosted checkout to buy USD 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 |
Finalize a top-up PaymentIntent after SCA and credit the user balance |
| POST | /api/v1/billing/topup/manual |
Manually top up credit balance by charging a payment method |
| POST | /api/v1/billing/topup/pay-intent |
Create an in-page Stripe Payment Element intent for a credit top-up |
| POST | /api/v1/billing/topup/paypal-capture |
Capture an approved PayPal order and credit the platform user balance |
| GET | /api/v1/billing/transactions |
As listinvoices: newest first, ties by id, withtotal for a TransactionPage |
Get credit
Section titled Get creditGET /api/v1/billing/credit
Authentication: an access token, sent as Authorization: Bearer <token>.
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
Fields of a 200 response:
| Field | Type |
|---|---|
balance |
number |
currency |
string |
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. |
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. |
Hosted checkout to buy USD account credit without a saved payment method
Section titled Hosted checkout to buy USD account credit without a saved payment methodPOST /api/v1/billing/topup/checkout
Hosted checkout to buy USD account credit without a saved payment method.
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. |
Finalize a top-up PaymentIntent after SCA and credit the user balance
Section titled Finalize a top-up PaymentIntent after SCA and credit the user balancePOST /api/v1/billing/topup/confirm-payment
Finalize a top-up PaymentIntent after SCA and credit the user balance.
USD credit comes from PaymentIntent metadata base_amount (set at
checkout/charge). Optional client amount may assert within $0.02.
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. |
Manually top up credit balance by charging a payment method
Section titled Manually top up credit balance by charging a payment methodPOST /api/v1/billing/topup/manual
Manually top up credit balance by charging a payment method.
data.amount is always USD. The gateway is charged in the user's
preferred pay currency via admin FX rates (same path as auto-topup).
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 |
payment_method_id |
integer | yes |
Responses
Section titled Responses| Status | Meaning |
|---|---|
200 |
Success. |
422 |
The request is not valid. detail lists each problem. |
Create an in-page Stripe Payment Element intent for a credit top-up
Section titled Create an in-page Stripe Payment Element intent for a credit top-upPOST /api/v1/billing/topup/pay-intent
Create an in-page Stripe Payment Element intent for a credit top-up.
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 |
save_method |
boolean | no |
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. |
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. |