Create sponsored transfer (quote)
Quotes a gas-sponsored transfer for an external end-user (someone who holds their own key and has no Bitnob wallet) and returns the exact payload they must sign. Bitnob pays the network gas and recoups it as a fee in the transferred token, so neither party needs to hold the native gas asset (SOL, ETH, or TRX).
Amounts. amount is a decimal string in the asset’s normal units (for example "10.50" USDC). By default (net mode) amount is what the recipient receives and the sender (from) is debited total_debit, which is recipient_amount plus fee (the sponsorship fee) plus partner_fee (your optional markup). Set treat_as_gross_amount: true for gross mode: amount becomes the sender’s total debit (total_debit equals amount) and the sponsorship and partner fees are deducted from it, so recipient_amount is amount minus those fees. Gross mode lets you sweep a full source balance without overdrawing it; the request is rejected (invalid_request) when amount does not exceed the fees. The response echoes treat_as_gross_amount and both recipient_amount and total_debit so you can confirm the split.
Flow. First call create (this endpoint) to get a sign block and an expires_at. Then have the end-user sign it verbatim with their own key. Then submit the signature or signatures to POST /sponsored-transfers/{id}/submit. Finally poll GET /sponsored-transfers/{id} (or subscribe to sponsored_transfer.* webhooks) until the status is terminal. Sign and submit before expires_at.
What to sign depends on sign.scheme:
solana_ed25519: sign the raw message bytes insign.message_base64with thefromed25519 key, then submit the base58 signature assignature.evm_7702: sign both the EIP-7702 authorization (sign.authorization) and the EIP-712 witness (sign.witness) with thefromkey, then submit both as 0x-prefixed 65-byte signatures.sign.digestsgives the raw 32-byte hashes if you use a non-standard signer.tron_router: sign the 0x-prefixed 32-byte digest insign.digestwith thefromsecp256k1 key and submit it astron_signature. Important: on a sender’s first sponsored transfer of a given token, the quote also returns asign.approveblock withsign.approve.neededset to true. When that block is present you must ALSO signsign.approve.digestwith the samefromkey and submit it astron_approve_signaturein the same submit call, alongsidetron_signature. This one-time approval is what lets the router pull the tokens on the sender’s behalf, and the transfer cannot be broadcast without it. It is needed only on the first transfer (later transfers do not return the block and need onlytron_signature), the single quoted fee already covers its cost, and Bitnob activates the sender’s account first if it is brand new.
Partner markup (optional). Include partner_fee to charge your own flat fee (in the same asset) to an address you control, on top of the sponsorship fee. address and amount are required together, the address must not equal the sender or recipient, and the amount is capped per chain. Supported on Solana, EVM, and Tron. Requires the Idempotency-Key header.
Authorizations
Headers
API version (defaults to the latest supported version if omitted).
v1 Unique key (1-255 printable ASCII chars) used to safely retry write operations. Same key + body returns the cached response; same key + different body returns 409.
1 - 255Body
Decimal amount in the asset's normal units (not base units). By default the recipient receives this amount; with treat_as_gross_amount, this is the sender's total debit.
"10.50"
Token symbol to transfer (a supported stablecoin), e.g. USDC on Solana/EVM or USDT on Tron.
"USDC"
Chain to transfer on: solana, ethereum, base, arbitrum, optimism, polygon, bsc, or tron.
"solana"
Sender address. This is your end-user's own address, which holds the token and signs the transfer (and, on Tron for a first-time sender, the one-time approval).
"7Np41oeYqPefeNQEHSv1UDhYrehxin3NStELsSKCT4K2"
Recipient address.
"3xTd...recipient"
Deprecated and ignored. The network follows the environment (live is mainnet, sandbox is testnet), so omit it. Any value sent is ignored, kept only for backward compatibility.
"mainnet"
Optional EVM paymaster router contract version. Omit for the chain default. Rejected if not allowed for the chain.
x >= 12
Treat amount as the sender's total debit and deduct sponsorship and partner fees from the recipient amount.
Response
Created
RFC 3339 quote expiry; present while status is quoted. Sign and submit before this time.
Machine-readable failure reason on a failed transfer, e.g. insufficient_token_balance, transfer_reverts, reverted.
Human-readable failure detail.
Bitnob sponsorship fee, charged in the transferred token.
Transfer id; use it in the submit and get endpoints.
Object type discriminator; always "sponsored_transfer".
"sponsored_transfer"
Your markup breakdown; present only if you attached partner_fee on the quote.
What the recipient receives (decimal).
"10.50"
The resolved EVM router contract version the transfer was quoted against (absent for non-EVM).
What the end-user must sign; present only while status is quoted.
Lifecycle status: quoted, validating, submitted, assembled (EVM only), tron_activating and tron_approving (Tron first-time onboarding), pending, completed, failed, expired, cancelled.
"quoted"
What leaves the sender (decimal). In gross mode this equals amount; otherwise it equals recipient_amount + fee + partner_fee.
"10.72"
Whether the request amount was treated as the sender's total debit.
On-chain transaction hash, set once broadcast.