DEVELOPER DOCUMENTATION

API documentation

Integrate invoices, checkout and payment notifications.

Quickstart

Create your first invoice.

  1. Prepare a store

    Enable its payment methods, configure providers and back up the project wallets.

  2. Create an API credential

    In your console’s Settings → API access, choose read/write and assign the project.

  3. Send the request

    Use your API host and copy your project and store IDs. Send decimal amounts as strings.

  4. Open checkout

    Redirect to links.checkout from the response. Verify settlement before fulfilling the order.

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new invoice.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: order-1042-attempt-1' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "amount": "49.90",
  "currency": "USD",
  "order_id": "order-1042",
  "exchange_rate_spread_percent": "0.5"
}'

Examples use placeholders and do not send requests from this page. See every invoice field and the response format →

Project & store IDs

Where to find YOUR_PROJECT_ID and YOUR_STORE_ID.

Use the UUIDs from your console, not project or store names or their readable identifiers.

PlaceholderWhere to find itUsed for
YOUR_PROJECT_IDProject → Settings → API IDs → Project API ID → Copy. Also shown in the store’s Basic tab.Project-level and store-level requests.
YOUR_STORE_IDProject → Stores → select a store → Basic → API IDs → Store API ID → Copy.Invoice creation and store payment-method requests.
  • Creating an invoice requires both IDs, even for the default store. The store must belong to that project, and the API credential must have access to the project.
  • Invoice creation, listing, detail and checkout return invoice_id: the same UUID sent in IPN/webhooks. Use it in invoice paths, not internal id or order_id. Since merchant 4.0.0, the old public_id response field is removed; update integrations before upgrading.
  • The REST API does not provide project/store listing routes. Copy IDs in the console, or use the scoped list_projects and list_stores MCP tools in merchant 5.0.0+.
  • Store → Basic → Store domains selects active merchant, pay and API hostnames. Returned checkout links and new callback links prefer that store, then the default store, then system defaults. Retired or unactivated names are never selected. Configure your SDK with the preferred API hostname; changing a preference does not redirect other active aliases.

Authentication & scope

Keep credentials on your server and grant only the access needed.

Default hostPurpose
merchant.example.comMerchant console and Settings
pay.example.comCustomer checkout
api.example.comMerchant API requests

Replace example.com with your domain. Existing installations keep their configured names; manage aliases in Settings → System.

Authorization: Bearer YOUR_MERCHANT_API_TOKEN
SettingHow it works
Access levelRead-only credentials can list and retrieve. Read/write credentials can also create invoices and update the documented asset policies.
ProjectsAssign the projects the credential may access. Store and invoice IDs must belong to an assigned project.
IP restrictionsOptionally allow exact public IPv4 or IPv6 egress addresses in Settings → API access.
Credential storageKeep tokens in your backend configuration. Never include a bearer credential in a browser or checkout link.

Public checkout routes use the invoice’s public ID and expose only checkout-safe data. Console sessions and administrative controls are separate from merchant API credentials.

Assets & wallets

Choose payment methods independently for each store.

  1. Read project payment assets and their readiness.
  2. Enable the native chain and configure its wallet and providers.
  3. Browse token candidates and verify the contract or mint before enabling a token.
  4. Select the store’s ordered payment methods. New invoices use its ready selections.

Tokens share their native chain’s wallet. Wallet balances return exact atomic amounts and advisory fiat values. Use the returned readiness fields to determine which methods can receive payments.

Verified ERC-20 tokens use the supported EVM networks; verified SPL tokens use Solana. Native payment methods are available across the 30 integrated networks. Monero uses a project-bound external view-only wallet connection.

Receive APIs and native/token coverage
RailSupportEvidenceRequirements
Native payment railssupportedTransaction-scannedBTC, SOL, ETH (Ethereum/Base/Arbitrum/OP), BNB, HYPE, AVAX, and POL; Bitcoin outputs, canonical EVM transactions/receipts, and parsed Solana transfers provide invoice evidence.
ERC-20 token railssupportedTransaction-scannedEthereum, Base, BNB Chain, HyperEVM, Avalanche, Polygon, Arbitrum, and Optimism require on-chain verification; indexed Transfer logs provide payment attribution.
SPL token railssupportedTransaction-scannedSolana candidates require mainnet and mint verification; exact token-balance deltas in parsed transactions provide payment attribution.
Additional UTXO native railssupportedTransaction-scannedBCH/LTC/DOGE use Esplora; BCH/DOGE also accept Bitcore, LTC/DOGE/DASH accept BlockCypher, Dash accepts Insight, and transparent ZEC accepts zcash-explorer. All also accept complete retained Core-compatible node-rpc blocks. Raw mode requires 1–48 confirmations, not mempool detection. Shielded Zcash is not supported.
Indexed account native railssupportedTransaction-scannedTRON uses tron-indexer or solidified node-rpc; XRP uses xrpl-jsonrpc; Stellar uses stellar-horizon or retained Stellar node-rpc ledgers; Cosmos Hub uses cometbft-jsonrpc; Algorand uses algorand-indexer or algod node-rpc; Hedera requires hedera-mirror, not an EVM relay.
Native ledger payment railssupportedTransaction-scannedAptos uses aptos-rest; Sui uses sui-graphql; NEAR uses near-jsonrpc; Kaspa uses kaspa-rest. Polkadot Asset Hub accepts substrate-rest or metadata-aware finalized node-rpc; Tezos accepts tezos-tzkt or full Octez node-rpc operations. Native receipts only; archive retention is required for older invoices.
Cardano and TON native railssupportedTransaction-scannedCardano requires cardano-koios and TON requires toncenter-v3. XRP tags, Stellar memo IDs, and TON invoice comments are returned as destination_tag and must be sent exactly.
Settlement integritysupportedIndependent verificationBy default, final settlement requires two independent providers to agree on exact transaction/event, amount, canonical block or slot and finality. Raw and shared EVM windows also verify complete coverage. An administrator may explicitly opt a chain into one trusted provider; this removes the independent cross-check, not identity, completeness or finality checks.
Monero native railsupportedProject-bound view-only wallet RPCOne dedicated external watch-only wallet-RPC behind an HTTPS method-allowlisting gateway creates account-0 subaddresses. The configured mainnet daemon threshold (default 2 independent sources, optional 1) provides settlement evidence. Native --restricted-rpc is incompatible with create_address; wallet backup and absence of a spend key are explicitly operator-attested, while no key material is sent to Wholly Crypto.

Exchange balances and per-asset wallet-or-exchange sweep choices are available in the console, not through the public v1 API. See exchange setup.

Invoice lifecycle

Payment evidence, settlement and order fulfilment.

StatusMeaning
newAwaiting a payment
processingPayment observed; accepted amount or finality pending
settledAccepted under invoice settlement policy, or manually
expiredDeadline passed; late monitoring may continue
invalidPayment cannot be accepted automatically
cancelledCancelled; only explicit reconciliation can reopen it

amount_status records none, partial, paid or overpaid. timing_status distinguishes on-time and late payments. Store rules decide the required confirmations and accepted underpayment tolerance.

Use the invoice’s invoice_id with the invoice detail route. A checkout redirect alone is not proof of settlement. Review exceptions through reconciliation.

Safe retries

Invoice creation requires Idempotency-Key. After a timeout, retry with the same credential, key and exact request body. Use a new key only for a new invoice.

EVM payment scanning

Shared native-block and ERC-20 discovery groups recent invoices separately from older catch-up work. Each invoice retains its durable history cursor. Token queries use at most 100 blocks per request and shrink for stricter provider limits. Two independent providers verify each window by default. Settings → Chain connections → Details can opt a chain into one trusted source, without independent cross-checking; canonical transaction, amount and confirmation checks remain. Connection details distinguish scanner delays, history restrictions and quota cooldowns from basic node health. Public RPC capacity is not guaranteed.

IPN & webhooks

Receive and verify payment events.

IPN receives every generated invoice event at the invoice's effective ipn_url. Webhooks receive only the events selected for each enabled store endpoint. Both POST the same JSON snapshot; they are independent, so enabling both can notify your application twice.

Set ipn_url when creating an invoice, or inherit the store default. IPN uses the Store → IPN secret; each Store → Webhooks endpoint has its own secret. Neither is your API key.

When should I fulfil an order?

For event-based handling, use event_type = invoice.settled together with status = settled to trigger an order check. Verify the current invoice and fulfil each order only once.

status is the invoice state when the event was created. event_type tells you what happened. payment.received can carry processing or settled; it does not mean a second payment and is not an independent fulfilment signal.

Which events and statuses are sent?

Event in settings/historyBody statusMeaning
invoice.creatednewInvoice created and awaiting payment. Also used when a controlled reopen returns an invoice to new.
payment.receivedResulting invoice statusA payment was recorded or the received amount increased. Usually processing or settled; this event alone is not proof of settlement.
invoice.processingprocessingPayment detected, but the accepted amount or required finality is not yet met. Partial payments are included.
invoice.settledsettledSettlement policy met, or accepted manually. Check resolution and your order before fulfilment.
invoice.expiredexpiredPayment deadline passed. A late payment can still change the status while monitoring continues.
invoice.invalidinvalidCannot be accepted automatically, payment evidence was lost, or a merchant rejected it. Review the invoice.
invoice.cancelledcancelledInvoice cancelled. Do not fulfil; a cancellation does not refund an on-chain payment.
Why Ethereum and Solana can send different event flows

Confirmations arrive later (Ethereum example)

Sequenceevent_typestatus
1invoice.creatednew
2payment.receivedprocessing
2invoice.processingprocessing
3invoice.settledsettled

Already final when detected (Solana example)

Sequenceevent_typestatus
1invoice.creatednew
2payment.receivedsettled
2invoice.settledsettled

These show event creation, not guaranteed delivery order. Either flow can happen on other chains depending on detection timing and settlement policy. Do not require a processing event before settled.

Fulfil once: receiver example and duplicate protection
ApproachHow to handle it
Event-based receiverKeep distinct events by signed event_id, then select invoice.settled with status = settled. Do not discard this event because payment.received with the same sequence arrived first.
SDK order-state inboxThe supplied PHP, Python and Node receiver examples collapse project + invoice_id + sequence. Process the saved state regardless of event_type, fetch the current invoice, and fulfil once if settled. Do not add an invoice.settled-only filter after this collapse.

A retry keeps event_id and the original body. Different events can share sequence but have different event_id values. Deduplicate deliveries by signed event_id for event-based handling; independently guard fulfilment by configured installation/project + invoice_id and your order. A later re-settlement must not credit the order twice.

HTTP receiver:
  Verify raw-body signature, timestamp and configured project/store scope.
  Save to a durable inbox; deduplicate the signed event_id.
  Return HTTP 2xx only after persistence succeeds.

Event-based background worker:
  Other events go to status/reconciliation handling, not fulfilment.
  Continue here only for event_type = invoice.settled and status = settled.
  Fetch the current invoice from your configured API origin.
  Check settled status, project/store, order, amount, currency and review policy.
  In one database transaction:
    Lock the order and check the scoped invoice has not been fulfilled.
    Credit/complete once and save the fulfilment record.
    Queue any external fulfilment with the same business idempotency key.

SDK order-state worker:
  Use the same current-invoice checks and fulfil-once transaction.
  Do not filter event_type after collapsing events by invoice revision.

Pseudocode, not a drop-in receiver.

All invoice states and payment exceptions
FieldValuesMeaning
statusnew, processing, settled, expired, invalid, cancelledInvoice state at event creation; not necessarily its current state at delivery.
amount_statusnone, partial, paid, overpaidAmount received, including accepted tolerance. paid is not confirmation finality.
timing_statuson_time, lateWhether payment met the invoice deadline.
resolutionautomatic, manually_settled, manually_invalidatedWhether normal rules or a manual acceptance/rejection determined the result.
requires_reviewfalse, trueException hint, not another invoice status or automatic permission to fulfil/refund.
SituationHandling
Underpayment / toleranceUnder automatic rules, partial does not settle. paid can include an accepted shortfall, but finality is still required. Use invoice status, not an amount comparison alone.
Overpaymentoverpaid can coexist with settled and requires_review = true. Apply your excess-payment policy; never credit the order twice or automatically refund an unverified address.
Late paymentexpired can later change while monitoring continues. timing_status = late flags review; do not automatically reopen or ship a cancelled order.
Manual acceptanceinvoice.settled can have resolution = manually_settled without qualifying on-chain funds. Decide whether your integration accepts this override; payment summary fields may be null.
Reorg / invalidationA newer revision can invalidate earlier payment evidence. Re-fetch current state and handle reversal through reconciliation. Do not ignore it just because the order was once settled.
Zero confirmations / zero amountZero-confirmation settlement can happen on detection and carries reorg risk. An explicitly allowed zero-amount invoice settles without a payment. Neither requires a payment.received event first.

Use status = settled for fulfilment, not amount_status = paid and not a checkout redirect. With zero required confirmations, settlement can happen on detection; that carries reorg risk.

Underpaid is amount_status = partial; overpaid is overpaid. paid means the accepted minimum, including the invoice's underpayment tolerance, has arrived. These are amount states, not invoice statuses. late is a timing_status, not a separate event.

A typical flow is new → processing → settled, but intermediate states can be skipped. An explicitly allowed zero-amount invoice settles without payment and keeps amount_status = none. Manual acceptance is marked manually_settled.

Callbacks are immutable snapshots, not live status responses. They may arrive late, out of order or more than once. Payment and status events can share an invoice sequence and the same invoice-state fields, but have different signed event_id and event_type values. Confirmation counts do not produce a guaranteed callback for every block.

What you receive

{
  "invoice_id": "11111111-2222-4333-8444-555555555555",
  "status": "settled",
  "amount_status": "paid",
  "timing_status": "on_time",
  "resolution": "automatic",
  "sequence": 3,
  "amount": "49.9",
  "currency": "EUR",
  "order_id": "order-1042",
  "payload_version": 2,
  "event_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
  "event_type": "invoice.settled",
  "occurred_at": "2026-09-14T12:05:00Z",
  "project_id": "11111111-1111-4111-8111-111111111111",
  "store_id": "22222222-2222-4222-8222-222222222222",
  "description": "Annual plan",
  "email": "ada@example.test",
  "customer": {
    "firstname": "Ada",
    "lastname": "Lovelace",
    "countryiso2": "GB"
  },
  "metadata": {
    "firstname": "Ada",
    "lastname": "Lovelace",
    "countryiso2": "GB",
    "cart_id": "cart-681"
  },
  "created_at": "2026-09-14T12:00:00Z",
  "updated_at": "2026-09-14T12:05:00Z",
  "expires_at": "2026-09-14T12:15:00Z",
  "monitoring_expires_at": "2026-09-21T12:15:00Z",
  "settled_at": "2026-09-14T12:05:00Z",
  "paid_chain": "ethereum",
  "paid_asset": "USDC",
  "paid_asset_amount": "58.17342",
  "paid_asset_amount_received": "58.17342",
  "paid_payment_method_id": "33333333-3333-4333-8333-333333333333",
  "settlement_exchange_rate": {
    "rate": "1.17",
    "units": "asset_per_invoice_currency",
    "currency": "EUR",
    "symbol": "USDC",
    "observed_at": "2026-09-14T12:05:00Z",
    "as_of": "2026-09-14T12:04:30Z",
    "pricing_provider": "kraken",
    "asset_provider": "kraken",
    "pricing_fetched_at": "2026-09-14T12:04:30Z",
    "asset_fetched_at": "2026-09-14T12:04:30Z",
    "stale": false,
    "is_fixed": false,
    "reference_currency": "USD",
    "uses_reference_proxy": false
  },
  "cancelled_at": null,
  "exchange_rate_spread_percent": "0.5",
  "underpayment_tolerance_percent": "1",
  "reason_code": "payment_confirmed",
  "requires_review": false,
  "links": {
    "checkout": "https://pay.example.com/invoice/11111111-2222-4333-8444-555555555555",
    "invoice": "https://api.example.com/v1/projects/11111111-1111-4111-8111-111111111111/invoices/11111111-2222-4333-8444-555555555555",
    "payments": "https://api.example.com/v1/projects/11111111-1111-4111-8111-111111111111/invoices/11111111-2222-4333-8444-555555555555/payments"
  },
  "payment_info": {
    "active_payment_method_id": "33333333-3333-4333-8333-333333333333",
    "method_count": 1,
    "methods_truncated": false,
    "methods": [
      {
        "payment_method_id": "33333333-3333-4333-8333-333333333333",
        "payment_rail": "onchain",
        "chain_slug": "ethereum",
        "network": "mainnet",
        "caip_network_id": "eip155:1",
        "asset_id": "44444444-4444-4444-8444-444444444444",
        "asset_key": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
        "caip_asset_id": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
        "asset_name": "USD Coin",
        "symbol": "USDC",
        "asset_kind": "token",
        "asset_decimals": 6,
        "contract_address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
        "token_standard": "erc20",
        "destination_address": "0x1111111111111111111111111111111111111111",
        "destination_tag": null,
        "status": "paid",
        "amounts": {
          "expected_amount": "58.17342",
          "expected_amount_atomic": "58173420",
          "received_amount": "58.17342",
          "received_amount_atomic": "58173420",
          "confirmed_amount": "58.17342",
          "confirmed_amount_atomic": "58173420",
          "unconfirmed_amount": "0",
          "unconfirmed_amount_atomic": "0",
          "minimum_payment_amount": "57.591686",
          "minimum_payment_amount_atomic": "57591686",
          "remaining_amount": "0",
          "remaining_amount_atomic": "0",
          "remaining_to_full_amount": "0",
          "remaining_to_full_amount_atomic": "0",
          "overpaid_amount": "0",
          "overpaid_amount_atomic": "0"
        },
        "acceptance": {
          "finality_mode": "confirmations",
          "required_confirmations": 2,
          "observed_confirmations": 2,
          "underpayment_tolerance_percent": "1"
        },
        "quote": {
          "effective_rate": "1.1658",
          "reference_rate": "1.16",
          "units": "asset_per_invoice_currency",
          "currency": "EUR",
          "symbol": "USDC",
          "exchange_rate_spread_percent": "0.5",
          "quote_expires_at": "2026-09-14T12:15:00Z",
          "provenance_available": true,
          "rounding": "up",
          "unrounded_payment_amount": "58.17342",
          "rounding_adjustment": "0",
          "pricing_provider": "kraken",
          "asset_provider": "kraken",
          "pricing_fetched_at": "2026-09-14T11:59:30Z",
          "asset_fetched_at": "2026-09-14T11:59:30Z"
        },
        "market_rate_at_event": {
          "rate": "1.17",
          "units": "asset_per_invoice_currency",
          "currency": "EUR",
          "symbol": "USDC",
          "observed_at": "2026-09-14T12:05:00Z",
          "pricing_provider": "kraken",
          "asset_provider": "kraken",
          "pricing_fetched_at": "2026-09-14T12:04:30Z",
          "asset_fetched_at": "2026-09-14T12:04:30Z",
          "as_of": "2026-09-14T12:04:30Z",
          "stale": false,
          "is_fixed": false,
          "reference_currency": "USD",
          "uses_reference_proxy": false
        },
        "payment_count": 1,
        "payments_truncated": false,
        "payments": [
          {
            "payment_id": "55555555-5555-4555-8555-555555555555",
            "payment_method_id": "33333333-3333-4333-8333-333333333333",
            "transaction_id": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
            "payment_hash": null,
            "event_index": 0,
            "payment_rail": "onchain",
            "chain_slug": "ethereum",
            "network": "mainnet",
            "asset_id": "44444444-4444-4444-8444-444444444444",
            "asset_key": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
            "caip_asset_id": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
            "symbol": "USDC",
            "asset_decimals": 6,
            "amount": "58.17342",
            "amount_atomic": "58173420",
            "status": "final",
            "counts_towards_received": true,
            "confirmations": 2,
            "block_height": 26000000,
            "observed_at": "2026-09-14T12:04:30Z",
            "chain_time": "2026-09-14T12:04:20Z",
            "finalized_at": "2026-09-14T12:05:00Z",
            "explorer_name": "Etherscan",
            "explorer_url": "https://etherscan.io/tx/0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
          }
        ],
        "links": {
          "payments": "https://api.example.com/v1/projects/11111111-1111-4111-8111-111111111111/invoices/11111111-2222-4333-8444-555555555555/payments?payment_method_id=33333333-3333-4333-8333-333333333333"
        }
      }
    ]
  }
}

amount is the original invoice total. payment_info describes observed crypto transfers, amounts still missing and locked rates. Version 2 also signs the event name, event ID and project/store scope.

All callback fields and extra invoice data
FieldTypeMeaning
invoice_idUUIDPublic invoice UUID, used by the authenticated invoice detail route
statusstringSnapshot invoice state: new, processing, settled, expired, invalid, cancelled
amount_statusstringnone, partial, paid, or overpaid; paid includes the accepted underpayment tolerance, not confirmation finality
timing_statusstringon_time or late
resolutionstringautomatic, manually_settled, or manually_invalidated
sequenceintegerIncreasing invoice revision; different events can share one revision. Compare without losing integer precision
amountdecimal stringOriginal invoice total, not the received crypto amount; preserve decimal precision
currencystringCurrency of amount, e.g. EUR for a EUR invoice paid with USDC
order_idstring | nullMerchant order reference
payload_versioninteger2 for newly generated 4.1.0+ events; absent on retained legacy events
event_idUUIDSigned event identity, unchanged on retries and manual redelivery
event_typestringOne of the seven subscription events
occurred_attimestampWhen this immutable event was created, not delivery time
project_idUUIDMerchant project scope; match to configured receiver
store_idUUIDMerchant store scope; match to configured receiver
descriptionstring | nullOriginal invoice description
emailstring | nullOptional customer email at event creation
customerobjectRecognized optional customer metadata fields; no guessed or enriched personal data
metadataobjectOriginal merchant metadata as it existed at event creation
created_attimestampInvoice creation time
updated_attimestampInvoice state update time
expires_attimestampInvoice payment deadline
monitoring_expires_attimestampLate-payment monitoring deadline
settled_attimestamp | nullSettlement time
paid_chainstring | null4.1.2+: chain slug of the proven settling method, e.g. ethereum; null without a saved qualifying settlement
paid_assetstring | null4.1.2+: native coin or token ticker, e.g. BTC, ETH or USDC; a display label, not unique asset identity
paid_asset_amountdecimal string | null5.0.1+: full locked amount requested in paid_asset units, before subtracting tolerance; saved at settlement
paid_asset_amount_receiveddecimal string | null5.0.1+: total valid amount received for the winning method at settlement, including accepted shortfalls/excess; frozen, not a live balance
paid_payment_method_idUUID | null4.1.2+: settling intent ID; matches payment_info.methods[].payment_method_id and its exact network/contract
settlement_exchange_rateobject | null4.1.2+: saved before-spread market snapshot at settlement, with explicit units, currency, source timestamps and quality flags; never repriced on delivery
cancelled_attimestamp | nullCancellation time
exchange_rate_spread_percentdecimal stringLocked spread, not the current store default
underpayment_tolerance_percentdecimal stringLocked invoice tolerance; each method also reports its effective tolerance
reason_codestring | nullMachine-readable state-transition reason
requires_reviewbooleanPayment exception hint; not permission to fulfil or refund automatically
linksobjectCheckout, authenticated invoice and payments URLs at event creation. Store → Basic domain preferences apply, then the default store, then the global primary; only active role-matched domains are used. Retries retain the original signed links; null if no active host record.
payment_infoobjectActual observed methods, exact amounts, locked quote, advisory market snapshot and bounded payment observations; see field groups below

Settlement summary: settlement_exchange_rate

FieldTypeMeaning
rate / units / currency / symbolstringsBefore-spread asset units per one invoice currency unit. Decimal string, not a payment amount or executed trade.
observed_at / as_oftimestampsSettlement capture time / older source timestamp. Do not treat cached data as a live tick.
pricing_provider / asset_provider / pricing_fetched_at / asset_fetched_atstrings / timestampsFiat and asset pricing sources and their fetch times, saved at settlement.
stale / is_fixed / uses_reference_proxy / reference_currencybooleans / stringSame quality flags as market_rate_at_event. Fixed project prices are labelled; reference currency is USD.
Missing snapshot or pricenullNo guessed historical rate. Before settlement all summary fields are null; missing prices alone leave proven paid_* identifiers available.

Payment methods: payment_info

FieldTypeMeaning
active_payment_method_idUUID | nullWinning or selected observed method. Null before detection or after invalidation; no default method is guessed.
method_count / methods_truncatedinteger / booleanTotal observed methods and whether the embedded methods list is incomplete.
methods[]object[]At most eight observed methods, active method first. No cross-asset totals.
payment_method_id / payment_railUUID / stringInvoice intent identity and onchain or lightning transport.
chain_slug / network / caip_network_idstringNetwork identity. Always pair token identity with its network.
asset_id / asset_key / caip_asset_idUUID / string / nullable stringVerified registry identity; symbols alone are not unique.
asset_name / symbol / asset_kindstringAsset display name, ticker and native or token kind.
contract_address / token_standardstring | nullToken contract or mint and standard; null for native assets.
asset_decimalsintegerAtomic precision; Lightning BTC uses 11.
destination_address / destination_tagstring | nullPublic receiving address and required memo/tag. Address is null for Lightning; never a private key.
statusstringMethod state: pending, partial, paid, overpaid, expired or invalid. Paid is not by itself invoice settlement.
payment_count / payments_truncated / payments[]integer / boolean / object[]Total observations and latest five or fewer. Each observation is described below.
links.paymentsHTTPS URL | nullAuthenticated paginated history for this method on the configured API origin.

Exact amounts: methods[].amounts

FieldTypeMeaning
expected_amountdecimal stringFull locked quote, after spread and upward rounding.
received_amount / confirmed_amountdecimal stringsValid detected funds / funds meeting this method's confirmation or finality policy.
unconfirmed_amountdecimal stringmax(received - confirmed, 0). Not an additional amount to send.
minimum_payment_amountdecimal stringAccepted threshold after tolerance. May be below the full quote.
remaining_amountdecimal stringmax(minimum accepted - received, 0). Additional funds needed to reach the accepted threshold, not confirmation progress.
remaining_to_full_amountdecimal stringmax(full quote - received, 0), ignoring tolerance.
overpaid_amountdecimal stringmax(received - full quote, 0). Does not authorize an automatic refund.
Every amount's *_atomic companioninteger stringExact smallest-unit representation. Use decimal or integer libraries; never float or JavaScript Number for money.

Confirmation policy: methods[].acceptance

FieldTypeMeaning
finality_mode / required_confirmationsstring / integerLocked confirmations or finalized policy. Zero confirmations is explicitly allowed by merchant policy, not universal network finality.
observed_confirmationsinteger | nullMinimum among valid observations, not just the newest transfer. Null for Lightning or no valid observations.
underpayment_tolerance_percentdecimal stringEffective method tolerance. Lightning uses zero even when the invoice has a nonzero on-chain tolerance.

Rates: methods[].quote and market_rate_at_event

FieldTypeMeaning
quote.effective_rate / units / currency / symbolstringsLocked asset_per_invoice_currency rate including spread; currency and symbol state the direction explicitly.
quote.exchange_rate_spread_percent / quote_expires_atdecimal string / timestampLocked spread and quote deadline. Never replaced with current store settings.
quote.reference_rate / unrounded_payment_amount / rounding_adjustmentdecimal string | nullBefore-spread reference, payment amount before rounding, and upward adjustment in asset units.
quote.pricing_provider / asset_provider / pricing_fetched_at / asset_fetched_atstring or timestamp | nullOriginal currency and asset pricing sources/times. No API keys or provider credentials.
quote.provenance_available / roundingboolean / stringFalse for old invoices without a saved source snapshot; rounding is up.
market_rate_at_eventobject | nullAdvisory cached market snapshot when this event was made. Missing data stays null; it never changes invoice amounts or delays for a network fetch.
market_rate_at_event.rate / units / currency / symbolstringsBefore-spread market rate, with the same explicit direction as quote.
market_rate_at_event.observed_at / as_of / pricing_fetched_at / asset_fetched_attimestampsEvent snapshot time / older of the two source times / each source time.
market_rate_at_event.pricing_provider / asset_providerstringsCached currency and asset sources, including configured custom-token prices.
market_rate_at_event.stale / is_fixed / uses_reference_proxy / reference_currencybooleans / stringWhether cache is stale, token price fixed or USD reference uses a stablecoin proxy. Reference currency is USD. Stale is advisory, never a fresh quote.

Transfer records: methods[].payments[] and GET …/payments

FieldTypeMeaning
payment_id / payment_method_idUUIDObservation identity / parent intent identity. Use payment_id for history deduplication.
transaction_id / payment_hash / event_indexstring | null / integerOn-chain hash and transfer/log/output index, or Lightning hash. Lightning has no transaction or explorer link.
payment_rail / chain_slug / network / asset_id / asset_key / caip_asset_id / symbol / asset_decimalsstrings / UUID / integerSame asset and network identifiers as the containing method.
amount / amount_atomicdecimal / integer stringsThis transfer's exact value, never a fiat conversion.
status / counts_towards_receivedstring / booleandetected, confirming and final count; reorged, replaced and invalid do not. Keep invalidated history for reconciliation.
confirmations / block_heightinteger | nullObservation's block data; confirmations null for Lightning.
observed_at / chain_time / finalized_attimestamp | nullFirst seen locally, trusted chain time if available, and policy-final time if reached.
explorer_name / explorer_urlstring | nullValidated public block-explorer reference, where supported.

Merchant 5.13.3 excludes verified internal gas-funding transfers from customer payment totals, payment_info, the invoice payments API, refund limits and payment.received events. Their chain/treasury records remain available for wallet accounting. Ordinary transfers and genuine overpayments still count. Existing signed callback bodies are never rewritten. If a historical settlement depended on internal funding instead of customer funds, reconciliation emits invoice.invalid with reason_code internal_gas_funding_excluded; review it instead of fulfilling again.

Merchant 4.1.0 adds payload_version 2 without moving or changing the original nine fields. Previously queued events keep their original body and may have no payload_version. event_id, event_type and project/store IDs are now inside the signed body; transport event/delivery headers remain unsigned.

payment_info describes observed payments, not every offered checkout option. Before detection its active_payment_method_id is null and methods is empty. Reorged/invalid observations can remain in methods even after the active method becomes null. Never add amounts from different assets or networks together.

All amounts, atomic integers, rates and percentages are strings. received_amount includes valid funds awaiting confirmation; confirmed_amount meets that method's finality policy. remaining_amount is max(minimum_payment_amount minus received_amount, 0); remaining_to_full_amount is max(expected_amount minus received_amount, 0). Example: 100 USDC expected, 99 received, 1% tolerance means remaining_amount 0 and remaining_to_full_amount 1. Finality is still required.

quote is the locked invoice calculation: asset units per one invoice currency unit. Spread is applied before upward rounding. Use expected_amount_atomic for exact payment comparison; a displayed rate alone may not reproduce upward rounding. Old invoices without stored source provenance expose null source/reference/rounding fields and provenance_available false, never today's data presented as a historical quote.

market_rate_at_event is advisory cached data before spread, frozen at event creation. It has source times, stale and reference-proxy flags; it is null if no usable cached pair exists. No live rate request blocks a notification, and this market observation never changes the amount owed. Fixed custom tokens are labelled is_fixed; DEX tokens use their project-specific source, not a same-symbol token.

Top-level paid_chain, paid_asset, paid_payment_method_id and settlement_exchange_rate (4.1.2+) identify the proven winning method after settlement, not a selected checkout option or a sum of different methods. Before settlement, after invalidation, for older unsnapshotted settlements, or for manual acceptance without qualifying policy-final funds, the summary fields are null. Symbols are display labels: follow the method ID for the exact network/asset/contract identity.

Merchant 5.0.1 adds paid_asset_amount and paid_asset_amount_received as exact decimal strings in paid_asset units; payload_version remains 2. paid_asset_amount is the full locked quote, including spread and upward rounding, never the tolerance threshold or a remaining balance. paid_asset_amount_received is the winning method's total valid receipts at settlement, including funds awaiting confirmation and any accepted shortfall or excess. Example: 100 USDC quoted, 99 received and accepted with tolerance gives 100 and 99, not 99 and 99. Both are frozen with the settlement snapshot; use payment_info.methods[].amounts for receipts at each event or the payments API for current records. They are null without a qualifying snapshot and for pre-5.0.1 snapshots; old queued event bodies are unchanged. Never convert exact decimal strings to floating point for accounting.

settlement_exchange_rate is the before-spread cached market observation captured with settlement, not the locked invoice quote or an executed exchange trade. Its shape matches market_rate_at_event; 1.17 asset_per_invoice_currency with EUR/USDC means 1 EUR = 1.17 USDC. Source timestamps and stale/fixed/proxy flags describe its quality. A missing pair leaves the rate null but a proven method still has paid_* fields. It never changes the amount owed or waits for a live provider call. Later payments using the same method, retries and redelivery cannot replace the saved snapshot, including a saved null rate. A genuine re-settlement or changed settling method captures a new snapshot; observed_at identifies that capture, while settled_at may retain the first settlement time. Old event bodies stay unchanged.

At most eight observed methods and five latest payment observations per method are included, with counts and truncation flags. Payload budgeting can reduce those arrays further. A payment observation is one transfer/log/UTXO output, not necessarily a unique transaction hash. Use GET /v1/projects/YOUR_PROJECT_ID/invoices/{invoice_id}/payments with payment_method_id, limit and offset for the complete current history. The invoice detail retains every quoted method and its quote_details. API links require your configured host and credentials, never forward a bearer token to an arbitrary callback-provided URL.

Lightning uses payment_hash instead of transaction_id; receiving address, explorer and observed confirmations are null. Its exact BTC amount uses 11 decimals (millisatoshis), and effective tolerance is zero. No BOLT11 payment preimage, wallet key, signing secret or provider credential is included. Customer/metadata fields belong only in merchant responses and signed callbacks, never public checkout; do not put credentials in metadata.

Paginated payment history →

Receive safely

  1. Verify the exact raw body with the matching secret before parsing. Store → IPN supplies the IPN secret, including custom ipn_url deliveries. Each Store → Webhooks endpoint has its own secret. Neither is your API token; rotating one does not rotate the others.
  2. Check the signed timestamp (SDK default: five minutes in either direction) and match signed project/store IDs to your receiver configuration when present. Durably queue before returning HTTP 2xx. For per-event processing, v2 event_id is signed; header IDs alone are not replay protection because those headers are not signed. For order-state inboxes, deduplicate invoice_id and sequence and compare the original invoice state fields, not the entire v2 body: different event types/IDs can share a revision.
  3. In a worker, fetch the current invoice from your configured API origin, not an arbitrary callback link. Match the stored order, project/store, amount and currency, require current settled status, and apply your manual-acceptance and exception policy. Lock the order and fulfil once in a database transaction, independently of event deduplication.
  4. Never apply an older sequence over a newer one. Different events can share a revision; do not combine revision-level deduplication with an invoice.settled-only filter. Reopening/reconciliation can change status; sequence, not a fixed status ranking, orders updates. Record reversals for review rather than fulfilling again.

Receiver examples: PHP · Python · Node.js / TypeScript.

Signature verification & delivery rules
import { createHmac, timingSafeEqual } from "node:crypto";

export function verifyWhollySignature(rawBody, header, signingSecret, toleranceSeconds = 300) {
  const match = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header || "");
  if (!match) return false;

  const timestamp = Number(match[1]);
  if (!Number.isSafeInteger(timestamp)) return false;
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - timestamp) > toleranceSeconds) return false;

  // rawBody must be the exact request Buffer, before JSON parsing.
  const expected = createHmac("sha256", signingSecret)
    .update(String(timestamp))
    .update(".")
    .update(rawBody)
    .digest();
  const presented = Buffer.from(match[2], "hex");
  return timingSafeEqual(expected, presented);
}
Delivery ruleDetails
HeadersWholly-Signature, Wholly-Event-Id, and Wholly-Delivery-Id; Content-Type is application/json.
SignatureHMAC-SHA256 over <unix timestamp>.<exact raw body>; header format t=<timestamp>,v1=<64 lowercase hex>.
SuccessAny HTTP 2xx response. Redirects are not followed; non-2xx responses are failures.
Timeouts5-second connect timeout and 10-second total request timeout.
Retry scheduleUp to 8 attempts for retryable failures: immediately, then delays of 10s, 1m, 5m, 15m, 1h, 6h, and 24h after the previous attempt finishes. IPN retries automatically; webhook automatic retry can be disabled per endpoint.
Target safetyPublic HTTPS only. DNS is revalidated and pinned for delivery; local/private/reserved targets are rejected.
Event retentionNotification event payloads and delivery retention are scheduled for 90 days; retained details are purged in bounded batches.
DeduplicationPersist the signed invoice_id and sequence scoped to the configured project. Wholly-Event-Id identifies an event; Wholly-Delivery-Id identifies a delivery record (retries reuse it; manual redelivery creates another). Neither ID header is signed.
Event namingVersion 2 signs event_id and event_type in the body. Legacy queued events have neither. Different event types can share an invoice sequence; reconcile invoice state by revision, or deduplicate individual events by signed event_id.
Secret rotationRotation has no overlap or version header and immediately changes signatures for queued, retried, and manual deliveries.
Paused deliveriesInsufficient processing credits pause IPN/webhooks, including retries. Incoming payments continue; queued notifications resume after funding within their payload-retention period.

AI assistants · MCP

Connect an assistant to your merchant installation.

Merchant 5.0.0 includes an opt-in MCP server on your configured API domain. It runs inside your installation, not through a shared Wholly Crypto relay.

  1. Open Settings → API access. Create a dedicated credential, assign only the projects the assistant needs, and start with read-only access. On an operator-hosted account, the operator enables the installation's MCP service first; you manage only your own credentials and grants.
  2. In AI connections · MCP, enable MCP, select the credential and save its MCP access. Existing credentials have no MCP access until explicitly enabled.
  3. Copy the MCP server URL into your client's remote HTTP server settings. With OAuth, sign in to your merchant console, review the client name and return address, choose a credential and approve. Your existing Basic Auth and TOTP protections still apply.
  4. Invoice creation additionally requires a read/write credential, Read + create invoices in its MCP policy, the mcp:invoice:create OAuth scope and explicit approval. An OAuth connection never gains projects added to a credential after approval.
{
  "mcpServers": {
    "whollycrypto": {
      "url": "https://api.example.com/mcp"
    }
  }
}

MCP setup guide →

ToolAccessPurpose
list_projectsReadEnabled projects assigned to the connection; limit/offset pagination.
list_storesReadStores, IDs and enabled status within project_id; limit/offset pagination.
list_payment_methodsReadConfigured chain, token and Lightning methods for project_id + store_id.
get_wallet_balancesReadReceiving addresses and cached balances, with freshness/availability fields; never wallet secrets.
list_invoicesReadProject invoices, filtered by store, status or search; limit/offset pagination.
get_invoiceReadFull invoice details and checkout link using project_id + invoice_id.
get_delivery_historyReadStore IPN/webhook statuses, attempts and HTTP results. Optional invoice_id/kind filters; no secrets or callback bodies.
convert_amountReadCached reference conversion using from, to and a decimal-string amount; not an invoice quote.
create_invoiceExplicit writeproject_id, store_id, idempotency_key and invoice (the existing invoice creation body). invoice.payment_methods filters enabled store methods; 5.4.0+ ignores inactive/unaccepted choices and falls back to store defaults if none match. Chain-only selects all active accepted assets. Chain-scoped asset_tickers are supported from 5.3.0. Returns the normal invoice response.
Protocol, OAuth & safety

