Skip to main content
This feature is currently only available in the sandbox environment.
Tender’s subwallet offering lets you provision and manage a full wallet infrastructure for each of your end-users. You create a wallet per user, assign blockchain addresses, watch those addresses for incoming deposits, and initiate outbound transfers — all via your merchant API credentials, without your users ever touching Tender directly.

How it works

1

Create a wallet

Provision a wallet tied to a unique reference you supply — typically your own user ID. Tender returns one address per supported network.
2

Add addresses

Create additional address slots on specific networks for an existing wallet. Each slot has an address_reference you choose.
3

Watch for deposits

Register addresses with Tender’s deposit monitor. When a deposit arrives, Tender sends a sub_user_wallet_transaction_detected webhook to your server.
4

Initiate transfers

Send funds from an address slot to any destination. Tender picks a native coin, token or gasless token transfer from the currency and network, and sends sub_user_wallet_transfer_confirmed (or sub_user_wallet_transfer_failed for a failed gasless transfer) when it settles.

Prerequisites

Authentication guide

These endpoints use Signed (HMAC) authentication — an HMAC-SHA256 signature is required on every request. See the authentication guide for code examples.
All subwallet endpoints share a limit of 120 requests per minute per merchant; GET /wallet/balance/:address is further limited to 30 per minute. See Rate limits.

Step 1 — Create a wallet

Call POST /wallet with a reference for the end-user. References are globally unique across Tender, so prefix them with something specific to your platform. Tender provisions the wallet and returns one address per supported network (EVM, TRON, BTC), each with its own generated address_reference and, where the network supports it, a gasless_address. Store the reference: it is the wallet_reference (and the transfer’s merchant_reference) in every later call for that user.

Create Wallet

Full parameters and response schema for POST /wallet

Step 2 — Add addresses to the wallet

Call POST /wallet/address with the wallet_reference, an address_reference of your choice (also globally unique), and the networks you want addresses on (EVM, TRON, BTC). All addresses from one call share that address_reference.

Create Address

Full parameters and response schema for POST /wallet/address
On networks where token transfers run gasless, tokens are spent from the slot’s gasless_address, not its address. Ask users to deposit tokens to the gasless_address when one is present.

Step 3 — Watch for deposits

Call POST /wallet/filter with the address and the network types to monitor (EVM, TRON, BTC). Once registered, Tender watches that address on-chain and sends a sub_user_wallet_transaction_detected webhook whenever a deposit is detected. The same deposit can be reported more than once as confirmations increase. Every webhook uses the envelope {"eventId": "<uuid>", "event": "<name>", "data": {…}}. sub_user_wallet_transaction_detected data fields:
Treat a deposit as settled only when confirmed is true or confirmations >= confirmationsRequired.

Add Deposit Filter

Full parameters and response schema for POST /wallet/filter

Step 4 — Initiate a transfer

Call POST /wallet/transfer with:
  • chain and currency (for example tron and usdt);
  • receiver and amount (human-readable units);
  • merchant_reference: the wallet reference to send from;
  • address_reference: the address slot to send from;
  • payment_reference: your own reference for this transfer, echoed in webhooks and the transaction list.
sender is optional; the source address is resolved from the two references. Supported chains: ethereum, tron, bitcoin The response depends on the transfer type:
  • Coin or on-chain token transfer: 200 with a tx_id. Tender sends sub_user_wallet_transfer_confirmed once the transaction confirms.
  • Gasless token transfer: 202 with an operation_id. Poll POST /wallet/transfer/status or wait for sub_user_wallet_transfer_confirmed / sub_user_wallet_transfer_failed.

Transfer Funds

Full parameters and response schema for POST /wallet/transfer
sub_user_wallet_transfer_confirmed data fields (on-chain transfers): For gasless transfers, sub_user_wallet_transfer_confirmed and sub_user_wallet_transfer_failed carry the same fields without blockNumber, plus:

Utility operations


Webhook events

Webhooks are delivered once, without retries. Use depositKey and transferKey to deduplicate, and use List Wallet Transactions to reconcile anything you missed. See Webhooks for how to configure your endpoint.

When the wallet service is unavailable

Any subwallet endpoint that talks to the blockchain can return 503 with Wallet service is temporarily unavailable. Please try again. Retry with backoff. For POST /wallet and POST /wallet/transfer, a 503 doesn’t tell you whether the action happened: check List Wallets or List Wallet Transactions before retrying.