Skip to main content
Most problems with a sponsored transfer fall into one of three groups, and each has a different fix:

When quoting fails

Branch on 429 by its code. Treating budget_exceeded like an ordinary rate limit makes you retry for hours.
Request quotes only when the user is about to confirm. Quoting every time someone opens a send screen uses up your quote rate and daily budget on transfers that never happen.

When submitting fails

A 409 conflict usually means a retry after a timeout. If the first submit reached Bitnob, the transfer is already moving. Retries with the same Idempotency-Key and body return the original response instead of 409, so reuse the key when you retry a submit.

When the transfer fails on chain

A transfer in failed status carries failure_code and failure_reason. It is terminal: that transfer won’t be retried. Other codes may be added. Show failure_reason in your logs, and fall back to a generic message for codes you don’t recognize.

Expired and canceled transfers

expired means the quote passed expires_at without a valid submission. Nothing was signed by Bitnob, and nothing moved. The status can lag: a quote may still read quoted shortly after expires_at. Treat any quote past expires_at as expired, whatever its status says. cancelled means the transfer was canceled before broadcast. Both are terminal and safe to retry with a new quote.

Never double-send

The user’s funds only move when a submitted quote broadcasts. Use these rules to make sure each payment intent results in at most one transfer:
  • Give each payment intent one quote Idempotency-Key and one submit Idempotency-Key, and reuse them on retries.
  • Before you request a replacement quote, check that the previous transfer is expired, failed, or cancelled, not still pending.
  • Store the transfer id against your payment intent as soon as the quote returns.