Use Streamable HTTP over HTTPS. Negotiate an advertised protocol version and include MCP-Protocol-Version on subsequent POSTs. Send Content-Type: application/json and Accept: application/json, text/event-stream. Responses are finite JSON; reconnects do not need an MCP session ID.

OAuth uses short-lived access tokens (15 minutes), one-time S256 PKCE codes (5 minutes) and rotating refresh tokens (connection lifetime 30 days). Reusing an already-used refresh token revokes that connection. Reconnect after expiry, credential rotation, policy changes or a canonical API-domain change.

OAuth discovery is public only when MCP is enabled. The resource parameter must equal the canonical URL returned by discovery, including /mcp. Dynamic registration is supported; remote client-ID metadata documents and client secrets are not.

For clients supporting custom Authorization headers, an MCP-enabled merchant API token can be used as Bearer instead. It retains its separate REST permissions; prefer OAuth for a connection restricted to MCP. Never paste credentials in chat, URLs, tool arguments or source control.

MCP shares the credential's per-minute REST quota and exact source-IP restrictions, plus API-host IP restrictions. OAuth does not bypass a whitelist. For remote AI clients, allow their documented egress IPs or leave this restriction off deliberately. No web security challenge or caching should be applied to MCP/OAuth routes.

HTTP errors: 401 needs authentication, 403 denies origin/IP/permission, 404 means MCP is disabled or the wrong host, 405 means use POST, 413 means the 32 KiB body limit, 429 includes Retry-After. JSON-RPC errors use error.code; tool-level failures use result.isError=true even with HTTP 200. Successful results include content and structuredContent.

Lists default to 25 rows, maximum 100; offset is bounded to 1000000. Tool replies are bounded to 2 MiB. Expired grants, authorization requests and rate buckets are pruned automatically; at most 100 active OAuth connections are shown in settings.

Disabled projects/stores cannot be operated through MCP. The connection can list a store's enabled state, but reading its payment methods, delivery history or creating invoices requires an enabled store. Ordinary console project users cannot administer MCP.

Use a new idempotency_key for a new invoice; after a timeout retry the same credential, key and identical invoice object. Decimal amounts, spread, tolerance, confirmations and checkout appearance follow the REST invoice contract. MCP never bypasses merchant payment or credit policy.

The initial tools cannot reveal private keys/recovery phrases, send or sweep funds, issue refunds, resend callbacks, change payment methods, edit accounts/domains or manage billing. Treat invoice descriptions, customer fields and metadata as untrusted data, not agent instructions. Connected AI providers receive the data you authorize them to read.

MethodPathContract
POST/mcpAuthenticated JSON-RPC: initialize, ping, tools/list, tools/call. Notification requests return 202; batches are rejected.
GET / DELETE/mcpAuthenticated 405: finite JSON responses, no standalone SSE stream and no server-side MCP session.
GET/.well-known/oauth-protected-resource/mcpCanonical resource URL and authorization-server discovery; also available at /.well-known/oauth-protected-resource.
GET/.well-known/oauth-authorization-serverOAuth endpoints, authorization_code/refresh_token, S256 PKCE and supported scopes.
POST/mcp/oauth/registerPublic-client registration: client_name and exact redirect_uris. HTTPS or loopback HTTP only. No client secret or remote metadata fetching.
GET/mcp/oauth/authorizeclient_id, redirect_uri, response_type=code, resource, code_challenge, code_challenge_method=S256, optional scope/state; redirects to console approval.
POST/mcp/oauth/tokenForm-encoded authorization_code + code + code_verifier + redirect_uri, or refresh_token + refresh_token. Always include client_id and resource.
POST/mcp/oauth/revokeForm-encoded client_id and token. Revokes the matching access/refresh-token connection.
Direct tool request example

Initialize and negotiate the protocol first through your MCP client. This shows a subsequent request.

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/mcp" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'MCP-Protocol-Version: 2025-11-25' \
  --header 'Accept: application/json, text/event-stream' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_invoices",
    "arguments": {
      "project_id": "YOUR_PROJECT_ID",
      "limit": 10
    }
  }
}'

Operator API

Provision hosted merchants with separate, scoped server-side keys.

Host several businesses and automate their setup through api.example.com/v1/operator. Available from 7.4.0 in Operator mode only. The ordinary Merchant API remains unchanged.

  1. Open Operator → Settings → Operator API and enable it (off by default). Create a separate credential with only the required permissions and hosted merchants.
  2. Keep the wc_operator_ key on your server. Use the API hostname, not the Operator panel hostname or a merchant key.
  3. Persist an Idempotency-Key and exact request body before every Operator POST. Read back the account after an uncertain outcome; never replace the key just to retry.
  4. Create a merchant with onboarding: direct and a password, or onboarding: invitation and no password. Then create projects/stores and issue a project-scoped merchant key for its checkout integration.
ScopeAccess
merchants.read / merchants.writeList/read and create/update hosted merchants.
users.read / users.write / users.securityRead/create/update users; change passwords or revoke sessions separately. Never creates an operator administrator.
invitations.read / invitations.writeList/read, create, replace and revoke one-time invitation/reset links. New users also need users.write; resets also need users.security.
credits.read / credits.write / fees.writeRead balances/ledger; grant or correct local credit; set prospective fees. Nonzero starting credits need credits.write.
topups.read / topups.writeRead or create hosted-merchant credit checkout requests. No API action can mark one paid.
projects.read / projects.write / reports.readProvision merchant projects, stores, appearance and payment settings; read invoices, wallet balances and financial reports.
merchant_credentials.read / merchant_credentials.writeManage ordinary scoped merchant keys. Powerful: those keys act independently after issuance.
events.read / webhooks.write / audit.read / health.readRead lifecycle history; configure signed lifecycle callbacks; read audit/capabilities/node health.
Onboarding, credits, permissions and safe retries
TopicRule
CredentialsOptional expiry and exact IPv4/IPv6 allowlist; 60 requests/minute by default, configurable 1–600. Every request checks the issuing administrator and current scopes. HTTP 429 includes Retry-After.
IsolationKeys access only their assigned hosted merchants. Creating merchants and viewing installation-wide reports require all-merchants access. The operator’s own business is excluded.
First sign-inDirect accounts acknowledge that the host can access their wallet keys. require_password_change adds a first-login password change. Invitation acceptance requires explicit custody acknowledgement, then normal sign-in. Basic Auth and existing TOTP remain in force.
InvitationsNew-user links last 48 hours; password-reset links last one hour. Tokens are one-use. Reissuing revokes the old link. SMTP acceptance is not a guarantee of inbox delivery; inspect email_delivery.
Safe retriesEvery Operator POST needs a 16–128 character key (letters, digits, -, _ or .). Same key and exact URL/body returns the saved outcome. Different bytes return 409. Secrets/links are omitted on replay; rotate or reissue through a new explicit operation when needed.
Uncertain outcomesoperator_request_in_progress means an operation is running or was interrupted before its receipt was recorded. Inspect the resource and audit; do not blindly submit a new key. Completed receipts are compacted after 30 days; old keys still cannot run again.
Credits and feesDecimal strings, at most six decimals. starting_credit is a one-time local grant. Adjustments need a signed amount, note and request_id, plus the HTTP retry key. fee_bps=100 means 1%; edits affect future invoices. Grants do not top up the installation’s own prepaid balance.
Pausingenabled=false disables a hosted account and revokes console sessions. payments_paused=true stops new invoices. Existing payment monitoring continues. Project/store creation and automation retain the installation’s credit policy.
Not exposedNo wallet secrets, signing, sending, refunds, permanent deletion, TOTP reset, domain changes or server-level configuration. Ordinary invoice requests still use a merchant key and the Merchant API.

Operator lifecycle webhooks

EventData
merchant.created / merchant.updatedmerchant_id, enabled, payments_paused, fee_bps.
user.created / user.updatedmerchant_id, user_id, enabled. Updated event covers email, enabled status and admin role changes.
invitation.accepted / password_reset.completedmerchant_id, user_id, invitation_id.
topup.settled / credit.balance_changedmerchant_id, ledger_id, kind, amount and balance. Read merchant credit currency or ledger detail when reconciling.

Operator lifecycle events are separate from invoice IPN/store webhooks. A subscription belongs to the Operator credential that created it, with up to 10 endpoints per key. Only future matching events are queued; use GET /events for retained history.

The body contains event_id, event_type, merchant_id, occurred_at and data. Verify Wholly-Signature over the exact raw body using the endpoint’s one-time signing_secret: HMAC-SHA256(secret, timestamp + '.' + raw_body), header t=...,v1=.... Enforce a short timestamp tolerance.

Use the SDK’s generic signature verifier, not its invoice-notification parser. Then validate merchant_id and event_type, persist/deduplicate event_id transactionally, and return 2xx only after durable acceptance. Wholly-Event-Id must match the signed body. Do not treat unsigned headers as business data.

Delivery is at least once, may arrive out of order, and is attempted up to 8 times. Read current resources to reconcile; occurred_at is not a monotonic sequence. Scope and enabled/expiry settings are rechecked before delivery. Disabled subscriptions pause already queued work but do not queue new events while disabled.

Events and delivery history are retained for 30 days. Installation automation policy can pause delivery. GET /webhooks/{id}/deliveries shows outcome and immutable payload; public API does not force-deliver an expired record.

{
  "event_id": "55555555-5555-4555-8555-555555555555",
  "event_type": "merchant.created",
  "merchant_id": "11111111-1111-4111-8111-111111111111",
  "occurred_at": "2026-10-01T12:00:00Z",
  "data": {
    "merchant_id": "11111111-1111-4111-8111-111111111111",
    "enabled": true,
    "payments_paused": false,
    "fee_bps": 300
  }
}

Create a merchant → · Accept an invitation →

Marketplace API

One checkout with protected vendor shares and controlled payouts.

One customer invoice, exact vendor shares and controlled same-asset payouts. Opt in per project. Version 8.0.0 supports Bitcoin mainnet and configured supported EVM native coins / standard ERC-20 tokens, not all receiving networks.

  1. Enable Marketplace in the project, choose participating stores and leave payouts paused while configuring it.
  2. Register vendors and independently verify their payout addresses. Destination creation is pending; approval needs destinations.approve.
  3. Create a separate Marketplace credential in Settings → API access. Ordinary Merchant, Operator and MCP credentials cannot spend Marketplace funds.
  4. Create an invoice with 1–100 positive decimal-string allocations whose total exactly equals the invoice amount. Every vendor needs an approved destination on a common supported store network.
  5. Wait for verified allocation availability. Prepare a payout, read its immutable recipients and cost limits, then approve its revision and exact plan_hash. Poll the payout or verify signed events.
TopicRule
CustodyCustomer funds enter project-controlled wallets first. The marketplace/server owner controls those keys until vendors are paid. This is not direct customer-to-vendor payment, escrow or a vendor login system.
Three vendorsA 300 USD invoice with three 100 USD shares and 4% commission allocates 96 USD-equivalent of the quoted crypto to each vendor, retaining 12 USD-equivalent gross commission. Crypto atomic units, not future fiat value, are guaranteed by the plan.
FeesThe existing processing charge applies once to the original settled invoice amount/currency. At a configured 1%, that is 3 USD of prepaid credits, leaving 9 USD-equivalent commission before chain fees. Vendor payouts do not create additional customer-sale fees.
AllocationLargest-remainder allocation preserves every atomic unit. Commission rounds down; vendor net is the remainder. Allocation override, invoice override, vendor override and store/project defaults are snapshotted. No new exchange rate is applied at payout.
Protected fundsOrdinary sends, sweeps, exchange deposits and credit auto-top-ups exclude Marketplace receiving addresses. Network fees and token gas require separate free native coins. Cached wallet values are advisory; independent live backing is checked before signing.
FinalityA positive chain floor and two independent compatible providers are required for Marketplace payout proof, even if checkout accepts zero confirmations or a single scanner. Provider cooldowns defer payment verification/payout, not otherwise-valid invoice creation.
ExceptionsUnderpayments accepted by ordinary checkout tolerance are held, not over-allocated. A privileged release may approve an exact smaller fully backed split. Overpayment alone never blocks the quoted vendor split on BTC or supported EVM native/ERC-20 methods. Excess stays held separately. Bitcoin returns protected change to the invoice address; separate project funds cover fees and any dust-floor top-up. Mixed methods, late/ambiguous/reorged payments and missing backing need review.
RefundsPrepare a full same-asset refund of one unambiguous confirmed received method, then separately approve it as a payout. Unpaid allocations and commission reverse. Once every vendor is paid, fund the primary wallet address separately; there is no clawback. Partial vendor batches and mixed-asset refunds require reconciliation first. Partial-amount refunds and commission withdrawals are not exposed in 8.0.0.
RetriesEvery POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
RevisionsMutable records require their current revision. Approve/resume also requires expected_plan_hash and confirm:true. Preparation reserves funds for 15 minutes; approval allows one hour. Expired unsigned work releases safely. Signed/uncertain transfers retain identities and reservations.
Automatic payoutsOff by default. Per-asset policies authorize approved destinations, positive minimum, per-payout/rolling-24-hour principal and native-fee/gas limits, interval and confirmations. Changing/revoking authority stops unsent work; observation continues. Limits include reserved and uncertain plans. Billing-paused policies are rescheduled fairly. An invalid invoice is held for review without blocking other eligible invoice groups.
Pause and recoveryLow credits and transfer safety gates still pause spending. Monitoring and ledger reconciliation continue. Resume reviews the same retained plan. A canonical EVM revert proven by two independent providers can be replaced after explicit approval, within the remaining fee budget; original hashes and fees stay recorded. Unknown outcomes or token delivery mismatches remain held. Back up the whole database and keys; reconcile submitted hashes after restore before allowing payouts.
Identifiers and paginationUse project UUID from Project Settings and store UUID from Stores → Basic → API IDs. Vendor/payout/asset IDs are returned by this API. invoice_id is the public invoice UUID. Paged resources return data and pagination {page,per_page,total,pages}; defaults 1/25, maximum 100 rows. Exact monetary values are strings.
Credential scopeKeys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Marketplace permissions

marketplace.read · vendors.write · destinations.write · destinations.approve · invoices.write · policies.write · commissions.override · payouts.write · payouts.approve · webhooks.write · reconciliation.write

Allocation states

pending · held · available · reserved · paid · refunding · refunded · shortfall

Payout states

awaiting_approval · queued · funding_gas · sending · confirming · partially_paid · paid · needs_attention · cancelled · expired

Marketplace events

Separate Marketplace signing secret, using the same Wholly signature headers and raw-body HMAC verification algorithm as invoice callbacks. Verify timestamp/signature, deduplicate event_id and return 2xx promptly. Delivery is at least once, up to eight attempts; history can redeliver the same event. Endpoint edits cancel old unsent deliveries instead of redirecting customer data. Invoice settlement is not vendor payout completion. Never send money solely because an external callback says to.

  • marketplace.invoice.created
  • marketplace.allocations.available
  • marketplace.allocations.held
  • marketplace.payout.approved
  • marketplace.payout.broadcast
  • marketplace.payout.confirmed
  • marketplace.payout.partial
  • marketplace.payout.failed
  • marketplace.payout.cancelled
  • marketplace.refund.prepared
  • marketplace.refund.confirmed
{
  "event_id": "11111111-1111-4111-8111-111111111111",
  "event_type": "marketplace.payout.confirmed",
  "payload_version": 1,
  "project_id": "YOUR_PROJECT_ID",
  "occurred_at": "2026-10-06T12:00:00Z",
  "data": {
    "payout_id": "YOUR_PAYOUT_ID",
    "asset_id": "YOUR_ASSET_ID",
    "amount_atomic": "28800000",
    "transactions": [
      {
        "transaction_id": "EXAMPLE_TRANSACTION_ID",
        "explorer_url": "https://mempool.space/tx/EXAMPLE_TRANSACTION_ID"
      }
    ]
  }
}

Set up multi-vendor payments · Create a Marketplace invoice

Errors & limits

Handle validation, quotas and retries predictably.

Check HTTP status and Content-Type before parsing a response. For a 429, wait at least the Retry-After duration before retrying.

LimitDetails
Request ratePer-credential quota: default 120 requests per UTC minute, configurable from 1 to 6000 in Settings → API. All authenticated v1 reads and writes, including idempotent retries and authorization/validation failures after authentication, share the allowance across domains, projects and processes. Invalid credentials, console routes and public checkout do not consume it.
Rate-limit headersAuthenticated v1 responses include X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix seconds at the next UTC-minute boundary). Excess requests return JSON 429 rate_limit_exceeded and integer-second Retry-After. Wait at least that long and add retry jitter. Fixed windows permit bursts at minute boundaries; this is not a requests-per-second guarantee.
Merchant body32 KiB maximum at the application router. The edge may reject an oversized request before a JSON error envelope is produced.
Invoice listlimit defaults to 50 and accepts 1–100; offset accepts 0–1,000,000. Search is at most 100 characters. Results are newest first and include total/has_more metadata.
Store methodsAt most 64 asset selections per store, enough for all 30 native chains plus the bounded verified-token catalog. Project policy, scanner capability, and a ready backed-up chain wallet still gate invoice creation.
Token discoveryCandidate limit defaults to 50 and accepts 1–100. Discovery results are not payment assets until on-chain verification succeeds.
Registered project tokensAt most 20 durable token assets per project. Already-registered assets can be reused without consuming another slot.
IdempotencyRequired for invoice creation. 1–128 visible ASCII characters without spaces; keys are unique per store, and a replay must use the original credential and exact raw body.
MetadataJSON object only, maximum 4,096 encoded bytes and five levels of nesting.
CallbacksPublic HTTPS URL up to 2,048 bytes. Notification request bodies are capped at 256 KiB; retained invoice event payloads are capped at 64 KiB with bounded payment histories.
Checkout assetsQR SVG responses are private and no-store because an underpayment changes the exact remainder. Revisioned PNG logos cache publicly for one year and are immutable.
API edgeManaged API upstream requests have a 30-second read timeout. Design callers for explicit timeouts shorter than their job budget.
Non-JSON failuresMalformed UUID/query extraction, wrong methods, and the 32 KiB length guard can return framework text/empty responses. Unknown /v1 paths currently return 404 console HTML; validate status and Content-Type before parsing.

Error reference

HTTPError codeMeaning
400invalid_reconciliation_actionAn exception status, reason, search or history-page filter is invalid.
500reconciliation_unavailableThe exception queue or evidence could not be loaded. Retry the read with backoff.
402billing_requiredA verified paired credit account and live authorization are required for each new invoice. Insufficient prepaid credits do not block creation or incoming payments: IPN, webhooks and Sweep pause instead, while fees continue to accrue. Creation remains blocked for suspended accounts, expired/invalid billing verification, an unreachable credit service or an unauthorized invoice fiat basis. Fees use the original invoice fiat amount, not crypto received, spread, overpayment or network fees. That amount and independent conversion are registered before checkout creation. Existing monitoring and invoice retrieval continue during outages. After funding, queued notifications resume within their normal payload-retention period, and enabled sweep rules resume. Check Settings → Fees and retry failed creation with the same Idempotency-Key.
400invalid_jsonMalformed JSON, an unknown field, or a body that does not match the documented request.
400idempotency_key_requiredCreate invoice omitted Idempotency-Key.
400invalid_idempotency_keyKey is empty, over 128 bytes, non-ASCII, contains whitespace, or contains a control byte.
400invalid_payment_requestA validated field or selected active method failed. Read error.message and error.details.payment_methods (PaymentMethodIssue[]) for the exact blocker. SDK 2.4.0+ adds safe actionable exception summaries and issue helpers; older PHP SDKs expose getApiMessage().
400invalid_invoice_statusList status is outside the six documented invoice states.
400invalid_callback_urlThe effective IPN target failed HTTPS, public-address, DNS, or SSRF validation.
400invalid_wallet_requestA wallet/address preparation input is invalid.
400invalid_token_assetToken chain, candidate query, CoinGecko identity, catalog metadata, or contract/mint input is invalid.
401authentication_requiredBearer token is absent, malformed, disabled, rotated, or unknown.
403source_ip_deniedCredential IP restriction does not include the request's exact public source address.
403source_ip_not_allowedThe hostname's source IP restriction excludes this client. An administrator can manage live-host allowlists in Settings → System; these apply in addition to credential IP restrictions.
503source_access_unavailableHostname access verification is temporarily unavailable. Retry later; restrictions fail closed.
403 / 409 / 500merchant_api_access_deniedAuthorization failed: permission/project scope can be 403, disabled project/store can be 409, and an authorization backend failure can be 500. Operator receiving wallets are reserved for the Operator panel, not merchant API credentials or MCP, even with an older explicit project grant.
403project_access_deniedA transactional create-time recheck found that the credential no longer has access to the project.
404invoice_not_foundNo invoice with that public ID exists in the authorized project, or checkout cannot expose it.
404payment_resource_not_foundA project, store, asset, or wallet needed while preparing the invoice no longer exists.
404token_candidate_not_foundThe project is unavailable or the token is no longer present in the current matched discovery catalog.
409idempotency_conflictThe store-scoped key already exists and either the credential differs or the exact raw request bytes differ.
409store_unavailableProject/store is disabled or unavailable.
409no_ready_payment_methodsNo store method is ready. Read error.message and error.details.payment_methods for chain_slug, asset_ticker and reason_code. Wallet backup/activation, installed adapter and pricing must be valid. From 6.0.6, scanner cooldowns, failed or stale health checks and missing provider quorum do not block creation.
409payment_method_unavailableA selected method became unavailable during the atomic create-time recheck.
409store_payment_method_not_selectedA store confirmation override was requested for an asset that is not currently selected by that store.
409wallet_unavailableA payment wallet became unavailable during the atomic create-time recheck.
409ipn_secret_requiredAn effective IPN URL exists but the store has no IPN signing secret.
409payment_resource_not_readyA required payment asset or wallet is disabled, unbacked-up, awaiting shared-account activation proof, exhausted, or otherwise not ready.
409account_activation_unverifiedXRP Ledger or Stellar account activation could not be proven against the configured number of healthy mainnet endpoints (default 2, optional 1); fund the exact account and retry verification.
400invalid_monero_wallet_rpcThe HTTPS endpoint, exact mainnet primary address, label, or complete Digest/Basic/header authentication input is invalid.
404monero_wallet_rpc_not_foundThe project-scoped Monero wallet-RPC binding does not exist.
409monero_wallet_rpc_not_readyThe Monero asset, two-daemon quorum, immutable binding, or explicit backup/view-only attestation is not ready.
409monero_wallet_rpc_unavailableInvoice creation requires an active, verified, attested project Monero wallet-RPC binding with a valid server-side credential.
503lightning_unavailableThe store's only ready method is Lightning and its wallet or quote could not be verified. Retry with the same idempotency key. When another ready on-chain method exists, an unavailable Lightning method is omitted instead.
422monero_wallet_rpc_verification_failedThe exact wallet, HTTPS pinning, synchronization, mainnet daemon quorum, or gateway method-denial proof failed.
503monero_wallet_rpc_failedThe external watch-only wallet-RPC could not safely provision and re-read the invoice subaddress; no fallback address is fabricated.
409token_chain_not_readyThe native chain asset is disabled, the discovery mapping changed during verification, or the project already has the current maximum of 20 registered token assets.
503dex_price_unavailableDEX provider unavailable, busy, rate-limited, stale response or malformed data. Retry after one minute; fixed pricing remains available.
422invalid_dex_priceInvalid price-mode combination or selected pool cannot provide a qualifying price for the exact contract. Choose another pool or fixed USD pricing.
422token_verification_failedEvery eligible node failed chain identity, contract code, decimals, balance-query, or mint verification.
422invalid_store_confirmation_policyThe store override is unavailable for this finality mode, outside the returned chain-aware bounds, or requests unsupported zero-confirmation acceptance.
409invoice_not_payableThe checkout invoice is terminal or its payment deadline has passed.
409invoice_payment_method_lockedA valid payment already selected a different asset; continue with active_payment_method_id.
409payment_method_not_payableThe selected method is complete or no longer accepts another payment.
422payment_qr_unavailableThe checkout payment request is too large to encode as an SVG QR image.
503payment_rates_unavailableNo fresh trustworthy quote is available for any ready payment method.
500authentication_unavailableBearer authentication could not safely read or validate its stored credential.
429rate_limit_exceededThis credential exhausted its current UTC-minute allowance. Wait at least Retry-After seconds; retry invoice creation with the same idempotency key.
500database_error / internal_errorTransient server-side failure; retry safely with the same idempotency key.

API overview

Choose an endpoint for its fields, examples and response.

Invoices

POSTCreate invoice/v1/projects/{project_id}/stores/{store_id}/invoicesGETList invoices/v1/projects/{project_id}/invoicesGETRetrieve invoice/v1/projects/{project_id}/invoices/{invoice_id}GETList invoice payments/v1/projects/{project_id}/invoices/{invoice_id}/payments

Payment methods

GETList project payment assets/v1/projects/{project_id}/payment-assetsPUTUpdate project asset policy/v1/projects/{project_id}/payment-assets/{asset_id}GETBrowse payment-token candidates/v1/projects/{project_id}/payment-token-candidatesPOSTVerify and register token/v1/projects/{project_id}/payment-token-assetsGETFind custom token DEX pools/v1/projects/{project_id}/payment-token-dex-poolsPOSTAdd or reprice custom token/v1/projects/{project_id}/payment-token-assets/customGETList store payment methods/v1/projects/{project_id}/stores/{store_id}/payment-assetsPUTReplace store payment methods/v1/projects/{project_id}/stores/{store_id}/payment-assetsPUTSet a store confirmation policy/v1/projects/{project_id}/stores/{store_id}/payment-assets/{asset_id}/confirmation-policy

Wallets

GETList project wallets and balances/v1/projects/{project_id}/wallets

Reconciliation

GETList payment exceptions/v1/projects/{project_id}/reconciliationGETRead reconciliation evidence/v1/projects/{project_id}/reconciliation/{invoice_id}

Marketplace API

GETCapabilities/v1/marketplace/capabilitiesGETMarketplace report/v1/marketplace/overviewGETProject settings/v1/marketplace/settingsPOSTSave project settings/v1/marketplace/settingsGETList vendors/v1/marketplace/vendorsPOSTCreate vendor/v1/marketplace/vendorsGETGet vendor/v1/marketplace/vendors/{vendor_id}POSTUpdate vendor/v1/marketplace/vendors/{vendor_id}/updatePOSTArchive vendor/v1/marketplace/vendors/{vendor_id}/archiveGETVendor destinations/v1/marketplace/vendors/{vendor_id}/destinationsPOSTAdd payout destination/v1/marketplace/vendors/{vendor_id}/destinationsPOSTApprove destination/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/approvePOSTDisable destination/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/disableGETVendor balances/v1/marketplace/vendors/{vendor_id}/balancesGETMarketplace invoices/v1/marketplace/invoicesPOSTCreate multi-vendor invoice/v1/marketplace/invoicesGETInvoice and allocations/v1/marketplace/invoices/{invoice_id}GETInvoice payment evidence/v1/marketplace/invoices/{invoice_id}/paymentsGETInvoice allocations/v1/marketplace/invoices/{invoice_id}/allocationsPOSTCancel unpaid invoice/v1/marketplace/invoices/{invoice_id}/cancelPOSTHold allocations/v1/marketplace/invoices/{invoice_id}/allocations/holdPOSTReview and release allocations/v1/marketplace/invoices/{invoice_id}/allocations/releasePOSTRebind unpaid destination/v1/marketplace/invoices/{invoice_id}/allocations/{allocation_id}/destinationPOSTPrepare full refund/v1/marketplace/invoices/{invoice_id}/refundGETFind payout allocations/v1/marketplace/allocationsGETProject ledger balances/v1/marketplace/balancesGETImmutable journal/v1/marketplace/ledgerGETPayout history/v1/marketplace/payoutsPOSTPreview allocation plan/v1/marketplace/payouts/previewPOSTPrepare payout/v1/marketplace/payoutsGETPayout details/v1/marketplace/payouts/{payout_id}POSTApprove and send/v1/marketplace/payouts/{payout_id}/approvePOSTReview and resume payout/v1/marketplace/payouts/{payout_id}/resumePOSTCancel unsigned work/v1/marketplace/payouts/{payout_id}/cancelGETAutomatic payout policies/v1/marketplace/policiesPOSTAuthorize payout policy/v1/marketplace/policiesGETMarketplace webhooks/v1/marketplace/webhooksPOSTCreate Marketplace webhook/v1/marketplace/webhooksPOSTUpdate Marketplace webhook/v1/marketplace/webhooks/{webhook_id}/updatePOSTDisable Marketplace webhook/v1/marketplace/webhooks/{webhook_id}/disableGETMarketplace events/v1/marketplace/eventsGETRead retained event/v1/marketplace/events/{event_id}GETMarketplace delivery history/v1/marketplace/webhook-deliveriesGETDelivery details/v1/marketplace/webhook-deliveries/{delivery_id}POSTRedeliver same event/v1/marketplace/webhook-deliveries/{delivery_id}/resend

Operator API

GETCapabilities/v1/operator/capabilitiesGETHealth/v1/operator/healthGETList Merchants/v1/operator/merchantsPOSTCreate Merchant/v1/operator/merchantsGETGet Merchant/v1/operator/merchants/{merchant_id}POSTUpdate Merchant/v1/operator/merchants/{merchant_id}GETList Users/v1/operator/merchants/{merchant_id}/usersPOSTCreate User/v1/operator/merchants/{merchant_id}/usersGETGet User/v1/operator/merchants/{merchant_id}/users/{user_id}POSTUpdate User/v1/operator/merchants/{merchant_id}/users/{user_id}POSTSet User Password/v1/operator/merchants/{merchant_id}/users/{user_id}/passwordPOSTRevoke User Sessions/v1/operator/merchants/{merchant_id}/users/{user_id}/revoke-sessionsGETList Invitations/v1/operator/merchants/{merchant_id}/invitationsPOSTCreate Invitation/v1/operator/merchants/{merchant_id}/invitationsGETGet Invitation/v1/operator/invitations/{invitation_id}POSTResend Invitation/v1/operator/invitations/{invitation_id}/resendPOSTRevoke Invitation/v1/operator/invitations/{invitation_id}/revokeGETGet Credits/v1/operator/merchants/{merchant_id}/creditsGETList Credit Ledger/v1/operator/merchants/{merchant_id}/credits/ledgerPOSTAdjust Credits/v1/operator/merchants/{merchant_id}/credits/adjustmentsGETList Topups/v1/operator/merchants/{merchant_id}/topupsPOSTCreate Topup/v1/operator/merchants/{merchant_id}/topupsGETGet Topup/v1/operator/merchants/{merchant_id}/topups/{topup_id}GETReports/v1/operator/reportsGETList Audit/v1/operator/auditGETList Events/v1/operator/eventsGETList Webhooks/v1/operator/webhooksPOSTCreate Webhook/v1/operator/webhooksPOSTUpdate Webhook/v1/operator/webhooks/{webhook_id}POSTRotate Webhook Secret/v1/operator/webhooks/{webhook_id}/rotateGETList Webhook Deliveries/v1/operator/webhooks/{webhook_id}/deliveriesGETList Projects/v1/operator/merchants/{merchant_id}/projectsPOSTCreate Project/v1/operator/merchants/{merchant_id}/projectsGETGet Project/v1/operator/merchants/{merchant_id}/projects/{project_id}POSTUpdate Project/v1/operator/merchants/{merchant_id}/projects/{project_id}GETList Stores/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesPOSTCreate Store/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesGETGet Store/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}POSTUpdate Store/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}GETGet Store Appearance/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearancePOSTUpdate Store Appearance/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearanceGETList Store Payment Assets/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsPOSTUpdate Store Payment Assets/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsGETList Store Webhooks/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksPOSTCreate Store Webhook/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksPOSTUpdate Store Webhook/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooks/{webhook_id}GETList Invoices/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoicesGETGet Invoice/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoices/{invoice_id}GETList Wallets/v1/operator/merchants/{merchant_id}/projects/{project_id}/walletsGETList Wallet Addresses/v1/operator/merchants/{merchant_id}/projects/{project_id}/wallets/{wallet_id}/addressesGETList Merchant Credentials/v1/operator/merchants/{merchant_id}/api-credentialsPOSTCreate Merchant Credential/v1/operator/merchants/{merchant_id}/api-credentialsPOSTUpdate Merchant Credential/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}POSTRotate Merchant Credential/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/rotatePOSTRevoke Merchant Credential/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/revokePOSTCheck invitation token/v1/onboarding/invitations/checkPOSTAccept invitation or password reset/v1/onboarding/invitations/accept

Checkout

GETCheckout shell/GETHosted checkout page/invoice/{invoice_id}GETCheckout-safe invoice/checkout-api/invoices/{invoice_id}GETStore checkout preview/invoice/preview/{project_id}GETCheckout preview data/checkout-api/previews/{project_id}GETStore checkout image/checkout-api/invoices/{invoice_id}/appearance-images/{kind}/{revision}/image.pngGETStore preview image/checkout-api/previews/{project_id}/stores/{store_id}/appearance-images/{kind}/{revision}/image.pngGETRevisioned preview logo/checkout-api/previews/{project_id}/logo/{revision}/image.pngGETPayment QR image/checkout-api/invoices/{invoice_id}/payment-methods/{intent_id}/qr.svgGETRevisioned checkout logo/checkout-api/invoices/{invoice_id}/logo/{revision}/image.png

Service

GETAPI service discovery/GETService health/healthz
GETCapabilities/v1/operator/capabilitiesRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/capabilities" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "api_version": "v1",
  "operator_version": "7.4.0",
  "scopes": [
    "health.read"
  ],
  "all_merchants": false,
  "merchant_ids": [
    "11111111-1111-4111-8111-111111111111"
  ],
  "onboarding": [
    "direct",
    "invitation"
  ],
  "write_methods": [
    "POST"
  ],
  "idempotency_required": true
}

Response fields

api_versionstring
operator_versionstring
scopes[]array
all_merchantsboolean
merchant_ids[]array
onboarding[]array
write_methods[]array
idempotency_requiredboolean
Usage notes
  • Requires health.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETHealth/v1/operator/healthRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/health" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "version": "7.4.0",
  "nodes": []
}

Response fields

versionstring
nodes[]array
Usage notes
  • Requires health.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Merchants/v1/operator/merchantsRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires merchants.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTCreate Merchant/v1/operator/merchantsRead + write

Create a hosted merchant and first administrator atomically, directly with a password or by invitation.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Example shop",
  "email": "admin@example.test",
  "onboarding": "direct",
  "password": "REPLACE_WITH_A_UNIQUE_TEMPORARY_PASSWORD",
  "require_password_change": true,
  "currency": "EUR",
  "starting_credit": "0",
  "external_id": "customer-1042"
}'

Request body

namestringrequired

Merchant name and globally unique first-admin email.

emailstringrequired

Merchant name and globally unique first-admin email.

onboardingdirect | invitationrequired

direct requires password, sends no invitation email. invitation omits password.

passwordstring · direct only

12–128 characters (at most 512 UTF-8 bytes); never returned or emailed. Use require_password_change for temporary passwords.

require_password_changebooleanoptional

Requires a new password at first login. Every directly provisioned account must acknowledge hosted wallet custody.

currencyfiat codeoptional

Prepaid account currency; defaults to regional currency and cannot subsequently change.

fee_bpsintegeroptional

0–10000; 100 means 1%. Uses the operator default when omitted. Requires fees.write.

starting_creditdecimal stringoptional

Exact one-time local grant. Nonzero requires credits.write. Does not refill the operator's installation balance.

external_idstringoptional

Unique integration reference, 1–120 characters.

default_timezoneIANA timezoneoptional

Defaults to the installation's regional timezone.

send_invitation_emailbooleanoptional

Invitation only. Requires configured SMTP; response distinguishes relay acceptance from account creation.

Response 201 or 200 application/json

Example response
{
  "merchant_id": "11111111-1111-4111-8111-111111111111",
  "user_id": "22222222-2222-4222-8222-222222222222",
  "merchant": {
    "id": "11111111-1111-4111-8111-111111111111",
    "name": "Example shop",
    "currency": "EUR",
    "balance": "0"
  },
  "onboarding": "direct",
  "access_link": null,
  "email_delivery": {
    "status": "not_requested"
  },
  "custody_acceptance_required": true
}

Response fields

merchant_idstring
user_idstring
merchantobject
idstring
namestring
currencystring
balancestring
onboardingstring
email_deliveryobject
statusstring
custody_acceptance_requiredboolean
Usage notes
  • Requires merchants.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Global merchant access required. Explicit fee overrides also need fees.write; nonzero starting_credit needs credits.write. Invitation onboarding also needs invitations.write. No automatic login, no Basic Auth bypass, no retroactive credit on retry.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETGet Merchant/v1/operator/merchants/{merchant_id}Read only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "id": "11111111-1111-4111-8111-111111111111",
  "name": "Example shop",
  "currency": "EUR",
  "balance": "10",
  "fee_bps": 300,
  "enabled": true,
  "payments_paused": false,
  "external_id": "customer-1042"
}

Response fields

idstring
namestring
currencystring
balancestring
fee_bpsinteger
enabledboolean
payments_pausedboolean
external_idstring
Usage notes
  • Requires merchants.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTUpdate Merchant/v1/operator/merchants/{merchant_id}Read + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "payments_paused": true
}'

Request body

namefieldsoptional
Disabling revokes sessions. payments_paused blocks new invoices, not scanning existing payments. Fee edits require fees.write and affect future invoices; account currency cannot change.Details

Disabling revokes sessions. payments_paused blocks new invoices, not scanning existing payments. Fee edits require fees.write and affect future invoices; account currency cannot change.

enabledfieldsoptional
Disabling revokes sessions. payments_paused blocks new invoices, not scanning existing payments. Fee edits require fees.write and affect future invoices; account currency cannot change.Details

Disabling revokes sessions. payments_paused blocks new invoices, not scanning existing payments. Fee edits require fees.write and affect future invoices; account currency cannot change.

payments_pausedfieldsoptional
Disabling revokes sessions. payments_paused blocks new invoices, not scanning existing payments. Fee edits require fees.write and affect future invoices; account currency cannot change.Details

Disabling revokes sessions. payments_paused blocks new invoices, not scanning existing payments. Fee edits require fees.write and affect future invoices; account currency cannot change.

fee_bpsfieldsoptional
Disabling revokes sessions. payments_paused blocks new invoices, not scanning existing payments. Fee edits require fees.write and affect future invoices; account currency cannot change.Details

Disabling revokes sessions. payments_paused blocks new invoices, not scanning existing payments. Fee edits require fees.write and affect future invoices; account currency cannot change.

external_idfieldsoptional
Disabling revokes sessions. payments_paused blocks new invoices, not scanning existing payments. Fee edits require fees.write and affect future invoices; account currency cannot change.Details

Disabling revokes sessions. payments_paused blocks new invoices, not scanning existing payments. Fee edits require fees.write and affect future invoices; account currency cannot change.

Response 200 application/json

Example response
{
  "id": "11111111-1111-4111-8111-111111111111",
  "name": "Example shop",
  "currency": "EUR",
  "balance": "10",
  "fee_bps": 300,
  "enabled": true,
  "payments_paused": false
}

Response fields

idstring
namestring
currencystring
balancestring
fee_bpsinteger
enabledboolean
payments_pausedboolean
Usage notes
  • Requires merchants.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Users/v1/operator/merchants/{merchant_id}/usersRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires users.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTCreate User/v1/operator/merchants/{merchant_id}/usersRead + write

