SPONGE WALLET API QUICK REFERENCE v0.2.2
Base: https://api.wallet.paysponge.com
Auth: Authorization: Bearer <SPONGE_API_KEY>
Ver: Sponge-Version: 0.2.2 (REQUIRED on every request)
Docs: This file is canonical (skills guide + params)
Capabilities: wallet + swaps (Solana/Base/Ethereum/Polygon/Arbitrum/Tempo) + bridges + payment links + paid external services (x402 + MPP) + trading + shopping + checkout + banking + Sponge Card + onramp
Paid services (search, image gen, scraping, AI, data, etc.):
GET /api/discover -> Step 1: find services by query/category
GET /api/discover/:serviceId -> Step 2: get endpoints, params, pricing (REQUIRED before fetch)
POST /api/paid/fetch -> Step 3: call service endpoint (auto-selects x402 USDC or MPP on Tempo)
POST /api/x402/fetch -> Step 3 alt: call service endpoint (x402 USDC only)
POST /api/mpp/fetch -> Step 3 alt: call service endpoint (MPP on Tempo; asset negotiated per endpoint, typically USDC.e)
POST /api/siwe/generate -> optional SIWE auth for endpoints that require EIP-4361 signatures
Wallet & tokens:
GET /api/balances -> get balances (includes Polymarket USDC.e)
POST /api/payment-links -> create reusable x402 payment link
GET /api/payment-links/:paymentLinkId -> get payment link status/details
POST /api/transfers/evm -> EVM transfer (ETH/USDC)
POST /api/transfers/solana -> Solana transfer (SOL/USDC)
POST /api/transfers/tempo -> Tempo transfer (pathUSD/AlphaUSD/BetaUSD/ThetaUSD)
POST /api/solana/sign -> Sign pre-built Solana transaction only
POST /api/solana/sign-and-send -> Sign and submit pre-built Solana transaction
POST /api/transactions/swap -> Solana swap (DFlow); also supports EVM chains
POST /api/transactions/swap/quote -> Solana swap quote only (DFlow)
POST /api/transactions/swap/execute -> Execute a previously obtained swap quote
POST /api/transactions/base-swap -> Base swap (0x)
POST /api/transactions/tempo-swap -> Tempo swap (StablecoinExchange DEX)
POST /api/transactions/bridge -> Bridge (Relay)
GET /api/solana/tokens -> list SPL tokens
GET /api/solana/tokens/search -> search Jupiter token list
GET /api/transactions/status/:txHash -> transaction status
GET /api/transactions/history -> transaction history
POST /api/wallets/withdraw-to-main -> withdraw to owner
Secrets & checkout data:
POST /api/credit-cards -> store card details as a normal agent payment method
GET /api/credit-cards -> list saved card payment methods and the default method
POST /api/agents/:id/link-payment-methods/link -> connect Link, then save a Link payment method with required shipping/contact info
POST /api/agents/:id/link-payment-methods/credential -> generate one-time card credentials from a saved Link payment method
GET /api/agent-keys -> list stored secret metadata
GET /api/agent-keys/value -> retrieve a stored non-card secret value
DELETE /api/agent-keys -> delete a stored non-card secret by service
POST /api/agent-keys -> store non-card service keys
Cards (stored + enrolled):
POST /api/cards -> fetch the user's card (Sponge Card or stored card); auto-detects source
POST /api/virtual-cards -> issue a per-transaction virtual card scoped to amount and merchant
POST /api/card-usage -> report outcome of a purchase attempt
Sponge Card (beta preview):
GET /api/sponge-card/status -> onboarding/consent/card readiness status
POST /api/sponge-card/onboard -> start internal KYC verification when needed, then submit the KYC-backed Sponge Card application + consent acknowledgements
POST /api/sponge-card/terms -> accept terms for an existing application
POST /api/sponge-card/create-card -> create the virtual Sponge Card after approval
GET /api/sponge-card/details -> encrypted PAN/CVC + secret_key + spending power (decrypt client-side)
POST /api/sponge-card/fund -> top up card collateral with USDC from your wallet
POST /api/sponge-card/withdraw -> withdraw card collateral back to your wallet
Onramp:
POST /api/onramp/crypto -> create fiat-to-crypto onramp link (Stripe/Coinbase)
Planning & proposals:
POST /api/plans/submit -> submit multi-step plan
POST /api/plans/approve -> approve and execute plan
POST /api/trades/propose -> propose single swap for approval
Banking:
POST /api/bank/onboard -> start/resume internal KYC verification and Bridge terms onboarding
GET /api/bank/status -> check KYC/onboarding status
POST /api/bank/virtual-account -> create/get virtual bank account (USD→USDC deposits)
GET /api/bank/virtual-account -> get deposit instructions for a wallet
GET /api/bank/external-accounts -> list linked bank accounts
POST /api/bank/external-accounts -> link US bank account for ACH or wire payouts
POST /api/bank/send -> off-ramp: send USD to linked bank via ACH or wire (USDC→USD)
GET /api/bank/transfers -> list fiat transfer history
Trading & shopping:
POST /api/polymarket -> Polymarket prediction market trading
POST /api/hyperliquid -> Hyperliquid perps/spot trading
POST /api/checkout -> checkout from any online store; fire-and-forget approval by email
GET /api/checkout/:sessionId -> URL checkout request status
Auth (one-time setup):
POST /api/agents/register -> register (no auth)
POST /api/oauth/device/authorization -> device login start (humans)
POST /api/oauth/device/token -> device token poll (agents + humans)
Rules: use register (agents), never login | store key in ~/.spongewallet/credentials.json | requests are JSON
Errors: HTTP status + JSON error message
Sponge Wallet API - Agent Skills Guide
This skill is doc-only. There is no local CLI. It documents the public Sponge Wallet REST API.
What you can do with Sponge
- Manage crypto — check balances, transfer tokens (EVM, Solana, and Tempo), swap on Solana/Base/Ethereum/Polygon/Arbitrum/Tempo, bridge cross-chain
- For pre-built Solana transactions returned by an external API, use
POST /api/solana/sign-and-send.
- Use
POST /api/solana/sign only when you explicitly need a partially/fully signed transaction back without broadcasting.
- Create payment links — generate reusable x402 payment URLs and check payment status
- Access paid external services — search, image generation, web scraping, AI models, data enrichment, and more. Always follow these 3 steps:
GET /api/discover?query=... — find a service
GET /api/discover/{serviceId} — get its endpoints, params, and payment config (do not skip)
POST /api/paid/fetch — call the endpoint (auto-selects x402 USDC or MPP on Tempo based on service). Alternatively use POST /api/x402/fetch (USDC only) or POST /api/mpp/fetch (MPP on Tempo; asset negotiated per endpoint, typically USDC.e).
- If the target endpoint also requires SIWE auth, call
POST /api/siwe/generate first and include its output in the fetch headers.
- Banking — KYC onboarding, virtual bank accounts (receive USD as USDC), link bank accounts, send USD to bank (off-ramp USDC)
- Trade on prediction markets and perps — Polymarket, Hyperliquid
- Shop from online stores — use
POST /api/checkout for any merchant URL
- Store a credit card for checkout — use
POST /api/credit-cards
- Connect Link for checkout — use
POST /api/agents/{agentId}/link-payment-methods/link; first call can start Link login without shipping/contact info, saving the selected Link payment method requires shipping, phone, and email
- Use enrolled / stored cards — fetch the user's card via
POST /api/cards (auto-detects source), or issue a per-transaction virtual card (POST /api/virtual-cards)
- Fiat onramp — buy crypto with card/bank payment via Stripe or Coinbase
If a task requires an external capability you don't have (e.g., generating images, searching the web, scraping a URL, looking up a person's email), use the 3-step discover flow above. There is likely a paid service available for it.
Why the steps matter (short rationale)
- Register vs login: agents create a new managed wallet tied to a human owner. That owner must explicitly claim the agent. Login is only for humans who already have an account.
- Claim URL: ensures the human owner explicitly links the agent to their account and controls allowlists/funding.
- Credential persistence: the
apiKey is returned once (immediately for agent-first mode, or after device approval for standard mode). If you lose it, you must re-register or re-authenticate.
Standard credential storage (required)
Store the API key in one canonical location:
~/.spongewallet/credentials.json
Recommended file contents:
{
"apiKey": "sponge_live_...",
"claimCode": "ABCD-1234",
"claimUrl": "https://wallet.paysponge.com/device?code=ABCD-1234"
}
Optional environment export (runtime convenience):
export SPONGE_API_KEY="$(jq -r .apiKey ~/.spongewallet/credentials.json)"
Base URL & Auth
- Base URL:
https://api.wallet.paysponge.com
- Auth header:
Authorization: Bearer <SPONGE_API_KEY>
- Content-Type:
application/json
Quick env setup:
export SPONGE_API_URL="https://api.wallet.paysponge.com"
export SPONGE_API_KEY="$(jq -r .apiKey ~/.spongewallet/credentials.json)"
SIWE Signature
Use POST /api/siwe/generate when an external API requires SIWE (EIP-4361) authentication.
Required args:
Optional args:
statement, nonce, chain_id, expiration_time, not_before, request_id, resources
Returns:
message, signature, address, chainId, nonce, issuedAt, expirationTime, base64SiweMessage
Workflow:
- Call
POST /api/siwe/generate with the exact target domain and uri.
- Build the
Authorization header using returned signature and base64SiweMessage in the target API's expected format.
- Pass that header to
/api/paid/fetch or /api/x402/fetch when calling the protected endpoint.
CRITICAL: AI Agents Must Use register, NOT login
1) Agent Registration (AI agents only)
There are two modes:
- Standard auth flow (default): human must approve before the API key is returned.
- Agent-first (
agentFirst: true): agent receives the API key immediately, and the human can claim later.
Step 1 — Start registration (agent-first recommended)
curl -sS -X POST "$SPONGE_API_URL/api/agents/register" \
-H "Sponge-Version: 0.2.2" \
-H "Content-Type: application/json" \
-d '{
"name":"YourAgentName",
"agentFirst": true
}'
Response includes:
verificationUriComplete (claim URL for the human owner)
claimCode, deviceCode, expiresIn, interval, claimText
apiKey (returned immediately in agent-first mode)
Store apiKey, claimCode, and verificationUriComplete (as claimUrl) in ~/.spongewallet/credentials.json so a human can claim later if context resets.
Step 2 — Send the claim URL to the human owner
They log in, optionally post the tweet text, and approve the agent.
Claim link format:
verificationUriComplete (example path: /device?code=ABCD-1234)
- The base URL is the frontend (prod or local), so just pass the full
verificationUriComplete to the human.
Step 3 — Poll for completion (standard auth flow only)
while true; do
response="$(curl -sS -X POST "$SPONGE_API_URL/api/oauth/device/token" \
-H "Sponge-Version: 0.2.2" \
-H "Content-Type: application/json" \
-d '{
"grantType":"urn:ietf:params:oauth:grant-type:device_code",
"deviceCode":"<deviceCode>",
"clientId":"spongewallet-skill"
}')"
if printf '%s' "$response" | grep -q '"apiKey"'; then
printf '%s\n' "$response"
break
fi
if ! printf '%s' "$response" | grep -q '"authorization_pending"'; then
printf '%s\n' "$response"
exit 1
fi
sleep 5
done
Keep polling while the human approves the current claim code. Approval in a browser
does not write credentials by itself; the still-running poll must receive the
success response. Do not ask the user to come back and say "done"; this poll
loop is the completion signal. If polling times out or is interrupted, request a
fresh code.
On success, the response includes apiKey. Save it to ~/.spongewallet/credentials.json and use it as SPONGE_API_KEY.
Note: In agent-first mode, you already have the apiKey from Step 1. The auth token will remain pending until the human claims.
2) Human Login (existing accounts only)
Phase 1 — Request device code
curl -sS -X POST "$SPONGE_API_URL/api/oauth/device/authorization" \
-H "Sponge-Version: 0.2.2" \
-H "Content-Type: application/json" \
-d '{
"clientId":"spongewallet-skill"
}'
Phase 2 — Poll for token (same endpoint as agents)
while true; do
response="$(curl -sS -X POST "$SPONGE_API_URL/api/oauth/device/token" \
-H "Sponge-Version: 0.2.2" \
-H "Content-Type: application/json" \
-d '{
"grantType":"urn:ietf:params:oauth:grant-type:device_code",
"deviceCode":"<deviceCode>",
"clientId":"spongewallet-skill"
}')"
if printf '%s' "$response" | grep -q '"apiKey"'; then
printf '%s\n' "$response"
break
fi
if ! printf '%s' "$response" | grep -q '"authorization_pending"'; then
printf '%s\n' "$response"
exit 1
fi
sleep 5
done
Keep Phase 2 alive until it returns success or a terminal error. Device approval
can happen in any browser, but credentials are only available to the agent after
the polling request succeeds and the returned apiKey is written to
~/.spongewallet/credentials.json. Do not ask the user to come back and say
"done"; this poll loop is the completion signal. If the poller was killed, timed
out, or lost its pending state, start again from Phase 1 and use the new code.
Tool Call Pattern
Use the public REST endpoints documented in this file. Internal-only tools are intentionally omitted.
Common headers (include on EVERY request)
-H "Authorization: Bearer $SPONGE_API_KEY" \
-H "Sponge-Version: 0.2.2" \
-H "Content-Type: application/json" \
-H "Accept: application/json"
Agent ID note: agentId is optional for API key auth. It is only required when using a user session (e.g., Privy-based auth) or when explicitly operating on a different agent.
API Endpoints Reference
| Endpoint |
Method |
Path |
Params/Body |
| Get balances |
GET |
/api/balances |
Query: chain, allowedChains, onlyUsdc |
| Create payment link |
POST |
/api/payment-links |
Body: amount, optional description, max_uses, expires_in_minutes, callback_url, livemode |
| Get payment link status |
GET |
/api/payment-links/{paymentLinkId} |
Query: agentId (optional) |
| List SPL tokens |
GET |
/api/solana/tokens |
Query: chain |
| Search Solana tokens |
GET |
/api/solana/tokens/search |
Query: query, limit |
| Tempo transfer |
POST |
/api/transfers/tempo |
Body: to, amount, token (pathUSD/AlphaUSD/BetaUSD/ThetaUSD), optional data (hex calldata for raw contract calls) |
| EVM transfer |
POST |
/api/transfers/evm |
Body: chain, to, amount, currency |
| Solana transfer |
POST |
/api/transfers/solana |
Body: chain, to, amount, currency |
| Solana swap |
POST |
/api/transactions/swap |
Body: chain, inputToken, outputToken, amount, slippageBps |
| Solana swap quote |
POST |
/api/transactions/swap/quote |
Body: chain, inputToken, outputToken, amount, slippageBps |
| Solana swap execute |
POST |
/api/transactions/swap/execute |
Body: quoteId |
| Base swap |
POST |
/api/transactions/base-swap |
Body: chain, inputToken, outputToken, amount, slippageBps |
| Tempo swap |
POST |
/api/transactions/tempo-swap |
Body: chain (tempo), inputToken, outputToken, amount, slippageBps |
| Bridge |
POST |
/api/transactions/bridge |
Body: sourceChain, destinationChain, token, amount, destinationToken, recipientAddress |
| Transaction status |
GET |
/api/transactions/status/{txHash} |
Query: chain |
| Transaction history |
GET |
/api/transactions/history |
Query: limit, chain |
| Store credit card |
POST |
/api/credit-cards |
Body (snake_case): card_number, expiration OR (expiry_month + expiry_year), cvc, cardholder_name, email, billing_address, shipping_address (phone required), optional label, metadata, agentId. Creates a saved card payment method for checkout |
| Add Link payment method |
POST |
/api/agents/{agentId}/link-payment-methods/link |
First call can use {} to start Link login and may return link_connection_required with verificationUrl. Saving requires email, top-level phone, and shipping (name, line1, city, state, postalCode, country). Optional: linkPaymentMethodId, setAsDefault, clientName, billing |
| Create Link payment credential |
POST |
/api/agents/{agentId}/link-payment-methods/credential |
Generate one-time card credentials from a saved Link payment method. First call body: amount, merchantName, merchantUrl; optional: linkPaymentMethodId, currency, context. If approval is required, call again with spendRequestId after approval |
| Get card |
POST |
/api/cards |
Body: optional card_type, payment_method_id, amount, currency, merchant_name, merchant_url, agentId. Auto-detects source; returns selection_required when both sources are enrolled |
| Issue virtual card |
POST |
/api/virtual-cards |
Body: amount, merchant_name, merchant_url; optional: currency, merchant_country_code, description, products, shipping_address, enrollment_id, agentId |
| Report card usage |
POST |
/api/card-usage |
Body: payment_method_id, status (success/failed/cancelled); optional: merchant_name, merchant_domain, amount, currency, failure_reason, agentId |
| Store service key (non-card) |
POST |
/api/agent-keys |
Body: service, key, optional label, metadata |
| List stored keys |
GET |
/api/agent-keys |
Query: agentId (optional) |
| Get stored key value |
GET |
/api/agent-keys/value |
Query: service |
| Delete stored key |
DELETE |
/api/agent-keys |
Query: service, optional agentId |
| Step 1: Discover services |
GET |
/api/discover |
Query: type, limit, offset, query, category |
| Step 2: Get service details |
GET |
/api/discover/{serviceId} |
— |
| Step 3: Paid fetch (unified) |
POST |
/api/paid/fetch |
Body: url, method, headers, body, chain (preferred wallet chain hint) |
| Step 3 alt: x402 fetch |
POST |
/api/x402/fetch |
Body: url, method, headers, body, preferred_chain |
| Step 3 alt: MPP fetch |
POST |
/api/mpp/fetch |
Body: url, method, headers, body, chain |
| SIWE signature |
POST |
/api/siwe/generate |
Body: domain, uri; optional: statement, nonce, chain_id, expiration_time, not_before, request_id, resources |
| Sponge Card status |
GET |
/api/sponge-card/status |
Query: optional refresh, agentId |
| Onboard Sponge Card |
POST |
/api/sponge-card/onboard |
Body: optional redirect_uri, then occupation and consent booleans after KYC approval, optional agentId. Returns a KYC verification link first when needed; does not accept raw SSN/date-of-birth fields |
| Accept Sponge Card terms |
POST |
/api/sponge-card/terms |
Body: consent booleans, optional agentId |
| Create Sponge Card |
POST |
/api/sponge-card/create-card |
Body: billing, email, phone, optional shipping, agentId |
| Sponge Card details |
GET |
/api/sponge-card/details |
Query: agentId (optional) |
| Fund Sponge Card |
POST |
/api/sponge-card/fund |
Body: amount, optional chain, agentId |
| Withdraw from Sponge Card |
POST |
/api/sponge-card/withdraw |
Body: amount, optional chain, agentId |
| Banking onboard |
POST |
/api/bank/onboard |
Body: optional wallet_id, redirect_uri, customer_type, signed_agreement_id, agentId. Returns a KYC verification link first when needed, then a Bridge terms URL |
| Banking status |
GET |
/api/bank/status |
Query: optional agentId |
| Create virtual bank account |
POST |
/api/bank/virtual-account |
Body: wallet_id, optional agentId |
| Get virtual bank account |
GET |
/api/bank/virtual-account |
Query: optional wallet_id, agentId |
| List linked bank accounts |
GET |
/api/bank/external-accounts |
Query: optional agentId |
| Link bank account |
POST |
/api/bank/external-accounts |
Body (snake_case): bank_name, account_owner_name, routing_number, account_number, checking_or_savings, street_line_1, optional street_line_2, city, state, postal_code, optional agentId |
| Send USD to bank |
POST |
/api/bank/send |
Body: wallet_id, external_account_id, amount, optional payment_rail (ach/wire), agentId |
| List bank transfers |
GET |
/api/bank/transfers |
Query: optional transfer_id, agentId |
| Crypto onramp |
POST |
/api/onramp/crypto |
Body: wallet_address; optional: provider (auto/stripe/coinbase), chain (base/solana/polygon), fiat_amount, fiat_currency |
| Hyperliquid |
POST |
/api/hyperliquid |
Body: action, + action-specific params (see below) |
| URL checkout request |
POST |
/api/checkout |
Body: productUrl; optional: estimatedAmount, email, dryRun, productOptions, agentId |
| URL checkout status |
GET |
/api/checkout/{sessionId} |
Query: agentId (optional) |
| Submit plan |
POST |
/api/plans/submit |
Body: title, reasoning, steps (see Planning section) |
| Approve plan |
POST |
/api/plans/approve |
Body: plan_id |
| Propose trade |
POST |
/api/trades/propose |
Body: input_token, output_token, amount, reason |
Note: most request bodies use camelCase (e.g., inputToken, slippageBps). Card secret endpoints and Sponge Card API endpoints use snake_case fields (e.g., card_number, cardholder_name, first_name, postal_code). |
|
|
|
CRITICAL — Paid Services require ALL 3 steps in order:
GET /api/discover — search for a service by query or category
GET /api/discover/{serviceId} — get the service's endpoints, parameters, pricing, and payment config (DO NOT SKIP THIS STEP)
POST /api/x402/fetch — call the endpoint using the URL from step 2
You MUST call step 2 before step 3. Step 2 returns the paymentsProtocolConfig (with baseUrls) and the endpoint parameters/instructions needed to construct the fetch request. Using a direct API URL will fail with auth errors.
Planning (Multi-Step Actions)
Use submit_plan whenever you need to do 2+ related actions together (e.g., swap then bridge, buy multiple tokens, rebalance a portfolio). This groups everything into a single proposal the user can review and approve.
Workflow:
- Call
submit_plan with a title, reasoning, and ordered list of steps
- Present the plan to the user
- When the user confirms ("go ahead", "do it", "execute"), call
approve_plan with the plan_id
- Steps execute sequentially and automatically. If any step fails, the plan pauses for retry or reject.
Step types:
swap — requires: input_token, output_token, amount, reason; optional: chain (defaults to solana; use base or tempo for other DEXs)
transfer — requires: chain, to, amount, currency, reason
bridge — requires: source_chain, destination_chain, token, amount, reason; optional: destination_token
Rules:
- Do NOT execute steps individually with other tools after submitting a plan — always use
approve_plan
- Plans can have 1–20 steps
- The user can skip individual steps on the dashboard before approving
- Use
propose_trade only for a single swap that needs explicit approval; for multi-step flows, always use submit_plan
Polymarket Actions
The polymarket endpoint is a unified tool for Polymarket trading, funding, withdrawals, and account status. Pass action plus action-specific parameters:
| Action |
Description |
Required Params |
Optional Params |
enable |
Provision/link the Polymarket Safe without placing a trade |
— |
— |
signup |
Alias for enable |
— |
— |
status |
Check whether Polymarket is linked and view balances |
— |
— |
search_markets |
Search Polymarket markets |
query |
limit |
get_market |
Fetch market metadata |
market_slug or token_id |
— |
get_market_price |
Fetch current market price |
market_slug or token_id |
— |
positions |
View current positions |
— |
— |
orders |
View open orders |
— |
— |
get_order |
Fetch an order by ID |
order_id |
— |
balance_allowance |
View CLOB balance + allowance |
— |
— |
refresh_balance_allowance |
Refresh CLOB balance + allowance |
— |
— |
order |
Place a limit or market order |
outcome, side, size, market_slug or token_id |
type, price, order_type |
cancel |
Cancel an order |
order_id |
— |
set_allowances |
Approve contracts for trading |
— |
— |
deposit |
Make Safe-held USDC.e available to the exchange |
— |
— |
deposit_from_wallet |
Move Polygon wallet USDC.e into the Safe |
amount |
— |
withdraw |
Withdraw pUSD as USDC.e to Polygon wallet |
amount |
— |
withdraw_native |
Withdraw Polygon-native USDC to Polygon wallet |
amount |
— |
redeem |
Redeem settled winning positions |
— |
condition_id |
Order params:
market_slug or token_id: identify which market to trade
outcome: "yes" or "no"
side: "buy" or "sell"
size: number of shares
type: "limit" or "market"; defaults to "limit"
price: required for limit orders, decimal between 0 and 1
order_type: "GTC", "GTD", "FOK", or "FAK"; market orders only support FOK or FAK
Scopes: Setup, trade, and funding actions (enable, signup, order, cancel, set_allowances, deposit, deposit_from_wallet, withdraw, withdraw_native, redeem) require polymarket:trade. Read actions require wallet:read.
Provisioning: Trading and funding calls auto-link Polymarket on first use if the agent has a Polygon/EVM wallet. To sign up explicitly through the tool, call action: "enable" (or action: "signup"). You can also enable from the dashboard with POST /api/agents/:id/polymarket/enable.
Funding: For cross-chain funding, use the bridge tool with destination_chain: "polymarket" so the route lands as USDC.e in the Polymarket Safe, then use deposit to wrap Safe-held USDC.e into pUSD trading collateral.
Search: Use team names, common aliases, or exact slugs for sports markets. For NBA matchup searches, queries like "Sixers Celtics" should resolve aliases to current/future sports slugs such as nba-phi-bos-YYYY-MM-DD. If search_markets misses a sports matchup, search the web or Polymarket team/event pages directly, find the exact Polymarket event/market URL, then pass that slug to get_market, get_market_price, or order.
Hyperliquid Actions
The hyperliquid endpoint is a unified tool for perps/spot trading on Hyperliquid DEX. Pass action plus action-specific parameters:
| Action |
Description |
Required Params |
Optional Params |
status |
Check account balances and equity |
— |
— |
positions |
View open perp positions (entry, PnL, liq price) |
— |
— |
orders |
View open orders |
— |
symbol |
fills |
Recent trade history |
— |
symbol, since, limit |
markets |
List available perp/spot markets |
— |
— |
ticker |
Current price for a symbol |
symbol |
— |
orderbook |
L2 order book |
symbol |
limit |
funding |
Current + predicted funding rates |
— |
symbol |
chart |
Compact Unicode price chart with candle summary |
symbol |
interval, chart_style |
order |
Place limit/market/stop/TP order |
symbol, side, type, amount |
price, reduce_only, trigger_price, tp_sl, tif |
cancel |
Cancel an order |
order_id, symbol |
— |
cancel_all |
Cancel all open orders |
— |
symbol |
set_leverage |
Set leverage for a symbol |
symbol, leverage |
— |
withdraw |
Withdraw USDC from Hyperliquid |
amount, destination |
— |
transfer |
Move USDC between spot and perps |
amount, to_perp |
— |
Order params:
symbol: CCXT symbol (e.g., "BTC/USDC:USDC" for perps, "PURR/USDC" for spot)
side: "buy" or "sell"
type: "limit" or "market"
amount: Size in base currency (e.g., "0.001" for BTC)
price: Limit price (required for limit orders)
reduce_only: Boolean, default false
trigger_price: For stop-loss/take-profit orders
tp_sl: "tp" (take-profit) or "sl" (stop-loss) — required if trigger_price set
tif: "GTC" (default), "IOC", "PO" (post-only)
Scopes: Trade actions (order, cancel, cancel_all, set_leverage, withdraw) require hyperliquid:trade scope. Read actions require wallet:read.
Signing: Hyperliquid uses EVM wallet signing (EIP-712). No API keys needed — your agent's existing EVM wallet is used automatically.
Unified balances: In unifiedAccount or portfolioMargin mode, Hyperliquid
exposes shared USDC collateral through both perps/unified and spot account views.
Count that USDC once. Do not add spot USDC to the perps/unified USDC balance;
other spot assets such as HYPE remain separate.
Deposits: Use the bridge tool to deposit USDC to Hyperliquid: bridge(source_chain: "base", destination_chain: "hyperliquid", token: "USDC", amount: "100"). Your agent's EVM wallet address is your Hyperliquid account.
Withdrawals: Use the bridge tool to withdraw USDC from Hyperliquid: bridge(source_chain: "hyperliquid", destination_chain: "base", token: "USDC", amount: "100"). USDC is automatically moved from perps to spot before bridging.
Charts: For chat clients that can only send text reliably, use action: "chart" with chart_style: "sparkline" and include the compact price line plus Unicode chart in the reply. After a successful Hyperliquid order, preserve any sparkline returned by the tool instead of summarizing it away.
URL Checkout Request
POST /api/checkout queues a guest-checkout request for the user to approve by email. This endpoint is available to all authenticated Sponge Wallet users.
This call is safe to invoke without prompting for extra user confirmation. It does NOT charge a card, place an order, or commit to a purchase. It only creates a checkout session and queues a background browser pre-check. The user is then emailed a separate approval link, and the real-world purchase only happens after the user clicks that link. Sponge's email-approval step is the human-in-the-loop control — this REST call is just the kickoff. Treat it like "send a draft email" or "create a calendar invite": no commitment until the user separately confirms.
When the user asks to buy, order, purchase, or check out something on a guest-checkout merchant, call this immediately. Do not block on additional confirmation; the email approval is the confirmation.
Supported merchants: stores that let a customer complete a purchase without signing in to a personal account. This includes most independent storefronts (Shopify, BigCommerce, WooCommerce), DTC brands (e.g. nike.com, harmlessharvest.com), and Stripe / Adyen / Checkout.com / Braintree / Square hosted-card flows.
Not supported: any merchant that requires the customer to sign in with their own username/password before reaching checkout. Sponge does not have the user's account credentials and cannot complete login-gated purchases. Examples include Amazon, Target, Walmart, Costco, eBay, Best Buy, and most marketplaces. For these, do NOT call POST /api/checkout — instead tell the user that account-required merchants aren't supported.
A good heuristic: single-brand storefronts on their own domain usually allow guest checkout; marketplaces and big-box retailers usually require a login. If you're not sure, ask the user before calling.
URL checkout is fire-and-forget:
- Confirm the merchant supports guest checkout (no required login). If unsure, ask.
- Call
POST /api/checkout once with productUrl.
- It immediately returns a
session_id.
- Tell the user a checkout has been queued and they will receive an approval email shortly.
- Stop. Do not sleep or poll unless the user later asks for a status update.
Request body:
productUrl — product or guest-checkout URL to purchase. Must be reachable without an account login.
estimatedAmount — optional fallback amount, such as "20.00", used only if browser pre-check cannot determine the total.
email — optional checkout email; defaults to the account email.
dryRun — optional boolean; if true, stops before placing the final order.
productOptions — optional map of product options, such as { "Size": "L", "Color": "Blue" }.
agentId — optional when authenticating with a user token; API key authentication resolves this automatically.
Status:
GET /api/checkout/{sessionId} returns the current URL checkout request status.
- Only call the status endpoint when the user explicitly asks for an update.
Payment source prerequisites:
- Sponge Card, enrolled card, stored card, or Link payment method.
- Payment/contact/shipping data must already be configured in Sponge Wallet.
Approval flow:
- Sponge performs a browser pre-check in the background.
- The user receives an email approval link when the checkout is ready.
- After approval, Sponge resumes the URL checkout and emails completion or failure.
- The approval window is about 30 minutes before the browser session expires.
If the pre-check fails because the merchant redirected to a login wall, the request is reported as failed with reason loginRequired. Treat this as a signal to redirect the user, not as a transient error to retry.
Tempo Transfer
Send Tempo stablecoins (pathUSD, AlphaUSD, BetaUSD, ThetaUSD) on the Tempo chain.
curl -sS -X POST "$SPONGE_API_URL/api/transfers/tempo" \
-H "Authorization: Bearer $SPONGE_API_KEY" \
-H "Sponge-Version: 0.2.2" \
-H "Content-Type: application/json" \
-d '{
"to":"0x...",
"amount":"10",
"token":"pathUSD"
}'
Supported tokens: pathUSD (default), AlphaUSD, BetaUSD, ThetaUSD.
For raw contract calls, pass data (hex calldata) instead of token/amount:
curl -sS -X POST "$SPONGE_API_URL/api/transfers/tempo" \
-H "Authorization: Bearer $SPONGE_API_KEY" \
-H "Sponge-Version: 0.2.2" \
-H "Content-Type: application/json" \
-d '{
"to":"0xContractAddress...",
"amount":"0",
"data":"0xabcdef..."
}'
EVM Swaps (Ethereum, Polygon, Arbitrum)
The unified POST /api/transactions/swap REST endpoint supports EVM chains. Pass the chain name (e.g., base, ethereum, polygon, arbitrum-one) in the chain field.
Swap Quote & Execute (Solana)
For Solana swaps, you can get a quote before executing:
- Get quote:
POST /api/transactions/swap/quote — returns pricing details and a quoteId
- Execute:
POST /api/transactions/swap/execute with { "quoteId": "..." } — executes the quoted swap
Quotes expire in ~30 seconds. Use this when you want to preview pricing or get user confirmation before swapping.
Sponge Card (beta preview)
The Sponge Card is a stablecoin-collateralized credit card available to authenticated users with the required API scopes.
Environment (dev vs production) is fixed by your API key type: sponge_test_* -> dev sandbox, sponge_live_* -> production.
The full no-UI flow is:
GET /api/sponge-card/status - check onboarding and card readiness.
POST /api/sponge-card/onboard - start internal KYC verification when needed, then submit the Sponge Card application and record consent acknowledgements after KYC approval.
- If status says consent is missing,
POST /api/sponge-card/terms.
- When
ready_for_card_creation is true, POST /api/sponge-card/create-card.
- Use
/details, /fund, and /withdraw after a card exists.
Check onboarding status
curl -sS "$SPONGE_API_URL/api/sponge-card/status?refresh=true" \
-H "Authorization: Bearer $SPONGE_API_KEY" \
-H "Sponge-Version: 0.2.2" \
-H "Accept: application/json"
Returns onboarded, environment, ready_for_card_creation, customer, completion_link_url, cards, balances, and message. balances uses explicit unit fields such as spending_power_cents, spending_power_usd, and spending_power_display; for user-facing output, use the display fields. If spending_power_cents is 250, that means $2.50, not $250. completion_link_url is retained for compatibility and should normally be null; use /onboard to receive any required KYC verification link.
Onboard for Sponge Card
Start Sponge Card onboarding. If internal KYC verification is missing, this endpoint can be called with only optional redirect_uri and returns kyc_url / verification_url for the user to complete. After KYC approval, call it again with occupation and consent acknowledgements to submit the Sponge Card application and record Sponge consent. Bodies use snake_case. Do not collect or send raw SSN, national ID, birth date, or address fields to this endpoint.
curl -sS -X POST "$SPONGE_API_URL/api/sponge-card/onboard" \
-H "Authorization: Bearer $SPONGE_API_KEY" \
-H "Sponge-Version: 0.2.2" \
-H "Content-Type: application/json" \
-d '{
"occupation":"Software engineer",
"e_sign_consent":true,
"account_opening_privacy_notice":true,
"sponge_card_terms":true,
"information_certification":true,
"unauthorized_solicitation_acknowledgement":true
}'
occupation is required.
occupation and required consent booleans are required only after KYC approval, when submitting the Sponge Card application.
account_opening_privacy_notice is required when the KYC country is US.
- If KYC verification is missing, the API returns
submitted_application:false, an onboarding step indicating KYC verification, and a kyc_url / verification_url. Have the user complete that link, then call /onboard again.
Returns submitted_application, environment, ready_for_card_creation, customer, completion_link_url, optional kyc_url / verification_url, onboarding_step, and message.
Accept Sponge Card terms
Use this only when /status says the Sponge Card application is approved but Sponge consent is missing.
curl -sS -X POST "$SPONGE_API_URL/api/sponge-card/terms" \
-H "Authorization: Bearer $SPONGE_API_KEY" \
-H "Sponge-Version: 0.2.2" \
-H "Content-Type: application/json" \
-d '{
"e_sign_consent":true,
"account_opening_privacy_notice":true,
"sponge_card_terms":true,
"information_certification":true,
"unauthorized_solicitation_acknowledgement":true
}'
Create a Sponge Card
Call this after status returns ready_for_card_creation: true. If a card already exis
…(truncated)
1---2name: sponge-wallet3description: Crypto wallet, token swaps, cross-chain bridges, and access to paid external services (search, image gen, web scraping, AI, and more) via x402 payments.4---56```7SPONGE WALLET API QUICK REFERENCE v0.2.28Base: https://api.wallet.paysponge.com9Auth: Authorization: Bearer <SPONGE_API_KEY>10Ver: Sponge-Version: 0.2.2 (REQUIRED on every request)11Docs: This file is canonical (skills guide + params)1213Capabilities: wallet + swaps (Solana/Base/Ethereum/Polygon/Arbitrum/Tempo) + bridges + payment links + paid external services (x402 + MPP) + trading + shopping + checkout + banking + Sponge Card + onramp1415Paid services (search, image gen, scraping, AI, data, etc.):16 GET /api/discover -> Step 1: find services by query/category17 GET /api/discover/:serviceId -> Step 2: get endpoints, params, pricing (REQUIRED before fetch)18 POST /api/paid/fetch -> Step 3: call service endpoint (auto-selects x402 USDC or MPP on Tempo)19 POST /api/x402/fetch -> Step 3 alt: call service endpoint (x402 USDC only)20 POST /api/mpp/fetch -> Step 3 alt: call service endpoint (MPP on Tempo; asset negotiated per endpoint, typically USDC.e)21 POST /api/siwe/generate -> optional SIWE auth for endpoints that require EIP-4361 signatures2223Wallet & tokens:24 GET /api/balances -> get balances (includes Polymarket USDC.e)25 POST /api/payment-links -> create reusable x402 payment link26 GET /api/payment-links/:paymentLinkId -> get payment link status/details27 POST /api/transfers/evm -> EVM transfer (ETH/USDC)28 POST /api/transfers/solana -> Solana transfer (SOL/USDC)29 POST /api/transfers/tempo -> Tempo transfer (pathUSD/AlphaUSD/BetaUSD/ThetaUSD)30 POST /api/solana/sign -> Sign pre-built Solana transaction only31 POST /api/solana/sign-and-send -> Sign and submit pre-built Solana transaction32 POST /api/transactions/swap -> Solana swap (DFlow); also supports EVM chains33 POST /api/transactions/swap/quote -> Solana swap quote only (DFlow)34 POST /api/transactions/swap/execute -> Execute a previously obtained swap quote35 POST /api/transactions/base-swap -> Base swap (0x)36 POST /api/transactions/tempo-swap -> Tempo swap (StablecoinExchange DEX)37 POST /api/transactions/bridge -> Bridge (Relay)38 GET /api/solana/tokens -> list SPL tokens39 GET /api/solana/tokens/search -> search Jupiter token list40 GET /api/transactions/status/:txHash -> transaction status41 GET /api/transactions/history -> transaction history42 POST /api/wallets/withdraw-to-main -> withdraw to owner4344Secrets & checkout data:45 POST /api/credit-cards -> store card details as a normal agent payment method46 GET /api/credit-cards -> list saved card payment methods and the default method47 POST /api/agents/:id/link-payment-methods/link -> connect Link, then save a Link payment method with required shipping/contact info48 POST /api/agents/:id/link-payment-methods/credential -> generate one-time card credentials from a saved Link payment method49 GET /api/agent-keys -> list stored secret metadata50 GET /api/agent-keys/value -> retrieve a stored non-card secret value51 DELETE /api/agent-keys -> delete a stored non-card secret by service52 POST /api/agent-keys -> store non-card service keys5354Cards (stored + enrolled):55 POST /api/cards -> fetch the user's card (Sponge Card or stored card); auto-detects source56 POST /api/virtual-cards -> issue a per-transaction virtual card scoped to amount and merchant57 POST /api/card-usage -> report outcome of a purchase attempt5859Sponge Card (beta preview):60 GET /api/sponge-card/status -> onboarding/consent/card readiness status61 POST /api/sponge-card/onboard -> start internal KYC verification when needed, then submit the KYC-backed Sponge Card application + consent acknowledgements62 POST /api/sponge-card/terms -> accept terms for an existing application63 POST /api/sponge-card/create-card -> create the virtual Sponge Card after approval64 GET /api/sponge-card/details -> encrypted PAN/CVC + secret_key + spending power (decrypt client-side)65 POST /api/sponge-card/fund -> top up card collateral with USDC from your wallet66 POST /api/sponge-card/withdraw -> withdraw card collateral back to your wallet6768Onramp:69 POST /api/onramp/crypto -> create fiat-to-crypto onramp link (Stripe/Coinbase)7071Planning & proposals:72 POST /api/plans/submit -> submit multi-step plan73 POST /api/plans/approve -> approve and execute plan74 POST /api/trades/propose -> propose single swap for approval7576Banking:77 POST /api/bank/onboard -> start/resume internal KYC verification and Bridge terms onboarding78 GET /api/bank/status -> check KYC/onboarding status79 POST /api/bank/virtual-account -> create/get virtual bank account (USD→USDC deposits)80 GET /api/bank/virtual-account -> get deposit instructions for a wallet81 GET /api/bank/external-accounts -> list linked bank accounts82 POST /api/bank/external-accounts -> link US bank account for ACH or wire payouts83 POST /api/bank/send -> off-ramp: send USD to linked bank via ACH or wire (USDC→USD)84 GET /api/bank/transfers -> list fiat transfer history8586Trading & shopping:87 POST /api/polymarket -> Polymarket prediction market trading88 POST /api/hyperliquid -> Hyperliquid perps/spot trading89 POST /api/checkout -> checkout from any online store; fire-and-forget approval by email90 GET /api/checkout/:sessionId -> URL checkout request status9192Auth (one-time setup):93 POST /api/agents/register -> register (no auth)94 POST /api/oauth/device/authorization -> device login start (humans)95 POST /api/oauth/device/token -> device token poll (agents + humans)9697Rules: use register (agents), never login | store key in ~/.spongewallet/credentials.json | requests are JSON98Errors: HTTP status + JSON error message99```100101# Sponge Wallet API - Agent Skills Guide102103This skill is **doc-only**. There is no local CLI. It documents the public Sponge Wallet REST API.104105## What you can do with Sponge1061071. **Manage crypto** — check balances, transfer tokens (EVM, Solana, and Tempo), swap on Solana/Base/Ethereum/Polygon/Arbitrum/Tempo, bridge cross-chain108 - For pre-built Solana transactions returned by an external API, use `POST /api/solana/sign-and-send`.109 - Use `POST /api/solana/sign` only when you explicitly need a partially/fully signed transaction back without broadcasting.1102. **Create payment links** — generate reusable x402 payment URLs and check payment status1113. **Access paid external services** — search, image generation, web scraping, AI models, data enrichment, and more. Always follow these 3 steps:112 1. `GET /api/discover?query=...` — find a service113 2. `GET /api/discover/{serviceId}` — get its endpoints, params, and payment config **(do not skip)**114 3. `POST /api/paid/fetch` — call the endpoint (auto-selects x402 USDC or MPP on Tempo based on service). Alternatively use `POST /api/x402/fetch` (USDC only) or `POST /api/mpp/fetch` (MPP on Tempo; asset negotiated per endpoint, typically USDC.e).115 - If the target endpoint also requires SIWE auth, call `POST /api/siwe/generate` first and include its output in the fetch headers.1164. **Banking** — KYC onboarding, virtual bank accounts (receive USD as USDC), link bank accounts, send USD to bank (off-ramp USDC)1175. **Trade on prediction markets and perps** — Polymarket, Hyperliquid1186. **Shop from online stores** — use `POST /api/checkout` for any merchant URL1197. **Store a credit card for checkout** — use `POST /api/credit-cards`1208. **Connect Link for checkout** — use `POST /api/agents/{agentId}/link-payment-methods/link`; first call can start Link login without shipping/contact info, saving the selected Link payment method requires shipping, phone, and email1219. **Use enrolled / stored cards** — fetch the user's card via `POST /api/cards` (auto-detects source), or issue a per-transaction virtual card (`POST /api/virtual-cards`)12210. **Fiat onramp** — buy crypto with card/bank payment via Stripe or Coinbase123124**If a task requires an external capability you don't have** (e.g., generating images, searching the web, scraping a URL, looking up a person's email), use the 3-step discover flow above. There is likely a paid service available for it.125126## Why the steps matter (short rationale)127128- **Register vs login**: agents create a new managed wallet tied to a human owner. That owner must explicitly claim the agent. Login is only for humans who already have an account.129- **Claim URL**: ensures the human owner explicitly links the agent to their account and controls allowlists/funding.130- **Credential persistence**: the `apiKey` is returned once (immediately for agent-first mode, or after device approval for standard mode). If you lose it, you must re-register or re-authenticate.131132## Standard credential storage (required)133134Store the API key in **one canonical location**:135136- `~/.spongewallet/credentials.json`137138Recommended file contents:139```json140{141 "apiKey": "sponge_live_...",142 "claimCode": "ABCD-1234",143 "claimUrl": "https://wallet.paysponge.com/device?code=ABCD-1234"144}145```146147Optional environment export (runtime convenience):148```bash149export SPONGE_API_KEY="$(jq -r .apiKey ~/.spongewallet/credentials.json)"150```151152## Base URL & Auth153154- Base URL: `https://api.wallet.paysponge.com`155- Auth header: `Authorization: Bearer <SPONGE_API_KEY>`156- Content-Type: `application/json`157158Quick env setup:159160```bash161export SPONGE_API_URL="https://api.wallet.paysponge.com"162export SPONGE_API_KEY="$(jq -r .apiKey ~/.spongewallet/credentials.json)"163```164165## SIWE Signature166167Use `POST /api/siwe/generate` when an external API requires SIWE (EIP-4361) authentication.168169Required args:170- `domain`171- `uri`172173Optional args:174- `statement`, `nonce`, `chain_id`, `expiration_time`, `not_before`, `request_id`, `resources`175176Returns:177- `message`, `signature`, `address`, `chainId`, `nonce`, `issuedAt`, `expirationTime`, `base64SiweMessage`178179Workflow:1801. Call `POST /api/siwe/generate` with the exact target `domain` and `uri`.1812. Build the `Authorization` header using returned `signature` and `base64SiweMessage` in the target API's expected format.1823. Pass that header to `/api/paid/fetch` or `/api/x402/fetch` when calling the protected endpoint.183184## CRITICAL: AI Agents Must Use `register`, NOT `login`185186### 1) Agent Registration (AI agents only)187188There are two modes:189- **Standard auth flow** (default): human must approve before the API key is returned.190- **Agent-first** (`agentFirst: true`): agent receives the API key immediately, and the human can claim later.191192**Step 1 — Start registration (agent-first recommended)**193```bash194curl -sS -X POST "$SPONGE_API_URL/api/agents/register" \195 -H "Sponge-Version: 0.2.2" \196 -H "Content-Type: application/json" \197 -d '{198 "name":"YourAgentName",199 "agentFirst": true200 }'201```202203Response includes:204- `verificationUriComplete` (claim URL for the human owner)205- `claimCode`, `deviceCode`, `expiresIn`, `interval`, `claimText`206- `apiKey` (returned immediately in agent-first mode)207208Store `apiKey`, `claimCode`, and `verificationUriComplete` (as `claimUrl`) in `~/.spongewallet/credentials.json` so a human can claim later if context resets.209210**Step 2 — Send the claim URL to the human owner**211They log in, optionally post the tweet text, and approve the agent.212213Claim link format:214- `verificationUriComplete` (example path: `/device?code=ABCD-1234`)215- The base URL is the frontend (prod or local), so just pass the full `verificationUriComplete` to the human.216217**Step 3 — Poll for completion (standard auth flow only)**218```bash219while true; do220 response="$(curl -sS -X POST "$SPONGE_API_URL/api/oauth/device/token" \221 -H "Sponge-Version: 0.2.2" \222 -H "Content-Type: application/json" \223 -d '{224 "grantType":"urn:ietf:params:oauth:grant-type:device_code",225 "deviceCode":"<deviceCode>",226 "clientId":"spongewallet-skill"227 }')"228229 if printf '%s' "$response" | grep -q '"apiKey"'; then230 printf '%s\n' "$response"231 break232 fi233234 if ! printf '%s' "$response" | grep -q '"authorization_pending"'; then235 printf '%s\n' "$response"236 exit 1237 fi238239 sleep 5240done241```242243Keep polling while the human approves the current claim code. Approval in a browser244does not write credentials by itself; the still-running poll must receive the245success response. Do not ask the user to come back and say "done"; this poll246loop is the completion signal. If polling times out or is interrupted, request a247fresh code.248249On success, the response includes `apiKey`. Save it to `~/.spongewallet/credentials.json` and use it as `SPONGE_API_KEY`.250251Note: In **agent-first mode**, you already have the `apiKey` from Step 1. The auth token will remain pending until the human claims.252253### 2) Human Login (existing accounts only)254255**Phase 1 — Request device code**256```bash257curl -sS -X POST "$SPONGE_API_URL/api/oauth/device/authorization" \258 -H "Sponge-Version: 0.2.2" \259 -H "Content-Type: application/json" \260 -d '{261 "clientId":"spongewallet-skill"262 }'263```264265**Phase 2 — Poll for token** (same endpoint as agents)266```bash267while true; do268 response="$(curl -sS -X POST "$SPONGE_API_URL/api/oauth/device/token" \269 -H "Sponge-Version: 0.2.2" \270 -H "Content-Type: application/json" \271 -d '{272 "grantType":"urn:ietf:params:oauth:grant-type:device_code",273 "deviceCode":"<deviceCode>",274 "clientId":"spongewallet-skill"275 }')"276277 if printf '%s' "$response" | grep -q '"apiKey"'; then278 printf '%s\n' "$response"279 break280 fi281282 if ! printf '%s' "$response" | grep -q '"authorization_pending"'; then283 printf '%s\n' "$response"284 exit 1285 fi286287 sleep 5288done289```290291Keep Phase 2 alive until it returns success or a terminal error. Device approval292can happen in any browser, but credentials are only available to the agent after293the polling request succeeds and the returned `apiKey` is written to294`~/.spongewallet/credentials.json`. Do not ask the user to come back and say295"done"; this poll loop is the completion signal. If the poller was killed, timed296out, or lost its pending state, start again from Phase 1 and use the new code.297298## Tool Call Pattern299300Use the public REST endpoints documented in this file. Internal-only tools are intentionally omitted.301302**Common headers (include on EVERY request)**303```bash304-H "Authorization: Bearer $SPONGE_API_KEY" \305-H "Sponge-Version: 0.2.2" \306-H "Content-Type: application/json" \307-H "Accept: application/json"308```309310**Agent ID note:** `agentId` is optional for API key auth. It is only required when using a user session (e.g., Privy-based auth) or when explicitly operating on a different agent.311312### API Endpoints Reference313314| Endpoint | Method | Path | Params/Body |315|----------|--------|------|-------------|316| Get balances | GET | `/api/balances` | Query: `chain`, `allowedChains`, `onlyUsdc` |317| Create payment link | POST | `/api/payment-links` | Body: `amount`, optional `description`, `max_uses`, `expires_in_minutes`, `callback_url`, `livemode` |318| Get payment link status | GET | `/api/payment-links/{paymentLinkId}` | Query: `agentId` (optional) |319| List SPL tokens | GET | `/api/solana/tokens` | Query: `chain` |320| Search Solana tokens | GET | `/api/solana/tokens/search` | Query: `query`, `limit` |321| Tempo transfer | POST | `/api/transfers/tempo` | Body: `to`, `amount`, `token` (pathUSD/AlphaUSD/BetaUSD/ThetaUSD), optional `data` (hex calldata for raw contract calls) |322| EVM transfer | POST | `/api/transfers/evm` | Body: `chain`, `to`, `amount`, `currency` |323| Solana transfer | POST | `/api/transfers/solana` | Body: `chain`, `to`, `amount`, `currency` |324| Solana swap | POST | `/api/transactions/swap` | Body: `chain`, `inputToken`, `outputToken`, `amount`, `slippageBps` |325| Solana swap quote | POST | `/api/transactions/swap/quote` | Body: `chain`, `inputToken`, `outputToken`, `amount`, `slippageBps` |326| Solana swap execute | POST | `/api/transactions/swap/execute` | Body: `quoteId` |327| Base swap | POST | `/api/transactions/base-swap` | Body: `chain`, `inputToken`, `outputToken`, `amount`, `slippageBps` |328| Tempo swap | POST | `/api/transactions/tempo-swap` | Body: `chain` (tempo), `inputToken`, `outputToken`, `amount`, `slippageBps` |329| Bridge | POST | `/api/transactions/bridge` | Body: `sourceChain`, `destinationChain`, `token`, `amount`, `destinationToken`, `recipientAddress` |330| Transaction status | GET | `/api/transactions/status/{txHash}` | Query: `chain` |331| Transaction history | GET | `/api/transactions/history` | Query: `limit`, `chain` |332| Store credit card | POST | `/api/credit-cards` | Body (snake_case): `card_number`, `expiration` OR (`expiry_month` + `expiry_year`), `cvc`, `cardholder_name`, `email`, `billing_address`, `shipping_address` (**phone required**), optional `label`, `metadata`, `agentId`. Creates a saved card payment method for checkout |333| Add Link payment method | POST | `/api/agents/{agentId}/link-payment-methods/link` | First call can use `{}` to start Link login and may return `link_connection_required` with `verificationUrl`. Saving requires `email`, top-level `phone`, and `shipping` (`name`, `line1`, `city`, `state`, `postalCode`, `country`). Optional: `linkPaymentMethodId`, `setAsDefault`, `clientName`, `billing` |334| Create Link payment credential | POST | `/api/agents/{agentId}/link-payment-methods/credential` | Generate one-time card credentials from a saved Link payment method. First call body: `amount`, `merchantName`, `merchantUrl`; optional: `linkPaymentMethodId`, `currency`, `context`. If approval is required, call again with `spendRequestId` after approval |335| **Get card** | POST | `/api/cards` | Body: optional `card_type`, `payment_method_id`, `amount`, `currency`, `merchant_name`, `merchant_url`, `agentId`. Auto-detects source; returns `selection_required` when both sources are enrolled |336| Issue virtual card | POST | `/api/virtual-cards` | Body: `amount`, `merchant_name`, `merchant_url`; optional: `currency`, `merchant_country_code`, `description`, `products`, `shipping_address`, `enrollment_id`, `agentId` |337| Report card usage | POST | `/api/card-usage` | Body: `payment_method_id`, `status` (success/failed/cancelled); optional: `merchant_name`, `merchant_domain`, `amount`, `currency`, `failure_reason`, `agentId` |338| Store service key (non-card) | POST | `/api/agent-keys` | Body: `service`, `key`, optional `label`, `metadata` |339| List stored keys | GET | `/api/agent-keys` | Query: `agentId` (optional) |340| Get stored key value | GET | `/api/agent-keys/value` | Query: `service` |341| Delete stored key | DELETE | `/api/agent-keys` | Query: `service`, optional `agentId` |342| **Step 1: Discover services** | GET | `/api/discover` | Query: `type`, `limit`, `offset`, `query`, `category` |343| **Step 2: Get service details** | GET | `/api/discover/{serviceId}` | — |344| **Step 3: Paid fetch (unified)** | POST | `/api/paid/fetch` | Body: `url`, `method`, `headers`, `body`, `chain` (preferred wallet chain hint) |345| **Step 3 alt: x402 fetch** | POST | `/api/x402/fetch` | Body: `url`, `method`, `headers`, `body`, `preferred_chain` |346| **Step 3 alt: MPP fetch** | POST | `/api/mpp/fetch` | Body: `url`, `method`, `headers`, `body`, `chain` |347| SIWE signature | POST | `/api/siwe/generate` | Body: `domain`, `uri`; optional: `statement`, `nonce`, `chain_id`, `expiration_time`, `not_before`, `request_id`, `resources` |348| **Sponge Card status** | GET | `/api/sponge-card/status` | Query: optional `refresh`, `agentId` |349| **Onboard Sponge Card** | POST | `/api/sponge-card/onboard` | Body: optional `redirect_uri`, then `occupation` and consent booleans after KYC approval, optional `agentId`. Returns a KYC verification link first when needed; does not accept raw SSN/date-of-birth fields |350| **Accept Sponge Card terms** | POST | `/api/sponge-card/terms` | Body: consent booleans, optional `agentId` |351| **Create Sponge Card** | POST | `/api/sponge-card/create-card` | Body: `billing`, `email`, `phone`, optional `shipping`, `agentId` |352| **Sponge Card details** | GET | `/api/sponge-card/details` | Query: `agentId` (optional) |353| **Fund Sponge Card** | POST | `/api/sponge-card/fund` | Body: `amount`, optional `chain`, `agentId` |354| **Withdraw from Sponge Card** | POST | `/api/sponge-card/withdraw` | Body: `amount`, optional `chain`, `agentId` |355| Banking onboard | POST | `/api/bank/onboard` | Body: optional `wallet_id`, `redirect_uri`, `customer_type`, `signed_agreement_id`, `agentId`. Returns a KYC verification link first when needed, then a Bridge terms URL |356| Banking status | GET | `/api/bank/status` | Query: optional `agentId` |357| Create virtual bank account | POST | `/api/bank/virtual-account` | Body: `wallet_id`, optional `agentId` |358| Get virtual bank account | GET | `/api/bank/virtual-account` | Query: optional `wallet_id`, `agentId` |359| List linked bank accounts | GET | `/api/bank/external-accounts` | Query: optional `agentId` |360| Link bank account | POST | `/api/bank/external-accounts` | Body (snake_case): `bank_name`, `account_owner_name`, `routing_number`, `account_number`, `checking_or_savings`, `street_line_1`, optional `street_line_2`, `city`, `state`, `postal_code`, optional `agentId` |361| Send USD to bank | POST | `/api/bank/send` | Body: `wallet_id`, `external_account_id`, `amount`, optional `payment_rail` (ach/wire), `agentId` |362| List bank transfers | GET | `/api/bank/transfers` | Query: optional `transfer_id`, `agentId` |363| Crypto onramp | POST | `/api/onramp/crypto` | Body: `wallet_address`; optional: `provider` (auto/stripe/coinbase), `chain` (base/solana/polygon), `fiat_amount`, `fiat_currency` |364| Hyperliquid | POST | `/api/hyperliquid` | Body: `action`, + action-specific params (see below) |365| URL checkout request | POST | `/api/checkout` | Body: `productUrl`; optional: `estimatedAmount`, `email`, `dryRun`, `productOptions`, `agentId` |366| URL checkout status | GET | `/api/checkout/{sessionId}` | Query: `agentId` (optional) |367| Submit plan | POST | `/api/plans/submit` | Body: `title`, `reasoning`, `steps` (see Planning section) |368| Approve plan | POST | `/api/plans/approve` | Body: `plan_id` |369| Propose trade | POST | `/api/trades/propose` | Body: `input_token`, `output_token`, `amount`, `reason` |370Note: most request bodies use camelCase (e.g., `inputToken`, `slippageBps`). Card secret endpoints and Sponge Card API endpoints use snake_case fields (e.g., `card_number`, `cardholder_name`, `first_name`, `postal_code`).371372> **CRITICAL — Paid Services require ALL 3 steps in order:**373> 1. `GET /api/discover` — search for a service by query or category374> 2. `GET /api/discover/{serviceId}` — get the service's endpoints, parameters, pricing, and payment config (**DO NOT SKIP THIS STEP**)375> 3. `POST /api/x402/fetch` — call the endpoint using the URL from step 2376>377> You MUST call step 2 before step 3. Step 2 returns the `paymentsProtocolConfig` (with baseUrls) and the endpoint parameters/instructions needed to construct the fetch request. Using a direct API URL will fail with auth errors.378379### Planning (Multi-Step Actions)380381Use `submit_plan` whenever you need to do 2+ related actions together (e.g., swap then bridge, buy multiple tokens, rebalance a portfolio). This groups everything into a single proposal the user can review and approve.382383**Workflow:**3841. Call `submit_plan` with a title, reasoning, and ordered list of steps3852. Present the plan to the user3863. When the user confirms ("go ahead", "do it", "execute"), call `approve_plan` with the `plan_id`3874. Steps execute sequentially and automatically. If any step fails, the plan pauses for retry or reject.388389**Step types:**390- `swap` — requires: `input_token`, `output_token`, `amount`, `reason`; optional: `chain` (defaults to solana; use `base` or `tempo` for other DEXs)391- `transfer` — requires: `chain`, `to`, `amount`, `currency`, `reason`392- `bridge` — requires: `source_chain`, `destination_chain`, `token`, `amount`, `reason`; optional: `destination_token`393394**Rules:**395- Do NOT execute steps individually with other tools after submitting a plan — always use `approve_plan`396- Plans can have 1–20 steps397- The user can skip individual steps on the dashboard before approving398- Use `propose_trade` only for a single swap that needs explicit approval; for multi-step flows, always use `submit_plan`399400### Polymarket Actions401402The `polymarket` endpoint is a unified tool for Polymarket trading, funding, withdrawals, and account status. Pass `action` plus action-specific parameters:403404| Action | Description | Required Params | Optional Params |405|--------|-------------|-----------------|-----------------|406| `enable` | Provision/link the Polymarket Safe without placing a trade | — | — |407| `signup` | Alias for `enable` | — | — |408| `status` | Check whether Polymarket is linked and view balances | — | — |409| `search_markets` | Search Polymarket markets | `query` | `limit` |410| `get_market` | Fetch market metadata | `market_slug` or `token_id` | — |411| `get_market_price` | Fetch current market price | `market_slug` or `token_id` | — |412| `positions` | View current positions | — | — |413| `orders` | View open orders | — | — |414| `get_order` | Fetch an order by ID | `order_id` | — |415| `balance_allowance` | View CLOB balance + allowance | — | — |416| `refresh_balance_allowance` | Refresh CLOB balance + allowance | — | — |417| `order` | Place a limit or market order | `outcome`, `side`, `size`, `market_slug` or `token_id` | `type`, `price`, `order_type` |418| `cancel` | Cancel an order | `order_id` | — |419| `set_allowances` | Approve contracts for trading | — | — |420| `deposit` | Make Safe-held USDC.e available to the exchange | — | — |421| `deposit_from_wallet` | Move Polygon wallet USDC.e into the Safe | `amount` | — |422| `withdraw` | Withdraw pUSD as USDC.e to Polygon wallet | `amount` | — |423| `withdraw_native` | Withdraw Polygon-native USDC to Polygon wallet | `amount` | — |424| `redeem` | Redeem settled winning positions | — | `condition_id` |425426**Order params:**427- `market_slug` or `token_id`: identify which market to trade428- `outcome`: `"yes"` or `"no"`429- `side`: `"buy"` or `"sell"`430- `size`: number of shares431- `type`: `"limit"` or `"market"`; defaults to `"limit"`432- `price`: required for limit orders, decimal between `0` and `1`433- `order_type`: `"GTC"`, `"GTD"`, `"FOK"`, or `"FAK"`; market orders only support `FOK` or `FAK`434435**Scopes:** Setup, trade, and funding actions (`enable`, `signup`, `order`, `cancel`, `set_allowances`, `deposit`, `deposit_from_wallet`, `withdraw`, `withdraw_native`, `redeem`) require `polymarket:trade`. Read actions require `wallet:read`.436437**Provisioning:** Trading and funding calls auto-link Polymarket on first use if the agent has a Polygon/EVM wallet. To sign up explicitly through the tool, call `action: "enable"` (or `action: "signup"`). You can also enable from the dashboard with `POST /api/agents/:id/polymarket/enable`.438439**Funding:** For cross-chain funding, use the bridge tool with `destination_chain: "polymarket"` so the route lands as USDC.e in the Polymarket Safe, then use `deposit` to wrap Safe-held USDC.e into pUSD trading collateral.440441**Search:** Use team names, common aliases, or exact slugs for sports markets. For NBA matchup searches, queries like `"Sixers Celtics"` should resolve aliases to current/future sports slugs such as `nba-phi-bos-YYYY-MM-DD`. If `search_markets` misses a sports matchup, search the web or Polymarket team/event pages directly, find the exact Polymarket event/market URL, then pass that slug to `get_market`, `get_market_price`, or `order`.442443### Hyperliquid Actions444445The `hyperliquid` endpoint is a unified tool for perps/spot trading on Hyperliquid DEX. Pass `action` plus action-specific parameters:446447| Action | Description | Required Params | Optional Params |448|--------|-------------|-----------------|-----------------|449| `status` | Check account balances and equity | — | — |450| `positions` | View open perp positions (entry, PnL, liq price) | — | — |451| `orders` | View open orders | — | `symbol` |452| `fills` | Recent trade history | — | `symbol`, `since`, `limit` |453| `markets` | List available perp/spot markets | — | — |454| `ticker` | Current price for a symbol | `symbol` | — |455| `orderbook` | L2 order book | `symbol` | `limit` |456| `funding` | Current + predicted funding rates | — | `symbol` |457| `chart` | Compact Unicode price chart with candle summary | `symbol` | `interval`, `chart_style` |458| `order` | Place limit/market/stop/TP order | `symbol`, `side`, `type`, `amount` | `price`, `reduce_only`, `trigger_price`, `tp_sl`, `tif` |459| `cancel` | Cancel an order | `order_id`, `symbol` | — |460| `cancel_all` | Cancel all open orders | — | `symbol` |461| `set_leverage` | Set leverage for a symbol | `symbol`, `leverage` | — |462| `withdraw` | Withdraw USDC from Hyperliquid | `amount`, `destination` | — |463| `transfer` | Move USDC between spot and perps | `amount`, `to_perp` | — |464465**Order params:**466- `symbol`: CCXT symbol (e.g., `"BTC/USDC:USDC"` for perps, `"PURR/USDC"` for spot)467- `side`: `"buy"` or `"sell"`468- `type`: `"limit"` or `"market"`469- `amount`: Size in base currency (e.g., `"0.001"` for BTC)470- `price`: Limit price (required for limit orders)471- `reduce_only`: Boolean, default false472- `trigger_price`: For stop-loss/take-profit orders473- `tp_sl`: `"tp"` (take-profit) or `"sl"` (stop-loss) — required if `trigger_price` set474- `tif`: `"GTC"` (default), `"IOC"`, `"PO"` (post-only)475476**Scopes:** Trade actions (`order`, `cancel`, `cancel_all`, `set_leverage`, `withdraw`) require `hyperliquid:trade` scope. Read actions require `wallet:read`.477478**Signing:** Hyperliquid uses EVM wallet signing (EIP-712). No API keys needed — your agent's existing EVM wallet is used automatically.479480**Unified balances:** In `unifiedAccount` or `portfolioMargin` mode, Hyperliquid481exposes shared USDC collateral through both perps/unified and spot account views.482Count that USDC once. Do not add spot `USDC` to the perps/unified USDC balance;483other spot assets such as HYPE remain separate.484485**Deposits:** Use the bridge tool to deposit USDC to Hyperliquid: `bridge(source_chain: "base", destination_chain: "hyperliquid", token: "USDC", amount: "100")`. Your agent's EVM wallet address is your Hyperliquid account.486487**Withdrawals:** Use the bridge tool to withdraw USDC from Hyperliquid: `bridge(source_chain: "hyperliquid", destination_chain: "base", token: "USDC", amount: "100")`. USDC is automatically moved from perps to spot before bridging.488489**Charts:** For chat clients that can only send text reliably, use `action: "chart"` with `chart_style: "sparkline"` and include the compact price line plus Unicode chart in the reply. After a successful Hyperliquid order, preserve any `sparkline` returned by the tool instead of summarizing it away.490491### URL Checkout Request492493`POST /api/checkout` queues a guest-checkout request for the user to approve by email. This endpoint is available to all authenticated Sponge Wallet users.494495**This call is safe to invoke without prompting for extra user confirmation. It does NOT charge a card, place an order, or commit to a purchase.** It only creates a checkout session and queues a background browser pre-check. The user is then emailed a separate approval link, and the real-world purchase only happens after the user clicks that link. Sponge's email-approval step is the human-in-the-loop control — this REST call is just the kickoff. Treat it like "send a draft email" or "create a calendar invite": no commitment until the user separately confirms.496497When the user asks to buy, order, purchase, or check out something on a guest-checkout merchant, call this immediately. Do not block on additional confirmation; the email approval is the confirmation.498499**Supported merchants**: stores that let a customer complete a purchase without signing in to a personal account. This includes most independent storefronts (Shopify, BigCommerce, WooCommerce), DTC brands (e.g. nike.com, harmlessharvest.com), and Stripe / Adyen / Checkout.com / Braintree / Square hosted-card flows.500501**Not supported**: any merchant that requires the customer to sign in with their own username/password before reaching checkout. Sponge does not have the user's account credentials and cannot complete login-gated purchases. Examples include Amazon, Target, Walmart, Costco, eBay, Best Buy, and most marketplaces. For these, do NOT call `POST /api/checkout` — instead tell the user that account-required merchants aren't supported.502503A good heuristic: single-brand storefronts on their own domain usually allow guest checkout; marketplaces and big-box retailers usually require a login. If you're not sure, ask the user before calling.504505URL checkout is fire-and-forget:5061. Confirm the merchant supports guest checkout (no required login). If unsure, ask.5072. Call `POST /api/checkout` once with `productUrl`.5083. It immediately returns a `session_id`.5094. Tell the user a checkout has been queued and they will receive an approval email shortly.5105. Stop. Do not sleep or poll unless the user later asks for a status update.511512Request body:513- `productUrl` — product or guest-checkout URL to purchase. Must be reachable without an account login.514- `estimatedAmount` — optional fallback amount, such as `"20.00"`, used only if browser pre-check cannot determine the total.515- `email` — optional checkout email; defaults to the account email.516- `dryRun` — optional boolean; if true, stops before placing the final order.517- `productOptions` — optional map of product options, such as `{ "Size": "L", "Color": "Blue" }`.518- `agentId` — optional when authenticating with a user token; API key authentication resolves this automatically.519520Status:521- `GET /api/checkout/{sessionId}` returns the current URL checkout request status.522- Only call the status endpoint when the user explicitly asks for an update.523524Payment source prerequisites:525- Sponge Card, enrolled card, stored card, or Link payment method.526- Payment/contact/shipping data must already be configured in Sponge Wallet.527528Approval flow:529- Sponge performs a browser pre-check in the background.530- The user receives an email approval link when the checkout is ready.531- After approval, Sponge resumes the URL checkout and emails completion or failure.532- The approval window is about 30 minutes before the browser session expires.533534If the pre-check fails because the merchant redirected to a login wall, the request is reported as failed with reason `loginRequired`. Treat this as a signal to redirect the user, not as a transient error to retry.535536### Tempo Transfer537538Send Tempo stablecoins (pathUSD, AlphaUSD, BetaUSD, ThetaUSD) on the Tempo chain.539540```bash541curl -sS -X POST "$SPONGE_API_URL/api/transfers/tempo" \542 -H "Authorization: Bearer $SPONGE_API_KEY" \543 -H "Sponge-Version: 0.2.2" \544 -H "Content-Type: application/json" \545 -d '{546 "to":"0x...",547 "amount":"10",548 "token":"pathUSD"549 }'550```551552Supported tokens: `pathUSD` (default), `AlphaUSD`, `BetaUSD`, `ThetaUSD`.553554For raw contract calls, pass `data` (hex calldata) instead of `token`/`amount`:555```bash556curl -sS -X POST "$SPONGE_API_URL/api/transfers/tempo" \557 -H "Authorization: Bearer $SPONGE_API_KEY" \558 -H "Sponge-Version: 0.2.2" \559 -H "Content-Type: application/json" \560 -d '{561 "to":"0xContractAddress...",562 "amount":"0",563 "data":"0xabcdef..."564 }'565```566567### EVM Swaps (Ethereum, Polygon, Arbitrum)568569The unified `POST /api/transactions/swap` REST endpoint supports EVM chains. Pass the chain name (e.g., `base`, `ethereum`, `polygon`, `arbitrum-one`) in the `chain` field.570571### Swap Quote & Execute (Solana)572573For Solana swaps, you can get a quote before executing:5745751. **Get quote:** `POST /api/transactions/swap/quote` — returns pricing details and a `quoteId`5762. **Execute:** `POST /api/transactions/swap/execute` with `{ "quoteId": "..." }` — executes the quoted swap577578Quotes expire in ~30 seconds. Use this when you want to preview pricing or get user confirmation before swapping.579580### Sponge Card (beta preview)581582The Sponge Card is a stablecoin-collateralized credit card available to authenticated users with the required API scopes.583584Environment (dev vs production) is fixed by your API key type: `sponge_test_*` -> dev sandbox, `sponge_live_*` -> production.585586The full no-UI flow is:5875881. `GET /api/sponge-card/status` - check onboarding and card readiness.5892. `POST /api/sponge-card/onboard` - start internal KYC verification when needed, then submit the Sponge Card application and record consent acknowledgements after KYC approval.5903. If status says consent is missing, `POST /api/sponge-card/terms`.5914. When `ready_for_card_creation` is true, `POST /api/sponge-card/create-card`.5925. Use `/details`, `/fund`, and `/withdraw` after a card exists.593594#### Check onboarding status595596```bash597curl -sS "$SPONGE_API_URL/api/sponge-card/status?refresh=true" \598 -H "Authorization: Bearer $SPONGE_API_KEY" \599 -H "Sponge-Version: 0.2.2" \600 -H "Accept: application/json"601```602603Returns `onboarded`, `environment`, `ready_for_card_creation`, `customer`, `completion_link_url`, `cards`, `balances`, and `message`. `balances` uses explicit unit fields such as `spending_power_cents`, `spending_power_usd`, and `spending_power_display`; for user-facing output, use the display fields. If `spending_power_cents` is `250`, that means `$2.50`, not `$250`. `completion_link_url` is retained for compatibility and should normally be `null`; use `/onboard` to receive any required KYC verification link.604605#### Onboard for Sponge Card606607Start Sponge Card onboarding. If internal KYC verification is missing, this endpoint can be called with only optional `redirect_uri` and returns `kyc_url` / `verification_url` for the user to complete. After KYC approval, call it again with `occupation` and consent acknowledgements to submit the Sponge Card application and record Sponge consent. Bodies use snake_case. Do not collect or send raw SSN, national ID, birth date, or address fields to this endpoint.608609```bash610curl -sS -X POST "$SPONGE_API_URL/api/sponge-card/onboard" \611 -H "Authorization: Bearer $SPONGE_API_KEY" \612 -H "Sponge-Version: 0.2.2" \613 -H "Content-Type: application/json" \614 -d '{615 "occupation":"Software engineer",616 "e_sign_consent":true,617 "account_opening_privacy_notice":true,618 "sponge_card_terms":true,619 "information_certification":true,620 "unauthorized_solicitation_acknowledgement":true621 }'622```623624- `occupation` is required.625- `occupation` and required consent booleans are required only after KYC approval, when submitting the Sponge Card application.626- `account_opening_privacy_notice` is required when the KYC country is `US`.627- If KYC verification is missing, the API returns `submitted_application:false`, an onboarding step indicating KYC verification, and a `kyc_url` / `verification_url`. Have the user complete that link, then call `/onboard` again.628629Returns `submitted_application`, `environment`, `ready_for_card_creation`, `customer`, `completion_link_url`, optional `kyc_url` / `verification_url`, `onboarding_step`, and `message`.630631#### Accept Sponge Card terms632633Use this only when `/status` says the Sponge Card application is approved but Sponge consent is missing.634635```bash636curl -sS -X POST "$SPONGE_API_URL/api/sponge-card/terms" \637 -H "Authorization: Bearer $SPONGE_API_KEY" \638 -H "Sponge-Version: 0.2.2" \639 -H "Content-Type: application/json" \640 -d '{641 "e_sign_consent":true,642 "account_opening_privacy_notice":true,643 "sponge_card_terms":true,644 "information_certification":true,645 "unauthorized_solicitation_acknowledgement":true646 }'647```648649#### Create a Sponge Card650651Call this after status returns `ready_for_card_creation: true`. If a card already exis652653…(truncated)