How it works
1
Get a quote
Call
POST /onramp/quote with the fiat amount and target cryptocurrency. Tender returns a
live exchange rate, an estimated crypto output, and a quoteId that is valid for 60
seconds.2
Initiate the on-ramp
Call
POST /onramp/initiate with the quoteId, the customer’s wallet address, and their
contact details. Tender creates a virtual bank account and returns the transfer details to
show your customer.3
Customer pays
Customer makes a local bank transfer to the virtual account. No crypto wallet or exchange
account is needed on their side — just a standard bank transfer.
4
Tender processes automatically
Once payment is confirmed, Tender runs the pipeline automatically:
- Converts the fiat to the target coin on the target chain
- Delivers the coin to the
targetAddresson thetargetChain
5
Poll for completion
Call
GET /onramp/{reference} to track progress. There are no on-ramp webhooks; the
stages object shows where the pipeline is at any moment.Pipeline stages
After payment is confirmed, the on-ramp moves through these stages in order:
Each stage has a
status of pending, in_progress, completed, failed, or skipped.
Overall status values
Key concepts
Quotes are required and single-use
Before initiating, you must call/onramp/quote to lock in a rate. The returned quoteId is:
- Time-limited — expires 60 seconds after it is created (shown as
expiresAt) - Single-use — consumed the moment it is passed to
/onramp/initiate, even if it has expired - Yours only — another merchant can’t redeem it
400 error.
Minimum amount
The fiat amount must be worth at least $15 USD at the quoted rate. Smaller amounts are rejected at the quote step.Rate limits
All on-ramp endpoints, including status polling, share a limit of 10 requests per minute per merchant. Cache the chains and coins lists, and poll status about every 30 seconds. See Rate limits.Virtual bank accounts expire
The virtual bank account returned by/onramp/initiate expires after 1 hour. If the customer
does not pay within that window, the on-ramp request moves to failed status.
Supported chains and currencies
Use the discovery endpoints to present your customers with what is available:GET /onramp/chains— chains that support on-ramp deliveryGET /onramp/coins— cryptocurrencies available, optionally filtered by chain
Integration
This section walks through every step of a real on-ramp integration, from discovery to polling for completion. All examples use the sandbox environment.Prerequisites
- A Tender merchant account with API credentials
- Your
TENDER_ACCESS_IDandTENDER_ACCESS_SECRETset as environment variables
Authentication guide
Onramp endpoints use Signed (HMAC) authentication — an HMAC-SHA256 signature is required on every request. Follow the authentication guide for full details
and code examples in Node.js, Python, and PHP before continuing.
makeHeaders() helper and a BASE constant as described in
that guide:
Step 1 — Discover available chains and coins
Show your customers which blockchains and currencies they can receive.Step 2 — Get a quote
Once the customer has chosen a target currency and entered their fiat amount, fetch a live quote.Step 3 — Show the quote to your customer
Display the estimated output and ask for confirmation before initiating.Step 4 — Initiate the on-ramp
After the customer confirms, call/onramp/initiate with the quoteId and their wallet address.
Step 5 — Display bank transfer details
Show the returnedbankTransfer details so the customer knows where to send money.
reference — you will use it to poll for status.
Step 6 — Poll for completion
PollGET /onramp/{reference} until status is crypto_sent (success) or failed. A status
of pending means a step is being retried; keep polling. Polling counts against the on-ramp
limit of 10 requests per minute, so poll about every 30 seconds.
On-ramps don’t send webhooks. Polling the status endpoint is the only way to track progress.
Inspecting stage progress
Thestages object in the status response shows the exact state of each pipeline step.