WWalleyOpen the wallet

Let any agent shop with your wallet

Your agent finds products, opens a checkout over the Universal Commerce Protocol, and asks Walley to pay. Walley issues a Stripe Shared Payment Token for that one order, and you see every purchase in your ledger.

Connect your agent in one message

Paste this into Claude, ChatGPT or any agent that can make HTTP requests:

You can shop for me with my Walley wallet. Read https://walley-ten.vercel.app/llms.txt and follow it exactly. Send my Walley API key on every request as "Authorization: Bearer <my key>". Check my balance first, show me the merchant, items and total, and only pay after I say yes. Use your name as agent_name.

Get the key from Connect an agent on your dashboard. Walley runs in Stripe test mode, so no real money moves. Add test money with card 4242 4242 4242 4242.

Accounts and API keys

Every Walley account has its own wallet and ledger. People sign in at /login. Agents send an API key on every request:

Authorization: Bearer wk_test_…

There are two ways to get one:

  • Your person creates it. On the dashboard, under Connect an agent. They can revoke it at any time, and the agent stops working at once.
  • The agent signs up itself. One request opens a new wallet. Give the sign-in link to your person: it signs them in once, and they then save an email and password.
curl -X POST https://walley-ten.vercel.app/api/agents/signup \
  -H 'Content-Type: application/json' \
  -d '{ "agent_name": "Ava (Claude)" }'
201 Created
{
  "account": { "id": "acct_…", "name": "Ava (Claude)", "kind": "agent" },
  "api_key": "wk_test_…",          // shown once: store it
  "sign_in_link": "https://walley-ten.vercel.app/api/auth/link?token=wl_…",
  "sign_in_link_expires_at": "…"   // one use, 7 days
}

Just trying it out? The public demo key wk_test_demo_scout_public opens a shared test wallet that tops itself back up. Without a valid key, wallet endpoints return 401.

How a purchase works

  1. 1

    Get a key

    POST /api/agents/signup

    Or use a key your person created on the dashboard. Send it on every call.

  2. 2

    Check the balance

    GET /api/wallet

    summary.available is what the agent may spend, in cents.

  3. 3

    Find products

    GET /api/catalog?q=coffee

    Each product has a merchant_id, an id and a price in cents.

  4. 4

    Open a UCP checkout

    POST /api/ucp/{merchant_id}/checkout-sessions

    Nothing is charged. You get a checkout id and the total.

  5. 5

    Ask the person

    Show the merchant, items and total. Pay only after a clear yes.

  6. 6

    Pay with Walley

    POST /api/wallet/pay

    Walley holds the funds, issues an SPT capped at the total, and the merchant charges it.

The purchase then shows up in GET /api/wallet and on the dashboard, with the agent's name, its reason, the SPT and a link to the Stripe payment.

Endpoints

Base URL https://walley-ten.vercel.app. All amounts are integers in US cents.

  • POST/api/agents/signupOpen a wallet: returns an API key and a sign-in link for your person (no key needed)
  • GET/api/walletBalance, ledger entries and spend per merchant (key)
  • POST/api/wallet/topupStripe Checkout link your person opens to add money (key)
  • GET/api/catalog?q=&merchant=Search products across merchants
  • GET/.well-known/ucpUCP discovery: merchants and checkout endpoints
  • POST/api/ucp/{merchant_id}/checkout-sessionsOpen a checkout with line_items
  • GET/api/ucp/{merchant_id}/checkout-sessions/{id}Read a checkout
  • POST/api/ucp/{merchant_id}/checkout-sessions/{id}/cancelCancel a checkout
  • POST/api/wallet/payPay for a checkout from the wallet (key)

Paying with the wallet

curl -X POST https://walley-ten.vercel.app/api/wallet/pay \
  -H "Authorization: Bearer $WALLEY_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "merchant_id": "night-owl-coffee",
    "checkout_id": "cs_ucp_0123456789abcdef0123",
    "agent_name": "Ava (Claude)",
    "reason": "User asked for cold brew for the office"
  }'

Paid

200 OK
{
  "status": "completed",
  "total_cents": 1400,
  "order": { "id": "ord_…", "payment_intent_id": "pi_…" },
  "shared_payment_token": "spt_…",
  "payment_intent": "pi_…"
}

Declined: nothing was charged

402 Payment Required
{
  "status": "declined",
  "message": "Insufficient wallet balance",
  "total_cents": 3000,
  "available_cents": 400,
  "shortfall_cents": 2600,
  "affordable_items": [],
  "suggested_topup_dollars": 26
}

On a decline, don't retry. Tell the person why, offer the affordable_items, or ask them to add money.

What protects the person

  • Balance hold

    Funds are held before any token exists, so an agent can't overspend.

  • One token per order

    Each SPT is capped at the exact total and expires in 15 minutes.

  • Per-order limit

    No single agent order can go over $500.

  • Everything is logged

    Declined attempts show as Blocked, with the agent's name and reason.

Try the whole flow with curl

B=https://walley-ten.vercel.app
K="Authorization: Bearer wk_test_demo_scout_public"   # public demo wallet; use your own key
curl -s -H "$K" "$B/api/wallet" | jq .summary
curl -s "$B/api/catalog?q=cold%20brew" | jq '.products[0]'
CID=$(curl -s -X POST "$B/api/ucp/night-owl-coffee/checkout-sessions" \
  -H 'Content-Type: application/json' \
  -d '{"line_items":[{"id":"NOC-COLD","quantity":1}]}' | jq -r .id)
curl -s -X POST "$B/api/wallet/pay" -H "$K" -H 'Content-Type: application/json' \
  -d "{\"merchant_id\":\"night-owl-coffee\",\"checkout_id\":\"$CID\",\"agent_name\":\"curl demo\",\"reason\":\"testing Walley\"}"