Cloak API

Quickstart

Build the complete flow: get a quote, create an order, sign the deposit, and poll for the result.

Examples in

The four calls

1

Quote

Calculate the transfer amount, fees, limits, and estimated delivery time. See POST /quote.

2

Order

Send the quote back unchanged and receive an unsigned v0 transaction. See POST /order.

3

Sign and submit

Your user signs once. This is the only signature in the entire flow. See Signing the transaction.

4

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.

Modeamount meansSender paysRecipient receives
exact_inFix the sender's debit10,000.00 USDC9,909.81 USDC
exact_outFix the delivered amount10,091.01 USDC10,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

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
done

Two 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

Beyond the amount being sent, their wallet pays roughly 0.002 SOL for the deposit transaction and its account rent. A max button computed from amountIn alone will overshoot and fail on-chain.

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.