---
name: bags-cash
description: |
    Pay x402-protected APIs with a BAGS hosted agent wallet (USDC credits, server-side policies).
    Use when the user has a BAGS invite code, wants to call paid APIs via BAGS Cash / BAGS Wallet,
    or mentions bags wallet / bags cash / getbags / x402 micropayments.

    TRIGGERS: x402, paid API, bags wallet, bags cash, getbags, invite code, redeem, micropayment,
    agent wallet, check endpoint, wallet fetch
homepage: https://www.getbags.app/wallet/skill.md
metadata:
    version: 0.2
---

# BAGS Cash — Hosted Agent Wallet

> Hosted skill URL: https://www.getbags.app/wallet/skill.md  
> Onboard (humans): https://www.getbags.app/wallet/onboard  
> Staging: replace the host with `https://staging.getbags.app`.

Call x402-protected APIs with a **hosted** BAGS wallet. Redeem an invite, discover services, **check** the exact quote + schema, then `fetch`. No local private keys — the agent holds only a token (`bag_agent_sk_*`).

## Why hosted (vs local-key wallets)

Local plaintext / keychain wallets break in ephemeral sandboxes (Claude Cowork, CI, short-lived VMs): the key dies with the machine. BAGS keeps custody + ledger server-side. Your agent only needs the token in `~/.bags/credentials.json` (or `Authorization: Bearer`). Policies (caps, allowlists, kill switch) are enforced on the server — the agent cannot bypass them by editing a local file.

## Wallet

| Task                           | Command                           |
| ------------------------------ | --------------------------------- |
| Redeem invite (saves token)    | `npx @getbags/cash redeem <code>` |
| Check balance + caps           | `npx @getbags/cash balance`       |
| Install this skill into a repo | `npx @getbags/cash init`          |

If there is no token yet, redeem first. If balance is too low, ask for another invite.

## Workflow: balance → discover → check → fetch

Match AgentCash’s agent loop; prefer this order every time.

### 1. Balance

```bash
npx @getbags/cash balance
```

### 2. Discover or search

```bash
npx @getbags/cash discover                    # BAGS merchant catalog
npx @getbags/cash discover weather forecast   # BAGS first, then open x402 index
npx @getbags/cash search "send physical mail" # NL search (catalog + ecosystem)
```

Prefer `source: bags` results (refund-guaranteed on BAGS merchants when that guarantee is live). Then `source: bazaar`. Default table columns: `url`, `method`, `price`, `merchant`, `source`. Use `--format json` for the raw payload (includes schemas when present).

### 3. Check (exact quote, no payment)

```bash
npx @getbags/cash check '<url>'
npx @getbags/cash check '<url>' -m POST -b '{"key":"value"}'
```

Returns HTTP status, whether payment is required, price in cents/USD, accept options (network/scheme), and input/output schemas when the endpoint advertises them. **Always check before an expensive or schema-sensitive fetch** to avoid 400s.

### 4. Fetch (pay + proxy)

```bash
npx @getbags/cash fetch '<url>'
npx @getbags/cash fetch '<url>' -m POST -b '{"key":"value"}'
npx @getbags/cash fetch '<url>' --max-price-cents 25
```

Payment receipt (amount, tx hash, network) → stderr; upstream body → stdout (pipe-friendly).

**Response envelope:** check top-level `status` / `code` first. `status: "success"` means the fetch completed as intended (including free/SIWX calls with `payment.paid: false`). A paid attempt that did not complete returns `status: "error"` with `PRE_PAYMENT_FAILED` or `NETWORK_NOT_ALLOWED` (nested `data.http_status` / `data.payment` keep the upstream diagnostic). Do not treat HTTP 200 alone as “paid OK” — and do not treat nested `http_status: 402` under `status: "success"` as a thing that happens anymore.

## Other commands

| Command                                                 | Purpose                             |
| ------------------------------------------------------- | ----------------------------------- |
| `transactions`                                          | Ledger / spend history              |
| `policies get` / `policies set --per-call-cap-cents=50` | Read/update spend caps              |
| `keys create\|list\|revoke`                             | Per-agent sub-keys                  |
| `register <origin>`                                     | Register origin into discover index |

## Important rules

- **Hosted token only** — never invent or store user private keys for BAGS Cash.
- **Check before fetch** when price or request shape is unclear.
- **Prefer `source: bags`**, then bazaar, then any trusted x402 URL via `fetch`.
- **Failed pre-payment requests cost nothing.** If payment settled and upstream still errored, read the stderr receipt / `transactions`.
- **Do not invent endpoints.** Use `discover` / `search` / `check` or a URL the user provided.

## Troubleshooting

| Code                                | Fix                                                                           |
| ----------------------------------- | ----------------------------------------------------------------------------- |
| `INSUFFICIENT_BALANCE`              | `bags balance` then redeem another invite                                     |
| `INVITE_INVALID` / `INVITE_EXPIRED` | Ask for a new invite code                                                     |
| `URL_BLOCKED`                       | Use a public `https` endpoint (SSRF gate)                                     |
| `CAP_EXCEEDED`                      | Wait, lower `--max-price-cents`, or `policies set`                            |
| `WALLET_SUSPENDED`                  | Dashboard / support                                                           |
| `WALLET_FETCH_DISABLED`             | Retry later (global kill switch)                                              |
| `VALIDATION_FAILED`                 | Fix url/method/body JSON                                                      |
| `NOT_FOUND`                         | Route not live on this env — set `BAGS_API_URL` or upgrade                    |
| `UPSTREAM_ERROR` / `TIMEOUT`        | Retry; `bags check <url>` for a fresh quote                                   |
| `NETWORK_NOT_ALLOWED`               | Test wallet vs mainnet (or vice versa) — use matching mode                    |
| `PRE_PAYMENT_FAILED`                | Payment did not broadcast; reservation reversed — fix quote / network / funds |
| `AUTH_MISSING_CREDENTIALS`          | `bags redeem <code>`                                                          |

Env: `BAGS_API_URL` (default `https://www.getbags.app`; staging example `https://staging.getbags.app`).  
Token path: `~/.bags/credentials.json`.

MCP: wallet tools on `https://www.getbags.app/api/mcp/mcp` — pass `Authorization: Bearer bag_agent_sk_...` or a `wallet_token` argument on each tool.
