Skip to content
Coritan Docs

Client API: Billing

Invoices, credit balance, top-ups, and hourly billing controls.

View as Markdown

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.

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 /api/v1/billing/credit

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

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 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.

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.

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 method

POST /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>.

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.

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 balance

POST /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>.

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.

Manually top up credit balance by charging a payment method

Section titled Manually top up credit balance by charging a payment method

POST /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>.

application/json (required)

Field Type Required
amount number or string yes
payment_method_id integer yes
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-up

POST /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>.

application/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
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.

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.