Hushxima
Marketplace

Balance

What accrues to your organisation, the ledger behind it, and how to take it out.

Your organisation holds a balance per chain. It is a claim against the platform treasury rather than a wallet you have keys to, which is why taking money out is a request rather than a transfer.

Where the balance comes from

Two things credit it, and the bigger one by far is your own margin on sales. Every settled order credits margin_total, the difference between the platform's price for the wallets and what you resold them at, on the order's chain. Nothing to claim and nothing to invoice: it lands as one ledger entry when the order settles. See Price breakdown for where that number comes from.

The other source is funding fees. Half of the platform take on every funding plan your organisation runs is credited back to you, on the plan's chain, once the fee is actually collected.

Withdrawals debit it. So does a refund, which reverses the share of the margin that the refunded amount represents. Everything that moves the balance lands in the ledger.

GET /balance returns both halves in one call: the per-chain totals, and the ledger entries behind them. Each entry carries a kind, a signed amount, an optional sale_id, and a ref_key that identifies it uniquely.

kindSignWhat it is
margin_credit+your margin on a settled order
funding_fee_share+your half of the platform fee on a funding plan
withdrawal−money you asked to take out
refund_debit−the pro-rata margin reversed by a refund
adjustment±a correction, such as a withdrawal whose payout failed
GET
/balance

Authorization

bearerAuth
AuthorizationBearer <token>

JWT from /auth/login (users) or an org API key (mk_...) for integrations.

In: header

Response Body

application/json

curl -X GET "https://example.com/balance"
{  "balances": [    {      "amount": "string",      "chain": "string"    }  ],  "ledger": [    {      "amount": "string",      "chain": "string",      "created_at": "string",      "id": 0,      "kind": "string",      "note": "string",      "payout_at": "string",      "payout_status": "string",      "payout_tx": "string",      "ref_key": "string",      "sale_id": "string"    }  ]}

Withdrawing

POST /balance/withdraw asks for an amount on a chain to be sent to an address you name. It is an organisation-admin action, so it needs a user session and an API key will not do.

What comes back is the ledger entry, not a transaction hash. The debit is recorded immediately and the payout is queued behind it, so the money leaves when the platform processes it.

The entry then tells you how the payout is doing. A withdrawal entry carries payout_status, which runs pending while the hold lasts, then broadcasting and awaiting_confirm, then confirmed with the transaction in payout_tx, and payout_at is the last time it moved. A payout that dies ends failed, and the balance is re-credited by an adjustment entry, so the money is never silently lost between the ledger and the chain.

Two things the call refuses outright: an amount of zero or less, with 400, and an amount above your balance on that chain, with 409 and both figures in the message.

The address is not inferred and not remembered. Every withdrawal names its own destination, and it is checked against nothing, so get it right.

POST
/balance/withdraw

Authorization

bearerAuth
AuthorizationBearer <token>

JWT from /auth/login (users) or an org API key (mk_...) for integrations.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X POST "https://example.com/balance/withdraw" \  -H "Content-Type: application/json" \  -d '{    "amount": "string",    "chain": "string",    "to_address": "string"  }'
{  "amount": "string",  "chain": "string",  "created_at": "string",  "id": 0,  "kind": "string",  "note": "string",  "payout_at": "string",  "payout_status": "string",  "payout_tx": "string",  "ref_key": "string",  "sale_id": "string"}

Withdrawing without asking

An organisation that wants its margin on its own wallet as soon as it is earned should not have to remember to ask. Register the destinations once, say when they are used, and the platform sends the money on its own.

Your destinations

POST /balance/withdraw-addresses registers an address for a chain, with an optional label. You can register several per chain; when a withdrawal goes out, one of the enabled addresses on that chain is picked at random, so the same wallet does not collect everything.

Addresses are checked at the door, base58 for Solana and 0x for the EVM chains. A typo here is not a failed request, it is money sent to nobody, over and over.

PUT /balance/withdraw-addresses/{addr_id} flips one between enabled and disabled, which is the reversible way to take a destination out of the rotation. DELETE removes it outright.

