Talk to usGet started
Guides

Fund the wallet

Three ways in, one balance. A top-up by card or stablecoin ends on Stripe's own page, a bank transfer is declared and matched when it lands, and a new account starts with a small gift. A card number never passes through the API.

Read the wallet

cURL
curl https://api.joomjoo.com/v1/wallet \
  -H "Authorization: Bearer $AGENTPAY_API_KEY"
200
{
  "currency": "USD",
  "onboarded": true,
  "balance": 32.96,
  "available": 22.96,
  "reserved": 10,
  "pending": 0,
  "balance_display": "$32.96",
  "available_display": "$22.96",
  "reserved_display": "$10.00",
  "pending_display": "$0.00",
  "cards_ready": [{ "last4": "8339", "network": "visa", "holds": 10 }],
  "ready_to_spend": 32.96,
  "charges_in_flight": [],
  "after_settlement": 32.96,
  "note": "A checkout whose total fits one of the 1 card(s) in cards_ready pays with it, no new card and no top-up needed. Call complete_purchase.",
  "request_id": "req_a1b2c3"
}

available is what a new card can be capped at. cards_ready lists open, never-charged single-use cards: a checkout whose total fits one of them pays with it, so ready_to_spend is the honest number for "can the agent buy this". charges_in_flight names authorized charges still settling; the balance becomes after_settlement once they clear. That is normal, not a failed purchase.

Top up by card or stablecoin

POST /v1/wallet/funding-sessions opens a Stripe Checkout page for the amount. Give url to the person. Stripe offers card and stablecoin; the wallet is credited the moment Stripe confirms.

curl https://api.joomjoo.com/v1/wallet/funding-sessions \
  -H "Authorization: Bearer $AGENTPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 50, "success_url": "https://yourapp.example/funded"}'
const session = await agentpay.wallet.createFundingSession({ amount: 50, success_url: "https://yourapp.example/funded" });
// send session.url to the person
session = agentpay.wallet.create_funding_session(amount=50, success_url="https://yourapp.example/funded")
200
{
  "funding_session_id": "cs_live_...",
  "url": "https://checkout.stripe.com/c/pay/...",
  "amount": 50,
  "amount_display": "$50.00",
  "status": "open",
  "pays_with": "card or stablecoin on the Stripe page",
  "credited": "the wallet is credited the moment Stripe confirms; subscribe to money.funded to know",
  "request_id": "req_a1b2c3"
}

Subscribe to money.funded to know when the money landed, or poll GET /v1/wallet. A fence can refuse an amount: 402 wallet_limit, funding_budget_reached or funding_unavailable, and the message says which.

Never ask the person for a card number and never type one yourself. The top-up always ends on Stripe's page.

Top up by bank transfer

POST /v1/wallet/bank-transfers declares a transfer and returns the account to send it to, with a reference code for the memo. The money is pending until it lands; then money.funded fires and the balance moves.

cURL
curl https://api.joomjoo.com/v1/wallet/bank-transfers \
  -H "Authorization: Bearer $AGENTPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 500, "rail": "wire_domestic", "sent_on": "2026-11-03", "sender_bank_name": "Chase", "idempotency_key": "topup-2026-11-03"}'
railCurrencyNotes
ach (default)USDUS domestic.
wire_domesticUSDUS wire.
wire_internationalUSDSWIFT. The response carries the SWIFT and intermediary codes.
uae_localAEDA UAE account. Defaults currency to AED.

Show the person the instructions object as it is. The reference_code in the transfer memo is what matches the money to the account; without it the transfer waits for a manual match.

The signup gift

A new account's first card is issued at onboarding, single use, loaded with a small gift. It shows up in cards_ready and pays a first checkout whose total fits it. The gift cannot be withdrawn and expires with the card.