Skip to guide
Subnano Docs First API request

Earnings, payouts and transactions

All financial endpoints require an owner session (Nano or verified email). Publishing keys have no financial-read or recipient-write authority. Responses use private, no-store and the financial problem catalog.

Method and pathPerspective
GET /api/v1/earningsCreator union of accepted sales, Post tips and Comment tips
GET /api/v1/payoutsThe same creator union, including absent/blocked outgoing obligations
GET /api/v1/transactionsBuyer's own incoming payment receipts
GET /api/v1/earnings/summary{summary,total,asOf} for the same filters
GET /api/v1/{earnings,payouts,transactions}/:sourceKind/:sourceIdOne owned source
PUT /api/v1/payouts/:sourceKind/:sourceId/recipientExplicit binding of an eligible original missing destination
GET /api/v1/statsCreator analytics, separate from raw accounting

sourceKind is sale, post_tip or post_comment_tip. sourceId is the original purchase/tip UUID; use the pair as the record identity. A payout UUID alone cannot identify all sources. The actual beneficiary of a Comment tip can be its Comment author. Current ownership, Post price and Profile cannot manufacture a historical beneficiary or amount.

Exact record and hash roles

History exposes original_beneficiary_id, approved_beneficiary_id, effective_beneficiary_id and beneficiary_basis (original, operator_historical or unresolved). beneficiary_id equals the effective identity for existing clients. An explicit operator decision can assign an otherwise unknown historical beneficiary; the original field stays null and incomplete original facts remain evidence_state: unresolved, including after a confirmed creator send. A present-day Post association grants unresolved history visibility only while no effective beneficiary exists. Ordinary account routing cannot replace a historical operator decision.

The machine-readable FinancialItem schema defines every returned field. Principal fields are:

FieldsMeaning
id,source_kind,source_id,payout_id,purchase_id,kindNative source and optional creator payout references
gross_amount_raw,commission_amount_raw,net_amount_rawActual original decimal raw strings, or null if evidence is incomplete
beneficiary_id,recipient_address,resolution_eligible,evidence_stateEffective beneficiary, bound routing and explicit unresolved/eligible state
created_at,received_at,paid_atIncoming acceptance time; creator confirmed-send time is separate and nullable
referenceOriginal available {post_id,post_title,post_handle,comment_id}
incoming_hashBuyer/tipper send to the allocated source account
receive_hashPlatform receive into that source account
block_hashCreator outgoing send hash; check paid/confirmed time for confirmation
commission_hashPlatform commission outgoing send hash; check its independent state
creator_expected_hash,creator_submitted_hash,commission_expected_hashPrepared/submitted evidence, not confirmed payout
commission_status,commission_paid_at,payout_legsIndependent creator/commission operations, statuses, amounts and available hashes
corroborating_hashes,error_message,purchase_cardOriginal identity corroboration, unresolved reason and buyer-only legacy card context

Each payout_legs.creator includes {operation_id,status,amount_raw,address,block_hash,expected_hash,submitted_hash,confirmed_at}. The commission leg has the same transfer evidence without a recipient address. Buyer histories redact the creator receiving address. Unknown amounts/hash/timestamps stay null; they are never replaced with today's price, zero, a buyer hash or the other leg's hash.

Use arbitrary-precision integers: gross = fee + net. 1 XNO = 10^30 raw. The original session snapshots its fee policy; current defaults are 750 basis points for sales and 500 for tips, with recorded integer split/rounding. Historical facts govern; never apply one blanket fee to all sources. A missing or nonconserving split is unresolved. Hash presence alone is not payout confirmation.

Status and totals

Creator status is pending, blocked, processing, submitted, needs_reconciliation, paid or failed. Blocked missing-address obligations remain owed without consuming a transfer attempt. Prepared/submitted operations remain visible before native outgoing checkpoints are repaired. paid requires creator confirmed-send evidence; it does not prove the creator wallet has signed its receive or can spend those funds. A confirmed commission never makes the creator paid. Incoming receipt, platform receive, purchase entitlement and creator payout are independent.

summary and each source_breakdown entry contain count, gross_raw, net_raw, commission_raw, earned_raw, unpaid_raw, confirmed_sent_raw, unresolved_count, last_payout_at. Known complete facts conserve totals; aggregates affected by unknown splits are null, with unresolved count. Confirmed-sent raw starts at "0" when none are proven. earned_raw means accepted creator amount owed, not a spendable wallet balance. Totals cover the entire selected scope rather than one page.

Filters and stable traversal

Lists return {items,total,summary,pagination:{asOf,nextCursor}}.

QuerySupported values
typeall, tip (both tip kinds), sale, post_tip, post_comment_tip
statusComma-separated creator statuses
startDate,endDateInclusive ISO date or timestamp; start must not exceed end
limit1–50, default 50
asOfNonfuture ISO issuance watermark; optional on first request
cursorOpaque continuation returned by the previous page

Rows order by received_at descending, source_kind in C order descending, then source_id descending; unknown dates follow known dates. Retain the same filters/perspective and copy nextCursor verbatim; it preserves asOf and the last position. Wrong filter identity, repeated scalar values, future watermark, malformed cursor or invalid date returns 400. Changing limit is allowed. New accepted sources after asOf do not enter that traversal. Payout status and unresolved evidence can change while traversing; asOf is not a historical database snapshot. Deduplicate by the native pair and restart a fresh traversal for an updated report.

Resolve an eligible missing recipient

Saving an address affects new allocations. Binding an earlier missing recipient is a deliberate, separate owner action and performs no transfer.

  1. GET the saved payout address and exact updatedAt revision.
  2. Read the financial source. Require resolution_eligible: true and your original beneficiary_id.
  3. PUT the source recipient with that exact pair:
PUT /api/v1/payouts/post_tip/<sourceId>/recipient
Authorization: Bearer <ownerAccessToken>
Content-Type: application/json

{"payoutAddress":"<saved Nano address>","addressUpdatedAt":"<exact saved updatedAt>"}

The active owner, saved validated address/revision and original conserving payment evidence are checked under the publication/operation locks. A source already carrying a destination, attempt or creator send intent cannot be redirected. Success records original source/beneficiary/amount and resolution provenance, returns recipientAddress,addressUpdatedAt,resolvedAt,beneficiaryId,amountRaw,status:"pending" plus the saved snake-case evidence. The same binding replays that result; different intent/stale revision returns 409 recipient-resolution-conflict. Missing/ineligible owner source can return 404.

An unresolved original beneficiary/split is never inferred from the current Post or wallet. Such recovery uses an operator-reviewed dry run and separate approval; ordinary account APIs cannot send/drain/retry another user's payout or change fees.

Creator analytics

GET /api/v1/stats?window=7d&sort=visits_desc&metrics=visits,unlocks returns {rows,trend,top_posts,refreshed_at,window,bucket,metrics}. Windows: 7d, 30d, lifetime. Sorts: visits_desc, unlocks_desc, comments_desc, tips_desc, total_revenue_desc, unlock_revenue_desc, tip_revenue_desc. Metrics: visits, unlocks, comments, tips, total/unlock/tip revenue XNO; optional post=<UUID> scopes a Post. Invalid window/sort use defaults; metrics normalize to supported entries. Numeric XNO analytics are for reporting; use raw financial history for reconciliation.