GET
/balance/withdraw-addresses

Authorization

bearerAuth
AuthorizationBearer <token>

JWT from /auth/login (users) or an org API key (mk_...) for integrations.

In: header

Response Body

application/json

curl -X GET "https://example.com/balance/withdraw-addresses"
[  {    "address": "string",    "chain": "string",    "created_at": "string",    "enabled": true,    "id": "string",    "label": "string"  }]
POST
/balance/withdraw-addresses

Authorization

bearerAuth
AuthorizationBearer <token>

JWT from /auth/login (users) or an org API key (mk_...) for integrations.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X POST "https://example.com/balance/withdraw-addresses" \  -H "Content-Type: application/json" \  -d '{    "address": "string",    "chain": "string"  }'
{  "address": "string",  "chain": "string",  "created_at": "string",  "enabled": true,  "id": "string",  "label": "string"}
PUT
/balance/withdraw-addresses/{addr_id}

Authorization

bearerAuth
AuthorizationBearer <token>

JWT from /auth/login (users) or an org API key (mk_...) for integrations.

In: header

Path Parameters

addr_id*String

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X PUT "https://example.com/balance/withdraw-addresses/string" \  -H "Content-Type: application/json" \  -d '{    "enabled": true  }'
{  "ok": true}
DELETE
/balance/withdraw-addresses/{addr_id}

Authorization

bearerAuth
AuthorizationBearer <token>

JWT from /auth/login (users) or an org API key (mk_...) for integrations.

In: header

Path Parameters

addr_id*String

Response Body

application/json

curl -X DELETE "https://example.com/balance/withdraw-addresses/string"
{  "ok": true}

When they are used

PUT /balance/withdraw-config sets the policy. GET reads it back.

FieldWhat it does
modeoff, per_sale or cron
cronthe schedule in cron mode, five-field crontab, UTC. Defaults to 0 6 * * *
min_amountfloor below which nothing goes out, in base units. 0 disables the floor
delay_secshow long a transfer is held before it is sent. Defaults to 300
next_run_atread-only, the next occurrence, set only in cron mode

per_sale sends that order's margin the moment it settles, on the order's chain. One withdrawal per sale, never two, whatever happens on our side. A margin under min_amount is not sent and not accumulated either: it stays on your balance, where the next mode can pick it up.

cron runs on your own schedule and looks at each chain in turn. A chain whose balance clears min_amount is withdrawn in full, in one entry. A chain below it is left alone until it clears.

off is the default, and an organisation that configures nothing behaves exactly as it always did.

Either way the debit lands in the ledger as an ordinary withdrawal entry, so GET /balance remains the whole story and there is no second place to look.

The hold is there on purpose. A withdrawal fired in the same instant as the settlement that earned it can get ahead of the money it is meant to send. Five minutes is the default for that reason; shorten it only if you know why.

Nothing goes out to an address we were not given. A chain you hold a balance on with no enabled address there is skipped, never guessed at. If the money is not moving, that is the first thing to check.

GET
/balance/withdraw-config

Authorization

bearerAuth
AuthorizationBearer <token>

JWT from /auth/login (users) or an org API key (mk_...) for integrations.

In: header

Response Body

application/json

curl -X GET "https://example.com/balance/withdraw-config"
{  "cron": "string",  "delay_secs": 0,  "min_amount": "string",  "mode": "string",  "next_run_at": "string"}
PUT
/balance/withdraw-config

Authorization

bearerAuth
AuthorizationBearer <token>

JWT from /auth/login (users) or an org API key (mk_...) for integrations.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X PUT "https://example.com/balance/withdraw-config" \  -H "Content-Type: application/json" \  -d '{    "cron": "string",    "delay_secs": 0,    "min_amount": "string",    "mode": "string"  }'
{  "cron": "string",  "delay_secs": 0,  "min_amount": "string",  "mode": "string",  "next_run_at": "string"}

Last updated on

On this page