Add a merchant administrator or a user restricted to selected projects.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "email": "staff@example.test",
  "display_name": "Store team",
  "onboarding": "invitation",
  "access_level": "projects",
  "project_ids": [
    "11111111-1111-4111-8111-111111111111"
  ],
  "send_invitation_email": false
}'

Request body

emailstringsrequired

Email is installation-unique.

display_namestringsrequired

Email is installation-unique.

onboardingsame as merchant creation

Invitation creation additionally requires invitations.write.

passwordsame as merchant creation

Invitation creation additionally requires invitations.write.

require_password_changesame as merchant creation

Invitation creation additionally requires invitations.write.

send_invitation_emailsame as merchant creation

Invitation creation additionally requires invitations.write.

access_leveladmin | projectsoptional

admin is only this merchant's administrator, never the installation/operator administrator.

project_ids[]UUID[]

Only projects owned by the merchant. Required selections for project-restricted access; never cross-tenant.

default_timezoneIANA timezoneoptional

Regional default when omitted.

Response 201 or 200 application/json

Example response
{
  "user": {
    "id": "22222222-2222-4222-8222-222222222222",
    "merchant_id": "11111111-1111-4111-8111-111111111111",
    "email": "admin@example.test",
    "display_name": "Shop administrator",
    "access_level": "admin",
    "project_ids": [],
    "enabled": true,
    "password_setup_required": false,
    "custody_acceptance_required": true,
    "password_change_required": true
  },
  "user_id": "22222222-2222-4222-8222-222222222222",
  "access_link": null,
  "email_delivery": {
    "status": "not_requested"
  },
  "merchant_id": "11111111-1111-4111-8111-111111111111"
}

Response fields

userobject
idstring
merchant_idstring
emailstring
display_namestring
access_levelstring
project_ids[]array
enabledboolean
password_setup_requiredboolean
custody_acceptance_requiredboolean
password_change_requiredboolean
user_idstring
email_deliveryobject
statusstring
merchant_idstring
Usage notes
  • Requires users.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETGet User/v1/operator/merchants/{merchant_id}/users/{user_id}Read only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

user_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "id": "22222222-2222-4222-8222-222222222222",
  "merchant_id": "11111111-1111-4111-8111-111111111111",
  "email": "admin@example.test",
  "display_name": "Shop administrator",
  "access_level": "admin",
  "project_ids": [],
  "enabled": true,
  "password_setup_required": false,
  "custody_acceptance_required": true,
  "password_change_required": true
}

Response fields

idstring
merchant_idstring
emailstring
display_namestring
access_levelstring
project_ids[]array
enabledboolean
password_setup_requiredboolean
custody_acceptance_requiredboolean
password_change_requiredboolean
Usage notes
  • Requires users.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTUpdate User/v1/operator/merchants/{merchant_id}/users/{user_id}Read + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

user_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "display_name": "Store manager"
}'

Request body

emailfieldsoptional

Updates supplied fields; last-admin protection remains. Passwords have a separate users.security operation.

display_namefieldsoptional

Updates supplied fields; last-admin protection remains. Passwords have a separate users.security operation.

enabledfieldsoptional

Updates supplied fields; last-admin protection remains. Passwords have a separate users.security operation.

access_levelfieldsoptional

Updates supplied fields; last-admin protection remains. Passwords have a separate users.security operation.

project_idsfieldsoptional

Updates supplied fields; last-admin protection remains. Passwords have a separate users.security operation.

default_timezonefieldsoptional

Updates supplied fields; last-admin protection remains. Passwords have a separate users.security operation.

Response 200 application/json

Example response
{
  "id": "22222222-2222-4222-8222-222222222222",
  "merchant_id": "11111111-1111-4111-8111-111111111111",
  "email": "admin@example.test",
  "display_name": "Shop administrator",
  "access_level": "admin",
  "project_ids": [],
  "enabled": true,
  "password_setup_required": false,
  "custody_acceptance_required": true,
  "password_change_required": true
}

Response fields

idstring
merchant_idstring
emailstring
display_namestring
access_levelstring
project_ids[]array
enabledboolean
password_setup_requiredboolean
custody_acceptance_requiredboolean
password_change_requiredboolean
Usage notes
  • Requires users.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTSet User Password/v1/operator/merchants/{merchant_id}/users/{user_id}/passwordRead + write

Set a hosted account password and revoke sessions. Existing TOTP is retained.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

user_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID/password" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "password": "REPLACE_WITH_A_NEW_UNIQUE_PASSWORD",
  "require_password_change": true
}'

Request body

passwordstringrequired

Changes password and revokes sessions, preserving TOTP. Requires users.security.

require_password_changebooleanoptional

User must set their own password on the next successful login.

Response 200 application/json

Example response
{
  "user_id": "11111111-1111-4111-8111-111111111111",
  "sessions_revoked": true,
  "totp_preserved": true
}

Response fields

user_idstring
sessions_revokedboolean
totp_preservedboolean
Usage notes
  • Requires users.security; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTRevoke User Sessions/v1/operator/merchants/{merchant_id}/users/{user_id}/revoke-sessionsRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

user_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID/revoke-sessions" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{}'

Response 200 application/json

Example response
{
  "user_id": "11111111-1111-4111-8111-111111111111",
  "sessions_revoked": true,
  "totp_preserved": true
}

Response fields

user_idstring
sessions_revokedboolean
totp_preservedboolean
Usage notes
  • Requires users.security; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Invitations/v1/operator/merchants/{merchant_id}/invitationsRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/invitations" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires invitations.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTCreate Invitation/v1/operator/merchants/{merchant_id}/invitationsRead + write

Create or replace a one-time invitation or password-reset link.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/invitations" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "user_id": "11111111-1111-4111-8111-111111111111",
  "send_email": false
}'

Request body

user_idUUID, boolean

Issue/replace a one-time link for an existing account. Activated users receive a one-hour reset link and require users.security.

send_emailUUID, boolean

Issue/replace a one-time link for an existing account. Activated users receive a one-hour reset link and require users.security.

new user fieldsalternative to user_id

Use email, display_name, access_level and project_ids to create an invited user; requires users.write.

Response 201 or 200 application/json

Example response
{
  "user_id": "22222222-2222-4222-8222-222222222222",
  "email": "admin@example.test",
  "kind": "invitation",
  "expires_at": "2026-10-03T12:00:00Z",
  "url": "https://merchant.example.com/account-access.html#token=YOUR_PRIVATE_INVITATION_TOKEN"
}

Response fields

user_idstring
emailstring
kindstring
expires_atstring
urlstring
Usage notes
  • Requires invitations.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETGet Invitation/v1/operator/invitations/{invitation_id}Read only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

invitation_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "id": "44444444-4444-4444-8444-444444444444",
  "user_id": "22222222-2222-4222-8222-222222222222",
  "merchant_id": "11111111-1111-4111-8111-111111111111",
  "kind": "invitation",
  "status": "pending",
  "created_at": "2026-10-01T12:00:00Z",
  "expires_at": "2026-10-03T12:00:00Z"
}

Response fields

idstring
user_idstring
merchant_idstring
kindstring
statusstring
created_atstring
expires_atstring
Usage notes
  • Requires invitations.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTResend Invitation/v1/operator/invitations/{invitation_id}/resendRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

invitation_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID/resend" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "send_email": false
}'

Request body

send_emailbooleanoptional

Replaces the prior token, never adds credit. Returns a newly generated link once. An already activated account needs users.security.

Response 200 application/json

Example response
{
  "user_id": "22222222-2222-4222-8222-222222222222",
  "email": "admin@example.test",
  "kind": "invitation",
  "expires_at": "2026-10-03T12:00:00Z",
  "url": "https://merchant.example.com/account-access.html#token=YOUR_PRIVATE_INVITATION_TOKEN"
}

Response fields

user_idstring
emailstring
kindstring
expires_atstring
urlstring
Usage notes
  • Requires invitations.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTRevoke Invitation/v1/operator/invitations/{invitation_id}/revokeRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

invitation_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID/revoke" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{}'

Response 200 application/json

Example response
{
  "revoked": true,
  "invitation_id": "44444444-4444-4444-8444-444444444444"
}

Response fields

revokedboolean
invitation_idstring
Usage notes
  • Requires invitations.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETGet Credits/v1/operator/merchants/{merchant_id}/creditsRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "id": "11111111-1111-4111-8111-111111111111",
  "name": "Example shop",
  "currency": "EUR",
  "balance": "10",
  "fee_bps": 300,
  "enabled": true,
  "payments_paused": false,
  "external_id": "customer-1042"
}

Response fields

idstring
namestring
currencystring
balancestring
fee_bpsinteger
enabledboolean
payments_pausedboolean
external_idstring
Usage notes
  • Requires credits.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Credit Ledger/v1/operator/merchants/{merchant_id}/credits/ledgerRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

qoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits/ledger" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires credits.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTAdjust Credits/v1/operator/merchants/{merchant_id}/credits/adjustmentsRead + write

Append a reasoned grant or correction to this merchant's prepaid ledger.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits/adjustments" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "amount": "10.00",
  "note": "Promotional credit",
  "request_id": "11111111-1111-4111-8111-111111111111"
}'

Request body

amountsigned decimal stringrequired

Positive grant or negative correction, up to six decimals in merchant credit currency. Not an on-chain transfer.

notestringrequired

Reason retained in the append-only ledger.

request_idUUIDrequired

Persist with the amount and reason, in addition to the HTTP Idempotency-Key.

Response 200 application/json

Example response
{
  "balance": "25"
}

Response fields

balancestring
Usage notes
  • Requires credits.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Topups/v1/operator/merchants/{merchant_id}/topupsRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires topups.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTCreate Topup/v1/operator/merchants/{merchant_id}/topupsRead + write

Create a checkout for prepaid credit; never manually mark it as paid.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "amount": "25.00",
  "request_id": "11111111-1111-4111-8111-111111111111"
}'

Request body

amountdecimal stringrequired

At least one unit of merchant credit currency. Requires a ready Operator receiving store.

request_idUUIDrequired

Persist across retries. Returns the existing invoice if already created. Credit is applied only after observed settlement.

Response 201 or 200 application/json

Example response
{
  "id": "44444444-4444-4444-8444-444444444444",
  "invoice_id": "33333333-3333-4333-8333-333333333333",
  "checkout_url": "https://pay.example.com/invoice/33333333-3333-4333-8333-333333333333"
}

Response fields

idstring
invoice_idstring
checkout_urlstring
Usage notes
  • Requires topups.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETGet Topup/v1/operator/merchants/{merchant_id}/topups/{topup_id}Read only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

topup_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups/YOUR_TOPUP_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "id": "44444444-4444-4444-8444-444444444444",
  "merchant_id": "11111111-1111-4111-8111-111111111111",
  "invoice_id": "33333333-3333-4333-8333-333333333333",
  "amount": "25",
  "currency": "EUR",
  "status": "pending",
  "invoice_status": "new",
  "checkout_url": "https://pay.example.com/invoice/33333333-3333-4333-8333-333333333333"
}

Response fields

idstring
merchant_idstring
invoice_idstring
amountstring
currencystring
statusstring
invoice_statusstring
checkout_urlstring
Usage notes
  • Requires topups.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETReports/v1/operator/reportsRead only

Read the Operator financial overview. Requires access to all hosted merchants.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Query parameters

periodoptional

Finance filters. period defaults last30; use custom with YYYY-MM-DD start/end. All-merchant credentials only.

startoptional

Finance filters. period defaults last30; use custom with YYYY-MM-DD start/end. All-merchant credentials only.

endoptional

Finance filters. period defaults last30; use custom with YYYY-MM-DD start/end. All-merchant credentials only.

currencyoptional

Finance filters. period defaults last30; use custom with YYYY-MM-DD start/end. All-merchant credentials only.

merchant_idoptional

Finance filters. period defaults last30; use custom with YYYY-MM-DD start/end. All-merchant credentials only.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/reports" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "summary": {
    "fees": "10",
    "costs": "3",
    "margin": "7",
    "credits": "25",
    "pending": 0,
    "missing_rates": 0
  },
  "merchants": [],
  "filters": {
    "period": "last30",
    "currency": "EUR",
    "timezone": "UTC"
  },
  "basis": "first_settlement_latest_net_fees"
}

Response fields

summaryobject
feesstring
costsstring
marginstring
creditsstring
pendinginteger
missing_ratesinteger
merchants[]array
filtersobject
periodstring
currencystring
timezonestring
basisstring
Usage notes
  • Requires reports.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Own-business rows, costs and counts are excluded before totals are calculated. An own-business merchant_id filter returns 404. Reporting uses the installation timezone.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Audit/v1/operator/auditRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Query parameters

merchant_idoptional

Filter permitted merchant, exact event type (events) or action text (audit). Retained events: 30 days.

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/audit" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires audit.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Events/v1/operator/eventsRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Query parameters

merchant_idoptional

Filter permitted merchant, exact event type (events) or action text (audit). Retained events: 30 days.

event_typeoptional

Filter permitted merchant, exact event type (events) or action text (audit). Retained events: 30 days.

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/events" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires events.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Webhooks/v1/operator/webhooksRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/webhooks" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires events.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTCreate Webhook/v1/operator/webhooksRead + write

Subscribe to future Operator lifecycle events. Not a store payment webhook.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/webhooks" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "url": "https://shop.example.test/operator-events",
  "events": [
    "merchant.created",
    "topup.settled"
  ],
  "merchant_ids": [],
  "enabled": true
}'

Request body

urlpublic HTTPS URLrequired

No credentials, private IPs or redirects. DNS/IP checked again when delivering.

events[]string[]required

Choose lifecycle events in the Operator guide, not invoice callbacks.

merchant_ids[]UUID[]optional

Empty means all merchants permitted by this credential. Live scope restrictions are rechecked.

enabledbooleanoptional

Paused endpoints retain queued deliveries; re-enabling resumes valid retained work.

Response 201 or 200 application/json

Example response
{
  "id": "11111111-1111-4111-8111-111111111111",
  "signing_secret": "wco_whsec_EXAMPLE_ONLY_SAVE_ONCE"
}

Response fields

idstring
signing_secretstring
Usage notes
  • Requires webhooks.write + events.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTUpdate Webhook/v1/operator/webhooks/{webhook_id}Read + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

webhook_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "url": "https://shop.example.test/operator-events",
  "events": [
    "topup.settled"
  ],
  "merchant_ids": [],
  "enabled": false
}'

Request body

urlpublic HTTPS URLrequired

No credentials, private IPs or redirects. DNS/IP checked again when delivering.

events[]string[]required

Choose lifecycle events in the Operator guide, not invoice callbacks.

merchant_ids[]UUID[]optional

Empty means all merchants permitted by this credential. Live scope restrictions are rechecked.

enabledbooleanoptional

Paused endpoints retain queued deliveries; re-enabling resumes valid retained work.

Response 200 application/json

Example response
{
  "id": "44444444-4444-4444-8444-444444444444",
  "signing_secret": null
}

Response fields

idstring
signing_secretJSON | null
Usage notes
  • Requires webhooks.write + events.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTRotate Webhook Secret/v1/operator/webhooks/{webhook_id}/rotateRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

webhook_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID/rotate" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{}'

Response 200 application/json

Example response
{
  "id": "11111111-1111-4111-8111-111111111111",
  "signing_secret": "wco_whsec_EXAMPLE_ONLY_SAVE_ONCE"
}

Response fields

idstring
signing_secretstring
Usage notes
  • Requires webhooks.write + events.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Webhook Deliveries/v1/operator/webhooks/{webhook_id}/deliveriesRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

webhook_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID/deliveries" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires events.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Projects/v1/operator/merchants/{merchant_id}/projectsRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires projects.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTCreate Project/v1/operator/merchants/{merchant_id}/projectsRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Online shop",
  "slug": "online-shop",
  "enabled": false
}'

Request body

namestringsrequired

Name and unique stable project identifier. Creates local wallets using the existing project bootstrap, never transfers funds.

slugstringsrequired

Name and unique stable project identifier. Creates local wallets using the existing project bootstrap, never transfers funds.

enabledoptional

enabled defaults true; creating paused and configuring a store first is recommended.

reporting_timezoneoptional

enabled defaults true; creating paused and configuring a store first is recommended.

checkout_titleoptional

enabled defaults true; creating paused and configuring a store first is recommended.

checkout_descriptionoptional

enabled defaults true; creating paused and configuring a store first is recommended.

checkout_themeoptional

enabled defaults true; creating paused and configuring a store first is recommended.

checkout_accent_coloroptional

enabled defaults true; creating paused and configuring a store first is recommended.

Response 201 or 200 application/json

Example response
{
  "id": "33333333-3333-4333-8333-333333333333",
  "slug": "example-shop",
  "name": "Example shop",
  "enabled": false,
  "reporting_currency": "EUR",
  "reporting_timezone": "Europe/Berlin",
  "stores": []
}

Response fields

idstring
slugstring
namestring
enabledboolean
reporting_currencystring
reporting_timezonestring
stores[]array
Usage notes
  • Requires projects.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETGet Project/v1/operator/merchants/{merchant_id}/projects/{project_id}Read only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "id": "33333333-3333-4333-8333-333333333333",
  "slug": "example-shop",
  "name": "Example shop",
  "enabled": false,
  "reporting_currency": "EUR",
  "reporting_timezone": "Europe/Berlin",
  "stores": []
}

Response fields

idstring
slugstring
namestring
enabledboolean
reporting_currencystring
reporting_timezonestring
stores[]array
Usage notes
  • Requires projects.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTUpdate Project/v1/operator/merchants/{merchant_id}/projects/{project_id}Read + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "enabled": true
}'

Request body

nameoptional

Partial update. Identifier and merchant ownership cannot change.

enabledoptional

Partial update. Identifier and merchant ownership cannot change.

reporting_currencyoptional

Partial update. Identifier and merchant ownership cannot change.

reporting_timezoneoptional

Partial update. Identifier and merchant ownership cannot change.

checkout_titleoptional

Partial update. Identifier and merchant ownership cannot change.

checkout_descriptionoptional

Partial update. Identifier and merchant ownership cannot change.

checkout_themeoptional

Partial update. Identifier and merchant ownership cannot change.

checkout_accent_coloroptional

Partial update. Identifier and merchant ownership cannot change.

Response 200 application/json

Example response
{
  "id": "33333333-3333-4333-8333-333333333333",
  "slug": "example-shop",
  "name": "Example shop",
  "enabled": false,
  "reporting_currency": "EUR",
  "reporting_timezone": "Europe/Berlin",
  "stores": []
}

Response fields

idstring
slugstring
namestring
enabledboolean
reporting_currencystring
reporting_timezonestring
stores[]array
Usage notes
  • Requires projects.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Stores/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires projects.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTCreate Store/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Web checkout",
  "slug": "web-checkout",
  "default_currency": "EUR",
  "enabled": false
}'

Request body

namestringsrequired

Store name and stable identifier.

slugstringsrequired

Store name and stable identifier.

default_currencyoptional

Use decimal strings for percentages. New stores inherit the project's default-store appearance.

invoice_expiry_minutesoptional

Use decimal strings for percentages. New stores inherit the project's default-store appearance.

exchange_rate_spread_percentoptional

Use decimal strings for percentages. New stores inherit the project's default-store appearance.

underpayment_tolerance_percentoptional

Use decimal strings for percentages. New stores inherit the project's default-store appearance.

enabledoptional

Configure accepted assets with payment-assets; zero-amount invoices default off.

is_defaultoptional

Configure accepted assets with payment-assets; zero-amount invoices default off.

allow_zero_amount_invoicesoptional

Configure accepted assets with payment-assets; zero-amount invoices default off.

allow_underpaymentsoptional

Configure accepted assets with payment-assets; zero-amount invoices default off.

allow_overpaymentsoptional

Configure accepted assets with payment-assets; zero-amount invoices default off.

allowed_chain_slugsoptional

Configure accepted assets with payment-assets; zero-amount invoices default off.

ipn_enabledoptional

IPN and return URLs follow existing URL validation. No arbitrary HTML/JavaScript.

default_ipn_urloptional

IPN and return URLs follow existing URL validation. No arbitrary HTML/JavaScript.

default_redirect_urloptional

IPN and return URLs follow existing URL validation. No arbitrary HTML/JavaScript.

default_cancel_urloptional

IPN and return URLs follow existing URL validation. No arbitrary HTML/JavaScript.

redirect_automaticallyoptional

IPN and return URLs follow existing URL validation. No arbitrary HTML/JavaScript.

checkout_languageoptional

Use supported language and active role domains; configure embedding origins explicitly.

embed_enabledoptional

Use supported language and active role domains; configure embedding origins explicitly.

allowed_embed_originsoptional

Use supported language and active role domains; configure embedding origins explicitly.

domainsoptional

Use supported language and active role domains; configure embedding origins explicitly.

Response 201 or 200 application/json

Example response
{
  "id": "44444444-4444-4444-8444-444444444444",
  "project_id": "33333333-3333-4333-8333-333333333333",
  "slug": "online",
  "name": "Online shop",
  "enabled": false,
  "default_currency": "EUR",
  "invoice_expiry_minutes": 60
}

Response fields

idstring
project_idstring
slugstring
namestring
enabledboolean
default_currencystring
invoice_expiry_minutesinteger
Usage notes
  • Requires projects.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETGet Store/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}Read only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

store_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "id": "44444444-4444-4444-8444-444444444444",
  "project_id": "33333333-3333-4333-8333-333333333333",
  "slug": "online",
  "name": "Online shop",
  "enabled": false,
  "default_currency": "EUR",
  "invoice_expiry_minutes": 60
}

Response fields

idstring
project_idstring
slugstring
namestring
enabledboolean
default_currencystring
invoice_expiry_minutesinteger
Usage notes
  • Requires projects.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTUpdate Store/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}Read + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

store_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "enabled": true
}'

Request body

store fieldsoptional

Same mutable settings as store creation, except slug. Only supplied fields change.

enabledboolean

Response 200 application/json

Example response
{
  "id": "44444444-4444-4444-8444-444444444444",
  "project_id": "33333333-3333-4333-8333-333333333333",
  "slug": "online",
  "name": "Online shop",
  "enabled": false,
  "default_currency": "EUR",
  "invoice_expiry_minutes": 60
}

Response fields

idstring
project_idstring
slugstring
namestring
enabledboolean
default_currencystring
invoice_expiry_minutesinteger
Usage notes
  • Requires projects.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETGet Store Appearance/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearanceRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

store_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/checkout-appearance" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "revision": 1,
  "settings": {
    "inherit_default_store": true
  },
  "effective": {
    "title": "Pay securely"
  }
}

Response fields

revisioninteger
settingsobject
inherit_default_storeboolean
effectiveobject
titlestring
Usage notes
  • Requires projects.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTUpdate Store Appearance/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearanceRead + write

Save a validated, revision-protected store design.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

store_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/checkout-appearance" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "revision": 1,
  "settings": {
    "inherit_default_store": false,
    "title": "Pay securely",
    "theme": "light"
  }
}'

Request body

revisionintegerrequired

Read the current revision with GET first. A stale revision fails without overwriting another editor.

settingsobjectrequired
Validated checkout appearance, including inherit_default_store, branding, intro/outro, font sizes and visibility. No arbitrary HTML/JavaScript. Uploading image bytes is console-only.Details

Validated checkout appearance, including inherit_default_store, branding, intro/outro, font sizes and visibility. No arbitrary HTML/JavaScript. Uploading image bytes is console-only.

inherit_default_storeboolean
titlestring
themestring

Response 200 application/json

Example response
{
  "settings": {
    "inherit_default_store": false,
    "title": "Pay securely",
    "theme": "light"
  },
  "revision": 2
}

Response fields

settingsobject
inherit_default_storeboolean
titlestring
themestring
revisioninteger
Usage notes
  • Requires projects.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Store Payment Assets/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

store_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": []
}

Response fields

data[]array
Usage notes
  • Requires projects.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTUpdate Store Payment Assets/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

store_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "assets": [
    {
      "asset_id": "11111111-1111-4111-8111-111111111111",
      "display_order": 0
    }
  ]
}'

Request body

assets[]object[]required
Full replacement of on-chain methods: asset_id UUID and display_order. [] clears accepted on-chain assets. Only verified project assets; does not configure Lightning.Details

Full replacement of on-chain methods: asset_id UUID and display_order. [] clears accepted on-chain assets. Only verified project assets; does not configure Lightning.

asset_idstring
display_orderinteger

Response 200 application/json

Example response
{
  "data": []
}

Response fields

data[]array
Usage notes
  • Requires projects.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Store Webhooks/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

store_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires projects.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTCreate Store Webhook/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

store_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Orders",
  "url": "https://shop.example.test/payments",
  "event_types": [
    "invoice.settled"
  ],
  "enabled": true,
  "automatic_redelivery": true
}'

Request body

namestrings / arrayrequired

Public HTTPS receiver and invoice event names from IPN & webhook documentation.

urlstrings / arrayrequired

Public HTTPS receiver and invoice event names from IPN & webhook documentation.

event_types[]strings / arrayrequired

Public HTTPS receiver and invoice event names from IPN & webhook documentation.

enabledbooleansoptional

Creation returns the signing secret once. These are store payment callbacks, not Operator lifecycle events.

automatic_redeliverybooleansoptional

Creation returns the signing secret once. These are store payment callbacks, not Operator lifecycle events.

Response 201 or 200 application/json

Example response
{
  "signing_secret": "EXAMPLE_ONLY_SAVE_ONCE",
  "endpoint": {
    "id": "44444444-4444-4444-8444-444444444444",
    "name": "Orders",
    "enabled": true
  },
  "secret_visible_once": true
}

Response fields

signing_secretstring
endpointobject
idstring
namestring
enabledboolean
secret_visible_onceboolean
Usage notes
  • Requires projects.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTUpdate Store Webhook/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooks/{webhook_id}Read + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

store_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

webhook_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks/YOUR_WEBHOOK_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Orders",
  "url": "https://shop.example.test/payments",
  "event_types": [
    "invoice.settled"
  ],
  "enabled": false,
  "automatic_redelivery": true
}'

Request body

namestrings / arrayrequired

Public HTTPS receiver and invoice event names from IPN & webhook documentation.

urlstrings / arrayrequired

Public HTTPS receiver and invoice event names from IPN & webhook documentation.

event_types[]strings / arrayrequired

Public HTTPS receiver and invoice event names from IPN & webhook documentation.

enabledbooleansoptional

Creation returns the signing secret once. These are store payment callbacks, not Operator lifecycle events.

automatic_redeliverybooleansoptional

Creation returns the signing secret once. These are store payment callbacks, not Operator lifecycle events.

Response 200 application/json

Example response
{
  "id": "44444444-4444-4444-8444-444444444444",
  "name": "Orders",
  "enabled": true
}

Response fields

idstring
namestring
enabledboolean
Usage notes
  • Requires projects.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Invoices/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoicesRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

limitoptional

Invoice pagination and filters, same as the project invoice list.

offsetoptional

Invoice pagination and filters, same as the project invoice list.

statusoptional

Invoice pagination and filters, same as the project invoice list.

store_idoptional

Invoice pagination and filters, same as the project invoice list.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/invoices" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 0,
    "has_more": false
  }
}

Response fields

data[]array
paginationobject
limitinteger
offsetinteger
totalinteger
has_moreboolean
Usage notes
  • Requires reports.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETGet Invoice/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoices/{invoice_id}Read only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

invoice_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/invoices/YOUR_INVOICE_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "invoice_id": "44444444-4444-4444-8444-444444444444",
  "project_id": "33333333-3333-4333-8333-333333333333",
  "amount": "25",
  "currency": "EUR",
  "status": "new",
  "metadata": {},
  "payment_intents": []
}

Response fields

invoice_idstring
project_idstring
amountstring
currencystring
statusstring
metadataobject
payment_intents[]array
Usage notes
  • Requires reports.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.
  • invoice_id is the public invoice ID returned at creation and in callbacks, not the internal id.

Errors

Error codes & retry rules

GETList Wallets/v1/operator/merchants/{merchant_id}/projects/{project_id}/walletsRead only

Read cached public wallet balances, never private keys or recovery phrases.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/wallets" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires reports.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Balances are cached observations with freshness fields, not a spendable-balance guarantee. Sending and key export are not available through this API.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Wallet Addresses/v1/operator/merchants/{merchant_id}/projects/{project_id}/wallets/{wallet_id}/addressesRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

project_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

wallet_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

limitoptional
Limit1–50, default25. Pass next_cursor as before for the next page. Omit before for page1. has_balance=false and hide_small_balances=false include empty/small balances.Details

Limit1–50, default25. Pass next_cursor as before for the next page. Omit before for page1. has_balance=false and hide_small_balances=false include empty/small balances.

beforeoptional
Limit1–50, default25. Pass next_cursor as before for the next page. Omit before for page1. has_balance=false and hide_small_balances=false include empty/small balances.Details

Limit1–50, default25. Pass next_cursor as before for the next page. Omit before for page1. has_balance=false and hide_small_balances=false include empty/small balances.

has_balanceoptional
Limit1–50, default25. Pass next_cursor as before for the next page. Omit before for page1. has_balance=false and hide_small_balances=false include empty/small balances.Details

Limit1–50, default25. Pass next_cursor as before for the next page. Omit before for page1. has_balance=false and hide_small_balances=false include empty/small balances.

hide_small_balancesoptional
Limit1–50, default25. Pass next_cursor as before for the next page. Omit before for page1. has_balance=false and hide_small_balances=false include empty/small balances.Details

Limit1–50, default25. Pass next_cursor as before for the next page. Omit before for page1. has_balance=false and hide_small_balances=false include empty/small balances.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/wallets/YOUR_WALLET_ID/addresses" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "wallet": {
    "id": "22222222-2222-4222-8222-222222222222",
    "chain_slug": "ethereum"
  },
  "items": [],
  "total": 0,
  "total_pages": 1,
  "next_cursor": null,
  "reporting_currency": "EUR",
  "has_balance": true,
  "hide_small_balances": true,
  "small_balance_threshold": {
    "amount": "0.20",
    "currency": "EUR"
  }
}

Response fields

walletobject
idstring
chain_slugstring
items[]array
totalinteger
total_pagesinteger
next_cursorJSON | null
reporting_currencystring
has_balanceboolean
hide_small_balancesboolean
small_balance_thresholdobject
amountstring
currencystring
Usage notes
  • Requires reports.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETList Merchant Credentials/v1/operator/merchants/{merchant_id}/api-credentialsRead only

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Query parameters

pageoptional
1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.Details

1-based page, 25 items per page. Search is supported on merchants, users, projects, stores, wallets, credentials and webhooks; native event lists use their specific filters.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "page": 1,
  "page_size": 25,
  "total": 0
}

Response fields

data[]array
pageinteger
page_sizeinteger
totalinteger
Usage notes
  • Requires merchant_credentials.read; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTCreate Merchant Credential/v1/operator/merchants/{merchant_id}/api-credentialsRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Store integration",
  "access_level": "read_only",
  "enabled": true,
  "ip_restriction_enabled": false,
  "allowed_ips": [],
  "project_ids": [
    "11111111-1111-4111-8111-111111111111"
  ]
}'

Request body

namestringrequired

Label for a new ordinary merchant key, not an Operator key.

access_levelread_only | read_writeoptional

Read/write enables the existing merchant API contract.

project_ids[]UUID[]

Projects owned by the selected merchant only; an empty list follows the existing all-merchant-projects policy.

enabledoptional

Existing merchant key controls. Secret returned only once; requires merchant_credentials.write.

ip_restriction_enabledoptional

Existing merchant key controls. Secret returned only once; requires merchant_credentials.write.

allowed_ips[]optional

Existing merchant key controls. Secret returned only once; requires merchant_credentials.write.

requests_per_minuteoptional

Existing merchant key controls. Secret returned only once; requires merchant_credentials.write.

Response 201 or 200 application/json

Example response
{
  "credential": {
    "id": "22222222-2222-4222-8222-222222222222",
    "name": "Checkout",
    "access_level": "read_only",
    "project_ids": [
      "33333333-3333-4333-8333-333333333333"
    ],
    "enabled": true
  },
  "token": "wc_live_EXAMPLE_ONLY_SAVE_ONCE"
}

Response fields

credentialobject
idstring
namestring
access_levelstring
project_ids[]array
enabledboolean
tokenstring
Usage notes
  • Requires merchant_credentials.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTUpdate Merchant Credential/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}Read + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

credential_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "Checkout",
  "access_level": "read_only",
  "enabled": true,
  "ip_restriction_enabled": false,
  "allowed_ips": [],
  "project_ids": [
    "33333333-3333-4333-8333-333333333333"
  ]
}'

Request body

namefieldsrequired

Send the complete current credential configuration with changes. project_ids defaults []; requests_per_minute defaults to the merchant API quota.

access_levelfieldsrequired

Send the complete current credential configuration with changes. project_ids defaults []; requests_per_minute defaults to the merchant API quota.

enabledfieldsrequired

Send the complete current credential configuration with changes. project_ids defaults []; requests_per_minute defaults to the merchant API quota.

ip_restriction_enabledfieldsrequired

Send the complete current credential configuration with changes. project_ids defaults []; requests_per_minute defaults to the merchant API quota.

allowed_ips[]fieldsrequired

Send the complete current credential configuration with changes. project_ids defaults []; requests_per_minute defaults to the merchant API quota.

project_ids[]array

Response 200 application/json

Example response
{
  "id": "22222222-2222-4222-8222-222222222222",
  "name": "Checkout",
  "access_level": "read_only",
  "project_ids": [
    "33333333-3333-4333-8333-333333333333"
  ],
  "enabled": true
}

Response fields

idstring
namestring
access_levelstring
project_ids[]array
enabledboolean
Usage notes
  • Requires merchant_credentials.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTRotate Merchant Credential/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/rotateRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

credential_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID/rotate" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{}'

Response 200 application/json

Example response
{
  "credential": {
    "id": "22222222-2222-4222-8222-222222222222",
    "name": "Checkout",
    "access_level": "read_only",
    "project_ids": [
      "33333333-3333-4333-8333-333333333333"
    ],
    "enabled": true
  },
  "token": "wc_live_EXAMPLE_ONLY_SAVE_ONCE"
}

Response fields

credentialobject
idstring
namestring
access_levelstring
project_ids[]array
enabledboolean
tokenstring
Usage notes
  • Requires merchant_credentials.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTRevoke Merchant Credential/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/revokeRead + write

Manage or inspect the named hosted merchant resource using a separate Operator credential.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_OPERATOR_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persisted for this operation

Path parameters

merchant_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

credential_idUUIDrequired

Canonical lowercase resource UUID; must belong to the credential's merchant scope.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID/revoke" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: operator-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{}'

Response 200 application/json

Example response
{
  "revoked": true
}

Response fields

revokedboolean
Usage notes
  • Requires merchant_credentials.write; only permitted hosted merchants. Operator keys do not access the owner's own-business workspace.
  • Persist a unique Idempotency-Key and the exact body before sending. Retries never repeat a committed action. Secret fields are omitted on replay; if a secret response was lost, inspect the created resource and explicitly rotate/reissue it. A 409 operator_request_in_progress can mean an interrupted request with unknown outcome: inspect the resource/audit; do not retry with a new key blindly.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTCheck invitation token/v1/onboarding/invitations/checkPublic

Token-only onboarding. Does not accept an Operator key or automatically sign in. Console login still requires the site's Basic Auth and existing TOTP.

Authentication & headers

Public

Request

curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/onboarding/invitations/check" \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "token": "YOUR_PRIVATE_INVITATION_TOKEN"
}'

Request body

tokenstringrequired

Secret from the invitation URL fragment. Never log it.

Response 200 application/json

Example response
{
  "kind": "invitation",
  "email": "admin@example.test",
  "merchant_name": "Example shop"
}

Response fields

kindstring
emailstring
merchant_namestring
Usage notes
  • 48-hour invitation; one-hour password-reset link. Single-use hashed tokens. Reissuing revokes the earlier link. Acceptance preserves TOTP and revokes old sessions.
  • No automatic retries. If acceptance times out, check the link status and try signing in; do not assume it failed. Rate limited by observed source IP. The recipient must give their own custody acknowledgement.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

POSTAccept invitation or password reset/v1/onboarding/invitations/acceptPublic

Token-only onboarding. Does not accept an Operator key or automatically sign in. Console login still requires the site's Basic Auth and existing TOTP.

Authentication & headers

Public

Request

curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/onboarding/invitations/accept" \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "token": "YOUR_PRIVATE_INVITATION_TOKEN",
  "password": "REPLACE_WITH_YOUR_OWN_UNIQUE_PASSWORD",
  "custody_acknowledged": true
}'

Request body

tokenstringrequired

Secret from the invitation URL fragment. Never log it.

passwordstringrequired

New password, 12–128 characters (at most 512 UTF-8 bytes).

custody_acknowledgedboolean

Must be true when accepting a new hosted-wallet invitation.

Response 200 application/json

Example response
{
  "password_set": true
}

Response fields

password_setboolean
Usage notes
  • 48-hour invitation; one-hour password-reset link. Single-use hashed tokens. Reissuing revokes the earlier link. Acceptance preserves TOTP and revokes old sessions.
  • No automatic retries. If acceptance times out, check the link status and try signing in; do not assume it failed. Rate limited by observed source IP. The recipient must give their own custody acknowledgement.
  • Response examples show selected fields. Treat additional response fields as additive.

Errors

Error codes & retry rules

GETCapabilities/v1/marketplace/capabilitiesRead only

Participating stores, configured assets, supported payout rails, native fee asset and readiness reasons. Temporary scanner availability does not widen the allowed asset set.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/capabilities?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETMarketplace report/v1/marketplace/overviewRead only

Filter store_id, asset_id, from and to (inclusive YYYY-MM-DD, UTC; default last 30 days; up to ten years). Exact account balances as of the end date and changes in the period. No estimated fiat earnings. A store filter excludes project-wide fees without an invoice.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/overview?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETProject settings/v1/marketplace/settingsRead only

Returns enabled, payouts_paused, commission_percent, revision and participating stores.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/settings?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTSave project settings/v1/marketplace/settingsRead + write

Replace the participating-store selection. revision 0 initializes settings; later edits require the returned revision. Commission is a decimal percentage, 0–100 with at most two decimal places.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopepolicies.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/settings" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 0,
  "enabled": true,
  "payouts_paused": true,
  "commission_percent": "4",
  "stores": [
    {
      "store_id": "YOUR_STORE_ID",
      "enabled": true,
      "commission_percent": null
    }
  ]
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

0

enabled

true

payouts_paused

true

commission_percent

"4"

stores[]object[]

[{"store_id":"YOUR_STORE_ID","enabled":true,"commission_percent":null}]

store_idstring
enabledboolean
commission_percentJSON | null

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires policies.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETList vendors/v1/marketplace/vendorsRead only

Paged vendors. Search q by name, external ID or email; status active, suspended or archived.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/vendors?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 0,
    "pages": 1
  }
}

Response fields

data[]array
paginationobject
pageinteger
per_pageinteger
totalinteger
pagesinteger
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTCreate vendor/v1/marketplace/vendorsRead + write

Name required (160 characters); external_id optional and project-unique (128); email optional (254); description up to 2000. commission_percent null inherits the store. A non-null override also requires commissions.override. Vendors are not hosted merchant accounts.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopevendors.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/vendors" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "name": "Example vendor",
  "external_id": "vendor-1042",
  "email": "vendor@example.com",
  "description": "",
  "status": "active",
  "commission_percent": null
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

name

"Example vendor"

external_id

"vendor-1042"

email

"vendor@example.com"

description

