API reference

Accounting

  • 1 endpoint

Export accounting data#

GET /accounting/export

Exports the request's space's accounting events of a range of days, ordered by transaction time: as JSON (one page: hasMore false) or as a CSV file (the same keys as columns, in AccountingEvent's order).

Auth
X-API-Key: any key
On-Behalf-Of
Honored: acts in the member's space
Idempotency-Key
Ignored
Success
200
Request

request.sh

curl "https://api.qbitflow.app/v2/accounting/export?from=2026-01-01&to=2026-03-31&format=json" \  -H "X-API-Key: $QBITFLOW_API_KEY"# 200: an array of AccountingEvent (format=csv: CSV text)
// Every payment, bill, refund and fee between two dates (both included). Any range: the SDK// requests it in windows of at most 92 days, both included (here 4), and concatenates them.const rows = await client.accounting.exportJsonRange('2026-01-01', '2026-12-31');for (const row of rows.slice(0, 5)) {	console.log(row.type, row.txUuid, row.txTimeUtc, row.grossAmountUsd, row.productName);} // The same as CSV text, its header line once.const csv = await client.accounting.exportCsvRange('2026-01-01', '2026-12-31');await writeFile('qbitflow-2026.csv', csv, { mode: 0o600 });
# The API exports at most 92 days at a time (both included): the *_range methods split any# range into windows, request them in order and join the results (the CSV header once).events = client.accounting.export_json_range("2026-01-01", "2026-12-31")for event in events:    print(event.type, event.tx_uuid, event.tx_time_utc.date(), event.gross_amount_usd) csv_text = client.accounting.export_csv_range("2026-01-01", "2026-12-31")with open("qbitflow-2026.csv", "w", encoding="utf-8") as file:    file.write(csv_text)
// The API exports at most 92 days at a time (both included): the …Range methods split any// range into windows, request them in order and join the results (the CSV header once).events, err := client.Accounting.ExportJSONRange(ctx, "2026-01-01", "2026-12-31")if err != nil {	log.Fatal(err)}for _, e := range events {	fmt.Println(e.Type, e.TxUUID, e.TxTimeUTC.Format(time.DateOnly), e.GrossAmountUSD, e.ProductName)} csv, err := client.Accounting.ExportCSVRange(ctx, "2026-01-01", "2026-12-31")if err != nil {	log.Fatal(err)}if err := os.WriteFile("qbitflow-2026.csv", []byte(csv), 0o600); err != nil {	log.Fatal(err)}
// The API exports at most 92 days at a time (both included): the range helpers split any range// into windows, request them in order and join the results (the CSV header once).$events = $client->accounting->exportJsonRange('2026-01-01', '2026-12-31');foreach ($events as $event) {	echo "{$event->type} {$event->txUuid} {$event->txTimeUtc->format('Y-m-d')} {$event->grossAmountUsd} USD {$event->productName}\n";} $csv = $client->accounting->exportCsvRange('2026-01-01', '2026-12-31'); // one header line, then the rows

Query parameters

  • fromstringRequired

    The first day (YYYY-MM-DD, UTC)

    dateformat

  • tostringRequired

    The last day (YYYY-MM-DD, UTC), included; at most 92 days after from, both included

    dateformat

  • formatstringRequired

    json: the rows in one page (a bounded list); csv: a file, one row per event

    oneof=csv json

Response

A page: { "items": AccountingEvent[], "hasMore": …, "nextCursor"?: … }. Pass nextCursor back as cursor for the next page; it is absent when hasMore is false.

49 fields of each AccountingEvent
  • txTimeUtcstring
  • typestring

    payment, bill, refund, organizationFee or referralFee

  • referencestringOptional

    The payment's reference (the merchant's), when it has one

  • relatedReferencestringOptional

    A refund of a payment: the payment's reference (a bill has none)

  • productNamestringOptional
  • customerReferencestringOptional
  • grossAmountUsdstringOptional

    What the customer paid (a refund: what went back, negative)

  • platformFeeUsdstringOptional

    QBitFlow's fee, the referrer's share included; absent when none (a refund)

  • referralFeeUsdstringOptional

    The referrer's share of the platform fee; absent when no referral applied

  • organizationFeeUsdstringOptional

    The organization's fee on a member's payment; absent when none

  • netAmountUsdstringOptional

    What the merchant received (a payment or a bill: after the fees) or sent back (a refund: the refunded amount, negative)

  • chainstring
  • currencystring

    What was paid, as markets name it: the token (USDC) or the chain's native currency (ETH, SOL)

  • currencyDecimalsinteger

    The currency's decimals: an amount × 10^currencyDecimals is its min units on-chain

  • currencyPriceUsdstringOptional

    The currency's USD price the amounts were converted at: grossAmountUsd / grossAmount, to 8 decimals (the original payment's or bill's on a refund). Absent without a gross amount

  • grossAmountstringOptional
  • grossAmountMinUnitsstringOptional

    Each amount's twin …MinUnits is the same amount on-chain: an integer string (JSON), × 10^-currencyDecimals = the amount

  • platformFeestringOptional

    QBitFlow's fee, the referrer's share included

  • platformFeeMinUnitsstringOptional
  • referralFeestringOptional

    The referrer's share, paid out of the platform fee: what a referralFee event earned. Absent when no referral applied (none, or past its deadline)

  • referralFeeMinUnitsstringOptional
  • organizationFeestringOptional

    Absent when none

  • organizationFeeMinUnitsstringOptional
  • netAmountstringOptional
  • netAmountMinUnitsstringOptional
  • networkFeesPaidBystringOptional

    payer (a payment or a bill: on top of the amount), merchant (a refund the space sent) or organization (a refund of a payment the organization held for its member, sent from its wallet)

    One of:

    • payerA payment or a bill: the payer, on top of the amount
    • merchantA refund the space sent from its wallet
    • organizationA refund of a payment the organization held for its member, sent from the organization's wallet
  • networkFeesstringOptional

    In networkFeesCurrency's units. Absent when not recorded (records made before they were)

  • networkFeesMinUnitsstringOptional

    In networkFeesCurrency's min units

  • networkFeesCurrencystringOptional

    What paid them: the currency on a payment or a bill (the payer's gas refund, taken in it), the chain's native currency (ETH, SOL) on a refund

  • networkFeesCurrencyDecimalsintegerOptional

    networkFeesCurrency's decimals

  • networkFeesCurrencyPriceUsdstringOptional

    networkFeesCurrency's USD price networkFeesUsd was converted at. Absent when unknown (a refund recorded before it was)

  • networkFeesUsdstringOptional

    Absent when unknown

  • platformFeePercentstringOptional

    QBitFlow's fee rate on the event

  • referralFeePercentstringOptional

    The referrer's share of the platform fee ("20" = 20 % of it), when a referral applied

  • organizationFeePercentstringOptional

    The organization's fee rate on the event, when it took one

  • fromAddressstringOptional

    Absent on referralFee rows

  • toAddressstringOptional

    Absent on referralFee rows

  • txHashstringOptional

    Absent on referralFee rows

  • blockNumberOrSlotstringOptional
  • tokenContractOrMintstringOptional

    The token's contract (EVM) or mint (Solana); absent for a native currency

  • explorerUrlstringOptional

    Absent on referralFee rows

  • receiptUrlstringOptional

    The transaction's page for its customer (the payment, bill or refund, as the customer's management link shows it: public, by its uuid). Absent on referralFee rows

  • txUuidstringOptional

    The event's transaction, prefixed by its type: pay@ (a payment), sub-hist@ (a bill), refund@ (a refund); absent on referralFee rows

  • relatedTxUuidstringOptional

    A refund: the refunded payment's (pay@…) or bill's (sub-hist@…) id

  • productUuidstringOptional

    Absent when the event has no product

  • productReferencestringOptional
  • productDescriptionstringOptional
  • customerUuidstringOptional
  • userUuidstringOptional

    The member whose space the event is in; absent for the organization's own

