Cloak API
Quickstart
Build the complete flow: get a quote, create an order, sign the deposit, and poll for the result.
The four calls
Quote
Calculate the transfer amount, fees, limits, and estimated delivery time. See POST /quote.
Order
Send the quote back unchanged and receive an unsigned v0 transaction. See POST /order.
Sign and submit
Your user signs once. This is the only signature in the entire flow. See Signing the transaction.
Poll until final
Check the order every few seconds and stop when final is true. See GET /status.
Choose the Amount Mode
The same amount has a different meaning in each mode. This comparison uses 10,000 USDC and a 50 bps partner fee.
| Mode | amount means | Sender pays | Recipient receives |
|---|---|---|---|
| exact_in | Fix the sender's debit | 10,000.00 USDC | 9,909.81 USDC |
| exact_out | Fix the delivered amount | 10,091.01 USDC | 10,000.00 USDC |
The complete flow below uses exact_out. To use exact_in, change only mode; the quote response supplies the resulting amounts and fees.
Complete flow
# Your key is issued with your partner account. Keep it server-side.
export VEILO_KEY="YOUR_API_KEY"
# 1. Quote. Ask what a 10,000.00 USDC delivery costs.
QUOTE=$(curl -sS -X POST "https://api.veilo.network/cloak/v1/quote" \
-H "Authorization: Bearer $VEILO_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": "10000000000",
"sourceAssetId": "veilo-usdc",
"destinationAssetId": "veilo-usdc",
"senderAddress": "SENDER_SOLANA_ADDRESS",
"recipientAddress": "RECIPIENT_SOLANA_ADDRESS",
"mode": "exact_out",
"feeBps": 50,
"feeRecipientAddress": "PARTNER_FEE_WALLET_ADDRESS"
}')
# 2. Order. Send the quote back unchanged.
ORDER=$(echo "$QUOTE" | jq '{
quote: .quote,
senderAddress: "SENDER_SOLANA_ADDRESS",
recipientAddress: "RECIPIENT_SOLANA_ADDRESS",
feeBps: 50,
feeRecipientAddress: "PARTNER_FEE_WALLET_ADDRESS"
}' | curl -sS -X POST "https://api.veilo.network/cloak/v1/order" \
-H "Authorization: Bearer $VEILO_KEY" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: $(uuidgen)" \
--data-binary @-)
TRACKING=$(echo "$ORDER" | jq -r .order.trackingId)
# 3. Sign. Not possible in shell. See "Signing the transaction".
# Hand .order.transaction (base64, unsigned v0) to your wallet layer.
# 4. Poll until final.
while :; do
S=$(curl -sS "https://api.veilo.network/cloak/v1/status/$TRACKING" -H "Authorization: Bearer $VEILO_KEY")
echo "$S" | jq -r '.order.status'
[ "$(echo "$S" | jq -r '.order.final')" = "true" ] && break
sleep 3
doneTwo things this example takes for granted
Amounts are raw base units, as strings. "10000000000" in a 6-decimal asset is 10,000 tokens. See Amounts & assets.
Send the quote back unchanged. Cloak rejects modified terms.
Keep SOL available for the deposit
What to build next
The example above is the happy path. Three things turn it into an integration you can put in front of users: error handling that branches on the stable code, an idempotency key on order creation, and a refresh call when the transaction expires before your user signs it.