""

status

"active"

commission_percent

null

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires vendors.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETGet vendor/v1/marketplace/vendors/{vendor_id}Read only

Return one vendor, revision and commission override.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTUpdate vendor/v1/marketplace/vendors/{vendor_id}/updateRead + write

Update vendor details; status active or suspended. Changing or removing commission_percent also requires commissions.override; unchanged values need only vendors.write. Restoring an archived vendor also requires reconciliation.write. Console financial edits require account reauthentication. Existing allocations retain their original commission and destinations.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopevendors.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/update" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "name": "Example vendor",
  "external_id": "vendor-1042",
  "email": "vendor@example.com",
  "description": "",
  "status": "active",
  "commission_percent": null,
  "revision": 1
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

name

"Example vendor"

external_id

"vendor-1042"

email

"vendor@example.com"

description

""

status

"active"

commission_percent

null

revision

1

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires vendors.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTArchive vendor/v1/marketplace/vendors/{vendor_id}/archiveRead + write

Archive only after unpaid and open invoice obligations are resolved; otherwise returns 409 vendor_has_obligations. History is retained. Temporarily use suspended status, or restore an old archived vendor with the update route and reconciliation.write.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopevendors.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/archive" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires vendors.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETVendor destinations/v1/marketplace/vendors/{vendor_id}/destinationsRead only

Versioned destinations and pending/approved/disabled states. Approval does not prove ownership.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 0,
    "pages": 1
  }
}

Response fields

data[]array
paginationobject
pageinteger
per_pageinteger
totalinteger
pagesinteger
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTAdd payout destination/v1/marketplace/vendors/{vendor_id}/destinationsRead + write

Register a valid mainnet BTC or supported EVM address, pending approval. Project-owned addresses, wrong network and zero EVM addresses are rejected.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopedestinations.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "chain_slug": "bitcoin",
  "network": "mainnet",
  "address": "VERIFIED_VENDOR_BTC_ADDRESS",
  "label": "Vendor BTC"
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

chain_slug

"bitcoin"

network

"mainnet"

address

"VERIFIED_VENDOR_BTC_ADDRESS"

label

"Vendor BTC"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires destinations.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTApprove destination/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/approveRead + write

Verify ownership independently first. Disable an existing approved destination on this vendor/network first; old snapshots are not redirected.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopedestinations.approve

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations/YOUR_DESTINATION_ID/approve" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires destinations.approve. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTDisable destination/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/disableRead + write

Stop new/unsent work using this version. A signed transaction cannot be revoked.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopedestinations.approve

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations/YOUR_DESTINATION_ID/disable" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires destinations.approve. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETVendor balances/v1/marketplace/vendors/{vendor_id}/balancesRead only

Exact retained ledger amounts grouped by immutable asset identity and account type; not live spendable wallet balances.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/balances?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETMarketplace invoices/v1/marketplace/invoicesRead only

Paged invoices; q searches order, email, description, metadata and invoice UUID. Filter store_id, vendor_id and Marketplace status. Ordinary invoices are excluded.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/invoices?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 0,
    "pages": 1
  }
}

Response fields

data[]array
paginationobject
pageinteger
per_pageinteger
totalinteger
pagesinteger
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTCreate multi-vendor invoice/v1/marketplace/invoicesRead + write

Reuse normal InvoiceCreateInput fields, plus store_id and allocations. Each vendor occurs once, 1–100 positive shares, sum exactly equal to amount. Optional invoice/per-allocation commission_percent requires commissions.override and console reauthentication for session requests. Returns data.invoice_id and links.checkout. No compatible common method returns a detailed error; no fallback to an incompatible asset.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopeinvoices.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/invoices" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "store_id": "YOUR_STORE_ID",
  "amount": "300.00",
  "currency": "USD",
  "order_id": "cart-1042",
  "allocations": [
    {
      "vendor_id": "VENDOR_A_UUID",
      "gross_amount": "100.00"
    },
    {
      "vendor_id": "VENDOR_B_UUID",
      "gross_amount": "100.00"
    },
    {
      "vendor_id": "VENDOR_C_UUID",
      "gross_amount": "100.00"
    }
  ]
}'

Request body

amountstringrequired
Unsigned plain decimal string; no sign or exponent, up to 48 integer digits and 30 decimal places. Must be positive by default. A store can allow zero-amount invoices in Stores → Invoice; zero totals settle without receiving funds, allocating addresses or processing fees.Details

Unsigned plain decimal string; no sign or exponent, up to 48 integer digits and 30 decimal places. Must be positive by default. A store can allow zero-amount invoices in Stores → Invoice; zero totals settle without receiving funds, allocating addresses or processing fees.

currencystring | nulloptional
Supported three-letter fiat currency, normalized to uppercase. Omitted or null inherits the store invoice currency. Creation also requires an independently available billing conversion rate.Details

Supported three-letter fiat currency, normalized to uppercase. Omitted or null inherits the store invoice currency. Creation also requires an independently available billing conversion rate.

payment_methods[]object[] | nulloptional
Select store-enabled methods for this invoice. Merchant 5.4.0+: ignore unknown/inactive/unaccepted choices; if none match, use store defaults. Omitted/null also uses store defaults; [] is invalid. Never enables a method or changes store settings. See selection schema below.Details

Select store-enabled methods for this invoice. Merchant 5.4.0+: ignore unknown/inactive/unaccepted choices; if none match, use store defaults. Omitted/null also uses store defaults; [] is invalid. Never enables a method or changes store settings. See selection schema below.

chain_slugstringrequired
Copy chain_slug in Project → Stores → Payment methods, or read it from GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, such as ethereum, base or bitcoin. A chain/rail pair may occur only once.Details

Copy chain_slug in Project → Stores → Payment methods, or read it from GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, such as ethereum, base or bitcoin. A chain/rail pair may occur only once.

asset_ids[]UUID[] | nulloptional
On-chain asset.id UUIDs, not contract addresses or invoice payment-method IDs. Use this OR asset_tickers. Omit both selectors for all active accepted assets on this chain. [] and duplicate/nil IDs are invalid. On 5.4.0+, ignore IDs not active/accepted on this chain in this store; an entirely unmatched selection uses store defaults.Details

On-chain asset.id UUIDs, not contract addresses or invoice payment-method IDs. Use this OR asset_tickers. Omit both selectors for all active accepted assets on this chain. [] and duplicate/nil IDs are invalid. On 5.4.0+, ignore IDs not active/accepted on this chain in this store; an entirely unmatched selection uses store defaults.

asset_tickers[]string[] | nulloptional
Merchant 5.3.0+. Symbols such as BTC, USDC or PEPE, scoped to chain_slug and this store. 1–64 unique tickers; trim/case-insensitive, 1–40 ASCII letters/digits/dot/underscore/hyphen. Use this OR asset_ids. On 5.4.0+, ignore unknown/inactive/unaccepted tickers. Ambiguous accepted symbols still fail: use asset_ids. Active selected methods need valid wallets and pricing; temporary on-chain scanner outages do not block creation from 6.0.6. Lightning optionally accepts only BTC.Details

Merchant 5.3.0+. Symbols such as BTC, USDC or PEPE, scoped to chain_slug and this store. 1–64 unique tickers; trim/case-insensitive, 1–40 ASCII letters/digits/dot/underscore/hyphen. Use this OR asset_ids. On 5.4.0+, ignore unknown/inactive/unaccepted tickers. Ambiguous accepted symbols still fail: use asset_ids. Active selected methods need valid wallets and pricing; temporary on-chain scanner outages do not block creation from 6.0.6. Lightning optionally accepts only BTC.

payment_railonchain | lightningoptional
Defaults to onchain. To choose Bitcoin Lightning, use {chain_slug: bitcoin, payment_rail: lightning} with no asset_ids; asset_tickers may optionally be [BTC]. Bitcoin on-chain does not include Lightning. The store's Lightning connection must already be enabled and ready.Details

Defaults to onchain. To choose Bitcoin Lightning, use {chain_slug: bitcoin, payment_rail: lightning} with no asset_ids; asset_tickers may optionally be [BTC]. Bitcoin on-chain does not include Lightning. The store's Lightning connection must already be enabled and ready.

order_idstring | nulloptional

Merchant order reference, 1–128 characters after trimming; control characters are rejected.

emailstring | nulloptional

Merchant-only customer email, normalized to a practical ASCII address with at most 254 characters. Omitted or null stores no email.

descriptionstring | nulloptional

Customer-facing description, 1–500 characters; line breaks and tabs are allowed.

expires_in_secondsinteger | nulloptional

Invoice quote lifetime from 300 through 86,400 seconds; omitted or null inherits store policy.

exchange_rate_spread_percentdecimal string | nulloptional
Quote markup from 0 through 100, with at most two decimal places. Omitted or null inherits the store default; "0" disables it for this invoice. Applied before upward rounding, then locked. Does not change the invoice fiat amount or the processing-fee basis.Details

Quote markup from 0 through 100, with at most two decimal places. Omitted or null inherits the store default; "0" disables it for this invoice. Applied before upward rounding, then locked. Does not change the invoice fiat amount or the processing-fee basis.

underpayment_tolerance_percentdecimal string | nulloptional

Accepted shortfall from 0 through 99.99 with at most two decimal places. Omitted or null inherits the store default.

ipn_urlstring | nulloptional

Public HTTPS callback, at most 2,048 bytes and without credentials or fragment. Overrides the store default; null/omitted inherits it.

redirect_urlstring | nulloptional

HTTPS success URL used after settlement, at most 2,048 bytes and without embedded credentials. Omitted or null inherits the store default and cannot clear it.

cancel_urlstring | nulloptional

HTTPS return URL used when checkout ends without successful payment. Omitted or null inherits the store default and cannot clear it.

redirect_automaticallyboolean | nulloptional

Omitted or null inherits store policy. true requires an effective redirect_url.

languagestring | nulloptional
Customer language: en, de, es, pt-BR, it, ru, zh-CN, fr, ko or ja. pt means Brazilian Portuguese and zh means Simplified Chinese. Supported regional tags such as de-DE normalize to the listed language. Omitted or null inherits the store language. Console language is separate.Details

Customer language: en, de, es, pt-BR, it, ru, zh-CN, fr, ko or ja. pt means Brazilian Portuguese and zh means Simplified Chinese. Supported regional tags such as de-DE normalize to the listed language. Omitted or null inherits the store language. Console language is separate.

checkout_appearanceobject | nulloptional
Partial presentation settings for this invoice. Omitted/null follows the store's current design. An object, including {}, freezes the resolved design and images at creation. See the override schema below; no financial settings, HTML, CSS, JavaScript or remote image URLs.Details

Partial presentation settings for this invoice. Omitted/null follows the store's current design. An object, including {}, freezes the resolved design and images at creation. See the override schema below; no financial settings, HTML, CSS, JavaScript or remote image URLs.

inherit_default_storebooleanoptional
true selects the project's default-store design as the base; otherwise use the target store's effective design. Overrides are then applied and saved independently; the resolved invoice flag is false.Details

true selects the project's default-store design as the base; otherwise use the target store's effective design. Overrides are then applied and saved independently; the resolved invoice flag is false.

titlestringoptional

Checkout heading, up to 120 characters. Empty uses the standard heading.

introstringoptional
Plain text, up to 2,000 characters each. Intro appears at the top, Outro at the bottom in every state. Newlines are preserved; safe text URLs become links. Empty string clears. Legacy customer_message is accepted as an alias for intro; do not send both.Details

Plain text, up to 2,000 characters each. Intro appears at the top, Outro at the bottom in every state. Newlines are preserved; safe text URLs become links. Empty string clears. Legacy customer_message is accepted as an alias for intro; do not send both.

outrostringoptional
Plain text, up to 2,000 characters each. Intro appears at the top, Outro at the bottom in every state. Newlines are preserved; safe text URLs become links. Empty string clears. Legacy customer_message is accepted as an alias for intro; do not send both.Details

Plain text, up to 2,000 characters each. Intro appears at the top, Outro at the bottom in every state. Newlines are preserved; safe text URLs become links. Empty string clears. Legacy customer_message is accepted as an alias for intro; do not send both.

intro_font_sizeintegeroptional

Pixels: 12, 14, 16, 18, 20 or 24. Default 16 unless inherited differently.

outro_font_sizeintegeroptional

Pixels: 12, 14, 16, 18, 20 or 24. Default 16 unless inherited differently.

themesystem | light | dim | darkoptional

Follow the customer device or use a fixed theme.

accent_colorstringoptional

#RRGGBB. Background, card and button may be empty for automatic colors. Text contrast is automatic.

background_colorstringoptional

#RRGGBB. Background, card and button may be empty for automatic colors. Text contrast is automatic.

card_colorstringoptional

#RRGGBB. Background, card and button may be empty for automatic colors. Text contrast is automatic.

button_colorstringoptional

#RRGGBB. Background, card and button may be empty for automatic colors. Text contrast is automatic.

logo_sizestringoptional

small, medium or large; left or center.

logo_alignmentstringoptional

small, medium or large; left or center.

imagesobjectoptional
Keys logo_light, logo_dark, favicon. Omitted key keeps the base image; null removes it. An object {store_id: UUID, kind?: logo_light|logo_dark|favicon} reuses that store's effective uploaded image in the SAME project. kind defaults to the target key. Upload in Store → Checkout first; copy the Store API ID from Basic → API IDs. Missing images or cross-project IDs return 400. No external URLs or image data accepted.Details

Keys logo_light, logo_dark, favicon. Omitted key keeps the base image; null removes it. An object {store_id: UUID, kind?: logo_light|logo_dark|favicon} reuses that store's effective uploaded image in the SAME project. kind defaults to the target key. Upload in Store → Checkout first; copy the Store API ID from Basic → API IDs. Missing images or cross-project IDs return 400. No external URLs or image data accepted.

logo_lightobject | nulloptional
store_idUUIDrequired
kindlogo_light | logo_dark | faviconoptional
logo_darkobject | nulloptional
store_idUUIDrequired
kindlogo_light | logo_dark | faviconoptional
faviconobject | nulloptional
store_idUUIDrequired
kindlogo_light | logo_dark | faviconoptional
show_order_idbooleanoptional

Show order ID details and a plain-text description below the title. details_expanded opens order ID details initially. Display only, not data redaction.

show_descriptionbooleanoptional

Show order ID details and a plain-text description below the title. details_expanded opens order ID details initially. Display only, not data redaction.

details_expandedbooleanoptional

Show order ID details and a plain-text description below the title. details_expanded opens order ID details initially. Display only, not data redaction.

show_project_namebooleanoptional
Merchant 5.6.0+: show or hide each name in the customer checkout header. Both default to true. Also available in Store → Checkout; inherited and invoice-snapshotted like other appearance settings. Display only, not data redaction.Details

Merchant 5.6.0+: show or hide each name in the customer checkout header. Both default to true. Also available in Store → Checkout; inherited and invoice-snapshotted like other appearance settings. Display only, not data redaction.

show_store_namebooleanoptional
Merchant 5.6.0+: show or hide each name in the customer checkout header. Both default to true. Also available in Store → Checkout; inherited and invoice-snapshotted like other appearance settings. Display only, not data redaction.Details

Merchant 5.6.0+: show or hide each name in the customer checkout header. Both default to true. Also available in Store → Checkout; inherited and invoice-snapshotted like other appearance settings. Display only, not data redaction.

featured_chains[]string[]optional
Ordered chain slugs, at most 60 unique values (lowercase letters, digits, hyphens; up to 64 characters). [] clears. Only available invoice methods are reordered.Details

Ordered chain slugs, at most 60 unique values (lowercase letters, digits, hyphens; up to 64 characters). [] clears. Only available invoice methods are reordered.

featured_asset_ids[]UUID[]optional
Up to 100 unique ordered asset IDs; [] clears. Default asset may be null. IDs come from payment-assets, not payment-intent IDs. These never enable methods; received payments and valid customer preferences take priority.Details

Up to 100 unique ordered asset IDs; [] clears. Default asset may be null. IDs come from payment-assets, not payment-intent IDs. These never enable methods; received payments and valid customer preferences take priority.

default_asset_idUUID|nulloptional
Up to 100 unique ordered asset IDs; [] clears. Default asset may be null. IDs come from payment-assets, not payment-intent IDs. These never enable methods; received payments and valid customer preferences take priority.Details

Up to 100 unique ordered asset IDs; [] clears. Default asset may be null. IDs come from payment-assets, not payment-intent IDs. These never enable methods; received payments and valid customer preferences take priority.

messagesobjectoptional
Language objects keyed by en, de, es, pt-BR, it, ru, zh-CN, fr, ko or ja, with waiting, confirming, paid, underpaid, expired plain strings (500 characters each). Only supplied languages/states change; {} clears all messages, {en:{}} clears English, and an empty state string clears that state. English is the fallback. Does not replace actual status.Details

Language objects keyed by en, de, es, pt-BR, it, ru, zh-CN, fr, ko or ja, with waiting, confirming, paid, underpaid, expired plain strings (500 characters each). Only supplied languages/states change; {} clears all messages, {en:{}} clears English, and an empty state string clears that state. English is the fallback. Does not replace actual status.

enobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
deobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
esobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
pt-BRobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
itobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
ruobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
zh-CNobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
frobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
koobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
jaobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
support_emailstringoptional

ASCII email, up to 254 characters. Empty clears.

support_urlstringoptional

HTTPS URLs up to 2,048 characters, without credentials. Empty clears. Links open in a new window.

terms_urlstringoptional

HTTPS URLs up to 2,048 characters, without credentials. Empty clears. Links open in a new window.

privacy_urlstringoptional

HTTPS URLs up to 2,048 characters, without credentials. Empty clears. Links open in a new window.

return_button_textstringoptional

Label up to 60 characters. Use top-level redirect_url/cancel_url/redirect_automatically/language for invoice behavior.

show_return_buttonbooleanoptional
Show the manual Return to merchant/cancel button in checkout, including terminal states. Omit to inherit the store appearance (default true); false hides it. Does not cancel an invoice, hide URLs in JSON or disable automatic success redirects. Set top-level redirect_automatically to false separately if needed. Requires merchant 8.1.4 or newer.Details

Show the manual Return to merchant/cancel button in checkout, including terminal states. Omit to inherit the store appearance (default true); false hides it. Does not cancel an invoice, hide URLs in JSON or disable automatic success redirects. Set top-level redirect_automatically to false separately if needed. Requires merchant 8.1.4 or newer.

metadataobject | nulloptional
Merchant-only JSON object; omitted or null becomes {}, maximum 4,096 encoded bytes and five nested levels. firstname, lastname, street, street2, zip, city, country, countryiso2, company, and vatid are validated, normalized, and projected into customer summary fields.Details

Merchant-only JSON object; omitted or null becomes {}, maximum 4,096 encoded bytes and five nested levels. firstname, lastname, street, street2, zip, city, country, countryiso2, company, and vatid are validated, normalized, and projected into customer summary fields.

firstnamestringoptional
lastnamestringoptional
streetstringoptional
street2stringoptional
zipstringoptional
citystringoptional
countrystringoptional
countryiso2stringoptional
companystringoptional
vatidstringoptional
project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

store_id

"YOUR_STORE_ID"

allocations[]object[]
[{"vendor_id":"VENDOR_A_UUID","gross_amount":"100.00"},{"vendor_id":"VENDOR_B_UUID","gross_amount":"100.00"},{"vendor_id":"VENDOR_C_UUID","gross_amount":"100.00"}]Details

[{"vendor_id":"VENDOR_A_UUID","gross_amount":"100.00"},{"vendor_id":"VENDOR_B_UUID","gross_amount":"100.00"},{"vendor_id":"VENDOR_C_UUID","gross_amount":"100.00"}]

vendor_idstring
gross_amountstring

Response 200 application/json

Example response
{
  "data": {
    "invoice_id": "YOUR_INVOICE_ID",
    "status": "new",
    "marketplace": {
      "state": "pending",
      "allocations": []
    }
  },
  "links": {
    "checkout": "https://pay.example.com/invoice/YOUR_INVOICE_ID"
  }
}

Response fields

dataobject
invoice_idstring
statusstring
marketplaceobject
statestring
allocations[]array
Usage notes
  • Requires invoices.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETInvoice and allocations/v1/marketplace/invoices/{invoice_id}Read only

Normal invoice details plus marketplace state, revision, hold_reason, frozen allocations, policy snapshot, latest 200 payments and latest 100 related payouts with truncation flags. Public checkout does not expose vendor data.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETInvoice payment evidence/v1/marketplace/invoices/{invoice_id}/paymentsRead only

Normal payment evidence with page/per_page. Observations are not vendor payouts.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/payments?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETInvoice allocations/v1/marketplace/invoices/{invoice_id}/allocationsRead only

Immutable share/commission/destination snapshots and exact gross, commission and net atomic values after qualified settlement.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTCancel unpaid invoice/v1/marketplace/invoices/{invoice_id}/cancelRead + write

Only an unpaid new or expired invoice. Late receipts are held for review. Revision is the Marketplace invoice revision.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopeinvoices.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/cancel" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires invoices.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTHold allocations/v1/marketplace/invoices/{invoice_id}/allocations/holdRead + write

Hold unsigned allocations without erasing obligations. Signed or uncertain payouts remain tracked.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopereconciliation.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/hold" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1,
  "reason": "Verify customer request"
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

reason

"Verify customer request"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires reconciliation.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTReview and release allocations/v1/marketplace/invoices/{invoice_id}/allocations/releaseRead + write

Recheck backing/finality. Optional approved_amount_atomic explicitly accepts a reduced fully backed split before allocation freeze; never fabricates receipt funds.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopereconciliation.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/release" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1,
  "reason": "Verified payment evidence"
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

reason

"Verified payment evidence"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires reconciliation.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTRebind unpaid destination/v1/marketplace/invoices/{invoice_id}/allocations/{allocation_id}/destinationRead + write

Allocation revision required. Only unreserved/unsigned work and a separately approved version for the same vendor on the original network. Audited; signed work cannot change.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopereconciliation.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/YOUR_ALLOCATION_ID/destination" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1,
  "destination_id": "YOUR_DESTINATION_ID",
  "reason": "Vendor verified replacement address"
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

destination_id

"YOUR_DESTINATION_ID"

reason

"Vendor verified replacement address"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires reconciliation.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTPrepare full refund/v1/marketplace/invoices/{invoice_id}/refundRead + write

Prepare a separately approved same-asset full received-amount refund. Before vendor payout reserve unpaid funds and reverse commission on confirmation. After all vendor payouts use separate free primary-address funds. Never infer the customer refund address from the sender.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopereconciliation.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/refund" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1,
  "payment_method_id": "YOUR_PAYMENT_METHOD_ID",
  "destination_address": "VERIFIED_CUSTOMER_REFUND_ADDRESS",
  "reason": "Customer cancellation",
  "maximum_network_fee_atomic": "10000",
  "maximum_gas_funding_atomic": "0",
  "fee_tier": "medium"
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

payment_method_id

"YOUR_PAYMENT_METHOD_ID"

destination_address

"VERIFIED_CUSTOMER_REFUND_ADDRESS"

reason

"Customer cancellation"

maximum_network_fee_atomic

"10000"

maximum_gas_funding_atomic

"0"

fee_tier

"medium"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires reconciliation.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETFind payout allocations/v1/marketplace/allocationsRead only

Paged candidates; filter status (available etc.), asset_id, vendor_id, store_id and q (vendor/order/invoice).

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/allocations?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 0,
    "pages": 1
  }
}

Response fields

data[]array
paginationobject
pageinteger
per_pageinteger
totalinteger
pagesinteger
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETProject ledger balances/v1/marketplace/balancesRead only

Exact grouped asset/account totals including held, available, reserved, paid, commission, refunds and network fees. External balancing account is excluded.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/balances?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETImmutable journal/v1/marketplace/ledgerRead only

Paged append-only movements; q reference/account, asset_id and vendor_id filters. Amounts use atomic strings; no entry can be edited or marked paid manually.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/ledger?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 0,
    "pages": 1
  }
}

Response fields

data[]array
paginationobject
pageinteger
per_pageinteger
totalinteger
pagesinteger
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETPayout history/v1/marketplace/payoutsRead only

Paged parents; filter state, asset_id, vendor_id or q ID/symbol. Paid means independent confirmation, not just broadcast.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/payouts?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 0,
    "pages": 1
  }
}

Response fields

data[]array
paginationobject
pageinteger
per_pageinteger
totalinteger
pagesinteger
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTPreview allocation plan/v1/marketplace/payouts/previewRead + write

Read-only accounting plan, no reservation or spend authority. Maximum fee is a user cap, not an estimated actual fee. Preparation performs live checks later.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopepayouts.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/payouts/preview" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "allocation_ids": [
    "YOUR_ALLOCATION_ID"
  ],
  "maximum_network_fee_atomic": "10000",
  "maximum_gas_funding_atomic": "0",
  "fee_tier": "medium"
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

allocation_ids[]

["YOUR_ALLOCATION_ID"]

maximum_network_fee_atomic

"10000"

maximum_gas_funding_atomic

"0"

fee_tier

"medium"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires payouts.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTPrepare payout/v1/marketplace/payoutsRead + write

Reserve 1–100 available allocation IDs in one asset/wallet. BTC requires all unpaid shares for each selected invoice in one multi-output batch. Budgets are atomic strings in the native fee asset. Creates an awaiting_approval plan, does not broadcast.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopepayouts.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/payouts" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "allocation_ids": [
    "YOUR_ALLOCATION_ID"
  ],
  "maximum_network_fee_atomic": "10000",
  "maximum_gas_funding_atomic": "0",
  "fee_tier": "medium"
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

allocation_ids[]

["YOUR_ALLOCATION_ID"]

maximum_network_fee_atomic

"10000"

maximum_gas_funding_atomic

"0"

fee_tier

"medium"

Response 200 application/json

Example response
{
  "data": {
    "id": "YOUR_PAYOUT_ID",
    "state": "awaiting_approval",
    "revision": 1,
    "plan_hash": "RETAINED_PLAN_HASH",
    "plan": {
      "amount_atomic": "28800000",
      "maximum_network_fee_atomic": "10000",
      "maximum_gas_funding_atomic": "0",
      "items": []
    },
    "transactions": []
  }
}

Response fields

dataobject
idstring
statestring
revisioninteger
plan_hashstring
planobject
amount_atomicstring
maximum_network_fee_atomicstring
maximum_gas_funding_atomicstring
items[]array
transactions[]array
Usage notes
  • Requires payouts.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETPayout details/v1/marketplace/payouts/{payout_id}Read only

Immutable plan/hash, revision, expiry, recipient items, preserved child attempts, progress, exact fees and explorer links. Never private keys or signed bytes.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {
    "id": "YOUR_PAYOUT_ID",
    "state": "awaiting_approval",
    "revision": 1,
    "plan_hash": "RETAINED_PLAN_HASH",
    "plan": {
      "amount_atomic": "28800000",
      "maximum_network_fee_atomic": "10000",
      "maximum_gas_funding_atomic": "0",
      "items": []
    },
    "transactions": []
  }
}

Response fields

dataobject
idstring
statestring
revisioninteger
plan_hashstring
planobject
amount_atomicstring
maximum_network_fee_atomicstring
maximum_gas_funding_atomicstring
items[]array
transactions[]array
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTApprove and send/v1/marketplace/payouts/{payout_id}/approveRead + write

Explicitly authorize the exact retained plan within its expiry. Queue bounded gas funding and vendor transactions in the background.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopepayouts.approve

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/approve" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1,
  "expected_plan_hash": "COPY_EXACT_PLAN_HASH_FROM_PREPARE",
  "confirm": true
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

expected_plan_hash

"COPY_EXACT_PLAN_HASH_FROM_PREPARE"

confirm

true

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires payouts.approve. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTReview and resume payout/v1/marketplace/payouts/{payout_id}/resumeRead + write

Only needs_attention. Reuse the retained plan/hash; confirmed recipients are never resent. Two independent providers must prove a canonical sufficiently confirmed EVM revert before a failed child can be replaced. Previous fees still consume the approved budget and all hashes remain in history. Unknown/partial token delivery returns payout_recovery_unverified; reservations remain held.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopepayouts.approve

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/resume" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1,
  "expected_plan_hash": "COPY_EXACT_PLAN_HASH_FROM_PREPARE",
  "confirm": true
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

expected_plan_hash

"COPY_EXACT_PLAN_HASH_FROM_PREPARE"

confirm

true

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires payouts.approve. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTCancel unsigned work/v1/marketplace/payouts/{payout_id}/cancelRead + write

Release only safely unsigned/unsubmitted reservations. Confirmed recipients and audit remain. Signed/uncertain work cannot be cancelled. An explicitly recovered, proven revert no longer blocks cancellation of the remaining unsigned work.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopepayouts.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/cancel" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires payouts.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETAutomatic payout policies/v1/marketplace/policiesRead only

Read per-asset policies, revision, next_attempt_at, last_checked_at and a safe last_error when preparation or authorization needs attention.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/policies?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": []
}

Response fields

data[]array
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTAuthorize payout policy/v1/marketplace/policiesRead + write

Exact atomic strings; minimum <= transfer <= daily principal, fee/gas caps <= their daily budgets. interval_seconds 60–604800; minimum_confirmations 1–100000 subject to chain floor. Revision 0 creates. Enabled policies may send without further clicks; keep false until reviewed.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopepolicies.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/policies" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "asset_id": "YOUR_ASSET_ID",
  "revision": 0,
  "enabled": false,
  "minimum_atomic": "100000",
  "transfer_limit_atomic": "10000000",
  "daily_limit_atomic": "30000000",
  "fee_limit_atomic": "10000",
  "daily_fee_limit_atomic": "30000",
  "gas_limit_atomic": "0",
  "daily_gas_limit_atomic": "0",
  "interval_seconds": 3600,
  "minimum_confirmations": 2
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

asset_id

"YOUR_ASSET_ID"

revision

0

enabled

false

minimum_atomic

"100000"

transfer_limit_atomic

"10000000"

daily_limit_atomic

"30000000"

fee_limit_atomic

"10000"

daily_fee_limit_atomic

"30000"

gas_limit_atomic

"0"

daily_gas_limit_atomic

"0"

interval_seconds

3600

minimum_confirmations

2

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires policies.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETMarketplace webhooks/v1/marketplace/webhooksRead only

Up to 20 endpoints plus supported event_types. Never returns encrypted or plaintext signing secrets.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/webhooks?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {
    "endpoints": [],
    "event_types": [
      "marketplace.invoice.created",
      "marketplace.allocations.available",
      "marketplace.allocations.held",
      "marketplace.payout.approved",
      "marketplace.payout.broadcast",
      "marketplace.payout.confirmed",
      "marketplace.payout.partial",
      "marketplace.payout.failed",
      "marketplace.payout.cancelled",
      "marketplace.refund.prepared",
      "marketplace.refund.confirmed"
    ]
  }
}

Response fields

dataobject
endpoints[]array
event_types[]array
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTCreate Marketplace webhook/v1/marketplace/webhooksRead + write

Public HTTPS only, no credentials, private destinations or redirects. Returns signing_secret once per retained idempotent create response; store securely. Separate from the store IPN secret.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopewebhooks.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/webhooks" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "url": "https://shop.example.com/marketplace-events",
  "enabled": true,
  "events": [
    "marketplace.payout.confirmed",
    "marketplace.payout.failed"
  ]
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

url

"https://shop.example.com/marketplace-events"

enabled

true

events[]

["marketplace.payout.confirmed","marketplace.payout.failed"]

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires webhooks.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTUpdate Marketplace webhook/v1/marketplace/webhooks/{webhook_id}/updateRead + write

Changes cancel old unsent deliveries. The secret remains unchanged; old immutable payloads are never redirected to a new URL.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopewebhooks.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/webhooks/YOUR_WEBHOOK_ID/update" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1,
  "url": "https://shop.example.com/marketplace-events",
  "enabled": true,
  "events": [
    "marketplace.payout.confirmed"
  ]
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

url

"https://shop.example.com/marketplace-events"

enabled

true

events[]

["marketplace.payout.confirmed"]

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires webhooks.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTDisable Marketplace webhook/v1/marketplace/webhooks/{webhook_id}/disableRead + write

Stop new deliveries; retained event history remains.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopewebhooks.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/webhooks/YOUR_WEBHOOK_ID/disable" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "revision": 1
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

revision

1

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires webhooks.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETMarketplace events/v1/marketplace/eventsRead only

Paged immutable event references. q searches type/reference; status filters event_type.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/events?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 0,
    "pages": 1
  }
}

Response fields

data[]array
paginationobject
pageinteger
per_pageinteger
totalinteger
pagesinteger
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETRead retained event/v1/marketplace/events/{event_id}Read only

Returns the immutable original event payload, not a reconstruction from current balances.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/events/YOUR_EVENT_ID?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {
    "event_id": "11111111-1111-4111-8111-111111111111",
    "event_type": "marketplace.payout.confirmed",
    "payload_version": 1,
    "project_id": "YOUR_PROJECT_ID",
    "occurred_at": "2026-10-06T12:00:00Z",
    "data": {
      "payout_id": "YOUR_PAYOUT_ID",
      "asset_id": "YOUR_ASSET_ID",
      "amount_atomic": "28800000",
      "transactions": [
        {
          "transaction_id": "EXAMPLE_TRANSACTION_ID",
          "explorer_url": "https://mempool.space/tx/EXAMPLE_TRANSACTION_ID"
        }
      ]
    }
  }
}

Response fields

dataobject
event_idstring
event_typestring
payload_versioninteger
project_idstring
occurred_atstring
dataobject
payout_idstring
asset_idstring
amount_atomicstring
transactions[]object[]
transaction_idstring
explorer_urlstring
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETMarketplace delivery history/v1/marketplace/webhook-deliveriesRead only

Paged deliveries, event type, attempts and last result. Filter status pending/sending/succeeded/failed/cancelled; q event type.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/webhook-deliveries?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 0,
    "pages": 1
  }
}

Response fields

data[]array
paginationobject
pageinteger
per_pageinteger
totalinteger
pagesinteger
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETDelivery details/v1/marketplace/webhook-deliveries/{delivery_id}Read only

Original URL, retained payload, HTTP result and safe error; no signing secret.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
ParameterType / locationRule
permissioncredential scopemarketplace.read

Query parameters

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

per_pageoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

qoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

statusoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

store_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

vendor_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

asset_idoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

fromoptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

tooptional

Use only filters documented for this resource. Paged lists default to 25 and allow up to 100 rows.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/marketplace/webhook-deliveries/YOUR_DELIVERY_ID?project_id=YOUR_PROJECT_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires marketplace.read. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

POSTRedeliver same event/v1/marketplace/webhook-deliveries/{delivery_id}/resendRead + write

Only finished deliveries and the unchanged active endpoint; up to 20 manual retries. Reuses event_id. A failed notification never authorizes a second payment.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MARKETPLACE_API_TOKEN
Idempotency-Keyrequired16–128 letters, digits, -, _ or .; persist with this exact request
ParameterType / locationRule
permissioncredential scopewebhooks.write

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/webhook-deliveries/YOUR_DELIVERY_ID/resend" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: marketplace-request-1042' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "confirm": true
}'

Request body

project_idUUIDrequired

An authorized project. Required on every request, including item URLs.

confirm

true

Response 200 application/json

Example response
{
  "data": {}
}

Response fields

dataobject
Usage notes
  • Requires webhooks.write. Response examples show selected fields; GET the resource for full retained evidence.
  • Every POST requires a persisted 16–128 character Idempotency-Key (letters, digits, -, _ or .). Reuse the same key and JSON instructions after a timeout. Different instructions return 409. Completed responses are retained for 30 days; old keys become non-reusable tombstones. Never change a key simply to bypass an uncertain result.
  • Keys have project lists, optional invoice-store restrictions, expiry, IP allowlist and a 1–600/minute quota (default 60). HTTP 429 includes Retry-After. Store-limited keys cannot see vendors, project balances, ledger, payouts or settings. Keep spending credentials only on trusted servers, never browsers or shipped mobile apps.

Errors

Error codes & retry rules

GETList payment exceptions/v1/projects/{project_id}/reconciliationRead only

One paginated review queue for underpaid, overpaid, late, reorged or ambiguous payments, failed deliveries, and disabled/expired methods. Cases acknowledged by an operator reopen when new evidence arrives.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN

Path parameters

project_idUUIDrequired

Project assigned to this credential.

Query parameters

statusstring

open (default), resolved, or all.

reasonstring

underpaid, overpaid, late, reorged, ambiguous, delivery_failed, disabled_method, or expired_method.

store_idUUID

Optional store filter.

pageinteger

1–40001. Fixed 25 cases per page.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/reconciliation?status=open&page=1" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{"data":[],"pagination":{"page":1,"per_page":25,"total":0,"has_more":false},"counts":{"open":0,"resolved":0}}

Response fields

data[]object[]always

Newest updated cases first. Use invoice_id, not internal id, in merchant detail URLs.

idUUIDalways

Internal record ID / customer-facing invoice UUID. invoice_id matches callback payloads.

invoice_idUUIDalways

Internal record ID / customer-facing invoice UUID. invoice_id matches callback payloads.

store_idUUIDalways

Owning store.

store_namestringalways

Owning store.

order_idstring | nullalways

Private merchant order reference and customer email.

emailstring | nullalways

Private merchant order reference and customer email.

amountdecimal stringalways

Original fiat invoice amount and currency.

currencystringalways

Original fiat invoice amount and currency.

invoice_statusinvoice statusalways

Current payment lifecycle status.

statusopen|resolvedalways

Case state and the exception types listed in the reason filter.

reasons[]string[]always

Case state and the exception types listed in the reason filter.

revisionintegeralways

Current review revision and update time.

updated_attimestampalways

Current review revision and update time.

paginationobjectalways

page (1–40001), per_page (25), total matching rows, has_more.

pageinteger
per_pageinteger
totalinteger
has_moreboolean
countsobjectalways

open and resolved totals for the whole project, independent of the current filters.

openinteger
resolvedinteger
Usage notes
  • Read-only, project-scoped and covered by the credential quota. Financial decisions and refunds remain console-only.
  • Rows contain id (internal UUID), invoice_id (public UUID, same as callbacks), store information, original fiat amount/currency, invoice_status, case status, reasons, revision and updated_at. Use invoice_id in the merchant detail endpoint.
  • Automatic detection follows the original invoice monitoring window; Rescan extends observation by one hour without enabling checkout. Post-settlement/cancelled methods continue to be monitored within that window.

Errors

Error codes & retry rules

GETRead reconciliation evidence/v1/projects/{project_id}/reconciliation/{invoice_id}Read only

Returns invoice, case, exact method totals and available refund amounts, observed transactions, delivery history, merchant decisions and linked refund transfers. It never exposes signing keys or callback secrets.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN

Path parameters

project_idUUIDrequired

Assigned project.

invoice_idUUIDrequired

Public invoice UUID, not internal id.

Query parameters

pageinteger

Decision-history page, starting at 1; 25 decisions per page.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/reconciliation/YOUR_PUBLIC_INVOICE_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{"invoice":{"invoice_id":"YOUR_PUBLIC_INVOICE_ID","status":"processing"},"case":{"status":"open","reasons":["underpaid"],"revision":1},"methods":[],"history":[],"history_pagination":{"page":1,"per_page":25,"total":0},"refunds":[],"observations":[],"deliveries":[]}

Response fields

invoiceobjectalways

Full merchant invoice: summary fields, private metadata and payment_intents. Not wrapped in data.

idUUIDalways

Internal invoice UUID. Do not use it in merchant detail or checkout paths.

