Who does what
Bitnob never holds the user’s key or the user’s funds. Tokens go straight from the sender’s address to the recipient, and the fee goes to Bitnob in the same transaction.
The fee model
Bitnob pays the network fee in the native asset and charges a sponsorship fee in the token being sent. The quote fixes the fee, so the user sees the exact cost before they sign, whatever happens to gas prices afterwards. A quote breaks the transfer into parts:total_debit always equals recipient_amount + fee.amount + partner_fee.amount.
Net mode and gross mode
amount on the quote request means one of two things:
- Net mode, the default:
amountis what the recipient receives. The fees are added on top, sototal_debitis more thanamount. Use it for payments, where the recipient must get an exact amount. - Gross mode, with
treat_as_gross_amount: true:amountis the sender’s total debit. The fees come out of it, so the recipient gets less thanamount. Use it to empty an address without overdrawing it. See Sweep a full balance.
A gross-mode quote carries
"treat_as_gross_amount": true, so you can check which mode was applied. Net-mode quotes leave the field out.
Amounts are decimal strings in the token’s normal units, for example "10.50" USDC. They are not base units. Responses drop trailing zeros, so "1.00" comes back as "1". Compare amounts as decimals, not as strings.
The fee covers the network cost of the transfer, so it depends on the chain and on network conditions, and a first-time Tron sender pays more because the quote includes the one-time approval. As a guide, mainnet quotes for 1 unit have come back at about 0.77 USDC on Base and about 2.57 USDT for a first-time sender on Tron. Always show the user the quoted fee.
Quotes expire
A quote is valid until itsexpires_at, an RFC 3339 timestamp about three minutes after it was created. The user must sign and you must submit before then. After it, Submit returns 409 with quote_expired, and you request a new quote. The quote’s status may still read quoted for a short while after expires_at, so go by the timestamp.
Keep the time between quote and submit short: request the quote when the user is ready to confirm, not when they open the screen. If the user takes a long time, re-quote, and show the new amounts before they sign again.
The lifecycle
A signature that doesn’t verify doesn’t fail the transfer. Submit returns422 and the quote stays quoted, so the user can sign again.
onboarding in the diagram stands for the chain-specific step: assembled on EVM, and tron_activating or tron_approving on Tron. Solana goes straight to pending.
Limits
- Quote rate. Requesting quotes too fast returns
429withrate_limited. - Daily budget. Your organization has a daily sponsored-gas budget. Past it, quotes return
429withbudget_exceededuntil the budget resets. - Capacity. Rarely, sponsorship capacity is briefly unavailable, and quotes return
503withcapacity_unavailable.
429 carries a Retry-After header. Handle failures and expiry covers how to respond to each.