REST API
HTTP endpoints for any language. No SDK needed — just HTTP calls.
Authentication
Public endpoints (GET /api/plans, GET /api/price, GET /api/auth) require no auth. All other endpoints require one of two methods:
Method 1: Wallet Signature (recommended)
Sign a message with any Solana wallet. No registration, no API keys, no database. Your wallet IS your identity.
1// 1. Get the message to sign2const res = await fetch("https://sow-beryl.vercel.app/api/auth")3const { data } = await res.json()4// data.message = "Buff API Authentication"56// 2. Sign it with your wallet7const message = new TextEncoder().encode(data.message)8const signature = await wallet.signMessage(message)9const sigBase64 = btoa(String.fromCharCode(...signature))1011// 3. Use on any protected endpoint12fetch("https://sow-beryl.vercel.app/api/roundup", {13 method: "POST",14 headers: {15 "Content-Type": "application/json",16 "x-wallet": wallet.publicKey.toBase58(),17 "x-signature": sigBase64,18 },19 body: JSON.stringify({ txValueUsd: 27.63, plan: "tree" }),20})Method 2: Static API Key
For server-to-server integrations where wallet signing is not practical.
curl -X POST https://sow-beryl.vercel.app/api/roundup \ -H "Content-Type: application/json" \ -H "x-api-key: your-api-key" \ -d '{"txValueUsd": 27.63, "plan": "tree"}'GET /api/auth
Get the authentication message to sign, and instructions.
1{2 "ok": true,3 "data": {4 "message": "Buff API Authentication",5 "instructions": "Sign this message with your Solana wallet..."6 }7}POST /api/auth
Verify your signature works before using protected endpoints.
curl -X POST https://sow-beryl.vercel.app/api/auth \ -H "Content-Type: application/json" \ -d '{"wallet": "YourPubkey...", "signature": "Base64Sig..."}'Rate Limiting
All API endpoints are rate-limited to 60 requests per minute per IP. Response headers include X-RateLimit-Limit and X-RateLimit-Remaining.
GET /api/plans
List all available plan tiers and defaults.
curl https://your-buff.vercel.app/api/plans1{2 "ok": true,3 "data": {4 "plans": {5 "seed": { "name": "Seed", "roundToUsd": 0.05, "buffFeePercent": 1.00 },6 "sprout": { "name": "Sprout", "roundToUsd": 0.10, "buffFeePercent": 0.75 },7 "tree": { "name": "Tree", "roundToUsd": 0.50, "buffFeePercent": 0.50 },8 "forest": { "name": "Forest", "roundToUsd": 1.00, "buffFeePercent": 0.25 }9 },10 "ceiling": 1.0,11 "defaultPlan": "sprout",12 "defaultAsset": "BTC",13 "defaultThreshold": 5.0,14 "supportedAssets": ["BTC", "ETH", "SOL", "USDC", "USDT"]15 }16}GET /api/price
Get real-time token prices (cached 30s).
curl https://your-buff.vercel.app/api/price1{2 "ok": true,3 "data": {4 "prices": { "SOL": 88.42, "BTC": 71080, "ETH": 2101.15, "USDC": 1.0, "USDT": 1.0 },5 "timestamp": 17100000000006 }7}POST /api/roundup
Calculate the round-up for a transaction value.
| Field | Type | Required | Description |
|---|---|---|---|
| txValueUsd | number | Yes | Total transaction value in USD |
| plan | string | No | Plan tier: seed, sprout, tree, forest |
| roundToUsd | number | No | Custom round-up increment (overrides plan) |
| ceiling | number | No | Max round-up (default: 1.00) |
curl -X POST https://your-buff.vercel.app/api/roundup \ -H "Content-Type: application/json" \ -d '{"txValueUsd": 27.63, "plan": "tree"}'1{2 "ok": true,3 "data": {4 "txValueUsd": 27.63,5 "roundToUsd": 0.50,6 "roundedToUsd": 28.00,7 "roundUpUsd": 0.37,8 "roundUpSol": 0.004185,9 "buffFeePercent": 0.50,10 "buffFeeUsd": 0.00185,11 "buffFeeSol": 0.0000209,12 "userInvestmentUsd": 0.36815,13 "userInvestmentSol": 0.004164,14 "solPriceUsd": 88.42,15 "skipped": false,16 "capped": false17 }18}POST /api/swap/quote
Get a Jupiter swap quote (SOL → target asset).
| Field | Type | Required | Description |
|---|---|---|---|
| inputLamports | number | Yes | Amount of SOL in lamports (1 SOL = 1e9) |
| targetAsset | string | No | BTC, ETH, SOL, USDC, USDT (default: BTC) |
| slippageBps | number | No | Slippage in basis points (default: 100 = 1%) |
curl -X POST https://your-buff.vercel.app/api/swap/quote \ -H "Content-Type: application/json" \ -d '{"inputLamports": 100000000, "targetAsset": "USDC"}'1{2 "ok": true,3 "data": {4 "inputLamports": 100000000,5 "inputSol": 0.1,6 "outputAmount": "8847771",7 "targetAsset": "USDC",8 "priceImpact": "0",9 "route": "Raydium → Orca"10 }11}POST /api/wallet/derive
Derive a Buff wallet public key from a signature. Returns only the public key — never the private key.
curl -X POST https://your-buff.vercel.app/api/wallet/derive \ -H "Content-Type: application/json" \ -d '{"signature":"base64-encoded-signature"}'1{2 "ok": true,3 "data": {4 "publicKey": "A2bBXAg4r8Rb2qFoycqBCsDDDmnDEKD8w1V3VPv1eR5T",5 "derivationMessage": "Buff Portfolio Wallet v1"6 }7}GET /api/portfolio/:address
Read all token balances and USD values for any Solana wallet.
curl "https://your-buff.vercel.app/api/portfolio/E71R6Ph2sS...?network=devnet"1{2 "ok": true,3 "data": {4 "walletAddress": "E71R6Ph2sS...",5 "network": "devnet",6 "balances": [{ "asset": "BTC", "balance": "0.00068", "usdValue": 48.20 }],7 "totalUsd": 48.20,8 "pendingSol": 0.004617,9 "pendingUsd": 0.41,10 "solPriceUsd": 88.0411 }12}GET /api/accumulator/:address
Check if a wallet has reached the investment threshold.
curl "https://your-buff.vercel.app/api/accumulator/E71R6Ph2sS...?threshold=5&network=devnet"1{2 "ok": true,3 "data": {4 "balanceSol": 0.004617,5 "balanceUsd": 0.41,6 "solPriceUsd": 88.04,7 "thresholdUsd": 5.0,8 "thresholdReached": false,9 "remaining": 4.5910 }11}POST /api/swap/execute
Submit a pre-signed transaction to the Solana network. The transaction must already be signed — the API just relays it.
curl -X POST https://your-buff.vercel.app/api/swap/execute \ -H "Content-Type: application/json" \ -d '{"signedTransaction":"base64-encoded-tx","network":"mainnet-beta"}'1{2 "ok": true,3 "data": {4 "txSignature": "4Hkbeas...",5 "confirmed": true,6 "network": "mainnet-beta"7 }8}