invoice_idUUIDalways

Public invoice UUID used by merchant detail and checkout paths.

project_idUUIDalways

Owning project.

store_idUUIDalways

Owning store.

sourcemanual | apialways

How the invoice was created.

order_idstring | nullalways

Merchant order reference.

emailstring | nullalways

Merchant-only customer email. Never returned by public checkout.

customer_namestring | nullalways

Derived display name from private firstname, lastname, and company metadata.

customer_addressstring | nullalways

Derived one-line merchant address from private company, street, street2, zip, city, country, countryiso2, and vatid metadata.

descriptionstring | nullalways

Customer-facing description.

amountdecimal stringalways

Canonical invoice amount.

currencystringalways

Normalized invoice currency/asset code.

exchange_rate_spread_percentdecimal stringalways

Locked quote spread: the creation override, or the store default when omitted. Applied before upward rounding; never changes on this invoice.

underpayment_tolerance_percentdecimal stringalways

Immutable accepted shortfall percentage snapshotted when the invoice was created.

statusinvoice statusalways

new, processing, settled, expired, invalid, or cancelled.

amount_statusamount statusalways

none, partial, paid, or overpaid. An explicitly allowed zero-amount invoice settles with none and no payment methods.

timing_statustiming statusalways

on_time or late.

resolutionresolutionalways

automatic, manually_settled, or manually_invalidated.

sequenceintegeralways

Monotonic invoice state sequence, starting at 1.

winning_payment_intent_idUUID | nullalways

Payment method that resolved the invoice, when selected.

expires_atRFC 3339 timestampalways

Quote/payment deadline.

monitoring_expires_atRFC 3339 timestampalways

Latest configured late-monitoring cutoff across payment methods.

settled_attimestamp | nullalways

Settlement time when settled.

cancelled_attimestamp | nullalways

Cancellation time when cancelled.

archived_attimestamp | nullalways

Archival time when archived.

created_atRFC 3339 timestampalways

Creation time.

updated_atRFC 3339 timestampalways

Last state update time.

ipn_urlstring | nullalways

Effective per-invoice IPN target. Merchant response only; omitted from public checkout.

redirect_urlstring | nullalways

Effective success URL used after settlement.

cancel_urlstring | nullalways

Effective return URL used when checkout ends without successful payment.

redirect_automaticallybooleanalways

Whether checkout should redirect automatically after success.

checkout_languagestringalways

Effective checkout language tag.

metadataobjectalways
Merchant metadata. Never returned by public checkout. Console payment tools add payment_tool provenance (id, kind, title, pricing, requested_amount, request_id); it does not prove payment. Authenticate callbacks and fulfill invoice.settled once per invoice_id.Details

Merchant metadata. Never returned by public checkout. Console payment tools add payment_tool provenance (id, kind, title, pricing, requested_amount, request_id); it does not prove payment. Authenticate callbacks and fulfill invoice.settled once per invoice_id.

payment_intents[]object[]always

Quoted payment methods and monitoring state.

idUUIDalways

Payment intent identifier; also used as checkout QR intent_id.

payment_railonchain | lightningalways
Invoice transport. Bitcoin on-chain and Lightning can share asset_id; use intent id plus this field, not symbol alone. This differs from the asset catalog's scanner payment_rail.Details

Invoice transport. Bitcoin on-chain and Lightning can share asset_id; use intent id plus this field, not symbol alone. This differs from the asset catalog's scanner payment_rail.

bolt11string | nullalways

Lightning payment request, otherwise null. Pay this request with a Lightning wallet, never send on-chain funds to its payment hash.

asset_idUUIDalways

Configured payment asset identifier.

asset_keystringalways

Canonical CAIP-style asset key.

chain_slugstringalways

Wholly Crypto chain identifier.

networkstringalways

Configured network, currently mainnet for supported payment assets.

caip_network_idstringalways

Canonical CAIP-2 network identifier.

caip_asset_idstring | nullalways

Canonical CAIP-19 identifier where registered.

symbolstringalways

Asset symbol.

asset_decimalsintegeralways

Atomic-unit precision. Lightning BTC uses 11 (millisatoshis), not on-chain Bitcoin's 8. Quotes are whole satoshis; receipts retain millisatoshi precision.

statusintent statusalways

pending, partial, paid, overpaid, expired, or invalid.

finality_modeconfirmations | finalizedalways

Finality policy.

required_confirmationsintegeralways

Required confirmations when applicable.

quote_ratedecimal stringalways

Asset units per one invoice currency unit, including the locked spread. For example 1.02 USDC per USD. Not the inverse rate.

quote_detailsobject | nullalways
Locked quote provenance: reference_rate before spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at and asset_fetched_at. Null on older invoices; no historical values are fabricated.Details

Locked quote provenance: reference_rate before spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at and asset_fetched_at. Null on older invoices; no historical values are fabricated.

expected_amountdecimal stringalways
Exact locked asset amount to pay after spread and upward rounding. From 4.1.1, recognized verified fiat stablecoins (such as USDC, USDT, DAI, USDS, EURC) round up to at most two decimals; 1.321 becomes 1.33, never 1.32. This is the expected amount even with zero tolerance. Other assets keep adaptive precision. Existing invoices are never repriced.Details

Exact locked asset amount to pay after spread and upward rounding. From 4.1.1, recognized verified fiat stablecoins (such as USDC, USDT, DAI, USDS, EURC) round up to at most two decimals; 1.321 becomes 1.33, never 1.32. This is the expected amount even with zero tolerance. Other assets keep adaptive precision. Existing invoices are never repriced.

expected_amount_atomicinteger stringalways

Exact amount in the asset's smallest unit.

minimum_payment_amountdecimal stringalways

Smallest amount accepted as paid after applying the invoice tolerance.

minimum_payment_amount_atomicinteger stringalways

Exact accepted threshold in the asset's smallest unit.

received_amountdecimal stringalways

Observed amount.

received_amount_atomicinteger stringalways

Observed atomic amount.

confirmed_amountdecimal stringalways

Confirmed/final amount.

confirmed_amount_atomicinteger stringalways

Confirmed/final atomic amount.

destination_addressstringalways

On-chain receiving address, or the 64-character payment hash for Lightning. Use bolt11 to pay Lightning; its hash is not a Bitcoin address.

destination_tagstring | nullalways

Required public payment reference where the rail uses one: XRP destination tag, Stellar memo ID, or TON invoice comment. Null for unique-address rails.

derivation_indexintegeralways

Reserved wallet child index; merchant detail only.

quote_expires_atRFC 3339 timestampalways

Quote expiry.

monitoring_expires_atRFC 3339 timestampalways

Late-monitoring cutoff for this method.

next_check_attimestamp | nullalways

Next scheduled chain check.

last_checked_attimestamp | nullalways

Last chain check.

last_chain_heightinteger | nullalways

Last trustworthy height observed by the monitor.

last_anchor_hashstring | nullalways

Last monitor anchor/block hash.

last_monitor_errorstring | nullalways

Safe monitoring diagnostic for operators.

first_payment_attimestamp | nullalways

First observed payment time.

fully_paid_attimestamp | nullalways

Time the accepted minimum amount was first reached.

finalized_attimestamp | nullalways

Time payment met finality policy.

caseobject | nullalways

Current case with status, reasons, revision and timestamps; null when no exception exists. Internal evidence is excluded.

statusstring
reasons[]array
revisioninteger
methods[]object[]always
id, wallet_id, asset_id, symbol, chain, decimals, expected_atomic, received_atomic, confirmed_atomic, refundable_atomic, address, tag, monitor_error, last_checked_at, monitoring_expires_at and spending_supported. Atomic amounts are strings.Details

id, wallet_id, asset_id, symbol, chain, decimals, expected_atomic, received_atomic, confirmed_atomic, refundable_atomic, address, tag, monitor_error, last_checked_at, monitoring_expires_at and spending_supported. Atomic amounts are strings.

history[]object[]always

Newest 25 decisions for this page: id, action, note, actor, result, created_at.

history_paginationobjectalways

page, per_page (25), total. Only decision history is paginated by page.

pageinteger
per_pageinteger
totalinteger
refunds[]object[]always
Newest 100 refunds: id, payment_intent_id, amount_atomic, destination, status, request, treasury_intent_id, transfer_status, created_at and transactions (id/status). Refund submission is console-only.Details

Newest 100 refunds: id, payment_intent_id, amount_atomic, destination, status, request, treasury_intent_id, transfer_status, created_at and transactions (id/status). Refund submission is console-only.

observations[]object[]always
Newest 100: payment_intent_id, transaction_id, event_index, amount, status, confirmations, observed_at, symbol, chain and disabled_at_detection. explorer_name/explorer_url are included when supported.Details

Newest 100: payment_intent_id, transaction_id, event_index, amount, status, confirmations, observed_at, symbol, chain and disabled_at_detection. explorer_name/explorer_url are included when supported.

deliveries[]object[]always

Newest 50: id, kind, status, attempts, response_status, error, next_attempt_at, event_type and created_at. No callback secrets.

Usage notes
  • case is null when the invoice has not generated an exception. The most recent 100 observations and 50 deliveries are returned; decision history is paginated.
  • refundable_atomic requires at least one network confirmation, excludes existing refund reservations, and is not a promise of spendable wallet funds. A live quote additionally validates wallet readiness, source balances and fees.
  • A broadcast refund means submitted to a chain endpoint, not independently confirmed receipt by the customer. Fees are additional and fiat processing fees are not automatically credited by issuing a refund.
  • Console project menu → Needs attention provides cancel, accept, reject, reopen, review, notes, Rescan, delivery retry and supported-chain refunds. Decisions use CSRF-protected sessions, a unique request_id, current case revision, a required note and explicit confirmation; bearer tokens cannot invoke those mutations.

Errors

Error codes & retry rules

GETAPI service discovery/Public

Managed API-host edge response confirming the v1 public API role. This response is produced by the managed proxy, not the merchant Axum router.

Authentication & headers

Public

Request

curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/"

Response 200 application/json

Example response
{
  "service": "Wholly Crypto API",
  "status": "ready",
  "version": "v1"
}

Response fields

servicestring
statusstring
versionstring
Usage notes
  • No bearer token is needed.
  • Only the managed API hostname guarantees this exact root response.

Errors

Error codes & retry rules

GETService health/healthzPublic

Checks application reachability and a two-second database ping. Use for monitoring, not as a substitute for invoice status.

Authentication & headers

Public

Request

curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/healthz"

Response 200 healthy; 503 database unavailable

Example response
{
  "status": "ok",
  "database": "ok",
  "version": "0.1.0"
}

Response fields

statusstring
databasestring
versionstring
Usage notes
  • No bearer token is needed.
  • The version value is the running package version, not the API path version.

Errors

Error codes & retry rules

GETList project payment assets/v1/projects/{project_id}/payment-assetsRead only

Lists native assets and verified tokens with project policy, chain-wallet readiness, and installed scanner/balance capabilities. scanner_ready is an adapter-build gate, not a live endpoint quorum result. From 6.0.6, creation retains configured methods during scanner downtime. Receiving verification still needs the configured healthy exact-role provider threshold (2 by default, optional 1).

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Enabled project assigned to the credential.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-assets" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Accept: application/json'

Response 200 application/json

Example response
{
  "data": [
    {
      "asset": {
        "id": "10000000-0000-4000-8000-000000000003",
        "asset_key": "eip155:1/slip44:60",
        "chain_slug": "ethereum",
        "network": "mainnet",
        "caip_network_id": "eip155:1",
        "caip_asset_id": "eip155:1/slip44:60",
        "asset_kind": "native",
        "payment_rail": "evm-native",
        "symbol": "ETH",
        "name": "Ethereum",
        "decimals": 18,
        "contract_address": null,
        "coingecko_id": "ethereum",
        "icon_path": "/assets/coingecko/ethereum.png",
        "token_standard": null,
        "metadata_verified_at": null,
        "payment_supported": true,
        "scanner_ready": true,
        "balance_ready": true,
        "default_finality_mode": "confirmations",
        "default_required_confirmations": 12,
        "default_monitoring_minutes": 60
      },
      "policy": {
        "enabled": true,
        "finality_mode": "confirmations",
        "required_confirmations": 12,
        "monitoring_minutes": 60,
        "late_monitoring_days": 30
      },
      "wallet": null,
      "wallet_readiness": "wallet_missing",
      "receive_readiness": { "ready": false, "invoice_creatable": false, "checked_at": "2026-09-16T09:00:00Z", "issues": [{ "chain_slug": "ethereum", "asset_id": "10000000-0000-4000-8000-000000000003", "asset_ticker": "ETH", "reason_code": "wallet_missing", "message": "ethereum / ETH: Create a project wallet for this chain.", "action": "wallets" }] }
    }
  ]
}

Response fields

data[]object[]
assetobjectalways

Durable native or verified token asset.

idUUIDalways

Durable payment-asset identifier used by project and store policy routes.

asset_keystringalways

Canonical CAIP-style native or contract asset identity.

chain_slugstringalways

Wholly Crypto chain identifier and configured network.

networkstringalways

Wholly Crypto chain identifier and configured network.

caip_network_idstringalways

Canonical network and asset identities.

caip_asset_idstring|nullalways

Canonical network and asset identities.

asset_kindnative | tokenalways

Whether settlement uses the chain currency or a verified contract/mint.

payment_railstringalways

Runtime rail: utxo, evm-native, solana-native, account-native, privacy-native, or token-transfer.

symbolstringalways

Display identity and exact atomic-unit precision.

namestringalways

Display identity and exact atomic-unit precision.

decimalsintegeralways

Display identity and exact atomic-unit precision.

contract_addressstring | nullalways

Canonical ERC-20 contract or SPL mint for tokens; null for native assets.

coingecko_idstring | nullalways

Discovery/pricing identity. Null for custom contracts; never infer a market price from their ticker. CoinGecko metadata alone never makes a token selectable.

custom_tokenbooleanalways

Custom on-chain-verified contract with project-scoped fixed USD or selected DEX pool pricing.

icon_pathpath | nullalways

Locally cached token icon when available.

token_standarderc20 | spl-token | nullalways

Verified runtime token standard; null for native assets.

metadata_verified_attimestamp | nullalways

On-chain metadata verification time for promoted tokens.

payment_supportedbooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

scanner_readybooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

balance_readybooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

default_finality_modeconfirmations | finalizedalways

Default finality model inherited by a new project policy.

default_required_confirmationsintegeralways

Default confirmation and monitoring policy.

default_monitoring_minutesintegeralways

Default confirmation and monitoring policy.

policyobject | nullalways
Project activation/finality policy, or null when not configured. Includes custom_price_mode (fixed/dex), custom_price_usd (fixed decimal string or null), custom_dex_pair (selected pool or null), and custom_dex (dex_id, quote_symbol, current price_usd or null, liquidity_usd, fetched_at, last_error). Custom pricing is shared by stores in this project.Details

Project activation/finality policy, or null when not configured. Includes custom_price_mode (fixed/dex), custom_price_usd (fixed decimal string or null), custom_dex_pair (selected pool or null), and custom_dex (dex_id, quote_symbol, current price_usd or null, liquidity_usd, fetched_at, last_error). Custom pricing is shared by stores in this project.

enabledbooleanrequired

Enables or disables the asset for the project. The native chain must be enabled before any token.

finality_modeconfirmations | finalizedrequired

Finality policy supported by the asset rail. finalized requires required_confirmations=1.

required_confirmationsintegerrequired
Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.Details

Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.

monitoring_minutesintegerrequired

1–10,080 minute polling window while an invoice is active.

late_monitoring_daysintegerrequired

0–3,650 days of monitoring after invoice expiry.

walletobject | nullalways

The chain's non-custodial project wallet. Tokens share their chain-native wallet.

idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

project_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

native_asset_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

chain_slugstringalways

Wallet chain and network.

networkstringalways

Wallet chain and network.

asset_symbolstringalways

Chain-native display identity.

asset_namestringalways

Chain-native display identity.

statuspending | active | disabled | erroralways

Operational wallet state.

labelstringalways

Operator label.

public_keystring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

primary_addressstring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

derivation_schemestring | nullalways

Address policy and format.

address_formatstring | nullalways

Address policy and format.

backup_confirmed_attimestamp | nullalways

Non-null after the operator confirms recovery backup.

activation_requiredbooleanalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

activation_verified_attimestamp|nullalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

receive_readinessobject | null5.5.0+
Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.Details

Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

monero_wallet_rpcMoneroWalletRpcBinding | nullalways
Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.Details

Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.

last_secret_revealed_attimestamp|nullalways

Console-side secret disclosure audit metadata.

secret_reveal_countintegeralways

Console-side secret disclosure audit metadata.

next_receive_indexintegeralways

Next reserved child-address index.

last_scanned_heightinteger|nullalways

Wallet scanner state.

last_scanned_attimestamp|nullalways

Wallet scanner state.

last_errorstring|nullalways

Wallet scanner state.

balances[]object[]always
Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.Details

Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.

wallet_idUUIDalways

Wallet and durable asset identities.

asset_idUUIDalways

Wallet and durable asset identities.

project_enabledbooleanalways

Whether this asset is currently enabled by the project's asset policy.

active_store_countintegeralways

Number of enabled stores that currently select this asset. This is an acceptance projection; read-only balance tracking remains independent.

active_store_ids[]UUID[]always

Enabled stores in this project that currently accept the asset. This permits exact local store filtering without another API request.

tracking_activebooleanalways
Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.Details

Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.

asset_kindnative | tokenalways

Native currency or verified contract/mint asset.

contract_addressstring | nullalways

Token contract or mint; null for native currency.

symbolstringalways

Display identity and atomic precision.

namestringalways

Display identity and atomic precision.

decimalsintegeralways

Display identity and atomic precision.

coingecko_idstring | nullalways

Pricing identity when mapped.

balancedecimal string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

balance_atomicinteger string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

price_usddecimal string | nullalways

Advisory cached USD unit price used for valuation.

value_usddecimal string | nullalways

Advisory fiat valuation when a current rate exists.

statuspending | refreshing | fresh | stale | erroralways
Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.Details

Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.

checked_attimestamp | nullalways

Time represented by a completed balance scan.

last_errorstring | nullalways

Safe operator diagnostic.

total_value_usddecimal string | nullalways

Advisory sum of balances with a current USD price.

balance_statuspending | refreshing | fresh | stale | error | unknownalways

Aggregated cache freshness; unknown is a defensive fallback and none of these states proves invoice settlement.

balance_checked_attimestamp | nullalways

Oldest relevant successful balance check represented by the aggregate.

recent_payments[]object[]always

Up to three newest valid detected, confirming, or final observations attributed to this exact wallet.

invoice_public_idUUIDalways

Customer-facing invoice identity associated with the observation.

chain_slugstringalways

Chain and native or verified token display symbol.

symbolstringalways

Chain and native or verified token display symbol.

transaction_idstringalways

Canonical transaction and transfer-event identity.

event_indexintegeralways

Canonical transaction and transfer-event identity.

amountdecimal stringalways

Exact observed asset amount without floating-point conversion.

statusdetected | confirming | finalalways

Current valid observation state. Reorged, replaced, and invalid observations are excluded.

confirmationsintegeralways

Latest observed confirmation count.

observed_atRFC 3339 timestampalways

Time Wholly Crypto first observed the payment.

created_atRFC 3339 timestampalways

Creation and last wallet update time.

updated_atRFC 3339 timestampalways

Creation and last wallet update time.

wallet_readinessreadiness enumalways
unsupported, project_disabled, project_asset_disabled, store_disabled, store_asset_disabled, wallet_missing, wallet_pending, wallet_disabled, wallet_error, backup_required, account_activation_required, external_wallet_rpc_required, or ready.Details

unsupported, project_disabled, project_asset_disabled, store_disabled, store_asset_disabled, wallet_missing, wallet_pending, wallet_disabled, wallet_error, backup_required, account_activation_required, external_wallet_rpc_required, or ready.

receive_readinessobject | null5.5.0+
Shared project receive-setup assessment. Includes wallet and independent scanner-provider checks, separate from balance freshness and sending gas. Null if no project policy exists. Invoice currency/rates are checked when creating an invoice.Details

Shared project receive-setup assessment. Includes wallet and independent scanner-provider checks, separate from balance freshness and sending gas. Null if no project policy exists. Invoice currency/rates are checked when creating an invoice.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

Usage notes
  • A token can be listed globally yet remain unselectable when scanner_ready or payment_supported is false.
  • The operator capability matrix also requires the scanner's exact endpoint role; a healthy endpoint serving an incompatible API is not counted.
  • Tokens share the project wallet of their native chain; they do not create another seed phrase.
  • Embedded wallet summaries are readiness-only and keep balances empty; use GET /v1/projects/{project_id}/wallets for enriched balances.

Errors

Error codes & retry rules

PUTUpdate project asset policy/v1/projects/{project_id}/payment-assets/{asset_id}Read + write

Creates or replaces the project policy for one durable asset and returns the refreshed project asset list. Disabling a native chain makes its native asset and tokens unavailable to new invoices, but preserves token policies, wallets, and store selections so they can be resumed later.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Content-Typerequiredapplication/json
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Enabled project assigned to the credential.

asset_idUUIDrequired

Asset id returned by the project asset list or token registration.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request PUT \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-assets/YOUR_ASSET_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "enabled": true,
  "finality_mode": "confirmations",
  "required_confirmations": 2,
  "monitoring_minutes": 60,
  "late_monitoring_days": 30
}'

Request body

enabledbooleanrequired

Enables or disables the asset for the project. The native chain must be enabled before any token.

finality_modeconfirmations | finalizedrequired

Finality policy supported by the asset rail. finalized requires required_confirmations=1.

required_confirmationsintegerrequired
Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.Details

Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.

monitoring_minutesintegerrequired

1–10,080 minute polling window while an invoice is active.

late_monitoring_daysintegerrequired

0–3,650 days of monitoring after invoice expiry.

Response 200 application/json

Example response
{
  "data": [
    { "asset": { "id": "ASSET_UUID", "symbol": "USDC", "asset_kind": "token", "scanner_ready": true }, "policy": { "enabled": true, "finality_mode": "confirmations", "required_confirmations": 2, "monitoring_minutes": 60, "late_monitoring_days": 30 }, "wallet_readiness": "ready" }
  ]
}

Response fields

data[]object[]
assetobjectalways

Durable native or verified token asset.

idUUIDalways

Durable payment-asset identifier used by project and store policy routes.

asset_keystringalways

Canonical CAIP-style native or contract asset identity.

chain_slugstringalways

Wholly Crypto chain identifier and configured network.

networkstringalways

Wholly Crypto chain identifier and configured network.

caip_network_idstringalways

Canonical network and asset identities.

caip_asset_idstring|nullalways

Canonical network and asset identities.

asset_kindnative | tokenalways

Whether settlement uses the chain currency or a verified contract/mint.

payment_railstringalways

Runtime rail: utxo, evm-native, solana-native, account-native, privacy-native, or token-transfer.

symbolstringalways

Display identity and exact atomic-unit precision.

namestringalways

Display identity and exact atomic-unit precision.

decimalsintegeralways

Display identity and exact atomic-unit precision.

contract_addressstring | nullalways

Canonical ERC-20 contract or SPL mint for tokens; null for native assets.

coingecko_idstring | nullalways

Discovery/pricing identity. Null for custom contracts; never infer a market price from their ticker. CoinGecko metadata alone never makes a token selectable.

custom_tokenbooleanalways

Custom on-chain-verified contract with project-scoped fixed USD or selected DEX pool pricing.

icon_pathpath | nullalways

Locally cached token icon when available.

token_standarderc20 | spl-token | nullalways

Verified runtime token standard; null for native assets.

metadata_verified_attimestamp | nullalways

On-chain metadata verification time for promoted tokens.

payment_supportedbooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

scanner_readybooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

balance_readybooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

default_finality_modeconfirmations | finalizedalways

Default finality model inherited by a new project policy.

default_required_confirmationsintegeralways

Default confirmation and monitoring policy.

default_monitoring_minutesintegeralways

Default confirmation and monitoring policy.

policyobject | nullalways
Project activation/finality policy, or null when not configured. Includes custom_price_mode (fixed/dex), custom_price_usd (fixed decimal string or null), custom_dex_pair (selected pool or null), and custom_dex (dex_id, quote_symbol, current price_usd or null, liquidity_usd, fetched_at, last_error). Custom pricing is shared by stores in this project.Details

Project activation/finality policy, or null when not configured. Includes custom_price_mode (fixed/dex), custom_price_usd (fixed decimal string or null), custom_dex_pair (selected pool or null), and custom_dex (dex_id, quote_symbol, current price_usd or null, liquidity_usd, fetched_at, last_error). Custom pricing is shared by stores in this project.

enabledbooleanrequired

Enables or disables the asset for the project. The native chain must be enabled before any token.

finality_modeconfirmations | finalizedrequired

Finality policy supported by the asset rail. finalized requires required_confirmations=1.

required_confirmationsintegerrequired
Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.Details

Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.

monitoring_minutesintegerrequired

1–10,080 minute polling window while an invoice is active.

late_monitoring_daysintegerrequired

0–3,650 days of monitoring after invoice expiry.

walletobject | nullalways

The chain's non-custodial project wallet. Tokens share their chain-native wallet.

idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

project_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

native_asset_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

chain_slugstringalways

Wallet chain and network.

networkstringalways

Wallet chain and network.

asset_symbolstringalways

Chain-native display identity.

asset_namestringalways

Chain-native display identity.

statuspending | active | disabled | erroralways

Operational wallet state.

labelstringalways

Operator label.

public_keystring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

primary_addressstring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

derivation_schemestring | nullalways

Address policy and format.

address_formatstring | nullalways

Address policy and format.

backup_confirmed_attimestamp | nullalways

Non-null after the operator confirms recovery backup.

activation_requiredbooleanalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

activation_verified_attimestamp|nullalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

receive_readinessobject | null5.5.0+
Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.Details

Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

monero_wallet_rpcMoneroWalletRpcBinding | nullalways
Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.Details

Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.

last_secret_revealed_attimestamp|nullalways

Console-side secret disclosure audit metadata.

secret_reveal_countintegeralways

Console-side secret disclosure audit metadata.

next_receive_indexintegeralways

Next reserved child-address index.

last_scanned_heightinteger|nullalways

Wallet scanner state.

last_scanned_attimestamp|nullalways

Wallet scanner state.

last_errorstring|nullalways

Wallet scanner state.

balances[]object[]always
Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.Details

Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.

wallet_idUUIDalways

Wallet and durable asset identities.

asset_idUUIDalways

Wallet and durable asset identities.

project_enabledbooleanalways

Whether this asset is currently enabled by the project's asset policy.

active_store_countintegeralways

Number of enabled stores that currently select this asset. This is an acceptance projection; read-only balance tracking remains independent.

active_store_ids[]UUID[]always

Enabled stores in this project that currently accept the asset. This permits exact local store filtering without another API request.

tracking_activebooleanalways
Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.Details

Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.

asset_kindnative | tokenalways

Native currency or verified contract/mint asset.

contract_addressstring | nullalways

Token contract or mint; null for native currency.

symbolstringalways

Display identity and atomic precision.

namestringalways

Display identity and atomic precision.

decimalsintegeralways

Display identity and atomic precision.

coingecko_idstring | nullalways

Pricing identity when mapped.

balancedecimal string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

balance_atomicinteger string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

price_usddecimal string | nullalways

Advisory cached USD unit price used for valuation.

value_usddecimal string | nullalways

Advisory fiat valuation when a current rate exists.

statuspending | refreshing | fresh | stale | erroralways
Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.Details

Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.

checked_attimestamp | nullalways

Time represented by a completed balance scan.

last_errorstring | nullalways

Safe operator diagnostic.

total_value_usddecimal string | nullalways

Advisory sum of balances with a current USD price.

balance_statuspending | refreshing | fresh | stale | error | unknownalways

Aggregated cache freshness; unknown is a defensive fallback and none of these states proves invoice settlement.

balance_checked_attimestamp | nullalways

Oldest relevant successful balance check represented by the aggregate.

recent_payments[]object[]always

Up to three newest valid detected, confirming, or final observations attributed to this exact wallet.

invoice_public_idUUIDalways

Customer-facing invoice identity associated with the observation.

chain_slugstringalways

Chain and native or verified token display symbol.

symbolstringalways

Chain and native or verified token display symbol.

transaction_idstringalways

Canonical transaction and transfer-event identity.

event_indexintegeralways

Canonical transaction and transfer-event identity.

amountdecimal stringalways

Exact observed asset amount without floating-point conversion.

statusdetected | confirming | finalalways

Current valid observation state. Reorged, replaced, and invalid observations are excluded.

confirmationsintegeralways

Latest observed confirmation count.

observed_atRFC 3339 timestampalways

Time Wholly Crypto first observed the payment.

created_atRFC 3339 timestampalways

Creation and last wallet update time.

updated_atRFC 3339 timestampalways

Creation and last wallet update time.

wallet_readinessreadiness enumalways
unsupported, project_disabled, project_asset_disabled, store_disabled, store_asset_disabled, wallet_missing, wallet_pending, wallet_disabled, wallet_error, backup_required, account_activation_required, external_wallet_rpc_required, or ready.Details

unsupported, project_disabled, project_asset_disabled, store_disabled, store_asset_disabled, wallet_missing, wallet_pending, wallet_disabled, wallet_error, backup_required, account_activation_required, external_wallet_rpc_required, or ready.

receive_readinessobject | null5.5.0+
Shared project receive-setup assessment. Includes wallet and independent scanner-provider checks, separate from balance freshness and sending gas. Null if no project policy exists. Invoice currency/rates are checked when creating an invoice.Details

Shared project receive-setup assessment. Includes wallet and independent scanner-provider checks, separate from balance freshness and sending gas. Null if no project policy exists. Invoice currency/rates are checked when creating an invoice.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

Usage notes
  • The body is a full policy replacement and rejects unknown fields.
  • Project enablement does not itself select the asset for any store.

Errors

Error codes & retry rules

GETBrowse payment-token candidates/v1/projects/{project_id}/payment-token-candidatesRead only

Searches locally cached CoinGecko contract mappings only on chains whose token invoice scanner and balance adapter are implemented. Results are discovery candidates, not trusted payment assets.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Enabled project assigned to the credential.

Query parameters

chain_slugstring

Required supported EVM chain slug or solana.

qstring

Optional name, symbol, CoinGecko id, contract, or mint substring; at most 80 characters.

limitinteger

Optional 1–100; defaults to 50.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-candidates?chain_slug=ethereum&q=USDC&limit=50" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [
    {
      "coingecko_id": "usd-coin",
      "chain_slug": "ethereum",
      "symbol": "USDC",
      "name": "USDC",
      "contract_address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "market_cap_rank": 7,
      "icon_path": "/assets/coingecko/usd-coin.png",
      "current_price_usd": "1.0001",
      "token_standard": "erc20",
      "scanner_ready": true,
      "registered_asset_id": null,
      "project_enabled": false
    }
  ]
}

Response fields

data[]object[]
coingecko_idstringalways

CoinGecko discovery identity used by the registration request.

chain_slugstringalways

Matched Wholly Crypto chain.

symbolstringalways

Catalog display identity.

namestringalways

Catalog display identity.

contract_addressstringalways

Matched contract or mint; it is verified on-chain before registration.

market_cap_rankinteger | nullalways

Discovery rank, not a trust or payment-readiness signal.

icon_pathpathalways

Locally cached CoinGecko icon path.

current_price_usddecimal string | nullalways

Advisory cached USD price.

token_standarderc20 | spl-tokenalways

Token standard supported by the selected chain adapter.

scanner_readybooleanalways

True only for candidates on a token rail implemented by this build.

registered_asset_idUUID | nullalways

Existing durable asset when already promoted.

project_enabledbooleanalways

Whether the registered asset is enabled for this project.

Usage notes
  • Supported token adapters: ERC-20 on Ethereum, Base, BNB Chain, HyperEVM, Avalanche, Polygon, Arbitrum, and Optimism; SPL on Solana.
  • Unsupported catalog chains are rejected instead of appearing selectable.
  • CoinGecko rank, icon, and price are advisory discovery data.

Errors

Error codes & retry rules

POSTVerify and register token/v1/projects/{project_id}/payment-token-assetsRead + write

Promotes one current candidate into the durable payment registry only after configured nodes verify chain identity, contract/mint identity, decimals, and a usable balance query. Registration never trusts CoinGecko metadata by itself, and each project is capped at 20 registered token assets.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Content-Typerequiredapplication/json
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Enabled project assigned to the credential.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-assets" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "chain_slug": "ethereum",
  "coingecko_id": "usd-coin",
  "enabled": true
}'

Request body

chain_slugstringrequired

ethereum, base, bnb-chain, hyperliquid, avalanche, polygon, arbitrum, optimism, or solana.

coingecko_idstringrequired
Exact candidate identity returned by token search. Preserve leading underscores or hyphens, such as _ or -6. Do not derive this ID from the token name or ticker.Details

Exact candidate identity returned by token search. Preserve leading underscores or hyphens, such as _ or -6. Do not derive this ID from the token name or ticker.

enabledbooleanoptional

Project policy state after verification; defaults to true.

Response 201 application/json

Example response
{
  "data": {
    "asset_id": "44444444-4444-4444-8444-444444444444",
    "chain_slug": "ethereum",
    "coingecko_id": "usd-coin",
    "contract_address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
    "token_standard": "erc20",
    "symbol": "USDC",
    "name": "USDC",
    "decimals": 6,
    "enabled": true,
    "metadata_verified_at": "2026-08-31T18:00:00Z"
  }
}

Response fields

dataobject
asset_idUUIDalways

Durable payment asset identifier.

chain_slugstringalways

Verified chain and retained discovery/pricing identity.

coingecko_idstringalways

Verified chain and retained discovery/pricing identity.

contract_addressstringalways

Canonical verified contract or mint.

token_standarderc20 | spl-tokenalways

Verified runtime token standard.

symbolstringalways

Promoted display identity and exact precision.

namestringalways

Promoted display identity and exact precision.

decimalsintegeralways

Promoted display identity and exact precision.

enabledbooleanalways

Initial project policy state.

metadata_verified_atRFC 3339 timestampalways

On-chain verification time.

Usage notes
  • Enable the chain's native project asset before registering its tokens.
  • A project can register at most 20 token assets; a new candidate beyond that ceiling returns token_chain_not_ready (409). Reusing an already-registered asset does not consume another slot.
  • Node verification can take longer than a catalog read; use an explicit client timeout.
  • After registration, select the asset for each store that should offer it.

Errors

Error codes & retry rules

GETFind custom token DEX pools/v1/projects/{project_id}/payment-token-dex-poolsRead only

Find up to 12 eligible pools by exact chain and base-token contract via DEX Screener, ordered by liquidity. This does not register or enable a token.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN

Path parameters

project_idUUIDrequired

Assigned project.

Query parameters

chain_slugstring

Supported EVM token chain or solana.

contract_addressstring

Exact ERC-20 contract or classic SPL mint.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-dex-pools?chain_slug=ethereum&contract_address=YOUR_TOKEN_CONTRACT" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{"data":[{"pair_address":"0x2222222222222222222222222222222222222222","dex_id":"uniswap","quote_symbol":"WETH","price_usd":"0.25","liquidity_usd":"250000.00","fetched_at":"2026-09-09T12:00:00Z","url":"https://dexscreener.com/ethereum/0x2222222222222222222222222222222222222222"}]}

Response fields

data[]object[]
pair_addressstringalways

Exact pool identifier, exchange ID (e.g. uniswap/pancakeswap), and display-only paired ticker.

dex_idstringalways

Exact pool identifier, exchange ID (e.g. uniswap/pancakeswap), and display-only paired ticker.

quote_symbolstringalways

Exact pool identifier, exchange ID (e.g. uniswap/pancakeswap), and display-only paired ticker.

price_usddecimal stringalways

USD price of the requested base token and total pool liquidity. At least $10,000 liquidity and a trade in the last hour are required.

liquidity_usddecimal stringalways

USD price of the requested base token and total pool liquidity. At least $10,000 liquidity and a trade in the last hour are required.

fetched_atRFC 3339 timestampalways

When the server retrieved the provider observation, not the timestamp of an on-chain trade.

urlHTTPS URLalways

Validated DEX Screener link to this pool.

Usage notes
  • An empty data array means no qualifying pool was found. Only pools where the exact requested contract is the base token are returned; quote-side USD prices are never assumed.
  • DEX listing is not a security audit. Minimum liquidity and recent activity reduce unusable quotes but do not prevent market manipulation.
  • Uniswap, PancakeSwap and other indexed DEXs are supported where the existing chain scanner supports tokens. API access remains project-scoped and rate-limited. Provider calls are also serialized and throttled.

Errors

Error codes & retry rules

POSTAdd or reprice custom token/v1/projects/{project_id}/payment-token-assets/customRead + write

Verifies a custom contract using configured chain nodes and registers it without requiring a CoinGecko listing. The fixed USD price or selected automatic DEX pool belongs to this project, not to the ticker or other projects. Repeating the same identity updates its project price without changing an existing enabled/disabled policy.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Content-Typerequiredapplication/json

Path parameters

project_idUUIDrequired

Project assigned to this write-capable credential.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-assets/custom" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "chain_slug": "ethereum",
  "contract_address": "YOUR_VERIFIED_TOKEN_CONTRACT",
  "name": "Example token",
  "symbol": "EXAMPLE",
  "price_usd": "0.25"
}'

Request body

chain_slugstringrequired

ethereum, base, bnb-chain, hyperliquid, avalanche, polygon, arbitrum, optimism, or solana. Fixed for this contract.

contract_addressstringrequired
ERC-20 contract (0x plus 40 hexadecimal characters), or a classic SPL mint. Nodes verify network identity and exact decimals; caller-supplied decimals and RPC URLs are rejected.Details

ERC-20 contract (0x plus 40 hexadecimal characters), or a classic SPL mint. Nodes verify network identity and exact decimals; caller-supplied decimals and RPC URLs are rejected.

namestringrequired
Display name (1–80 characters) and ticker (1–16 letters/digits/dots/underscores/hyphens, first character alphanumeric). Existing identities cannot be renamed by this endpoint.Details

Display name (1–80 characters) and ticker (1–16 letters/digits/dots/underscores/hyphens, first character alphanumeric). Existing identities cannot be renamed by this endpoint.

symbolstringrequired
Display name (1–80 characters) and ticker (1–16 letters/digits/dots/underscores/hyphens, first character alphanumeric). Existing identities cannot be renamed by this endpoint.Details

Display name (1–80 characters) and ticker (1–16 letters/digits/dots/underscores/hyphens, first character alphanumeric). Existing identities cannot be renamed by this endpoint.

price_modefixed | dexoptional

Defaults to fixed for backwards compatibility. DEX uses a specific pool discovered for the exact chain and contract.

price_usddecimal stringfixed mode

Fixed USD value of ONE token, positive, at most 30 decimals, maximum 1000000000000000000000000. No exponent or floats. Omit in dex mode.

dex_pair_addressstringdex mode
Pool address from payment-token-dex-pools. Required in dex mode; omit in fixed mode. The server rechecks pool identity, price, liquidity and activity on every save.Details

Pool address from payment-token-dex-pools. Required in dex mode; omit in fixed mode. The server rechecks pool identity, price, liquidity and activity on every save.

Response 200 application/json

Example response
{"data":{"asset_id":"44444444-4444-4444-8444-444444444444"}}

Response fields