With format=csv: CSV text (Content-Type: text/csv), as an attachment.

Edge cases

The contract's rules for these routes: Query parameters & validation · Output · Scoping.

Read all 3

Query parameters & validation

  • from and to are required and must be YYYY-MM-DD (dateformat); a missing or malformed value → 400 validation_failed on its name.
  • format is required and must be oneof=csv json; any other value → 400 validation_failed on format.
  • The window is at most 92 days, from and to included (about 3 months): a longer one → 400 validation_failed on to, with details.max: 92. to before from → 400 validation_failed on to. (bad_request is no longer answered.)
  • The dates are the transactions', in UTC, both days included: an event is in the export of the day its transaction's block was mined (txTimeUtc), whenever QBitFlow recorded it (a payment mined at 23:59:50 and recorded after midnight is that day's). An event recorded without its block counts at its record's time (a payment's or a bill's recording, a refund's approval), which is then its txTimeUtc. So consecutive exports never miss nor repeat an event.

Output

  • format=json → 200 with Content-Type: application/json: a bounded list, the {items, hasMore, nextCursor} envelope (pagination) in one page: every AccountingEvent of the window in items ([] when there is nothing in range), hasMore: false, no nextCursor (limit and cursor aren't read: the window bounds the export).
  • format=csv → 200 with Content-Type: text/csv and Content-Disposition: attachment; filename="qbitflow_<from>_to_<to>.csv"; the body always is the header row (columns from the csv:"..." tags) followed by one row per event, and nothing else (nothing in range → only the header row). A failure while reading the data is the normal JSON error envelope, without the CSV headers. The handler's return type only describes the JSON format.
  • Events are ordered by txTimeUtc, then type, then txUuid: the same order on every export. txTimeUtc is always in UTC (Z).
  • The export is flat, for spreadsheets: one column per key, the same keys in JSON and CSV. It is the documented exception to the currency object (naming): the currency is named by currency (its symbol), chain and currencyDecimals, never nested.
  • CSV columns are in reading order, the field order of AccountingEvent above: what happened and when (txTimeUtc … customerReference), the USD amounts from gross to net (grossAmountUsd … netAmountUsd), the same amounts in the currency paid, each followed by its min units (chain … netAmountMinUnits), the network fees (networkFeesPaidBy … networkFeesUsd), the rates (platformFeePercent … organizationFeePercent), the on-chain proof (fromAddress … receiptUrl), then the ids (txUuid … userUuid). Read a column by its header name, not its position.
  • Every amount is a decimal string in JSON ("7.5", "-100"; naming) and a plain number in CSV. Amounts are in the currency's units (7.5 USDC, 0.1 ETH), exact; each currency amount has its …MinUnits twin, the same amount on-chain as an integer string (grossAmountMinUnits, platformFeeMinUnits, referralFeeMinUnits, organizationFeeMinUnits, netAmountMinUnits, networkFeesMinUnits): an amount × 10^decimals is its min units.
    • currency is what was paid, as markets name it: the token (USDC) or the chain's native currency (ETH, SOL; Base's is ETH, its chain BASE). Always set, a native currency's too. tokenContractOrMint is absent (an empty cell) for a native currency. currencyDecimals is its decimals.
    • currencyPriceUsd is the currency's USD price the amounts were converted at, grossAmountUsd / grossAmount (8 decimals): the payment's or the bill's at its time; on a refund, the refunded transaction's (a refund is valued at what was paid, not at the day it was sent). Absent (an empty cell) without a gross amount.
  • No value is no key (naming): a value the row doesn't have is absent from JSON (never null, "" or 0) and an empty cell in CSV (the column is always there). That is: a fee that doesn't apply (organizationFee* without an organization fee, referralFee* without a referral or past its deadline, platformFee* on a refund), its rate (…Percent), an amount not known (network fees not recorded, a price not recorded), and reference, relatedTxUuid / relatedReference (refunds only), productUuid and the other product* fields (no product), customerUuid / customerReference (no customer), userUuid (the organization's own events).
  • CSV cells are never formulas. A cell starting with =, +, -, @, a tab or a carriage return (a product, customer or reference text a member or a payer chose) is written with a leading single quote, so a spreadsheet shows it as text instead of running it: a product named =HYPERLINK("…") exports as '=HYPERLINK("…"). Numbers stay numbers (a refund's -12.5). JSON is unchanged.
  • platformFeePercent, referralFeePercent and organizationFeePercent are the rates charged on the event, percent strings ("1.5" = 1.5 %), the same in JSON and CSV; absent when the fee doesn't apply.
  • customerReference is the merchant's reference of the customer: the one its checkout was given (customerReference, kept on the payment, the subscription and each bill, with or without a customer at QBitFlow), else its customer's reference. A refund takes its payment's or bill's.
  • Amounts are the on-chain split (settlement.split), never recomputed from the rates: platformFee / platformFeeUsd is what the merchant paid QBitFlow, the referrer's share included (the contracts pay it out of the platform fee), so grossAmount = platformFee + organizationFee + netAmount exactly (an absent fee counting 0), in the currency and in USD: grossAmountUsd is what was charged, and netAmountUsd the rest once the fees are taken (on records whose USD parts were each rounded on their own, netAmountUsd may differ from the merchant's recorded share by a micro-dollar; the currency amounts are exact). A payment or bill recorded without its split makes the export fail (500) rather than show no fees. So does a refund whose payment or bill can't be read: never a row without its currency.
  • A refund's net is the refunded amount: netAmount / netAmountUsd equal grossAmount / grossAmountUsd (negative), what left the wallet that sent it (QBitFlow's and the organization's fees aren't refunded: its fee columns are absent). A refund sends back a share of what the customer paid, the network fees they paid on top included (refundPercent of paidMinUnits, Refunds): a full refund's grossAmount is the payment's grossAmount plus its networkFees.
  • Network fees are never part of the net. networkFees is the transaction's network fees in networkFeesCurrency's units (its decimals networkFeesCurrencyDecimals, its min units networkFeesMinUnits), networkFeesUsd the same at networkFeesCurrencyPriceUsd, and networkFeesPaidBy whose wallet paid them:
    • payer on a payment or a bill (and an organizationFee row): the customer paid them on top of the amount, so they are not the merchant's cost. They are in the event's own currency (the gas refund the contracts took in it): networkFeesCurrency = currency, at currencyPriceUsd. Absent on records made before they were recorded ("0" when recorded as none).
    • merchant on a refund the space sent from its wallet: a cost of the merchant's, to book apart. They are in the chain's native currency (ETH, SOL), not the refunded token, at its price when the refund was recorded (networkFeesCurrencyPriceUsd; it and networkFeesUsd are absent on refunds recorded before it was). networkFees is absent on refunds recorded before their fees were (unknown).
    • organization on a refund of a payment the organization held for its member: the organization's wallet sent it (and paid its fees), in the native currency as above. The row is in the member's export.
  • Each AccountingEvent type is one of payment, bill (a subscription's bill), refund, organizationFee or referralFee. txUuid is the event's transaction id with its type's prefix: pay@ (a payment, an organization fee's), sub-hist@ (a bill), refund@ (a refund). A refund names what it refunded by relatedTxUuid (pay@… or sub-hist@…) and, for a payment, its relatedReference (a bill has no reference: absent). reference is the payment's own reference (absent without one).
  • organizationFee and referralFee events are the exporter's income from another space's payment or bill (in the requested dates, like every event):
    • organizationFee: the fees the organization earned on its members' payments. Only the organization's export has them; a member's export never does.
    • referralFee: the fees earned by the exporter's own referral (its organization's, or the member's), none without one.
    • An organizationFee event carries the full detail of its member's payment or bill (gross amount, split, product, customer, chain data), with the fee type, so the fee can be reconciled. The fee earned is its organizationFee / organizationFeeUsd columns. Its addresses are the payment's (toAddress is the wallet paid: the member's, or the organization's for a payment it held), not where the fee went (the organization's wallet).
    • A referralFee event is another organization's payment or bill: it only tells what the referrer earned, when and on which chain. It has type, txTimeUtc, chain, blockNumberOrSlot, currency, currencyDecimals, currencyPriceUsd, tokenContractOrMint, referralFeePercent, referralFeeUsd, referralFee and referralFeeMinUnits (the fee earned), and nothing else: every other field (txUuid, receiptUrl, txHash, explorerUrl, the addresses, the product and customer fields, the payment's amounts and every networkFees* column) is absent from JSON and an empty cell in CSV.
  • referralFeePercent, referralFeeUsd and referralFee are the referrer's share of the platform fee (it is included in platformFee): the rate that applied ("20" = 20 % of the platform fee) and the amounts paid. Absent when no referral applied, including a referral past its deadline.

Scoping

  • Results are the request's space's (spaces), in its mode: the organization's export, or a member's (their session or key, On-Behalf-Of, or the dashboard switched into their space). An export never includes another organization's events.
  • An export is the space's ledger (its payments, bills, refunds and the fees it earned), not a wallet's: the organization's export doesn't show the funds it holds for its members (recorded in the member's space, the organization earning its organizationFee), their releases to the members, nor the refunds of held payments it sent (in the member's export, networkFeesPaidBy: organization).

The codes named here

  • 400validation_failed

    path/query/body failed binding or validation, or a business rule about one input (a field named in errors)