dataobject
asset_idstring
Usage notes
  • After registration, select asset_id in the store's payment-assets endpoint; registration alone never enables a store method.
  • Custom and catalog tokens share the 20-token project limit. The same contract on different chains is a different payment asset.
  • Existing catalog contracts return 409: use catalog registration to retain automatic market rates. A custom ticker never borrows a namesake token's price.
  • Fixed prices are operator estimates. Automatic DEX prices are spot observations from the selected pool via DEX Screener, not a manipulation-resistant oracle. The store spread and upward rounding still apply, with fresh fiat rates. Already-issued quotes are unchanged.
  • For DEX mode first discover a pool, then send price_mode: dex and dex_pair_address, omitting price_usd. A shared background task refreshes selected pools every minute. Failed checks or prices older than five minutes remove this token from new quotes; there is no silent fixed-price or ticker fallback.
  • Only standard ERC-20 and classic SPL tokens are accepted. Token-2022/extensions and native-only chains are rejected. Technical verification is not an issuer/contract security audit; fee-on-transfer, rebasing or blacklisting tokens can behave incompatibly.
  • Use a client timeout of at least 60 seconds. Verification is bounded and can try node fallbacks. Invalid input returns 400; failed chain/contract checks return 422; identity conflicts or limits return 409.

Errors

Error codes & retry rules

GETList store payment methods/v1/projects/{project_id}/stores/{store_id}/payment-assetsRead only

Lists on-chain assets in data and separate Lightning readiness in lightning. On-chain methods require ready chain wallets. Lightning uses the verified external receiving connection selected in the store, independently of the on-chain Bitcoin wallet.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Project assigned to the credential; it may be paused.

store_idUUIDrequired

Store belonging to project_id; it may be paused.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [
    { "asset": { "id": "ASSET_UUID", "chain_slug": "ethereum", "symbol": "USDC", "asset_kind": "token", "token_standard": "erc20", "scanner_ready": true }, "project_policy": { "enabled": true, "required_confirmations": 12 }, "selected": true, "display_order": 0, "confirmation_policy": { "finality_mode": "confirmations", "project_required_confirmations": 12, "override_required_confirmations": 3, "effective_required_confirmations": 3, "editable": true, "minimum_required_confirmations": 0, "maximum_required_confirmations": 48 }, "wallet": { "id": "WALLET_UUID", "status": "active" }, "wallet_readiness": "ready" }
  ],
  "lightning": { "payment_rail": "lightning", "symbol": "BTC", "asset_decimals": 11, "enabled": true, "ready": true }
}

Response fields

data[]object[]
assetobjectalways

Project-visible native or verified token asset.

idUUIDalways

Durable payment-asset identifier used by project and store policy routes.

asset_keystringalways

Canonical CAIP-style native or contract asset identity.

chain_slugstringalways

Wholly Crypto chain identifier and configured network.

networkstringalways

Wholly Crypto chain identifier and configured network.

caip_network_idstringalways

Canonical network and asset identities.

caip_asset_idstring|nullalways

Canonical network and asset identities.

asset_kindnative | tokenalways

Whether settlement uses the chain currency or a verified contract/mint.

payment_railstringalways

Runtime rail: utxo, evm-native, solana-native, account-native, privacy-native, or token-transfer.

symbolstringalways

Display identity and exact atomic-unit precision.

namestringalways

Display identity and exact atomic-unit precision.

decimalsintegeralways

Display identity and exact atomic-unit precision.

contract_addressstring | nullalways

Canonical ERC-20 contract or SPL mint for tokens; null for native assets.

coingecko_idstring | nullalways

Discovery/pricing identity. Null for custom contracts; never infer a market price from their ticker. CoinGecko metadata alone never makes a token selectable.

custom_tokenbooleanalways

Custom on-chain-verified contract with project-scoped fixed USD or selected DEX pool pricing.

icon_pathpath | nullalways

Locally cached token icon when available.

token_standarderc20 | spl-token | nullalways

Verified runtime token standard; null for native assets.

metadata_verified_attimestamp | nullalways

On-chain metadata verification time for promoted tokens.

payment_supportedbooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

scanner_readybooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

balance_readybooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

default_finality_modeconfirmations | finalizedalways

Default finality model inherited by a new project policy.

default_required_confirmationsintegeralways

Default confirmation and monitoring policy.

default_monitoring_minutesintegeralways

Default confirmation and monitoring policy.

project_policyobject | nullalways

Parent project policy.

enabledbooleanrequired

Enables or disables the asset for the project. The native chain must be enabled before any token.

finality_modeconfirmations | finalizedrequired

Finality policy supported by the asset rail. finalized requires required_confirmations=1.

required_confirmationsintegerrequired
Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.Details

Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.

monitoring_minutesintegerrequired

1–10,080 minute polling window while an invoice is active.

late_monitoring_daysintegerrequired

0–3,650 days of monitoring after invoice expiry.

selectedbooleanalways
Whether this method is part of the store's saved desired configuration. It is offered when its project policy, wallet, installed adapter and pricing are valid. Temporary scanner outages do not remove it from new invoices.Details

Whether this method is part of the store's saved desired configuration. It is offered when its project policy, wallet, installed adapter and pricing are valid. Temporary scanner outages do not remove it from new invoices.

display_orderinteger | nullalways

Store checkout order when selected.

confirmation_policyobject | nullalways

Effective store policy for a project-configured asset. Null when no project policy exists.

finality_modeconfirmations | finalizedalways

Whether settlement uses a configurable block count or network finality.

project_required_confirmationsintegeralways

Current project default used by future invoices when no store override is set.

override_required_confirmationsinteger | nullalways

Store-specific count, or null to inherit the project default.

effective_required_confirmationsintegeralways

Count that new invoices for this store and asset will snapshot.

editablebooleanalways

False for finalized networks whose finality policy cannot be overridden.

minimum_required_confirmationsintegeralways

Inclusive chain-aware lower bound; 0 is exposed only on rails that support detection-time acceptance.

maximum_required_confirmationsintegeralways

Inclusive chain-aware upper bound.

walletobject | nullalways

Chain wallet shared by native and token assets.

idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

project_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

native_asset_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

chain_slugstringalways

Wallet chain and network.

networkstringalways

Wallet chain and network.

asset_symbolstringalways

Chain-native display identity.

asset_namestringalways

Chain-native display identity.

statuspending | active | disabled | erroralways

Operational wallet state.

labelstringalways

Operator label.

public_keystring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

primary_addressstring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

derivation_schemestring | nullalways

Address policy and format.

address_formatstring | nullalways

Address policy and format.

backup_confirmed_attimestamp | nullalways

Non-null after the operator confirms recovery backup.

activation_requiredbooleanalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

activation_verified_attimestamp|nullalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

receive_readinessobject | null5.5.0+
Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.Details

Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

monero_wallet_rpcMoneroWalletRpcBinding | nullalways
Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.Details

Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.

last_secret_revealed_attimestamp|nullalways

Console-side secret disclosure audit metadata.

secret_reveal_countintegeralways

Console-side secret disclosure audit metadata.

next_receive_indexintegeralways

Next reserved child-address index.

last_scanned_heightinteger|nullalways

Wallet scanner state.

last_scanned_attimestamp|nullalways

Wallet scanner state.

last_errorstring|nullalways

Wallet scanner state.

balances[]object[]always
Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.Details

Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.

wallet_idUUIDalways

Wallet and durable asset identities.

asset_idUUIDalways

Wallet and durable asset identities.

project_enabledbooleanalways

Whether this asset is currently enabled by the project's asset policy.

active_store_countintegeralways

Number of enabled stores that currently select this asset. This is an acceptance projection; read-only balance tracking remains independent.

active_store_ids[]UUID[]always

Enabled stores in this project that currently accept the asset. This permits exact local store filtering without another API request.

tracking_activebooleanalways
Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.Details

Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.

asset_kindnative | tokenalways

Native currency or verified contract/mint asset.

contract_addressstring | nullalways

Token contract or mint; null for native currency.

symbolstringalways

Display identity and atomic precision.

namestringalways

Display identity and atomic precision.

decimalsintegeralways

Display identity and atomic precision.

coingecko_idstring | nullalways

Pricing identity when mapped.

balancedecimal string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

balance_atomicinteger string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

price_usddecimal string | nullalways

Advisory cached USD unit price used for valuation.

value_usddecimal string | nullalways

Advisory fiat valuation when a current rate exists.

statuspending | refreshing | fresh | stale | erroralways
Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.Details

Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.

checked_attimestamp | nullalways

Time represented by a completed balance scan.

last_errorstring | nullalways

Safe operator diagnostic.

total_value_usddecimal string | nullalways

Advisory sum of balances with a current USD price.

balance_statuspending | refreshing | fresh | stale | error | unknownalways

Aggregated cache freshness; unknown is a defensive fallback and none of these states proves invoice settlement.

balance_checked_attimestamp | nullalways

Oldest relevant successful balance check represented by the aggregate.

recent_payments[]object[]always

Up to three newest valid detected, confirming, or final observations attributed to this exact wallet.

invoice_public_idUUIDalways

Customer-facing invoice identity associated with the observation.

chain_slugstringalways

Chain and native or verified token display symbol.

symbolstringalways

Chain and native or verified token display symbol.

transaction_idstringalways

Canonical transaction and transfer-event identity.

event_indexintegeralways

Canonical transaction and transfer-event identity.

amountdecimal stringalways

Exact observed asset amount without floating-point conversion.

statusdetected | confirming | finalalways

Current valid observation state. Reorged, replaced, and invalid observations are excluded.

confirmationsintegeralways

Latest observed confirmation count.

observed_atRFC 3339 timestampalways

Time Wholly Crypto first observed the payment.

created_atRFC 3339 timestampalways

Creation and last wallet update time.

updated_atRFC 3339 timestampalways

Creation and last wallet update time.

wallet_readinessreadiness enumalways

Wallet/policy status only; use receive_readiness for scanner prerequisites.

receive_readinessobject | null5.5.0+
Shared receive setup plus store acceptance. Uses cached observations; not a reservation or guarantee. Creation rechecks requirements and the actual invoice exchange rate.Details

Shared receive setup plus store acceptance. Uses cached observations; not a reservation or guarantee. Creation rechecks requirements and the actual invoice exchange rate.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

lightningobject
payment_railstring
symbolstring
asset_decimalsinteger
enabledboolean
readyboolean
Usage notes
  • selected is on-chain configuration; wallet_readiness is its live eligibility gate.
  • The lightning response member contains payment_rail: lightning, symbol: BTC, asset_decimals: 11, enabled and ready. It never contains node credentials. Configure this method in the store's console; updating the assets array does not change Lightning.
  • confirmation_policy applies only to on-chain methods. Lightning settles without block confirmations and requires its full BOLT11 amount, without partial-payment tolerance.
  • Native and token methods on one chain use the same invoice destination for that chain wallet.
  • Embedded wallet summaries are readiness-only and keep balances empty; use the dedicated project wallets route for current values.

Errors

Error codes & retry rules

PUTReplace store payment methods/v1/projects/{project_id}/stores/{store_id}/payment-assetsRead + write

Atomically replaces the store's complete ordered asset subset and returns the refreshed list. Omitted assets are deselected.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Content-Typerequiredapplication/json
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Project assigned to the credential; it may be paused.

store_idUUIDrequired

Store belonging to project_id; it may be paused.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request PUT \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "assets": [
    {
      "asset_id": "YOUR_ASSET_ID",
      "display_order": 0
    }
  ]
}'

Request body

assets[]object[]required

Complete replacement list, at most 64 entries. Each entry contains a unique asset_id and unique display_order from 0 through 10,000.

asset_idUUIDrequired
display_orderintegeroptional

Response 200 application/json

Example response
{
  "data": [
    { "asset": { "id": "44444444-4444-4444-8444-444444444444", "symbol": "USDC" }, "selected": true, "display_order": 0, "confirmation_policy": { "finality_mode": "confirmations", "project_required_confirmations": 12, "override_required_confirmations": null, "effective_required_confirmations": 12, "editable": true, "minimum_required_confirmations": 0, "maximum_required_confirmations": 48 }, "wallet_readiness": "ready" }
  ]
}

Response fields

data[]object[]
assetobjectalways

Project-visible native or verified token asset.

idUUIDalways

Durable payment-asset identifier used by project and store policy routes.

asset_keystringalways

Canonical CAIP-style native or contract asset identity.

chain_slugstringalways

Wholly Crypto chain identifier and configured network.

networkstringalways

Wholly Crypto chain identifier and configured network.

caip_network_idstringalways

Canonical network and asset identities.

caip_asset_idstring|nullalways

Canonical network and asset identities.

asset_kindnative | tokenalways

Whether settlement uses the chain currency or a verified contract/mint.

payment_railstringalways

Runtime rail: utxo, evm-native, solana-native, account-native, privacy-native, or token-transfer.

symbolstringalways

Display identity and exact atomic-unit precision.

namestringalways

Display identity and exact atomic-unit precision.

decimalsintegeralways

Display identity and exact atomic-unit precision.

contract_addressstring | nullalways

Canonical ERC-20 contract or SPL mint for tokens; null for native assets.

coingecko_idstring | nullalways

Discovery/pricing identity. Null for custom contracts; never infer a market price from their ticker. CoinGecko metadata alone never makes a token selectable.

custom_tokenbooleanalways

Custom on-chain-verified contract with project-scoped fixed USD or selected DEX pool pricing.

icon_pathpath | nullalways

Locally cached token icon when available.

token_standarderc20 | spl-token | nullalways

Verified runtime token standard; null for native assets.

metadata_verified_attimestamp | nullalways

On-chain metadata verification time for promoted tokens.

payment_supportedbooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

scanner_readybooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

balance_readybooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

default_finality_modeconfirmations | finalizedalways

Default finality model inherited by a new project policy.

default_required_confirmationsintegeralways

Default confirmation and monitoring policy.

default_monitoring_minutesintegeralways

Default confirmation and monitoring policy.

project_policyobject | nullalways

Parent project policy.

enabledbooleanrequired

Enables or disables the asset for the project. The native chain must be enabled before any token.

finality_modeconfirmations | finalizedrequired

Finality policy supported by the asset rail. finalized requires required_confirmations=1.

required_confirmationsintegerrequired
Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.Details

Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.

monitoring_minutesintegerrequired

1–10,080 minute polling window while an invoice is active.

late_monitoring_daysintegerrequired

0–3,650 days of monitoring after invoice expiry.

selectedbooleanalways
Whether this method is part of the store's saved desired configuration. It is offered when its project policy, wallet, installed adapter and pricing are valid. Temporary scanner outages do not remove it from new invoices.Details

Whether this method is part of the store's saved desired configuration. It is offered when its project policy, wallet, installed adapter and pricing are valid. Temporary scanner outages do not remove it from new invoices.

display_orderinteger | nullalways

Store checkout order when selected.

confirmation_policyobject | nullalways

Effective store policy for a project-configured asset. Null when no project policy exists.

finality_modeconfirmations | finalizedalways

Whether settlement uses a configurable block count or network finality.

project_required_confirmationsintegeralways

Current project default used by future invoices when no store override is set.

override_required_confirmationsinteger | nullalways

Store-specific count, or null to inherit the project default.

effective_required_confirmationsintegeralways

Count that new invoices for this store and asset will snapshot.

editablebooleanalways

False for finalized networks whose finality policy cannot be overridden.

minimum_required_confirmationsintegeralways

Inclusive chain-aware lower bound; 0 is exposed only on rails that support detection-time acceptance.

maximum_required_confirmationsintegeralways

Inclusive chain-aware upper bound.

walletobject | nullalways

Chain wallet shared by native and token assets.

idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

project_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

native_asset_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

chain_slugstringalways

Wallet chain and network.

networkstringalways

Wallet chain and network.

asset_symbolstringalways

Chain-native display identity.

asset_namestringalways

Chain-native display identity.

statuspending | active | disabled | erroralways

Operational wallet state.

labelstringalways

Operator label.

public_keystring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

primary_addressstring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

derivation_schemestring | nullalways

Address policy and format.

address_formatstring | nullalways

Address policy and format.

backup_confirmed_attimestamp | nullalways

Non-null after the operator confirms recovery backup.

activation_requiredbooleanalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

activation_verified_attimestamp|nullalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

receive_readinessobject | null5.5.0+
Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.Details

Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

monero_wallet_rpcMoneroWalletRpcBinding | nullalways
Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.Details

Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.

last_secret_revealed_attimestamp|nullalways

Console-side secret disclosure audit metadata.

secret_reveal_countintegeralways

Console-side secret disclosure audit metadata.

next_receive_indexintegeralways

Next reserved child-address index.

last_scanned_heightinteger|nullalways

Wallet scanner state.

last_scanned_attimestamp|nullalways

Wallet scanner state.

last_errorstring|nullalways

Wallet scanner state.

balances[]object[]always
Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.Details

Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.

wallet_idUUIDalways

Wallet and durable asset identities.

asset_idUUIDalways

Wallet and durable asset identities.

project_enabledbooleanalways

Whether this asset is currently enabled by the project's asset policy.

active_store_countintegeralways

Number of enabled stores that currently select this asset. This is an acceptance projection; read-only balance tracking remains independent.

active_store_ids[]UUID[]always

Enabled stores in this project that currently accept the asset. This permits exact local store filtering without another API request.

tracking_activebooleanalways
Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.Details

Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.

asset_kindnative | tokenalways

Native currency or verified contract/mint asset.

contract_addressstring | nullalways

Token contract or mint; null for native currency.

symbolstringalways

Display identity and atomic precision.

namestringalways

Display identity and atomic precision.

decimalsintegeralways

Display identity and atomic precision.

coingecko_idstring | nullalways

Pricing identity when mapped.

balancedecimal string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

balance_atomicinteger string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

price_usddecimal string | nullalways

Advisory cached USD unit price used for valuation.

value_usddecimal string | nullalways

Advisory fiat valuation when a current rate exists.

statuspending | refreshing | fresh | stale | erroralways
Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.Details

Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.

checked_attimestamp | nullalways

Time represented by a completed balance scan.

last_errorstring | nullalways

Safe operator diagnostic.

total_value_usddecimal string | nullalways

Advisory sum of balances with a current USD price.

balance_statuspending | refreshing | fresh | stale | error | unknownalways

Aggregated cache freshness; unknown is a defensive fallback and none of these states proves invoice settlement.

balance_checked_attimestamp | nullalways

Oldest relevant successful balance check represented by the aggregate.

recent_payments[]object[]always

Up to three newest valid detected, confirming, or final observations attributed to this exact wallet.

invoice_public_idUUIDalways

Customer-facing invoice identity associated with the observation.

chain_slugstringalways

Chain and native or verified token display symbol.

symbolstringalways

Chain and native or verified token display symbol.

transaction_idstringalways

Canonical transaction and transfer-event identity.

event_indexintegeralways

Canonical transaction and transfer-event identity.

amountdecimal stringalways

Exact observed asset amount without floating-point conversion.

statusdetected | confirming | finalalways

Current valid observation state. Reorged, replaced, and invalid observations are excluded.

confirmationsintegeralways

Latest observed confirmation count.

observed_atRFC 3339 timestampalways

Time Wholly Crypto first observed the payment.

created_atRFC 3339 timestampalways

Creation and last wallet update time.

updated_atRFC 3339 timestampalways

Creation and last wallet update time.

wallet_readinessreadiness enumalways

Wallet/policy status only; use receive_readiness for scanner prerequisites.

receive_readinessobject | null5.5.0+
Shared receive setup plus store acceptance. Uses cached observations; not a reservation or guarantee. Creation rechecks requirements and the actual invoice exchange rate.Details

Shared receive setup plus store acceptance. Uses cached observations; not a reservation or guarantee. Creation rechecks requirements and the actual invoice exchange rate.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

Usage notes
  • The array accepts at most 64 unique assets and display orders.
  • Selections are saved desired configuration and may be staged before a wallet is backed up or while a chain is paused. Invoice creation still offers only methods whose project policy, native parent policy, wallet, and runtime checks are ready.
  • Send an empty assets array to configure no payment methods.

Errors

Error codes & retry rules

PUTSet a store confirmation policy/v1/projects/{project_id}/stores/{store_id}/payment-assets/{asset_id}/confirmation-policyRead + write

Sets or clears one store-specific confirmation override and returns the refreshed store payment-method list. The asset must already be selected for the store. Configuration remains available while the project, store, chain, or wallet is paused.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Content-Typerequiredapplication/json
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Project assigned to the credential; it may be paused.

store_idUUIDrequired

Store belonging to project_id; it may be paused.

asset_idUUIDrequired

Currently selected store payment asset to update.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request PUT \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets/YOUR_ASSET_ID/confirmation-policy" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "strategy": "custom",
  "required_confirmations": 0
}'

Request body

strategyinherit | customrequired

Tagged strategy. inherit removes the store override; custom requires required_confirmations.

required_confirmationsintegercustom only

Whole number inside the minimum/maximum returned for this asset. Unknown or extra fields are rejected.

Response 200 application/json

Example response
{
  "data": [
    {
      "asset": { "id": "YOUR_ASSET_ID", "chain_slug": "bitcoin", "symbol": "BTC" },
      "selected": true,
      "display_order": 0,
      "confirmation_policy": {
        "finality_mode": "confirmations",
        "project_required_confirmations": 2,
        "override_required_confirmations": 0,
        "effective_required_confirmations": 0,
        "editable": true,
        "minimum_required_confirmations": 0,
        "maximum_required_confirmations": 10000
      },
      "wallet_readiness": "ready"
    }
  ]
}

Response fields

data[]object[]
assetobjectalways

Project-visible native or verified token asset.

idUUIDalways

Durable payment-asset identifier used by project and store policy routes.

asset_keystringalways

Canonical CAIP-style native or contract asset identity.

chain_slugstringalways

Wholly Crypto chain identifier and configured network.

networkstringalways

Wholly Crypto chain identifier and configured network.

caip_network_idstringalways

Canonical network and asset identities.

caip_asset_idstring|nullalways

Canonical network and asset identities.

asset_kindnative | tokenalways

Whether settlement uses the chain currency or a verified contract/mint.

payment_railstringalways

Runtime rail: utxo, evm-native, solana-native, account-native, privacy-native, or token-transfer.

symbolstringalways

Display identity and exact atomic-unit precision.

namestringalways

Display identity and exact atomic-unit precision.

decimalsintegeralways

Display identity and exact atomic-unit precision.

contract_addressstring | nullalways

Canonical ERC-20 contract or SPL mint for tokens; null for native assets.

coingecko_idstring | nullalways

Discovery/pricing identity. Null for custom contracts; never infer a market price from their ticker. CoinGecko metadata alone never makes a token selectable.

custom_tokenbooleanalways

Custom on-chain-verified contract with project-scoped fixed USD or selected DEX pool pricing.

icon_pathpath | nullalways

Locally cached token icon when available.

token_standarderc20 | spl-token | nullalways

Verified runtime token standard; null for native assets.

metadata_verified_attimestamp | nullalways

On-chain metadata verification time for promoted tokens.

payment_supportedbooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

scanner_readybooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

balance_readybooleanalways
Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.Details

Build-time registry gates. scanner_ready means the payment scanner runtime is installed; payment confirmation needs the configured number of healthy exact-role providers (2 by default, optional 1); temporary scanner availability does not block invoice creation from 6.0.6. balance_ready is true only for implemented balance adapters.

default_finality_modeconfirmations | finalizedalways

Default finality model inherited by a new project policy.

default_required_confirmationsintegeralways

Default confirmation and monitoring policy.

default_monitoring_minutesintegeralways

Default confirmation and monitoring policy.

project_policyobject | nullalways

Parent project policy.

enabledbooleanrequired

Enables or disables the asset for the project. The native chain must be enabled before any token.

finality_modeconfirmations | finalizedrequired

Finality policy supported by the asset rail. finalized requires required_confirmations=1.

required_confirmationsintegerrequired
Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.Details

Bitcoin and EVM rails accept zero; other confirmation rails require at least one, finalized-only rails require exactly one, and EVM rails are bounded to 0–48 so every transfer remains inside the transaction replay window.

monitoring_minutesintegerrequired

1–10,080 minute polling window while an invoice is active.

late_monitoring_daysintegerrequired

0–3,650 days of monitoring after invoice expiry.

selectedbooleanalways
Whether this method is part of the store's saved desired configuration. It is offered when its project policy, wallet, installed adapter and pricing are valid. Temporary scanner outages do not remove it from new invoices.Details

Whether this method is part of the store's saved desired configuration. It is offered when its project policy, wallet, installed adapter and pricing are valid. Temporary scanner outages do not remove it from new invoices.

display_orderinteger | nullalways

Store checkout order when selected.

confirmation_policyobject | nullalways

Effective store policy for a project-configured asset. Null when no project policy exists.

finality_modeconfirmations | finalizedalways

Whether settlement uses a configurable block count or network finality.

project_required_confirmationsintegeralways

Current project default used by future invoices when no store override is set.

override_required_confirmationsinteger | nullalways

Store-specific count, or null to inherit the project default.

effective_required_confirmationsintegeralways

Count that new invoices for this store and asset will snapshot.

editablebooleanalways

False for finalized networks whose finality policy cannot be overridden.

minimum_required_confirmationsintegeralways

Inclusive chain-aware lower bound; 0 is exposed only on rails that support detection-time acceptance.

maximum_required_confirmationsintegeralways

Inclusive chain-aware upper bound.

walletobject | nullalways

Chain wallet shared by native and token assets.

idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

project_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

native_asset_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

chain_slugstringalways

Wallet chain and network.

networkstringalways

Wallet chain and network.

asset_symbolstringalways

Chain-native display identity.

asset_namestringalways

Chain-native display identity.

statuspending | active | disabled | erroralways

Operational wallet state.

labelstringalways

Operator label.

public_keystring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

primary_addressstring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

derivation_schemestring | nullalways

Address policy and format.

address_formatstring | nullalways

Address policy and format.

backup_confirmed_attimestamp | nullalways

Non-null after the operator confirms recovery backup.

activation_requiredbooleanalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

activation_verified_attimestamp|nullalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

receive_readinessobject | null5.5.0+
Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.Details

Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

monero_wallet_rpcMoneroWalletRpcBinding | nullalways
Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.Details

Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.

last_secret_revealed_attimestamp|nullalways

Console-side secret disclosure audit metadata.

secret_reveal_countintegeralways

Console-side secret disclosure audit metadata.

next_receive_indexintegeralways

Next reserved child-address index.

last_scanned_heightinteger|nullalways

Wallet scanner state.

last_scanned_attimestamp|nullalways

Wallet scanner state.

last_errorstring|nullalways

Wallet scanner state.

balances[]object[]always
Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.Details

Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.

wallet_idUUIDalways

Wallet and durable asset identities.

asset_idUUIDalways

Wallet and durable asset identities.

project_enabledbooleanalways

Whether this asset is currently enabled by the project's asset policy.

active_store_countintegeralways

Number of enabled stores that currently select this asset. This is an acceptance projection; read-only balance tracking remains independent.

active_store_ids[]UUID[]always

Enabled stores in this project that currently accept the asset. This permits exact local store filtering without another API request.

tracking_activebooleanalways
Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.Details

Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.

asset_kindnative | tokenalways

Native currency or verified contract/mint asset.

contract_addressstring | nullalways

Token contract or mint; null for native currency.

symbolstringalways

Display identity and atomic precision.

namestringalways

Display identity and atomic precision.

decimalsintegeralways

Display identity and atomic precision.

coingecko_idstring | nullalways

Pricing identity when mapped.

balancedecimal string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

balance_atomicinteger string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

price_usddecimal string | nullalways

Advisory cached USD unit price used for valuation.

value_usddecimal string | nullalways

Advisory fiat valuation when a current rate exists.

statuspending | refreshing | fresh | stale | erroralways
Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.Details

Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.

checked_attimestamp | nullalways

Time represented by a completed balance scan.

last_errorstring | nullalways

Safe operator diagnostic.

total_value_usddecimal string | nullalways

Advisory sum of balances with a current USD price.

balance_statuspending | refreshing | fresh | stale | error | unknownalways

Aggregated cache freshness; unknown is a defensive fallback and none of these states proves invoice settlement.

balance_checked_attimestamp | nullalways

Oldest relevant successful balance check represented by the aggregate.

recent_payments[]object[]always

Up to three newest valid detected, confirming, or final observations attributed to this exact wallet.

invoice_public_idUUIDalways

Customer-facing invoice identity associated with the observation.

chain_slugstringalways

Chain and native or verified token display symbol.

symbolstringalways

Chain and native or verified token display symbol.

transaction_idstringalways

Canonical transaction and transfer-event identity.

event_indexintegeralways

Canonical transaction and transfer-event identity.

amountdecimal stringalways

Exact observed asset amount without floating-point conversion.

statusdetected | confirming | finalalways

Current valid observation state. Reorged, replaced, and invalid observations are excluded.

confirmationsintegeralways

Latest observed confirmation count.

observed_atRFC 3339 timestampalways

Time Wholly Crypto first observed the payment.

created_atRFC 3339 timestampalways

Creation and last wallet update time.

updated_atRFC 3339 timestampalways

Creation and last wallet update time.

wallet_readinessreadiness enumalways

Wallet/policy status only; use receive_readiness for scanner prerequisites.

receive_readinessobject | null5.5.0+
Shared receive setup plus store acceptance. Uses cached observations; not a reservation or guarantee. Creation rechecks requirements and the actual invoice exchange rate.Details

Shared receive setup plus store acceptance. Uses cached observations; not a reservation or guarantee. Creation rechecks requirements and the actual invoice exchange rate.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

Usage notes
  • Use {"strategy":"inherit"} to remove the store override and follow the current project default for future invoices.
  • Finalized networks return editable false and use Network finality; they do not accept a custom block-count override.
  • A value of 0 means accept on detection with no network confirmation and no reorg protection. It is accepted only where minimum_required_confirmations is 0.
  • Policy changes affect only new invoices. Existing invoices retain the project/store confirmation policy snapshot captured at creation.
  • Updates are one asset at a time; serialize concurrent edits for the same store asset and use the refreshed response as current state.

Errors

Error codes & retry rules

GETList project wallets and balances/v1/projects/{project_id}/walletsRead only

Returns public wallet metadata plus every registered balance-capable asset on the wallet's exact chain and network. All 30 native chain rails are covered; verified ERC-20 and SPL assets are also tracked. Assets appear immediately, even before their first scan or when they are not accepted for payments. project_enabled reports payment acceptance; tracking_active independently reports read-only refresh eligibility. Monero requires its project-bound external view-only wallet-RPC. Console Scan balances prioritizes bounded reads with per-asset progress/errors; only complete cycles update fresh totals. Invoice settlement remains driven by transaction-level monitoring and confirmation policy, not these cached balances.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Enabled project assigned to the credential.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/wallets" \
  --header "Authorization: Bearer $WHOLLY_TOKEN"

Response 200 application/json

Example response
{
  "data": [
    {
      "id": "55555555-5555-4555-8555-555555555555",
      "project_id": "11111111-1111-4111-8111-111111111111",
      "native_asset_id": "10000000-0000-4000-8000-000000000003",
      "chain_slug": "ethereum",
      "network": "mainnet",
      "asset_symbol": "ETH",
      "asset_name": "Ethereum",
      "status": "active",
      "label": "Primary Ethereum wallet",
      "public_key": "0x…",
      "primary_address": "0x…",
      "derivation_scheme": "bip44",
      "address_format": "eip55",
      "backup_confirmed_at": "2026-08-31T17:00:00Z",
      "last_secret_revealed_at": null,
      "secret_reveal_count": 0,
      "next_receive_index": 43,
      "last_scanned_height": 23123456,
      "last_scanned_at": "2026-08-31T18:05:00Z",
      "last_error": null,
      "balances": [
        { "wallet_id": "55555555-5555-4555-8555-555555555555", "asset_id": "10000000-0000-4000-8000-000000000003", "project_enabled": true, "tracking_active": true, "asset_kind": "native", "contract_address": null, "symbol": "ETH", "name": "Ethereum", "decimals": 18, "coingecko_id": "ethereum", "balance": "0.125", "balance_atomic": "125000000000000000", "price_usd": "4500", "value_usd": "562.50", "status": "fresh", "checked_at": "2026-08-31T18:05:00Z", "last_error": null },
        { "wallet_id": "55555555-5555-4555-8555-555555555555", "asset_id": "10000000-0000-4000-8000-000000000099", "project_enabled": false, "tracking_active": true, "asset_kind": "token", "contract_address": "0xA0b86991c6218b36c1d19d4a2e9eb0cE3606eB48", "symbol": "USDC", "name": "USDC", "decimals": 6, "coingecko_id": "usd-coin", "balance": null, "balance_atomic": null, "price_usd": "1", "value_usd": null, "status": "pending", "checked_at": null, "last_error": null }
      ],
      "total_value_usd": "562.50",
      "balance_status": "fresh",
      "balance_checked_at": "2026-08-31T18:05:00Z",
      "recent_payments": [
        { "invoice_public_id": "0a6a98db-d93d-48ee-8c3c-fd45f90c4a50", "chain_slug": "ethereum", "symbol": "USDC", "transaction_id": "0x…", "event_index": 0, "amount": "25", "status": "final", "confirmations": 12, "observed_at": "2026-08-31T18:04:00Z" }
      ],
      "created_at": "2026-08-31T16:00:00Z",
      "updated_at": "2026-08-31T18:05:00Z"
    }
  ]
}

Response fields

data[]object[]
idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

project_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

native_asset_idUUIDalways

Wallet, owner project, and chain-native asset identifiers.

chain_slugstringalways

Wallet chain and network.

networkstringalways

Wallet chain and network.

asset_symbolstringalways

Chain-native display identity.

asset_namestringalways

Chain-native display identity.

statuspending | active | disabled | erroralways

Operational wallet state.

labelstringalways

Operator label.

public_keystring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

primary_addressstring | nullalways

Public wallet identity; no seed phrase or private key is exposed.

derivation_schemestring | nullalways

Address policy and format.

address_formatstring | nullalways

Address policy and format.

backup_confirmed_attimestamp | nullalways

Non-null after the operator confirms recovery backup.

activation_requiredbooleanalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

activation_verified_attimestamp|nullalways
XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.Details

XRP and Stellar shared accounts remain unavailable until the operator funds the displayed address and the configured scanner providers verify that exact account. The durable proof does not expire; live scanner health is checked separately for payment verification, not invoice creation.

receive_readinessobject | null5.5.0+
Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.Details

Included on wallet listings: project receiving setup and chain scanner prerequisites. Separate from balances, token gas and send readiness. Other wallet responses may leave it null.

readybooleanalways

Receive setup checks pass. Does not describe spending readiness, gas, balance refresh, or a guaranteed future quote.

invoice_creatableboolean6.0.6+
Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.Details

Configuration permits an invoice method despite temporary scanner warnings. Currency pricing is checked at creation. This is not payment verification: ready can be false while invoice_creatable is true. Missing wallets, disabled policy and unsupported adapters still fail safely.

checked_attimestampalways

Assessment time. No network request or address allocation is made by a listing.

issues[]object[]always
Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.Details

Empty when ready; otherwise a receive warning or configuration blocker. Check invoice_creatable to distinguish temporary scanner warnings from invoice setup failures.

chain_slugstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_idUUIDwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

asset_tickerstringwhen known

Identifies the affected chain and asset. Lightning can omit asset_id.

reason_codestringalways
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.Details

scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled, or asset_not_accepted.

messagestringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

actionstringwhen available
Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.Details

Merchant-facing explanation and action identifier: chain_connections, wallets, rates, payment_methods, project_settings or store_settings. No credentials or private provider URLs.

required_endpoint_rolestring | nullon-chain
Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.Details

Preferred scanner API role (legacy field). Use accepted_endpoint_roles for the complete compatibility list. Basic node health does not prove payment-history support.

accepted_endpoint_roles[]string[] | nullon-chain
Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.Details

Compatible API dialects, not proof of endpoint history or capacity. Raw node-rpc supports BTC/BCH/LTC/DOGE/DASH and transparent ZEC (complete decoded blocks, 1–48 confirmations), solidified native TRX, native ALGO via algod, XTZ via Octez, finalized Asset Hub DOT via SCALE metadata and native XLM via Stellar RPC with invoice memo ID. Pruned or incomplete history does not qualify. These raw adapters do not add token rails. Indexed APIs remain alternatives; see the rail table below. Mixed raw/indexed sources verify bounded windows independently; the default remains two independent providers, not aliases of one operator. Basic node height, ORDnet chain info and an EVM relay for a non-EVM rail are not receive proofs. Monero still needs a project-bound view-only wallet-RPC.

healthy_endpointsintegeron-chain

Healthy matching endpoints, not the independent-provider count.

usable_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

required_independent_providersintegeron-chain
Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.Details

Usable verification slots, capped at two. required_independent_providers is the chain setting: 2 by default, or 1 after explicit administrator opt-in. In two-provider mode, different provider keys AND hosts are required. Disabled, stale (over ten minutes), or cooling-down sources do not fill a slot. Lightning uses its own connection rules.

last_checked_attimestamp | nullon-chain

Latest matching endpoint health check, separate from assessment time.

monero_wallet_rpcMoneroWalletRpcBinding | nullalways
Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.Details

Sanitized external view-only wallet-RPC binding state for Monero. Includes endpoint, authentication mode, account-0 primary address, technical proof flags/heights, and operator attestation timestamps; credentials, wallet keys, and wallet files are never serialized.

last_secret_revealed_attimestamp|nullalways

Console-side secret disclosure audit metadata.

secret_reveal_countintegeralways

Console-side secret disclosure audit metadata.

next_receive_indexintegeralways

Next reserved child-address index.

last_scanned_heightinteger|nullalways

Wallet scanner state.

last_scanned_attimestamp|nullalways

Wallet scanner state.

last_errorstring|nullalways

Wallet scanner state.

balances[]object[]always
Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.Details

Cached balances for every one of the 30 native chain rails, plus verified ERC-20 and SPL assets. A configured external view-only wallet-RPC is required for Monero.

wallet_idUUIDalways

Wallet and durable asset identities.

asset_idUUIDalways

Wallet and durable asset identities.

project_enabledbooleanalways

Whether this asset is currently enabled by the project's asset policy.

active_store_countintegeralways

Number of enabled stores that currently select this asset. This is an acceptance projection; read-only balance tracking remains independent.

active_store_ids[]UUID[]always

Enabled stores in this project that currently accept the asset. This permits exact local store filtering without another API request.

tracking_activebooleanalways
Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.Details

Whether this read-capable wallet and registered same-chain asset are eligible for background balance refreshes. Project and payment-method acceptance switches do not pause read-only tracking.

asset_kindnative | tokenalways

Native currency or verified contract/mint asset.

contract_addressstring | nullalways

Token contract or mint; null for native currency.

symbolstringalways

Display identity and atomic precision.

namestringalways

Display identity and atomic precision.

decimalsintegeralways

Display identity and atomic precision.

coingecko_idstring | nullalways

Pricing identity when mapped.

balancedecimal string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

balance_atomicinteger string|nullalways

Exact display and atomic balance across the wallet primary address and issued invoice addresses. Null while a complete value is unavailable.

price_usddecimal string | nullalways

Advisory cached USD unit price used for valuation.

value_usddecimal string | nullalways

Advisory fiat valuation when a current rate exists.

statuspending | refreshing | fresh | stale | erroralways
Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.Details

Cached scan state. refreshing can retain a completed balance: use checked_at for its age. Pending means no completed snapshot. None of these states proves a transfer is pending or an invoice settled.

checked_attimestamp | nullalways

Time represented by a completed balance scan.

last_errorstring | nullalways

Safe operator diagnostic.

total_value_usddecimal string | nullalways

Advisory sum of balances with a current USD price.

balance_statuspending | refreshing | fresh | stale | error | unknownalways

Aggregated cache freshness; unknown is a defensive fallback and none of these states proves invoice settlement.

balance_checked_attimestamp | nullalways

Oldest relevant successful balance check represented by the aggregate.

recent_payments[]object[]always

Up to three newest valid detected, confirming, or final observations attributed to this exact wallet.

invoice_public_idUUIDalways

Customer-facing invoice identity associated with the observation.

chain_slugstringalways

Chain and native or verified token display symbol.

symbolstringalways

Chain and native or verified token display symbol.

transaction_idstringalways

Canonical transaction and transfer-event identity.

event_indexintegeralways

Canonical transaction and transfer-event identity.

amountdecimal stringalways

Exact observed asset amount without floating-point conversion.

statusdetected | confirming | finalalways

Current valid observation state. Reorged, replaced, and invalid observations are excluded.

confirmationsintegeralways

Latest observed confirmation count.

observed_atRFC 3339 timestampalways

Time Wholly Crypto first observed the payment.

created_atRFC 3339 timestampalways

Creation and last wallet update time.

updated_atRFC 3339 timestampalways

Creation and last wallet update time.

Usage notes
  • This bearer route never returns a recovery phrase, private key, encrypted secret, or spending method.
  • A newly registered same-chain asset is returned with null balances and pending status before its first completed scan; it is never reported as a fabricated zero.
  • Disabling a project, wallet for payment acceptance, native rail, or individual asset does not stop read-only balance tracking: active and disabled wallets with a primary address continue refreshing every registered, supported same-chain asset. Pending and error wallets are not scanned.
  • project_enabled reports only the project's asset acceptance policy and can be false while tracking_active remains true.
  • balance and balance_atomic are exact strings; price_usd, value_usd, and total_value_usd are advisory and can be null. Fresh balance status does not guarantee a fresh market price.
  • Valuation prefers CoinGecko prices up to two hours old. Native coins and verified canonical USDC/USDT can fall back to enabled Kraken/Binance USD quotes up to five minutes old, primary provider first. No assumed dollar peg or ticker-only custom-token pricing; project fixed/DEX prices stay separate. Invoice quotes are unchanged.
  • Pending has no complete snapshot. Refreshing keeps the last completed amount and checked_at; it does not mean a blockchain transfer is pending. Stale/error amounts may also retain older values. Never treat an unavailable cache as zero or as a missing payment. Routine EVM/Solana refreshes reuse recently checked empty addresses for up to 30 minutes between audits, while funded, new and changed addresses are rechecked. Explicit console Scan balances requests a full scan.
  • recent_payments is bounded to three observations per wallet and excludes invalidated history.

Errors

Error codes & retry rules

POSTCreate invoice/v1/projects/{project_id}/stores/{store_id}/invoicesRead + write

Creates an invoice atomically with wallet destinations, fresh exact quotes, audit history, and notification outbox entries. Replaying identical raw body bytes with the same credential and Idempotency-Key returns the original invoice.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Idempotency-KeyrequiredUnique 1–128 visible ASCII characters without whitespace.
Content-Typerecommendedapplication/json. The current raw-body handler parses JSON without enforcing the media type.
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Copy Project API ID from Project → Settings → API IDs. Must be assigned to the credential; a readable project identifier is not accepted.

store_idUUIDrequired

Copy Store API ID from Project → Stores → select a store → Basic → API IDs. Required even for the default store; must be enabled and belong to project_id.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new invoice.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: order-1042-attempt-1' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "amount": "49.90",
  "currency": "USD"
}'

Request body

amountstringrequired
Unsigned plain decimal string; no sign or exponent, up to 48 integer digits and 30 decimal places. Must be positive by default. A store can allow zero-amount invoices in Stores → Invoice; zero totals settle without receiving funds, allocating addresses or processing fees.Details

Unsigned plain decimal string; no sign or exponent, up to 48 integer digits and 30 decimal places. Must be positive by default. A store can allow zero-amount invoices in Stores → Invoice; zero totals settle without receiving funds, allocating addresses or processing fees.

currencystring | nulloptional
Supported three-letter fiat currency, normalized to uppercase. Omitted or null inherits the store invoice currency. Creation also requires an independently available billing conversion rate.Details

Supported three-letter fiat currency, normalized to uppercase. Omitted or null inherits the store invoice currency. Creation also requires an independently available billing conversion rate.

payment_methods[]object[] | nulloptional
Select store-enabled methods for this invoice. Merchant 5.4.0+: ignore unknown/inactive/unaccepted choices; if none match, use store defaults. Omitted/null also uses store defaults; [] is invalid. Never enables a method or changes store settings. See selection schema below.Details

Select store-enabled methods for this invoice. Merchant 5.4.0+: ignore unknown/inactive/unaccepted choices; if none match, use store defaults. Omitted/null also uses store defaults; [] is invalid. Never enables a method or changes store settings. See selection schema below.

chain_slugstringrequired
Copy chain_slug in Project → Stores → Payment methods, or read it from GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, such as ethereum, base or bitcoin. A chain/rail pair may occur only once.Details

Copy chain_slug in Project → Stores → Payment methods, or read it from GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, such as ethereum, base or bitcoin. A chain/rail pair may occur only once.

asset_ids[]UUID[] | nulloptional
On-chain asset.id UUIDs, not contract addresses or invoice payment-method IDs. Use this OR asset_tickers. Omit both selectors for all active accepted assets on this chain. [] and duplicate/nil IDs are invalid. On 5.4.0+, ignore IDs not active/accepted on this chain in this store; an entirely unmatched selection uses store defaults.Details

On-chain asset.id UUIDs, not contract addresses or invoice payment-method IDs. Use this OR asset_tickers. Omit both selectors for all active accepted assets on this chain. [] and duplicate/nil IDs are invalid. On 5.4.0+, ignore IDs not active/accepted on this chain in this store; an entirely unmatched selection uses store defaults.

asset_tickers[]string[] | nulloptional
Merchant 5.3.0+. Symbols such as BTC, USDC or PEPE, scoped to chain_slug and this store. 1–64 unique tickers; trim/case-insensitive, 1–40 ASCII letters/digits/dot/underscore/hyphen. Use this OR asset_ids. On 5.4.0+, ignore unknown/inactive/unaccepted tickers. Ambiguous accepted symbols still fail: use asset_ids. Active selected methods need valid wallets and pricing; temporary on-chain scanner outages do not block creation from 6.0.6. Lightning optionally accepts only BTC.Details

Merchant 5.3.0+. Symbols such as BTC, USDC or PEPE, scoped to chain_slug and this store. 1–64 unique tickers; trim/case-insensitive, 1–40 ASCII letters/digits/dot/underscore/hyphen. Use this OR asset_ids. On 5.4.0+, ignore unknown/inactive/unaccepted tickers. Ambiguous accepted symbols still fail: use asset_ids. Active selected methods need valid wallets and pricing; temporary on-chain scanner outages do not block creation from 6.0.6. Lightning optionally accepts only BTC.

payment_railonchain | lightningoptional
Defaults to onchain. To choose Bitcoin Lightning, use {chain_slug: bitcoin, payment_rail: lightning} with no asset_ids; asset_tickers may optionally be [BTC]. Bitcoin on-chain does not include Lightning. The store's Lightning connection must already be enabled and ready.Details

Defaults to onchain. To choose Bitcoin Lightning, use {chain_slug: bitcoin, payment_rail: lightning} with no asset_ids; asset_tickers may optionally be [BTC]. Bitcoin on-chain does not include Lightning. The store's Lightning connection must already be enabled and ready.

order_idstring | nulloptional

Merchant order reference, 1–128 characters after trimming; control characters are rejected.

emailstring | nulloptional

Merchant-only customer email, normalized to a practical ASCII address with at most 254 characters. Omitted or null stores no email.

descriptionstring | nulloptional

Customer-facing description, 1–500 characters; line breaks and tabs are allowed.

expires_in_secondsinteger | nulloptional

Invoice quote lifetime from 300 through 86,400 seconds; omitted or null inherits store policy.

exchange_rate_spread_percentdecimal string | nulloptional
Quote markup from 0 through 100, with at most two decimal places. Omitted or null inherits the store default; "0" disables it for this invoice. Applied before upward rounding, then locked. Does not change the invoice fiat amount or the processing-fee basis.Details

Quote markup from 0 through 100, with at most two decimal places. Omitted or null inherits the store default; "0" disables it for this invoice. Applied before upward rounding, then locked. Does not change the invoice fiat amount or the processing-fee basis.

underpayment_tolerance_percentdecimal string | nulloptional

Accepted shortfall from 0 through 99.99 with at most two decimal places. Omitted or null inherits the store default.

ipn_urlstring | nulloptional

Public HTTPS callback, at most 2,048 bytes and without credentials or fragment. Overrides the store default; null/omitted inherits it.

redirect_urlstring | nulloptional

HTTPS success URL used after settlement, at most 2,048 bytes and without embedded credentials. Omitted or null inherits the store default and cannot clear it.

cancel_urlstring | nulloptional

HTTPS return URL used when checkout ends without successful payment. Omitted or null inherits the store default and cannot clear it.

redirect_automaticallyboolean | nulloptional

Omitted or null inherits store policy. true requires an effective redirect_url.

languagestring | nulloptional
Customer language: en, de, es, pt-BR, it, ru, zh-CN, fr, ko or ja. pt means Brazilian Portuguese and zh means Simplified Chinese. Supported regional tags such as de-DE normalize to the listed language. Omitted or null inherits the store language. Console language is separate.Details

Customer language: en, de, es, pt-BR, it, ru, zh-CN, fr, ko or ja. pt means Brazilian Portuguese and zh means Simplified Chinese. Supported regional tags such as de-DE normalize to the listed language. Omitted or null inherits the store language. Console language is separate.

checkout_appearanceobject | nulloptional
Partial presentation settings for this invoice. Omitted/null follows the store's current design. An object, including {}, freezes the resolved design and images at creation. See the override schema below; no financial settings, HTML, CSS, JavaScript or remote image URLs.Details

Partial presentation settings for this invoice. Omitted/null follows the store's current design. An object, including {}, freezes the resolved design and images at creation. See the override schema below; no financial settings, HTML, CSS, JavaScript or remote image URLs.

inherit_default_storebooleanoptional
true selects the project's default-store design as the base; otherwise use the target store's effective design. Overrides are then applied and saved independently; the resolved invoice flag is false.Details

true selects the project's default-store design as the base; otherwise use the target store's effective design. Overrides are then applied and saved independently; the resolved invoice flag is false.

titlestringoptional

Checkout heading, up to 120 characters. Empty uses the standard heading.

introstringoptional
Plain text, up to 2,000 characters each. Intro appears at the top, Outro at the bottom in every state. Newlines are preserved; safe text URLs become links. Empty string clears. Legacy customer_message is accepted as an alias for intro; do not send both.Details

Plain text, up to 2,000 characters each. Intro appears at the top, Outro at the bottom in every state. Newlines are preserved; safe text URLs become links. Empty string clears. Legacy customer_message is accepted as an alias for intro; do not send both.

outrostringoptional
Plain text, up to 2,000 characters each. Intro appears at the top, Outro at the bottom in every state. Newlines are preserved; safe text URLs become links. Empty string clears. Legacy customer_message is accepted as an alias for intro; do not send both.Details

Plain text, up to 2,000 characters each. Intro appears at the top, Outro at the bottom in every state. Newlines are preserved; safe text URLs become links. Empty string clears. Legacy customer_message is accepted as an alias for intro; do not send both.

intro_font_sizeintegeroptional

Pixels: 12, 14, 16, 18, 20 or 24. Default 16 unless inherited differently.

outro_font_sizeintegeroptional

Pixels: 12, 14, 16, 18, 20 or 24. Default 16 unless inherited differently.

themesystem | light | dim | darkoptional

Follow the customer device or use a fixed theme.

accent_colorstringoptional

#RRGGBB. Background, card and button may be empty for automatic colors. Text contrast is automatic.

background_colorstringoptional

#RRGGBB. Background, card and button may be empty for automatic colors. Text contrast is automatic.

card_colorstringoptional

#RRGGBB. Background, card and button may be empty for automatic colors. Text contrast is automatic.

button_colorstringoptional

#RRGGBB. Background, card and button may be empty for automatic colors. Text contrast is automatic.

logo_sizestringoptional

small, medium or large; left or center.

logo_alignmentstringoptional

small, medium or large; left or center.

imagesobjectoptional
Keys logo_light, logo_dark, favicon. Omitted key keeps the base image; null removes it. An object {store_id: UUID, kind?: logo_light|logo_dark|favicon} reuses that store's effective uploaded image in the SAME project. kind defaults to the target key. Upload in Store → Checkout first; copy the Store API ID from Basic → API IDs. Missing images or cross-project IDs return 400. No external URLs or image data accepted.Details

Keys logo_light, logo_dark, favicon. Omitted key keeps the base image; null removes it. An object {store_id: UUID, kind?: logo_light|logo_dark|favicon} reuses that store's effective uploaded image in the SAME project. kind defaults to the target key. Upload in Store → Checkout first; copy the Store API ID from Basic → API IDs. Missing images or cross-project IDs return 400. No external URLs or image data accepted.

logo_lightobject | nulloptional
store_idUUIDrequired
kindlogo_light | logo_dark | faviconoptional
logo_darkobject | nulloptional
store_idUUIDrequired
kindlogo_light | logo_dark | faviconoptional
faviconobject | nulloptional
store_idUUIDrequired
kindlogo_light | logo_dark | faviconoptional
show_order_idbooleanoptional

Show order ID details and a plain-text description below the title. details_expanded opens order ID details initially. Display only, not data redaction.

show_descriptionbooleanoptional

Show order ID details and a plain-text description below the title. details_expanded opens order ID details initially. Display only, not data redaction.

details_expandedbooleanoptional

Show order ID details and a plain-text description below the title. details_expanded opens order ID details initially. Display only, not data redaction.

show_project_namebooleanoptional
Merchant 5.6.0+: show or hide each name in the customer checkout header. Both default to true. Also available in Store → Checkout; inherited and invoice-snapshotted like other appearance settings. Display only, not data redaction.Details

Merchant 5.6.0+: show or hide each name in the customer checkout header. Both default to true. Also available in Store → Checkout; inherited and invoice-snapshotted like other appearance settings. Display only, not data redaction.

show_store_namebooleanoptional
Merchant 5.6.0+: show or hide each name in the customer checkout header. Both default to true. Also available in Store → Checkout; inherited and invoice-snapshotted like other appearance settings. Display only, not data redaction.Details

Merchant 5.6.0+: show or hide each name in the customer checkout header. Both default to true. Also available in Store → Checkout; inherited and invoice-snapshotted like other appearance settings. Display only, not data redaction.

featured_chains[]string[]optional
Ordered chain slugs, at most 60 unique values (lowercase letters, digits, hyphens; up to 64 characters). [] clears. Only available invoice methods are reordered.Details

Ordered chain slugs, at most 60 unique values (lowercase letters, digits, hyphens; up to 64 characters). [] clears. Only available invoice methods are reordered.

featured_asset_ids[]UUID[]optional
Up to 100 unique ordered asset IDs; [] clears. Default asset may be null. IDs come from payment-assets, not payment-intent IDs. These never enable methods; received payments and valid customer preferences take priority.Details

Up to 100 unique ordered asset IDs; [] clears. Default asset may be null. IDs come from payment-assets, not payment-intent IDs. These never enable methods; received payments and valid customer preferences take priority.

default_asset_idUUID|nulloptional
Up to 100 unique ordered asset IDs; [] clears. Default asset may be null. IDs come from payment-assets, not payment-intent IDs. These never enable methods; received payments and valid customer preferences take priority.Details

Up to 100 unique ordered asset IDs; [] clears. Default asset may be null. IDs come from payment-assets, not payment-intent IDs. These never enable methods; received payments and valid customer preferences take priority.

messagesobjectoptional
Language objects keyed by en, de, es, pt-BR, it, ru, zh-CN, fr, ko or ja, with waiting, confirming, paid, underpaid, expired plain strings (500 characters each). Only supplied languages/states change; {} clears all messages, {en:{}} clears English, and an empty state string clears that state. English is the fallback. Does not replace actual status.Details

Language objects keyed by en, de, es, pt-BR, it, ru, zh-CN, fr, ko or ja, with waiting, confirming, paid, underpaid, expired plain strings (500 characters each). Only supplied languages/states change; {} clears all messages, {en:{}} clears English, and an empty state string clears that state. English is the fallback. Does not replace actual status.

enobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
deobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
esobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
pt-BRobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
itobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
ruobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
zh-CNobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
frobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
koobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
jaobjectoptional
waitingstringoptional
confirmingstringoptional
paidstringoptional
underpaidstringoptional
expiredstringoptional
support_emailstringoptional

ASCII email, up to 254 characters. Empty clears.

support_urlstringoptional

HTTPS URLs up to 2,048 characters, without credentials. Empty clears. Links open in a new window.

terms_urlstringoptional

HTTPS URLs up to 2,048 characters, without credentials. Empty clears. Links open in a new window.

privacy_urlstringoptional

HTTPS URLs up to 2,048 characters, without credentials. Empty clears. Links open in a new window.

return_button_textstringoptional

Label up to 60 characters. Use top-level redirect_url/cancel_url/redirect_automatically/language for invoice behavior.

show_return_buttonbooleanoptional
Show the manual Return to merchant/cancel button in checkout, including terminal states. Omit to inherit the store appearance (default true); false hides it. Does not cancel an invoice, hide URLs in JSON or disable automatic success redirects. Set top-level redirect_automatically to false separately if needed. Requires merchant 8.1.4 or newer.Details

Show the manual Return to merchant/cancel button in checkout, including terminal states. Omit to inherit the store appearance (default true); false hides it. Does not cancel an invoice, hide URLs in JSON or disable automatic success redirects. Set top-level redirect_automatically to false separately if needed. Requires merchant 8.1.4 or newer.

metadataobject | nulloptional
Merchant-only JSON object; omitted or null becomes {}, maximum 4,096 encoded bytes and five nested levels. firstname, lastname, street, street2, zip, city, country, countryiso2, company, and vatid are validated, normalized, and projected into customer summary fields.Details

Merchant-only JSON object; omitted or null becomes {}, maximum 4,096 encoded bytes and five nested levels. firstname, lastname, street, street2, zip, city, country, countryiso2, company, and vatid are validated, normalized, and projected into customer summary fields.

firstnamestringoptional
lastnamestringoptional
streetstringoptional
street2stringoptional
zipstringoptional
citystringoptional
countrystringoptional
countryiso2stringoptional
companystringoptional
vatidstringoptional
cart_idstring

Response 201 new invoice; 200 exact idempotent replay

Example response
{
  "data": {
    "id": "2f798f9f-01f2-42f0-9d10-5581d6116b4c",
    "invoice_id": "0a6a98db-d93d-48ee-8c3c-fd45f90c4a50",
    "project_id": "11111111-1111-4111-8111-111111111111",
    "store_id": "22222222-2222-4222-8222-222222222222",
    "source": "api",
    "order_id": "order-1042",
    "email": "ada@example.com",
    "customer_name": "Ada Lovelace · Example GmbH",
    "customer_address": "Example GmbH · 12 Example Street · Suite 2 · 10115 Berlin · Germany (DE) · VAT DE123456789",
    "description": "Annual plan",
    "amount": "49.9",
    "currency": "USD",
    "exchange_rate_spread_percent": "0.5",
    "underpayment_tolerance_percent": "1",
    "status": "new",
    "amount_status": "none",
    "timing_status": "on_time",
    "resolution": "automatic",
    "sequence": 1,
    "winning_payment_intent_id": null,
    "expires_at": "2026-08-31T18:15:00Z",
    "monitoring_expires_at": "2026-09-07T18:15:00Z",
    "settled_at": null,
    "cancelled_at": null,
    "archived_at": null,
    "created_at": "2026-08-31T18:00:00Z",
    "updated_at": "2026-08-31T18:00:00Z",
    "ipn_url": "https://merchant.example/wholly/ipn",
    "redirect_url": "https://merchant.example/orders/1042",
    "cancel_url": "https://merchant.example/cart",
    "redirect_automatically": true,
    "checkout_language": "en",
    "metadata": { "cart_id": "cart-681", "firstname": "Ada", "lastname": "Lovelace", "street": "12 Example Street", "street2": "Suite 2", "zip": "10115", "city": "Berlin", "country": "Germany", "countryiso2": "DE", "company": "Example GmbH", "vatid": "DE123456789" },
    "payment_intents": [
      {
        "id": "33333333-3333-4333-8333-333333333333",
        "asset_id": "10000000-0000-4000-8000-000000000001",
        "asset_key": "bip122:000000000019d6689c085ae165831e93/slip44:0",
        "chain_slug": "bitcoin",
        "network": "mainnet",
        "caip_network_id": "bip122:000000000019d6689c085ae165831e93",
        "caip_asset_id": "bip122:000000000019d6689c085ae165831e93/slip44:0",
        "symbol": "BTC",
        "asset_decimals": 8,
        "status": "pending",
        "finality_mode": "confirmations",
        "required_confirmations": 1,
        "quote_rate": "0.000009218",
        "quote_details": null,
        "expected_amount": "0.00046",
        "expected_amount_atomic": "46000",
        "minimum_payment_amount": "0.0004554",
        "minimum_payment_amount_atomic": "45540",
        "received_amount": "0",
        "received_amount_atomic": "0",
        "confirmed_amount": "0",
        "confirmed_amount_atomic": "0",
        "destination_address": "bc1q…example",
        "destination_tag": null,
        "derivation_index": 42,
        "quote_expires_at": "2026-08-31T18:15:00Z",
        "monitoring_expires_at": "2026-09-07T18:15:00Z",
        "next_check_at": "2026-08-31T18:00:00Z",
        "last_checked_at": null,
        "last_chain_height": null,
        "last_anchor_hash": null,
        "last_monitor_error": null,
        "first_payment_at": null,
        "fully_paid_at": null,
        "finalized_at": null
      }
    ]
  },
  "links": {
    "checkout": "https://pay.example.com/invoice/0a6a98db-d93d-48ee-8c3c-fd45f90c4a50"
  }
}

Response fields

dataobject
idUUIDalways

Internal invoice UUID. Do not use it in merchant detail or checkout paths.

invoice_idUUIDalways

Public invoice UUID used by merchant detail and checkout paths.

project_idUUIDalways

Owning project.

store_idUUIDalways

Owning store.

sourcemanual | apialways

How the invoice was created.

order_idstring | nullalways

Merchant order reference.

emailstring | nullalways

Merchant-only customer email. Never returned by public checkout.

customer_namestring | nullalways

Derived display name from private firstname, lastname, and company metadata.

customer_addressstring | nullalways

Derived one-line merchant address from private company, street, street2, zip, city, country, countryiso2, and vatid metadata.

descriptionstring | nullalways

Customer-facing description.

amountdecimal stringalways

Canonical invoice amount.

currencystringalways

Normalized invoice currency/asset code.

exchange_rate_spread_percentdecimal stringalways

Locked quote spread: the creation override, or the store default when omitted. Applied before upward rounding; never changes on this invoice.

underpayment_tolerance_percentdecimal stringalways

Immutable accepted shortfall percentage snapshotted when the invoice was created.

statusinvoice statusalways

new, processing, settled, expired, invalid, or cancelled.

amount_statusamount statusalways

none, partial, paid, or overpaid. An explicitly allowed zero-amount invoice settles with none and no payment methods.

timing_statustiming statusalways

on_time or late.

resolutionresolutionalways

automatic, manually_settled, or manually_invalidated.

sequenceintegeralways

Monotonic invoice state sequence, starting at 1.

winning_payment_intent_idUUID | nullalways

Payment method that resolved the invoice, when selected.

expires_atRFC 3339 timestampalways

Quote/payment deadline.

monitoring_expires_atRFC 3339 timestampalways

Latest configured late-monitoring cutoff across payment methods.

settled_attimestamp | nullalways

Settlement time when settled.

cancelled_attimestamp | nullalways

Cancellation time when cancelled.

archived_attimestamp | nullalways

Archival time when archived.

created_atRFC 3339 timestampalways

Creation time.

updated_atRFC 3339 timestampalways

Last state update time.

ipn_urlstring | nullalways

Effective per-invoice IPN target. Merchant response only; omitted from public checkout.

redirect_urlstring | nullalways

Effective success URL used after settlement.

cancel_urlstring | nullalways

Effective return URL used when checkout ends without successful payment.

redirect_automaticallybooleanalways

Whether checkout should redirect automatically after success.

checkout_languagestringalways

Effective checkout language tag.

metadataobjectalways
Merchant metadata. Never returned by public checkout. Console payment tools add payment_tool provenance (id, kind, title, pricing, requested_amount, request_id); it does not prove payment. Authenticate callbacks and fulfill invoice.settled once per invoice_id.Details

Merchant metadata. Never returned by public checkout. Console payment tools add payment_tool provenance (id, kind, title, pricing, requested_amount, request_id); it does not prove payment. Authenticate callbacks and fulfill invoice.settled once per invoice_id.

cart_idstring
firstnamestring
lastnamestring
streetstring
street2string
zipstring
citystring
countrystring
countryiso2string
companystring
vatidstring
payment_intents[]object[]always

Quoted payment methods and monitoring state.

idUUIDalways

Payment intent identifier; also used as checkout QR intent_id.

payment_railonchain | lightningalways
Invoice transport. Bitcoin on-chain and Lightning can share asset_id; use intent id plus this field, not symbol alone. This differs from the asset catalog's scanner payment_rail.Details

Invoice transport. Bitcoin on-chain and Lightning can share asset_id; use intent id plus this field, not symbol alone. This differs from the asset catalog's scanner payment_rail.

bolt11string | nullalways

Lightning payment request, otherwise null. Pay this request with a Lightning wallet, never send on-chain funds to its payment hash.

asset_idUUIDalways

Configured payment asset identifier.

asset_keystringalways

Canonical CAIP-style asset key.

chain_slugstringalways

Wholly Crypto chain identifier.

networkstringalways

Configured network, currently mainnet for supported payment assets.

caip_network_idstringalways

Canonical CAIP-2 network identifier.

caip_asset_idstring | nullalways

Canonical CAIP-19 identifier where registered.

symbolstringalways

Asset symbol.

asset_decimalsintegeralways

Atomic-unit precision. Lightning BTC uses 11 (millisatoshis), not on-chain Bitcoin's 8. Quotes are whole satoshis; receipts retain millisatoshi precision.

statusintent statusalways

pending, partial, paid, overpaid, expired, or invalid.

finality_modeconfirmations | finalizedalways

Finality policy.

required_confirmationsintegeralways

Required confirmations when applicable.

quote_ratedecimal stringalways

Asset units per one invoice currency unit, including the locked spread. For example 1.02 USDC per USD. Not the inverse rate.

quote_detailsobject | nullalways
Locked quote provenance: reference_rate before spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at and asset_fetched_at. Null on older invoices; no historical values are fabricated.Details

Locked quote provenance: reference_rate before spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at and asset_fetched_at. Null on older invoices; no historical values are fabricated.

expected_amountdecimal stringalways
Exact locked asset amount to pay after spread and upward rounding. From 4.1.1, recognized verified fiat stablecoins (such as USDC, USDT, DAI, USDS, EURC) round up to at most two decimals; 1.321 becomes 1.33, never 1.32. This is the expected amount even with zero tolerance. Other assets keep adaptive precision. Existing invoices are never repriced.Details

Exact locked asset amount to pay after spread and upward rounding. From 4.1.1, recognized verified fiat stablecoins (such as USDC, USDT, DAI, USDS, EURC) round up to at most two decimals; 1.321 becomes 1.33, never 1.32. This is the expected amount even with zero tolerance. Other assets keep adaptive precision. Existing invoices are never repriced.

expected_amount_atomicinteger stringalways

Exact amount in the asset's smallest unit.

minimum_payment_amountdecimal stringalways

Smallest amount accepted as paid after applying the invoice tolerance.

minimum_payment_amount_atomicinteger stringalways

Exact accepted threshold in the asset's smallest unit.

received_amountdecimal stringalways

Observed amount.

received_amount_atomicinteger stringalways

Observed atomic amount.

confirmed_amountdecimal stringalways

Confirmed/final amount.

confirmed_amount_atomicinteger stringalways

Confirmed/final atomic amount.

destination_addressstringalways

On-chain receiving address, or the 64-character payment hash for Lightning. Use bolt11 to pay Lightning; its hash is not a Bitcoin address.

destination_tagstring | nullalways

Required public payment reference where the rail uses one: XRP destination tag, Stellar memo ID, or TON invoice comment. Null for unique-address rails.

derivation_indexintegeralways

Reserved wallet child index; merchant detail only.

quote_expires_atRFC 3339 timestampalways

Quote expiry.

monitoring_expires_atRFC 3339 timestampalways

Late-monitoring cutoff for this method.

next_check_attimestamp | nullalways

Next scheduled chain check.

last_checked_attimestamp | nullalways

Last chain check.

last_chain_heightinteger | nullalways

Last trustworthy height observed by the monitor.

last_anchor_hashstring | nullalways

Last monitor anchor/block hash.

last_monitor_errorstring | nullalways

Safe monitoring diagnostic for operators.

first_payment_attimestamp | nullalways

First observed payment time.

fully_paid_attimestamp | nullalways

Time the accepted minimum amount was first reached.

finalized_attimestamp | nullalways

Time payment met finality policy.

Usage notes
  • payment_methods filters store-enabled methods for this invoice only. Omitted/null keeps all store methods; [] is invalid. Find the small chain_slug hint and displayed asset tickers in Project → Stores → Payment methods. The API payment-assets list supplies chain_slug, asset.symbol and asset.id. Use {chain_slug: ethereum, asset_tickers: [USDC, USDT]} for accepted Ethereum tokens; BTC and PEPE work the same way on their selected chains. Tickers are case-insensitive, chain-scoped, and resolve only inside the store. Two accepted contracts with the same ticker return 400 instead of choosing one, even if one is not ready; use asset_ids for that case. Native assets, catalog tokens and custom tokens follow the same rules. Each chain/rail may appear once; at most 64 final methods. Merchant 5.4.0+: unknown, disabled, wrong-chain or unaccepted choices are ignored. If the entire selection has no active accepted matches, store defaults apply; otherwise only matching choices are used. A chain-only entry includes every active accepted on-chain asset. Active selected methods need valid wallets, installed scanner adapters and trustworthy rates. From 6.0.6, unavailable scanners, cooldowns and pending/stale health checks do not block invoice creation or remove configured on-chain methods. Detection retries automatically; settlement still requires provider quorum and confirmations. Monitor receive_readiness and keep providers available: an invoice can remain unverified until scanners recover. Monero subaddress allocation and Lightning BOLT11 generation still require their external wallet/node service. Failures return error.message plus error.details.payment_methods with chain_slug, asset_ticker, reason_code and, for scanner diagnostics, required_endpoint_role, healthy_endpoints and required_independent_providers. TRON accepts indexed history or supported raw solidified native-block APIs; basic health alone does not prove scanner compatibility. Pricing failures identify the asset/currency. Nothing enables an unaccepted asset or changes store policy. On merchant versions before 5.4.0, unknown/inactive explicit choices fail instead. Existing invoice methods never expand when store settings change. Lightning must be selected separately. Replays keep the original methods, and changing selections with the same Idempotency-Key returns 409.
  • checkout_appearance supports every presentation setting listed above. Omitted fields inherit, arrays replace, and nested message fields merge; an empty message object clears that scope. The resolved design and images are saved for this invoice without editing the store. Read appearance from public checkout JSON to inspect the result. The whole request is limited to 32 KiB and resolved settings to 20 KiB.
  • Changing checkout_appearance with the same Idempotency-Key returns 409; retry with identical raw bytes. Appearance does not change amounts, rates, accepted assets, confirmation requirements, real status or embedding permissions. No HTML, CSS, scripts or remote image fetching.
  • exchange_rate_spread_percent overrides the store default for this invoice: omit or send null to inherit, or send "0" to disable it. Existing invoice quotes never change.
  • Spread is applied before upward rounding. Fees remain based on the original invoice fiat amount, excluding the spread.
  • Always send the returned expected_amount or expected_amount_atomic. Rounding is upward, limited by asset precision, 0.1% of the amount and one fiat minor unit.
  • Retries must keep the same credential, Idempotency-Key and exact body bytes. Changing the spread with the same key returns 409 idempotency_conflict.
  • An exact replay is checked before new quote, callback DNS or address preparation. Credential scope and project/store authorization are still checked on every request.
  • An effective ipn_url requires the store IPN signing secret. Unknown body fields are rejected.

Errors

Error codes & retry rules

GETList invoices/v1/projects/{project_id}/invoicesRead only

Returns a compact newest-first page of scoped invoice summaries, including merchant-only email and customer fields derived from recognized metadata. Search, status, and store filters are evaluated server-side; the response includes total and has_more for predictable paging.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Enabled project assigned to the credential.

Query parameters

store_idUUID

Optional exact store filter.

statusenum

Optional new, processing, settled, expired, invalid, or cancelled.

limitinteger

Optional 1–100; defaults to 50.

offsetinteger

Optional 0–1,000,000; defaults to 0.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices?search=order-1042&status=processing&limit=50&offset=0" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Accept: application/json'

Response 200 application/json

Example response
{
  "data": [
    {
      "id": "2f798f9f-01f2-42f0-9d10-5581d6116b4c",
      "invoice_id": "0a6a98db-d93d-48ee-8c3c-fd45f90c4a50",
      "project_id": "11111111-1111-4111-8111-111111111111",
      "store_id": "22222222-2222-4222-8222-222222222222",
      "source": "api",
      "order_id": "order-1042",
      "email": "ada@example.com",
      "customer_name": "Ada Lovelace · Example GmbH",
      "customer_address": "Example GmbH · 12 Example Street · Suite 2 · 10115 Berlin · Germany (DE) · VAT DE123456789",
      "description": "Annual plan",
      "amount": "49.9",
      "currency": "USD",
      "exchange_rate_spread_percent": "0.5",
      "underpayment_tolerance_percent": "1",
      "status": "processing",
      "amount_status": "paid",
      "timing_status": "on_time",
      "resolution": "automatic",
      "sequence": 3,
      "winning_payment_intent_id": "33333333-3333-4333-8333-333333333333",
      "expires_at": "2026-08-31T18:15:00Z",
      "monitoring_expires_at": "2026-09-07T18:15:00Z",
      "settled_at": null,
      "cancelled_at": null,
      "archived_at": null,
      "created_at": "2026-08-31T18:00:00Z",
      "updated_at": "2026-08-31T18:04:10Z"
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "total": 143,
    "has_more": true
  }
}

Response fields

data[]object[]
idUUIDalways

Internal invoice UUID. Do not use it in merchant detail or checkout paths.

invoice_idUUIDalways

Public invoice UUID used by merchant detail and checkout paths.

project_idUUIDalways

Owning project.

store_idUUIDalways

Owning store.

sourcemanual | apialways

How the invoice was created.

order_idstring | nullalways

Merchant order reference.

emailstring | nullalways

Merchant-only customer email. Never returned by public checkout.

customer_namestring | nullalways

Derived display name from private firstname, lastname, and company metadata.

customer_addressstring | nullalways

Derived one-line merchant address from private company, street, street2, zip, city, country, countryiso2, and vatid metadata.

descriptionstring | nullalways

Customer-facing description.

amountdecimal stringalways

Canonical invoice amount.

currencystringalways

Normalized invoice currency/asset code.

exchange_rate_spread_percentdecimal stringalways

Locked quote spread: the creation override, or the store default when omitted. Applied before upward rounding; never changes on this invoice.

underpayment_tolerance_percentdecimal stringalways

Immutable accepted shortfall percentage snapshotted when the invoice was created.

statusinvoice statusalways

new, processing, settled, expired, invalid, or cancelled.

amount_statusamount statusalways

none, partial, paid, or overpaid. An explicitly allowed zero-amount invoice settles with none and no payment methods.

timing_statustiming statusalways

on_time or late.

resolutionresolutionalways

automatic, manually_settled, or manually_invalidated.

sequenceintegeralways

Monotonic invoice state sequence, starting at 1.

winning_payment_intent_idUUID | nullalways

Payment method that resolved the invoice, when selected.

expires_atRFC 3339 timestampalways

Quote/payment deadline.

monitoring_expires_atRFC 3339 timestampalways

Latest configured late-monitoring cutoff across payment methods.

settled_attimestamp | nullalways

Settlement time when settled.

cancelled_attimestamp | nullalways

Cancellation time when cancelled.

archived_attimestamp | nullalways

Archival time when archived.

created_atRFC 3339 timestampalways

Creation time.

updated_atRFC 3339 timestampalways

Last state update time.

paginationobject
limitintegeralways

Effective page size, 1–100.

offsetintegeralways

Effective zero-based row offset, 0–1,000,000.

totalintegeralways

Total rows matching project, store, status, and search filters in the page snapshot.

has_morebooleanalways

True when offset plus the returned row count is below total.

Usage notes
  • Sorted by created_at descending, then internal id descending.
  • List items are InvoiceSummary objects; email, customer_name, and customer_address are merchant-only. Call detail for raw metadata and payment intents.
  • For the next page set offset to pagination.offset + pagination.limit only when has_more is true.
  • The count and page are read from one repeatable-read database snapshot; concurrent writes appear on a later request.

Errors

Error codes & retry rules

GETRetrieve invoice/v1/projects/{project_id}/invoices/{invoice_id}Read only

Returns a complete merchant invoice detail and the current active checkout URL. Use this route for polling and reconciliation.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Enabled project assigned to the credential.

invoice_idUUIDrequired

The invoice_id returned during creation/listing, not internal id.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices/YOUR_PUBLIC_INVOICE_ID" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Accept: application/json'

Response 200 application/json

Example response
{
  "data": {
    "id": "2f798f9f-01f2-42f0-9d10-5581d6116b4c",
    "invoice_id": "0a6a98db-d93d-48ee-8c3c-fd45f90c4a50",
    "project_id": "11111111-1111-4111-8111-111111111111",
    "store_id": "22222222-2222-4222-8222-222222222222",
    "source": "api",
    "order_id": "order-1042",
    "email": "ada@example.com",
    "customer_name": "Ada Lovelace · Example GmbH",
    "customer_address": "Example GmbH · 12 Example Street · Suite 2 · 10115 Berlin · Germany (DE) · VAT DE123456789",
    "description": "Annual plan",
    "amount": "49.9",
    "currency": "USD",
    "exchange_rate_spread_percent": "0.5",
    "underpayment_tolerance_percent": "1",
    "status": "settled",
    "amount_status": "paid",
    "timing_status": "on_time",
    "resolution": "automatic",
    "sequence": 4,
    "winning_payment_intent_id": "33333333-3333-4333-8333-333333333333",
    "expires_at": "2026-08-31T18:15:00Z",
    "monitoring_expires_at": "2026-09-07T18:15:00Z",
    "settled_at": "2026-08-31T18:05:00Z",
    "cancelled_at": null,
    "archived_at": null,
    "created_at": "2026-08-31T18:00:00Z",
    "updated_at": "2026-08-31T18:05:00Z",
    "ipn_url": "https://merchant.example/wholly/ipn",
    "redirect_url": "https://merchant.example/orders/1042",
    "cancel_url": "https://merchant.example/cart",
    "redirect_automatically": true,
    "checkout_language": "en",
    "metadata": { "cart_id": "cart-681", "firstname": "Ada", "lastname": "Lovelace", "street": "12 Example Street", "street2": "Suite 2", "zip": "10115", "city": "Berlin", "country": "Germany", "countryiso2": "DE", "company": "Example GmbH", "vatid": "DE123456789" },
    "payment_intents": [
      {
        "id": "33333333-3333-4333-8333-333333333333",
        "asset_id": "10000000-0000-4000-8000-000000000001",
        "asset_key": "bip122:000000000019d6689c085ae165831e93/slip44:0",
        "chain_slug": "bitcoin",
        "network": "mainnet",
        "caip_network_id": "bip122:000000000019d6689c085ae165831e93",
        "caip_asset_id": "bip122:000000000019d6689c085ae165831e93/slip44:0",
        "symbol": "BTC",
        "asset_decimals": 8,
        "status": "paid",
        "finality_mode": "confirmations",
        "required_confirmations": 1,
        "quote_rate": "0.000009218",
        "quote_details": null,
        "expected_amount": "0.00046",
        "expected_amount_atomic": "46000",
        "minimum_payment_amount": "0.0004554",
        "minimum_payment_amount_atomic": "45540",
        "received_amount": "0.0004554",
        "received_amount_atomic": "45540",
        "confirmed_amount": "0.0004554",
        "confirmed_amount_atomic": "45540",
        "destination_address": "bc1q…example",
        "destination_tag": null,
        "derivation_index": 42,
        "quote_expires_at": "2026-08-31T18:15:00Z",
        "monitoring_expires_at": "2026-09-07T18:15:00Z",
        "next_check_at": null,
        "last_checked_at": "2026-08-31T18:05:00Z",
        "last_chain_height": 912345,
        "last_anchor_hash": "000000000000000000example",
        "last_monitor_error": null,
        "first_payment_at": "2026-08-31T18:03:00Z",
        "fully_paid_at": "2026-08-31T18:03:00Z",
        "finalized_at": "2026-08-31T18:05:00Z"
      }
    ]
  },
  "links": {
    "checkout": "https://pay.example.com/invoice/0a6a98db-d93d-48ee-8c3c-fd45f90c4a50"
  }
}

Response fields

dataobject
idUUIDalways

Internal invoice UUID. Do not use it in merchant detail or checkout paths.

invoice_idUUIDalways

Public invoice UUID used by merchant detail and checkout paths.

project_idUUIDalways

Owning project.

store_idUUIDalways

Owning store.

sourcemanual | apialways

How the invoice was created.

order_idstring | nullalways

Merchant order reference.

emailstring | nullalways

Merchant-only customer email. Never returned by public checkout.

customer_namestring | nullalways

Derived display name from private firstname, lastname, and company metadata.

customer_addressstring | nullalways

Derived one-line merchant address from private company, street, street2, zip, city, country, countryiso2, and vatid metadata.

descriptionstring | nullalways

Customer-facing description.

amountdecimal stringalways

Canonical invoice amount.

currencystringalways

Normalized invoice currency/asset code.

exchange_rate_spread_percentdecimal stringalways

Locked quote spread: the creation override, or the store default when omitted. Applied before upward rounding; never changes on this invoice.

underpayment_tolerance_percentdecimal stringalways

Immutable accepted shortfall percentage snapshotted when the invoice was created.

statusinvoice statusalways

new, processing, settled, expired, invalid, or cancelled.

amount_statusamount statusalways

none, partial, paid, or overpaid. An explicitly allowed zero-amount invoice settles with none and no payment methods.

timing_statustiming statusalways

on_time or late.

resolutionresolutionalways

automatic, manually_settled, or manually_invalidated.

sequenceintegeralways

Monotonic invoice state sequence, starting at 1.

winning_payment_intent_idUUID | nullalways

Payment method that resolved the invoice, when selected.

expires_atRFC 3339 timestampalways

Quote/payment deadline.

monitoring_expires_atRFC 3339 timestampalways

Latest configured late-monitoring cutoff across payment methods.

settled_attimestamp | nullalways

Settlement time when settled.

cancelled_attimestamp | nullalways

Cancellation time when cancelled.

archived_attimestamp | nullalways

Archival time when archived.

created_atRFC 3339 timestampalways

Creation time.

updated_atRFC 3339 timestampalways

Last state update time.

ipn_urlstring | nullalways

Effective per-invoice IPN target. Merchant response only; omitted from public checkout.

redirect_urlstring | nullalways

Effective success URL used after settlement.

cancel_urlstring | nullalways

Effective return URL used when checkout ends without successful payment.

redirect_automaticallybooleanalways

Whether checkout should redirect automatically after success.

checkout_languagestringalways

Effective checkout language tag.

metadataobjectalways
Merchant metadata. Never returned by public checkout. Console payment tools add payment_tool provenance (id, kind, title, pricing, requested_amount, request_id); it does not prove payment. Authenticate callbacks and fulfill invoice.settled once per invoice_id.Details

Merchant metadata. Never returned by public checkout. Console payment tools add payment_tool provenance (id, kind, title, pricing, requested_amount, request_id); it does not prove payment. Authenticate callbacks and fulfill invoice.settled once per invoice_id.

cart_idstring
firstnamestring
lastnamestring
streetstring
street2string
zipstring
citystring
countrystring
countryiso2string
companystring
vatidstring
payment_intents[]object[]always

Quoted payment methods and monitoring state.

idUUIDalways

Payment intent identifier; also used as checkout QR intent_id.

payment_railonchain | lightningalways
Invoice transport. Bitcoin on-chain and Lightning can share asset_id; use intent id plus this field, not symbol alone. This differs from the asset catalog's scanner payment_rail.Details

Invoice transport. Bitcoin on-chain and Lightning can share asset_id; use intent id plus this field, not symbol alone. This differs from the asset catalog's scanner payment_rail.

bolt11string | nullalways

Lightning payment request, otherwise null. Pay this request with a Lightning wallet, never send on-chain funds to its payment hash.

asset_idUUIDalways

Configured payment asset identifier.

asset_keystringalways

Canonical CAIP-style asset key.

chain_slugstringalways

Wholly Crypto chain identifier.

networkstringalways

Configured network, currently mainnet for supported payment assets.

caip_network_idstringalways

Canonical CAIP-2 network identifier.

caip_asset_idstring | nullalways

Canonical CAIP-19 identifier where registered.

symbolstringalways

Asset symbol.

asset_decimalsintegeralways

Atomic-unit precision. Lightning BTC uses 11 (millisatoshis), not on-chain Bitcoin's 8. Quotes are whole satoshis; receipts retain millisatoshi precision.

statusintent statusalways

pending, partial, paid, overpaid, expired, or invalid.

finality_modeconfirmations | finalizedalways

Finality policy.

required_confirmationsintegeralways

Required confirmations when applicable.

quote_ratedecimal stringalways

Asset units per one invoice currency unit, including the locked spread. For example 1.02 USDC per USD. Not the inverse rate.

quote_detailsobject | nullalways
Locked quote provenance: reference_rate before spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at and asset_fetched_at. Null on older invoices; no historical values are fabricated.Details

Locked quote provenance: reference_rate before spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at and asset_fetched_at. Null on older invoices; no historical values are fabricated.

expected_amountdecimal stringalways
Exact locked asset amount to pay after spread and upward rounding. From 4.1.1, recognized verified fiat stablecoins (such as USDC, USDT, DAI, USDS, EURC) round up to at most two decimals; 1.321 becomes 1.33, never 1.32. This is the expected amount even with zero tolerance. Other assets keep adaptive precision. Existing invoices are never repriced.Details

Exact locked asset amount to pay after spread and upward rounding. From 4.1.1, recognized verified fiat stablecoins (such as USDC, USDT, DAI, USDS, EURC) round up to at most two decimals; 1.321 becomes 1.33, never 1.32. This is the expected amount even with zero tolerance. Other assets keep adaptive precision. Existing invoices are never repriced.

expected_amount_atomicinteger stringalways

Exact amount in the asset's smallest unit.

minimum_payment_amountdecimal stringalways

Smallest amount accepted as paid after applying the invoice tolerance.

minimum_payment_amount_atomicinteger stringalways

Exact accepted threshold in the asset's smallest unit.

received_amountdecimal stringalways

Observed amount.

received_amount_atomicinteger stringalways

Observed atomic amount.

confirmed_amountdecimal stringalways

Confirmed/final amount.

confirmed_amount_atomicinteger stringalways

Confirmed/final atomic amount.

destination_addressstringalways

On-chain receiving address, or the 64-character payment hash for Lightning. Use bolt11 to pay Lightning; its hash is not a Bitcoin address.

destination_tagstring | nullalways

Required public payment reference where the rail uses one: XRP destination tag, Stellar memo ID, or TON invoice comment. Null for unique-address rails.

derivation_indexintegeralways

Reserved wallet child index; merchant detail only.

quote_expires_atRFC 3339 timestampalways

Quote expiry.

monitoring_expires_atRFC 3339 timestampalways

Late-monitoring cutoff for this method.

next_check_attimestamp | nullalways

Next scheduled chain check.

last_checked_attimestamp | nullalways

Last chain check.

last_chain_heightinteger | nullalways

Last trustworthy height observed by the monitor.

last_anchor_hashstring | nullalways

Last monitor anchor/block hash.

last_monitor_errorstring | nullalways

Safe monitoring diagnostic for operators.

first_payment_attimestamp | nullalways

First observed payment time.

fully_paid_attimestamp | nullalways

Time the accepted minimum amount was first reached.

finalized_attimestamp | nullalways

Time payment met finality policy.

Usage notes
  • A scoped lookup deliberately returns invoice_not_found when the public ID is not in the authorized project.
  • links.checkout uses Store → Basic → Store domains: this store's active pay hostname, then its default store's choice, then the system primary. Retired/draft or wrong-service hosts are ignored. This also applies to creation and MCP responses; links are resolved at response time, including idempotent replays. Signed callback links are frozen at event creation, not rewritten on retries. These preferences generate links only; they do not redirect traffic or change IP restrictions.

Errors

Error codes & retry rules

GETList invoice payments/v1/projects/{project_id}/invoices/{invoice_id}/paymentsRead only

Complete current transfer history, including invalidated observations. Use this when a callback marks payments_truncated. This is current state, not a reconstruction of an older event.

Authentication & headers
HeaderPresenceRule
AuthorizationrequiredBearer YOUR_MERCHANT_API_TOKEN
Acceptrecommendedapplication/json

Path parameters

project_idUUIDrequired

Project assigned to this credential.

invoice_idUUIDrequired

Public invoice_id returned at creation.

Query parameters

payment_method_idUUIDoptional

Limit to one invoice payment method.

limitinteger

1–100; default 25.

offsetinteger

0–1,000,000; default 0.

Request

: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices/YOUR_PUBLIC_INVOICE_ID/payments?limit=25&offset=0" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Accept: application/json'

Response 200 application/json

Example response
{
  "invoice_id": "11111111-2222-4333-8444-555555555555",
  "data": [{
    "payment_id": "44444444-4444-4444-8444-444444444444",
    "payment_method_id": "33333333-3333-4333-8333-333333333333",
    "transaction_id": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "payment_hash": null,
    "event_index": 12,
    "payment_rail": "onchain",
    "chain_slug": "ethereum",
    "network": "mainnet",
    "asset_id": "55555555-5555-4555-8555-555555555555",
    "asset_key": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
    "caip_asset_id": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
    "symbol": "USDC",
    "asset_decimals": 6,
    "amount": "58.17342",
    "amount_atomic": "58173420",
    "status": "final",
    "counts_towards_received": true,
    "confirmations": 2,
    "block_height": 25975377,
    "observed_at": "2026-09-14T12:03:00Z",
    "chain_time": "2026-09-14T12:02:48Z",
    "finalized_at": "2026-09-14T12:04:00Z",
    "explorer_name": "Etherscan",
    "explorer_url": "https://etherscan.io/tx/0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  }],
  "pagination": {"limit": 25, "offset": 0, "total": 1, "has_more": false}
}

Response fields

invoice_idstring
data[]object[]
payment_idstring
payment_method_idstring
transaction_idstring
payment_hashJSON | null
event_indexinteger
payment_railstring
chain_slugstring
networkstring
asset_idstring
asset_keystring
caip_asset_idstring
symbolstring
asset_decimalsinteger
amountstring
amount_atomicstring
statusstring
counts_towards_receivedboolean
confirmationsinteger
block_heightinteger
observed_atstring
chain_timestring
finalized_atstring
explorer_namestring
explorer_urlstring
paginationobject
limitinteger
offsetinteger
totalinteger
has_moreboolean
Usage notes
  • An observation is a token log, UTXO output or other rail transfer, not necessarily a unique transaction hash. Deduplicate by payment_id; transaction_id plus event_index identifies the chain transfer.
  • status is detected, confirming, final, reorged, replaced or invalid. Only counts_towards_received observations contribute to received amounts. Never add amounts across different assets.
  • Lightning records use payment_hash with null transaction_id, confirmations and explorer links; BTC precision is 11 (millisatoshis). No preimages, BOLT11 or wallet secrets are exposed.
  • Sorted by observed_at descending, then payment_id descending. Count and page use one repeatable-read snapshot; later pages may change as payments arrive. Deduplicate by payment_id when paginating a live invoice.
  • Existing read-only project scope, IP restrictions and per-credential rate limits apply. Never follow a callback-provided link with your token unless its origin matches your configured API host.

Errors

Error codes & retry rules

GETCheckout shell/Public

Managed checkout-host root that serves the checkout application without selecting an invoice. Customer integrations should normally use links.checkout instead.

Authentication & headers

Public

Request

curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://pay.example.com/" \
  --output 'checkout.html'

Response 200 text/html

Example response
<!doctype html>
<!-- Hosted Wholly Crypto checkout shell -->
Usage notes
  • No bearer token is needed.
  • The managed checkout edge allows GET/HEAD and rejects other methods.

Errors

Error codes & retry rules

GETHosted checkout page/invoice/{invoice_id}Public

Customer-facing HTML checkout. The page fetches checkout-safe JSON from the same checkout host. Embedding is denied unless the store enables it and explicitly allows the parent HTTPS origin.

Authentication & headers

Public

Path parameters

invoice_idUUIDrequired

Public invoice UUID returned by the merchant API.

Request

curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://pay.example.com/invoice/YOUR_PUBLIC_INVOICE_ID" \
  --output 'checkout.html'

Response 200 text/html

Example response
<!doctype html>
<!-- Hosted Wholly Crypto checkout application -->
Usage notes
  • No bearer token is accepted or needed.
  • The HTML shell itself returns 200 even when an invoice is absent; its checkout JSON request then receives invoice_not_found.
  • The response is no-store, noindex, and has invoice-specific frame-ancestors CSP.
  • Disabled project/store or an unknown invoice does not expose checkout data.

Errors

Error codes & retry rules

GETCheckout-safe invoice/checkout-api/invoices/{invoice_id}Public

Returns only fields needed to render checkout. It deliberately omits internal IDs, customer email and derived address fields, IPN URL, merchant metadata, wallet IDs, derivation paths, and monitor diagnostics.

Authentication & headers

Public

Path parameters

invoice_idUUIDrequired

Public invoice UUID.

Request

curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID" \
  --header 'Accept: application/json'

Response 200 application/json

Example response
{
  "data": {
    "invoice_id": "0a6a98db-d93d-48ee-8c3c-fd45f90c4a50",
    "order_id": "order-1042",
    "description": "Annual plan",
    "amount": "49.9",
    "currency": "USD",
    "exchange_rate_spread_percent": "0.5",
    "underpayment_tolerance_percent": "1",
    "status": "processing",
    "amount_status": "partial",
    "timing_status": "on_time",
    "sequence": 3,
    "active_payment_method_id": "33333333-3333-4333-8333-333333333333",
    "payment_method_locked": true,
    "server_time": "2026-08-31T18:10:00Z",
    "expires_at": "2026-08-31T18:15:00Z",
    "expires_in_seconds": 300,
    "payment_open": true,
    "redirect_url": "https://merchant.example/orders/1042",
    "cancel_url": "https://merchant.example/cart",
    "redirect_automatically": true,
    "checkout_language": "en",
    "project": {
      "name": "Example project",
      "checkout_title": "Complete your payment",
      "checkout_description": "Send the exact amount shown.",
      "theme": "system",
      "accent_color": "#42e39b",
      "logo_url": "/checkout-api/invoices/…/logo/…/image.png"
    },
    "store": { "name": "Online shop" },
    "payment_methods": [
      {
        "id": "33333333-3333-4333-8333-333333333333",
        "asset_key": "bip122:000000000019d6689c085ae165831e93/slip44:0",
        "chain_slug": "bitcoin",
        "chain_name": "Bitcoin",
        "network": "mainnet",
        "caip_network_id": "bip122:000000000019d6689c085ae165831e93",
        "caip_asset_id": "bip122:000000000019d6689c085ae165831e93/slip44:0",
        "asset_name": "Bitcoin",
        "symbol": "BTC",
        "asset_icon_url": "/assets/coingecko/bitcoin.png",
        "asset_kind": "native",
        "contract_address": null,
        "token_standard": null,
        "asset_decimals": 8,
        "status": "partial",
        "payable": true,
        "finality_mode": "confirmations",
        "required_confirmations": 1,
        "expected_amount": "0.00046",
        "expected_amount_atomic": "46000",
        "minimum_payment_amount": "0.0004554",
        "minimum_payment_amount_atomic": "45540",
        "received_amount": "0.0002",
        "received_amount_atomic": "20000",
        "remaining_amount": "0.0002554",
        "remaining_amount_atomic": "25540",
        "confirmed_amount": "0",
        "confirmed_amount_atomic": "0",
        "destination_address": "bc1q…example",
        "destination_tag": null,
        "quote_expires_at": "2026-08-31T18:15:00Z",
        "payment_uri": "bitcoin:bc1q…example?amount=0.00026",
        "qr_url": "/checkout-api/invoices/…/payment-methods/…/qr.svg?sequence=3&amount_atomic=26000",
        "address_explorer_name": "mempool.space",
        "address_explorer_url": "https://mempool.space/address/…",
        "transaction_count": 0,
        "transactions_truncated": false,
        "transactions": []
      }
    ]
  }
}

Response fields

dataobject
invoice_idUUIDalways

Public invoice UUID.

order_idstring | nullalways

Merchant order reference.

descriptionstring | nullalways

Customer-facing description.

amountdecimal stringalways

Invoice amount.

currencystringalways

Invoice currency.

exchange_rate_spread_percentdecimal stringalways

Effective quote spread locked at creation, including a per-invoice override.

underpayment_tolerance_percentdecimal stringalways

Accepted shortfall percentage for this invoice.

statusinvoice statusalways

Current invoice status.

amount_statusamount statusalways

none, partial, paid, or overpaid. An explicitly allowed zero-amount invoice settles with none and no payment methods.

timing_statustiming statusalways

on_time or late.

sequenceintegeralways

Current state sequence.

active_payment_method_idUUID | nullalways

The listed payment method that has received funds. Checkout remains on this method so an underpayment is not continued with an incompatible asset.

payment_method_lockedbooleanalways

True after a valid payment selects active_payment_method_id.

server_timeRFC 3339 timestampalways

Server clock captured for this response; use it with expires_at to avoid customer-device clock skew.

expires_atRFC 3339 timestampalways

Invoice deadline.

expires_in_secondsintegeralways

Whole seconds remaining at server_time, rounded up and clamped to zero.

payment_openbooleanalways

True only while a new or processing invoice is before its deadline and has at least one payable method with an amount remaining.

redirect_urlstring | nullalways

Customer return target after successful settlement.

cancel_urlstring | nullalways

Customer return target when leaving without successful settlement.

redirect_automaticallybooleanalways

Automatic redirect policy.

checkout_languagestringalways

Checkout language.

projectobjectalways

name, checkout_title, checkout_description, theme, accent_color, and logo_url.

namestring
checkout_titlestring
checkout_descriptionstring
themestring
accent_colorstring
logo_urlstring
storeobjectalways

Public store name.

namestring
appearanceobjectalways

Effective presentation: frozen per-invoice override when supplied, otherwise the store's current design. Never changes financial fields or safety warnings.

inherit_default_storebooleanalways

True when the project's default store supplies this appearance. False for independent stores and frozen invoice overrides.

invoice_overridebooleanalways

True when checkout_appearance was supplied at invoice creation. Omitted/null keeps this false.

titlestringalways

Plain merchant heading, top message and bottom message. intro replaces customer_message; old stored copy is preserved. Never evaluate as markup.

introstringalways

Plain merchant heading, top message and bottom message. intro replaces customer_message; old stored copy is preserved. Never evaluate as markup.

outrostringalways

Plain merchant heading, top message and bottom message. intro replaces customer_message; old stored copy is preserved. Never evaluate as markup.

intro_font_sizeintegeralways

Font sizes in pixels: 12, 14, 16, 18, 20 or 24.

outro_font_sizeintegeralways

Font sizes in pixels: 12, 14, 16, 18, 20 or 24.

customer_messagestringalways

Deprecated compatibility alias of intro. Use intro for new integrations.

themesystem | light | dim | darkalways

Customer-device preference or a fixed theme.

accent_colorstringalways

Strict #RRGGBB colors. Optional colors are empty for automatic values; foreground contrast is calculated.

background_colorstringalways

Strict #RRGGBB colors. Optional colors are empty for automatic values; foreground contrast is calculated.

card_colorstringalways

Strict #RRGGBB colors. Optional colors are empty for automatic values; foreground contrast is calculated.

button_colorstringalways

Strict #RRGGBB colors. Optional colors are empty for automatic values; foreground contrast is calculated.

logo_sizestringalways

small, medium or large; left or center. Images are contained, not cropped.

logo_alignmentstringalways

small, medium or large; left or center. Images are contained, not cropped.

imagesobjectalways

Optional logo_light, logo_dark and favicon URLs: scoped, same-origin normalized PNG images.

show_order_idbooleanalways

Order ID visibility, description below the title and initial order ID expansion. Amount remains visible; these are display controls, not data redaction.

show_descriptionbooleanalways

Order ID visibility, description below the title and initial order ID expansion. Amount remains visible; these are display controls, not data redaction.

details_expandedbooleanalways

Order ID visibility, description below the title and initial order ID expansion. Amount remains visible; these are display controls, not data redaction.

show_project_namebooleanalways

Merchant 5.6.0+: header name visibility. Both default to true. Project/store identity remains available in JSON.

show_store_namebooleanalways

Merchant 5.6.0+: header name visibility. Both default to true. Project/store identity remains available in JSON.

featured_chains[]arrayalways

Ordered preferences, applied only to methods already present in the invoice. Missing or disabled methods are ignored.

featured_asset_ids[]arrayalways

Ordered preferences, applied only to methods already present in the invoice. Missing or disabled methods are ignored.

default_asset_idUUID | nullalways

Suggested initial method. A valid remembered customer preference or a method already receiving funds takes priority.

messagesobjectalways
Plain text for en, de, es, pt-BR, it, ru, zh-CN, fr, ko and ja, keyed by waiting, confirming, paid, underpaid and expired. English fallback for missing merchant messages. Supplementary; never replaces actual status. Merchant-written content is not automatically translated.Details

Plain text for en, de, es, pt-BR, it, ru, zh-CN, fr, ko and ja, keyed by waiting, confirming, paid, underpaid and expired. English fallback for missing merchant messages. Supplementary; never replaces actual status. Merchant-written content is not automatically translated.

enobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
deobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
esobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
pt-BRobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
itobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
ruobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
zh-CNobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
frobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
koobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
jaobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
support_emailstringalways

Optional contact and HTTPS links, without URL credentials. External links open in a new window.

support_urlstringalways

Optional contact and HTTPS links, without URL credentials. External links open in a new window.

terms_urlstringalways

Optional contact and HTTPS links, without URL credentials. External links open in a new window.

privacy_urlstringalways

Optional contact and HTTPS links, without URL credentials. External links open in a new window.

return_button_textstringalways

Optional label only. Success/cancel targets and redirect policy still belong to the invoice.

show_return_buttonbooleanalways

Manual return/cancel button visibility; defaults to true. Applies to active and terminal states, not automatic success redirects. Available from merchant 8.1.4.

payment_methods[]object[]always

Checkout-safe payment methods.

payment_railonchain | lightningalways

Lightning remains a Bitcoin method, separate from on-chain BTC. Identify the choice by intent id and rail, not only asset_id.

bolt11string | nullalways

Signed Lightning request; null for on-chain methods. Never pay after payable becomes false.

payment_hashstring | nullalways

Lightning payment hash for reconciliation, not a receiving address. Null for on-chain methods.

idUUIDalways

Payment intent identifier.

asset_idUUIDalways

Asset UUID used by appearance preferences; distinct from this invoice's payment intent id.

asset_keystringalways

Canonical asset key.

chain_slugstringalways

Machine and display chain names.

chain_namestringalways

Machine and display chain names.

networkstringalways

Payment network.

caip_network_idstringalways

Canonical network identity used to disambiguate the selected chain.

caip_asset_idstring | nullalways

Canonical exact asset identity, including a verified token contract or mint when applicable.

asset_namestringalways

Payment asset display values.

symbolstringalways

Payment asset display values.

asset_icon_urlstring | nullalways

Same-origin locally cached asset icon, or null when no verified CoinGecko mapping exists.

asset_kindnative | tokenalways

Distinguishes native currency from contract/mint payment.

contract_addressstring | nullalways

Canonical ERC-20 contract or SPL mint for tokens; null for native currency.

token_standarderc20 | spl-token | nullalways

Verified token runtime, or null for native currency.

asset_decimalsintegeralways

Atomic-unit precision: 11 for Lightning BTC millisatoshis, 8 for on-chain BTC satoshis.

statusintent statusalways

Current payment-method status.

payablebooleanalways

True only when this exact method can currently accept payment; false for inactive methods after another asset receives funds.

finality_modestringalways

Finality policy.

required_confirmationsintegeralways

Finality policy.

expected_amountdecimalalways
Full locked quote in display and actual on-chain units. Recognized fiat stablecoins use at most two quote decimals, always rounded up after spread; other assets use adaptive precision. Actual token decimals, received funds and partial-payment remainders stay exact. Use returned amounts unchanged.Details

Full locked quote in display and actual on-chain units. Recognized fiat stablecoins use at most two quote decimals, always rounded up after spread; other assets use adaptive precision. Actual token decimals, received funds and partial-payment remainders stay exact. Use returned amounts unchanged.

expected_amount_atomicinteger stringalways
Full locked quote in display and actual on-chain units. Recognized fiat stablecoins use at most two quote decimals, always rounded up after spread; other assets use adaptive precision. Actual token decimals, received funds and partial-payment remainders stay exact. Use returned amounts unchanged.Details

Full locked quote in display and actual on-chain units. Recognized fiat stablecoins use at most two quote decimals, always rounded up after spread; other assets use adaptive precision. Actual token decimals, received funds and partial-payment remainders stay exact. Use returned amounts unchanged.

minimum_payment_amountdecimalalways

Accepted settlement threshold after applying underpayment tolerance.

minimum_payment_amount_atomicinteger stringalways

Accepted settlement threshold after applying underpayment tolerance.

received_amountdecimalalways

Observed amount.

received_amount_atomicinteger stringalways

Observed amount.

remaining_amountdecimal stringalways

Exact display amount still needed to reach the accepted threshold, clamped to zero.

remaining_amount_atomicinteger stringalways

Shortfall to the accepted threshold in atomic units. This is not the requested payment amount: tolerance affects acceptance only.

confirmed_amountdecimalalways

Confirmed/final amount.

confirmed_amount_atomicinteger stringalways

Confirmed/final amount.

destination_addressstringalways

On-chain destination and optional reference. For Lightning this is the payment hash with no tag; pay the bolt11/payment_uri instead.

destination_tagstring|nullalways

On-chain destination and optional reference. For Lightning this is the payment hash with no tag; pay the bolt11/payment_uri instead.

quote_expires_atRFC 3339 timestampalways

Quote expiry.

payment_uristring | nullalways
Chain-aware request: ERC-681, Solana Pay, native URI, or lightning:<bolt11>. Amount-bearing requests use the full expected amount minus received funds, never the tolerance threshold. Null when payable is false, including after a tolerated shortfall is accepted. Lightning QR encodes the full Lightning request, not the payment hash.Details

Chain-aware request: ERC-681, Solana Pay, native URI, or lightning:<bolt11>. Amount-bearing requests use the full expected amount minus received funds, never the tolerance threshold. Null when payable is false, including after a tolerated shortfall is accepted. Lightning QR encodes the full Lightning request, not the payment hash.

qr_urlpath | nullalways

Sequence- and exact-remainder-revisioned same-origin SVG QR path, or null when payable is false. The SVG is no-store.

address_explorer_namestring|nullalways

Validated mainnet explorer fallback where supported.

address_explorer_urlstring|nullalways

Validated mainnet explorer fallback where supported.

transaction_countintegeralways

Total distinct public, valid transactions observed for this method.

transactions_truncatedbooleanalways

True when transaction_count exceeds the returned recent transaction list.

transactions[]object[]always

Up to 10 most recent public, valid transactions. Exact received totals remain independent of this display bound.

transaction_idstringalways

Observed transaction identifier.

statusdetected | confirming | finalalways

Public observation state.

confirmationsintegeralways

Observed confirmation count.

block_heightinteger | nullalways

Observed block/ledger height.

explorer_namestringwhen returned

Validated fixed explorer name.

explorer_urlstringwhen returned

Validated fixed mainnet explorer URL.

Usage notes
  • No bearer token is needed.
  • Cache-Control is no-store and search indexing is disabled.
  • Treat invoice_id as customer-facing capability data; avoid publishing it unnecessarily.
  • asset_icon_url is a same-origin local asset; customer checkout never needs to contact CoinGecko to render it.
  • When destination_tag is non-null, display and copy it beside the address: it is a required XRP destination tag, Stellar memo ID, or TON invoice comment and must be sent exactly.
  • For verified tokens, asset_kind is token, contract_address identifies the exact ERC-20 contract or SPL mint, token_standard identifies the rail, and payment_uri carries that token identity.

Errors

Error codes & retry rules

GETStore checkout preview/invoice/preview/{project_id}Public

Renders the saved store appearance with an illustrative amount and real accepted-asset metadata. Switch between waiting, confirming, paid, underpaid and expired examples without creating payments.

Authentication & headers

Public

Path parameters

project_idUUIDrequired

Project UUID copied into the preview link by the authenticated console.

Query parameters

store_idUUID,optional

Store belonging to this project. Omit to use its first/default store.

statestring,optional

waiting, confirming, paid, underpaid or expired. Browser-only illustration.

Request

curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://pay.example.com/invoice/preview/YOUR_PROJECT_ID?store_id=YOUR_STORE_ID&state=confirming" \
  --output 'checkout-preview.html'

Response 200 text/html

Example response
<!doctype html>
<!-- Hosted branding preview; no invoice is created -->
Usage notes
  • The preview is branding-only and must never be sent to a customer as a payment request.
  • No receiving address, payable QR, wallet action, redirect or payment polling. Examples do not change actual invoice status.
  • The response is no-store, noindex, and cannot be embedded.

Errors

Error codes & retry rules

GETCheckout preview data/checkout-api/previews/{project_id}Public

Returns effective store appearance and safe accepted-asset metadata. payment_methods remains empty; preview_methods contains no payment addresses, quotes or private wallet data.

Authentication & headers

Public

Path parameters

project_idUUIDrequired

Project UUID from the console preview link.

Query parameters

store_idUUID,optional

Must belong to this project; mismatched IDs return 404. Unknown query fields are rejected.

Request

curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID?store_id=YOUR_STORE_ID" \
  --header 'Accept: application/json'

Response 200 application/json

Example response
{
  "data": {
    "preview": true,
    "invoice_id": "YOUR_PROJECT_ID",
    "amount": "100.00",
    "currency": "USD",
    "project": {
      "name": "Example project",
      "checkout_title": "Complete your payment",
      "checkout_description": "Choose a network and send the exact amount shown.",
      "theme": "system",
      "accent_color": "#42e39b",
      "logo_url": "/checkout-api/previews/…/logo/…/image.png"
    },
    "appearance": {"inherit_default_store": true, "theme": "system", "accent_color": "#42E39B", "images": {}},
    "preview_methods": [],
    "payment_methods": []
  }
}

Response fields

dataobject
previewboolean
invoice_idstring
amountstring
currencystring
projectobject
namestring
checkout_titlestring
checkout_descriptionstring
themestring
accent_colorstring
logo_urlstring
appearanceobject
inherit_default_storebooleanalways

True when the project's default store supplies this appearance. False for independent stores and frozen invoice overrides.

invoice_overridebooleanalways

True when checkout_appearance was supplied at invoice creation. Omitted/null keeps this false.

titlestringalways

Plain merchant heading, top message and bottom message. intro replaces customer_message; old stored copy is preserved. Never evaluate as markup.

introstringalways

Plain merchant heading, top message and bottom message. intro replaces customer_message; old stored copy is preserved. Never evaluate as markup.

outrostringalways

Plain merchant heading, top message and bottom message. intro replaces customer_message; old stored copy is preserved. Never evaluate as markup.

intro_font_sizeintegeralways

Font sizes in pixels: 12, 14, 16, 18, 20 or 24.

outro_font_sizeintegeralways

Font sizes in pixels: 12, 14, 16, 18, 20 or 24.

customer_messagestringalways

Deprecated compatibility alias of intro. Use intro for new integrations.

themesystem | light | dim | darkalways

Customer-device preference or a fixed theme.

accent_colorstringalways

Strict #RRGGBB colors. Optional colors are empty for automatic values; foreground contrast is calculated.

background_colorstringalways

Strict #RRGGBB colors. Optional colors are empty for automatic values; foreground contrast is calculated.

card_colorstringalways

Strict #RRGGBB colors. Optional colors are empty for automatic values; foreground contrast is calculated.

button_colorstringalways

Strict #RRGGBB colors. Optional colors are empty for automatic values; foreground contrast is calculated.

logo_sizestringalways

small, medium or large; left or center. Images are contained, not cropped.

logo_alignmentstringalways

small, medium or large; left or center. Images are contained, not cropped.

imagesobjectalways

Optional logo_light, logo_dark and favicon URLs: scoped, same-origin normalized PNG images.

show_order_idbooleanalways

Order ID visibility, description below the title and initial order ID expansion. Amount remains visible; these are display controls, not data redaction.

show_descriptionbooleanalways

Order ID visibility, description below the title and initial order ID expansion. Amount remains visible; these are display controls, not data redaction.

details_expandedbooleanalways

Order ID visibility, description below the title and initial order ID expansion. Amount remains visible; these are display controls, not data redaction.

show_project_namebooleanalways

Merchant 5.6.0+: header name visibility. Both default to true. Project/store identity remains available in JSON.

show_store_namebooleanalways

Merchant 5.6.0+: header name visibility. Both default to true. Project/store identity remains available in JSON.

featured_chains[]arrayalways

Ordered preferences, applied only to methods already present in the invoice. Missing or disabled methods are ignored.

featured_asset_ids[]arrayalways

Ordered preferences, applied only to methods already present in the invoice. Missing or disabled methods are ignored.

default_asset_idUUID | nullalways

Suggested initial method. A valid remembered customer preference or a method already receiving funds takes priority.

messagesobjectalways
Plain text for en, de, es, pt-BR, it, ru, zh-CN, fr, ko and ja, keyed by waiting, confirming, paid, underpaid and expired. English fallback for missing merchant messages. Supplementary; never replaces actual status. Merchant-written content is not automatically translated.Details

Plain text for en, de, es, pt-BR, it, ru, zh-CN, fr, ko and ja, keyed by waiting, confirming, paid, underpaid and expired. English fallback for missing merchant messages. Supplementary; never replaces actual status. Merchant-written content is not automatically translated.

enobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
deobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
esobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
pt-BRobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
itobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
ruobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
zh-CNobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
frobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
koobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
jaobject
waitingstring
confirmingstring
paidstring
underpaidstring
expiredstring
support_emailstringalways

Optional contact and HTTPS links, without URL credentials. External links open in a new window.

support_urlstringalways

Optional contact and HTTPS links, without URL credentials. External links open in a new window.

terms_urlstringalways

Optional contact and HTTPS links, without URL credentials. External links open in a new window.

privacy_urlstringalways

Optional contact and HTTPS links, without URL credentials. External links open in a new window.

return_button_textstringalways

Optional label only. Success/cancel targets and redirect policy still belong to the invoice.

show_return_buttonbooleanalways

Manual return/cancel button visibility; defaults to true. Applies to active and terminal states, not automatic success redirects. Available from merchant 8.1.4.

preview_methods[]array
payment_methods[]array
Usage notes
  • No bearer token is accepted or needed.
  • No invoice, destination, wallet, transaction, IPN, webhook, or merchant metadata is returned.
  • Use the authenticated console to obtain the correct pay-domain preview link.

Errors

Error codes & retry rules

GETStore checkout image/checkout-api/invoices/{invoice_id}/appearance-images/{kind}/{revision}/image.pngPublic

Returns a normalized store logo or favicon belonging to this invoice. Use appearance.images URLs from checkout data.

Authentication & headers

Public

Path parameters

invoice_idUUIDrequired

Public invoice UUID.

kindenumrequired

logo_light, logo_dark or favicon.

revisionUUIDrequired

Current image revision.

Request

curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/appearance-images/logo_light/YOUR_IMAGE_REVISION/image.png" \
  --output 'store-logo.png'

Response 200 image/png

Example response
(binary PNG response)
Usage notes
  • Use appearance.images from checkout JSON. Frozen invoice images keep working after their source store replaces or removes an upload. Explicitly removed, wrong-invoice, wrong-kind and unknown revisions return 404; a snapshot never falls back to a current store image.
  • Without an invoice override, the current effective store image is used and replaced/removed revisions return 404. PNG only, nosniff and private caching.
  • Store image uploads accept bounded PNG, JPEG or WebP in the authenticated console; never SVG, HTML or remote image URLs.

Errors

Error codes & retry rules

GETStore preview image/checkout-api/previews/{project_id}/stores/{store_id}/appearance-images/{kind}/{revision}/image.pngPublic

Returns a normalized preview image only for the matching project, store, kind and current revision.

Authentication & headers

Public

Path parameters

project_idUUIDrequired

Project UUID.

store_idUUIDrequired

Store belonging to the project.

kindenumrequired

logo_light, logo_dark or favicon.

revisionUUIDrequired

Current image revision.

Request

curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/appearance-images/logo_light/YOUR_IMAGE_REVISION/image.png" \
  --output 'store-preview-logo.png'

Response 200 image/png

Example response
(binary PNG response)
Usage notes
  • Use appearance.images from preview data. Unknown or mismatched IDs return 404. No wallet or payment information is exposed.

Errors

Error codes & retry rules

GETPayment QR image/checkout-api/invoices/{invoice_id}/payment-methods/{intent_id}/qr.svgPublic

Generates a 512×512 SVG QR for the exact chain-aware payment payload of an invoice payment method.

Authentication & headers

Public

Path parameters

invoice_idUUIDrequired

Public invoice UUID.

intent_idUUIDrequired

Payment method id from checkout JSON.

Request

curl --fail-with-body --max-time 30 \
  --request GET \
  --url "https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/payment-methods/YOUR_INTENT_ID/qr.svg" \
  --output 'payment-qr.svg'

Response 200 image/svg+xml

Example response
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">…</svg>
Usage notes
  • No bearer token is needed.
  • Use the sequence- and remainder-revisioned qr_url returned by checkout JSON; the SVG is private and no-store.
  • After a partial payment it requests the exact remaining amount and stays locked to that asset.
  • Returns 409 after expiry, completion, or when another method is active; returns payment_qr_unavailable (422) if the request is too large to encode.

Errors

Error codes & retry rules

Reference for Wholly Crypto 8.3.2. For your installed version, open Settings → API access → Documentation in your console. View releases.