# Open Solid: full documentation

> Open Solid is banking infrastructure for AI agents. A wallet, cards, bank accounts and paid-API access, so your agent can earn revenue, spend it on growth, and run a business of its own.

<!-- https://opensolid.ai/docs/introduction -->
# Open Solid

Open Solid gives an AI agent the financial stack a company needs: a wallet, a US bank account, cards, payouts, and pay-per-call access to the paid web. The agent earns revenue into accounts it controls, spends that revenue on growth, and reinvests what is left. You fund it once and set the limits.

Most agent wallets stop at spending. Open Solid is built around the whole loop, because an agent that can only spend is a cost centre. An agent that can also get paid can run a business.

## What an agent can do

- **Hold money.** One USDC balance, reachable on Solana and Base. See [Agent wallet](/docs/wallet).
- **Get paid.** Open a US bank account with real routing and account numbers. Dollars that arrive convert to USDC in the wallet. See [Bank accounts](/docs/banking).
- **Pay for software and ads.** A reloadable card for ad platforms and subscriptions, or a fresh prepaid card for one checkout. See [Cards](/docs/cards).
- **Pay people.** Push to a debit card, send ACH to a bank, or pay Venmo and PayPal. See [Payouts](/docs/payouts).
- **Pay any x402 API.** Video generation, voice, data, inference, priced per call, with a ceiling you pin. See [Paying any x402 API](/docs/paid-apis).

## Who it is for

Open Solid is for developers building agents that operate with real money: autonomous founders, growth operators, procurement agents, and anything that needs to pay for its own tools. If your agent needs to sign up for a service, put a card on file, and keep it funded from revenue, this is the platform.

## How it is delivered

Everything is plain HTTPS, and the same surface is exposed as MCP tools. Paid actions settle over the [x402 protocol](/docs/concepts#pay-per-call): the endpoint answers `402 Payment Required` with a price, and the agent's client pays it in USDC and retries. There are no monthly plans.

> Open Solid's money movement runs on Laso Finance, a FinCEN-registered money services business, and its regulated banking and card-issuing partners. During the preview, API calls go to `https://laso.finance`.

## Next

- [Quickstart](/docs/quickstart): connect an agent and make its first call in a few minutes.
- [The founder loop](/docs/founder-loop): the recipe for an agent that pays for its own growth.
- [Room for Baby](/case-studies/room-for-baby): a live company built and run by an agent on Open Solid.

---

<!-- https://opensolid.ai/docs/quickstart -->
# Quickstart

This takes about five minutes. You need an agent that can either run a shell command or connect to an MCP server. Claude Code, Hermes, Cursor, Codex and most agent frameworks can do both.

## 1. Give your agent the skill

The fastest path is one line. Paste it into a chat with your agent:

```text
Read https://opensolid.ai/SKILL.md and follow the instructions to set up your Open Solid wallet and start building.
```

The agent reads the skill, runs a dependency-free setup helper, and creates an account. It sends you a **claim link**. Open it to sign in and take ownership of the account. The agent never opens that link itself.

### Or connect over MCP

If you would rather wire it up yourself, add the MCP server. There is no key to paste. The first connection opens your browser so you can sign in and approve the agent.

```bash
# Claude Code
claude mcp add --transport http opensolid https://laso.finance/mcp

# Hermes
hermes mcp add opensolid --url https://laso.finance/mcp --auth oauth
```

```json
{ "mcpServers": { "opensolid": { "url": "https://laso.finance/mcp" } } }
```

## 2. Fund the wallet

Ask your agent for its wallet address. It reads it from `getAgentWallet`:

```json
{
  "has_wallet": true,
  "wallet_address": "3MZVk97x9SeRxbYpc3jhzRfU2fyA3emYutnqfn9kNfYX",
  "base_wallet_address": "0x4E2b9a1C7d3F5086aB12cD34eF56a7890b1C2d3E",
  "balance_usdc": 0,
  "needs_funding": true
}
```

Send **USDC on Solana** to `wallet_address` or **USDC on Base** to `base_wallet_address`. Both land in the same balance. $25 is plenty to try every product.

> `user_id` is an account id, not a deposit address. Funds sent to it are lost.

## 3. Set a spend limit

In the dashboard, set the most any single payment can be. It defaults to $1,000 and ranges from $1 to $50,000. The agent can read the limit and cannot change it. See [Spend limits and guardrails](/docs/guardrails).

## 4. Make the first call

Tell your agent:

```text
Check my Open Solid balance, then order a $5 USA prepaid card and show me
the last four digits when it's ready.
```

Behind that sentence the agent calls `GET /get-account-balance`, pays `GET /get-card?amount=5` over x402, and polls `GET /get-card-data` until `status` is `ready`. That usually takes 7 to 10 seconds.

## Next

- [The founder loop](/docs/founder-loop): give the agent a business to run.
- [Core concepts](/docs/concepts): wallets, balances, pay-per-call and credentials.

---

<!-- https://opensolid.ai/docs/concepts -->
# Core concepts

Five terms appear throughout these docs and always mean the same thing.

## Wallet

The agent's key and its money. It signs to prove who the agent is, and it holds the USDC the agent spends. By default Open Solid custodies the wallet for you (a **managed wallet**), so the agent never handles a private key. Agents that already pay from their own x402 wallet can bring it instead.

## Balance

The USDC the wallet can spend, held on **Solana** or **Base**. It is the only money in the system. Every price in these docs is quoted in dollars and settled in USDC. The agent never has to think in tokens: cards are denominated in dollars and payouts arrive in dollars. The chain is plumbing.

There is a second number, the **account balance**, which is a ledger of deposits and purchases. Paying for something moves USDC from the wallet into the account and debits it. `GET /get-account-balance` shows both.

## Pay-per-call

How Open Solid charges. There is no plan and no subscription. The agent calls a paid endpoint, the endpoint answers `402 Payment Required` with a price, the agent pays that price in USDC, and the call goes through. That handshake is the [x402 protocol](https://www.x402.org/). With a managed wallet, `agentX402Pay` runs it for you, and over MCP the paid tools settle automatically.

Fees are **added to** the requested amount. A $100 payout with a 4.8% fee costs $104.80 and the recipient receives $100. `GET /get-pricing` lists every product's fee and limits with no auth.

## Credentials

The setup helper stores an API key and a short-lived session at `~/.laso/credentials.json`. The session's `id_token` is a bearer token for every endpoint that reads or acts on the agent's own account. It expires after about an hour, and the helper renews it for free.

```bash
curl -fsS https://laso.finance/get-account-balance \
  -H "Authorization: Bearer $(jq -r .id_token ~/.laso/credentials.json)"
```

Never put a key in a command argument, a repository, or a chat message.

## Card

A card loaded from the balance and spent at a merchant. **Reloadable cards** stay open across many charges and are topped up from the wallet. Use them for ad platforms and subscriptions. **Prepaid cards** are loaded once for an exact checkout total. A **payout** goes the other way: USDC leaves the balance and arrives as dollars on someone's debit card or in their bank account.

---

<!-- https://opensolid.ai/docs/founder-loop -->
# The founder loop

An agent that can only spend is a cost centre. The founder loop gives it a way to get paid and the rules for spending what it earns, so its budget grows only as fast as it finds profit.

```text
Wallet ──► Card ──► Ads and tools ──► Customers ──► Revenue
  ▲                                                    │
  └──────────── Bank account sweeps to wallet ◄────────┘
```

This is the same shape Laso Finance uses to run its own paid acquisition, and the shape [Room for Baby](/case-studies/room-for-baby) runs today.

## 1. Write the charter

Give the agent one objective, in writing, and keep it in a file it reads at the start of every run:

> Maximize contribution margin from genuinely new customers. Spend only from your own wallet. Never exceed the per-payment spend limit, and never split a payment to get under it.

Contribution margin is revenue retained minus direct variable costs: processing, platform fees, generation costs, anything that exists because a sale happened. Fixed costs are not deducted.

## 2. Open the accounts

The agent can do every step here except identity verification.

1. **Wallet.** Created at signup. See [Agent wallet](/docs/wallet).
2. **Bank account.** An on-ramp account with routing and account numbers, so customers, marketplaces and payment processors can pay it. See [Bank accounts](/docs/banking).
3. **Reloadable card.** One card to put on file with every ad platform and SaaS tool. See [Cards](/docs/cards).

## 3. Measure all the way to money

Most growth setups stop at `click → signup`. The loop needs to reach the cash:

```text
ad click → new customer → transaction → (revenue − direct costs) → margin
```

So the agent's first job is instrumentation: capture the click ID and UTM parameters on landing, attach them to the customer, and attribute each settled transaction back to the campaign that produced it.

## 4. Spend from the wallet, not from you

When revenue settles, the agent tops up its card for the next round of near-term spend:

```bash
curl "https://laso.finance/fund-card-balance?amount=150" \
  -H "Authorization: Bearer $LASO_ID_TOKEN"
```

Funding a card is free; the full amount lands on the card. Paid APIs (video, voice, data) are called directly from the wallet with a pinned price. See [Paying any x402 API](/docs/paid-apis).

## 5. Run daily, with memory in git

Schedule one run a day. Each run:

1. Reads the charter and a **state file**: verified facts, live experiments, failed hypotheses, lessons.
2. Pulls ad, traffic and revenue data.
3. Decides what to change and makes the changes it is allowed to.
4. Commits what it learned to the state file and sends you a short report.

When measurement breaks or a landing page can be improved, it opens a pull request like any engineer.

## 6. Settle before reinvesting

Three rules make the ledger safe to spend from:

- **Settle before spending.** Never reinvest against a click, a signup or a pending order. Only recognised revenue counts.
- **Append, never rewrite.** Refunds and chargebacks append a negative row that offsets future earnings.
- **Make payouts idempotent.** Send an `Idempotency-Key` on every POST you might retry, so a retry replays the original response instead of paying twice.

## Starter prompt

```text
You are the founder and operator of a new company. Your objective is in
CHARTER.md; your memory is in STATE.md. Use Open Solid for all money: read
https://opensolid.ai/SKILL.md to connect. Open a bank account (send me the
identity link), create a reloadable card, and propose a first $100 experiment
before spending anything. Commit what you learn to STATE.md after every run.
```

---

<!-- https://opensolid.ai/docs/earning -->
# Earning revenue

Revenue is what turns an agent from a cost into a company. Open Solid gives the agent three ways to be paid, and all three end in the same USDC balance.

## A US bank account

The most familiar rail for customers. An **on-ramp account** is a virtual US bank account with real ACH and wire details. Dollars sent to it convert to USDC and land in the agent's wallet. Put its routing and account numbers into a payment processor's payout settings, a marketplace, an affiliate programme or an invoice.

Opening one needs a one-time identity check by the human who owns the account. The agent handles everything else. See [Bank accounts](/docs/banking).

## Stablecoin payments

Customers, partners and other agents can pay USDC straight to the wallet address on Solana or Base. There is no fee and no conversion.

## Charging other agents per call

If your agent's company sells data, generation or analysis, it can put an [x402](https://www.x402.org/) price on its own HTTP endpoint. Other agents, including other Open Solid agents, pay per request in USDC to a wallet address you choose. No accounts, no keys, no invoices.

## Watching revenue arrive

- `listBankingTransactions` lists credits to the bank account.
- `GET /get-account-balance` reports the wallet and the account ledger together.
- `POST /register-webhook` sends a signed notification for deposits, so the agent doesn't have to poll.

## Attribute it

Revenue is only useful to a growth agent if it can be traced to the spend that produced it. Record the campaign, click ID or referrer alongside every customer, and book each settled transaction against it. That ledger is what the agent reinvests from. See [The founder loop](/docs/founder-loop).

---

<!-- https://opensolid.ai/docs/growth-spend -->
# Spending on growth

A company built by an agent spends money in three places: ad platforms, creative and data tools, and software subscriptions. Each has a rail that fits it.

| Spend | Typical vendors | Rail |
| --- | --- | --- |
| Ads | Pinterest, Meta, Google, X, OpenAI Ads | Reloadable card on file |
| Software | Hosting, domains, email, analytics | Reloadable card, or a prepaid card for one-off checkouts |
| Generation | Video, image, voice and music models | x402 per call where offered, otherwise the card |
| Data | Search, scraping, enrichment, market data | x402 per call |
| People | Illustrators, editors, freelancers | Debit card payout or bank payment |

## Ads

Create one reloadable card and add it as the payment method on every ad platform. Keep only near-term spend on it: when revenue settles, top it up from the wallet with `GET /fund-card-balance`, which is free. If the card runs dry, the campaign pauses rather than overspending.

## Creative tools

Room for Baby's agent makes its marketing with three paid tools: generated video, an AI voiceover and licensed music. Subscriptions go on the card. Per-generation APIs that speak x402 are paid straight from the wallet with `agentX402Pay` and a price ceiling, so a surprise price is refused rather than paid.

## Leave a note on every charge

Every external payment accepts a `note`: one sentence on why the agent paid and who it was for. It appears next to the charge in your activity feed, so a week of spending reads like a log.

```json
{ "data": { "url": "https://api.example.com/v1/generate", "maxAmountUsdc": 0.5,
  "note": "Three 8-second clips for this week's Pinterest pins" } }
```

---

<!-- https://opensolid.ai/docs/wallet -->
# Agent wallet

Every Open Solid account has a **managed agent wallet**: a wallet Open Solid custodies on the agent's behalf, with one USDC balance reachable on Solana and Base. The agent makes ordinary authenticated HTTP calls and the platform settles payments for it. It never holds a private key.

## Read the wallet

```bash
curl https://laso.finance/getAgentWallet \
  -H "Authorization: Bearer $LASO_ID_TOKEN"
```

```json
{
  "user_id": "usr_...",
  "has_wallet": true,
  "wallet_address": "3MZVk97x9SeRxbYpc3jhzRfU2fyA3emYutnqfn9kNfYX",
  "balance_usdc": 0,
  "needs_funding": true,
  "solana_balance_usdc": 0,
  "base_wallet_address": "0x4E2b9a1C7d3F5086aB12cD34eF56a7890b1C2d3E",
  "base_balance_usdc": 0
}
```

Fund it with **USDC on Solana** to `wallet_address` or **USDC on Base** to `base_wallet_address`. Both count toward one balance. A bank account can also sweep dollars into it. See [Bank accounts](/docs/banking).

## The calls

The wallet calls take a `data` object and return a `result` object.

| Call | Purpose |
| --- | --- |
| `announceAgentConnection` | Tell the human the agent connected. Call right after sign-in. |
| `getAgentWallet` | Read the addresses and balance |
| `agentX402Pay` | Pay an Open Solid route or any external x402 endpoint |
| `agentWalletTransfer` | Send USDC out to a Solana or Base address |
| `moveAgentWalletFunds` | Move USDC between the wallet's two networks |
| `getAgentSpendLimit` | Read the owner's per-payment cap |

## Wallet balance and account balance

`getAgentWallet` reports USDC held on-chain. `GET /get-account-balance` also reports the **account balance**, a ledger. Paying for something moves USDC from the wallet into the account, where it is recorded as a deposit and then debited by the purchase. After a purchase the account balance usually reads zero while `total_deposits` grows. Both numbers are correct.

## Bring your own wallet

Agents that already pay from a self-custody x402 wallet (Locus, Sponge, Ampersend and others) can call the paid routes directly with their own client and sign in with a wallet signature. Pick one approach per agent, not both.

---

<!-- https://opensolid.ai/docs/cards -->
# Cards

An agent on Open Solid can hold two kinds of card. Use a **reloadable card** for anything recurring, and a **prepaid card** for a single checkout.

## Reloadable cards

One card, many charges. Put it on file with ad platforms and SaaS tools, and top it up from the wallet as revenue lands. Reloadable cards need a one-time identity check by the account owner, done in the dashboard.

### Create one

```bash
curl -X POST https://laso.finance/create-reloadable-card \
  -H "Authorization: Bearer $LASO_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"usd_amount": 50}'
```

Creating a card is free. Cards are reusable by default; pass `"reusable": false` for a card that closes after its first approved charge. A `402` means the card balance is short, so fund it and retry. A `400` means the owner hasn't finished card setup in the dashboard.

### Top it up

```bash
curl "https://laso.finance/fund-card-balance?amount=150" \
  -H "Authorization: Bearer $LASO_ID_TOKEN"
```

No fee. The full amount lands on the card balance.

### List cards and transactions

```bash
curl "https://laso.finance/get-card-data?card_type=Reloadable" \
  -H "Authorization: Bearer $LASO_ID_TOKEN"
```

Each card returns `card_id`, `last4`, `expiry`, `balance`, `spend_limit`, `reusable` and `status` (`open`, `paused` or `closed`). `GET /list-card-transactions` returns its charges.

## Prepaid cards

A U.S. card loaded once for an exact amount, from $5 to $1,000, with no fee. It's issued in seconds. Good for a domain, a one-off purchase, or a merchant you don't want to leave a reloadable card with.

```bash
# Paid over x402: the price is the amount on the card
curl "https://laso.finance/get-card?amount=32"

# Then poll until status is "ready" (usually 7-10 seconds)
curl "https://laso.finance/get-card-data?card_id=crd_..." \
  -H "Authorization: Bearer $LASO_ID_TOKEN"
```

Prepaid cards work at U.S. merchants, and physical goods must ship to a U.S. address. For non-U.S. merchants, use the international prepaid card (`GET /order-intl-card`, $100 to $1,000, queued and usually fulfilled within 24 hours).

## Check the merchant first

Before ordering a card for a specific store, search the acceptance database. It's free:

```bash
curl "https://laso.finance/search-merchants?q=pinterest" \
  -H "Authorization: Bearer $LASO_ID_TOKEN"
```

`accepted` means it has worked there, `not_accepted` means it was declined, and `unknown` means a past attempt was unclear. A merchant that isn't listed simply hasn't been tried yet.

---

<!-- https://opensolid.ai/docs/payouts -->
# Payouts

Companies pay people. An agent on Open Solid can pay a contractor, a partner or a supplier from its own wallet. The recipient receives the full amount, and the fee is added on top.

| Rail | Route | Amount | Fee |
| --- | --- | --- | --- |
| Debit card (USD, EUR, GBP) | `GET /get-push-to-card` | $10 to ~$9,500 | 4.8%, 1.50 minimum |
| Bank account (ACH) | `GET /send-bank-payment` | $10 to $50,000 | 0.25%, $1.50 minimum |
| Venmo or PayPal | `GET /send-payment` | $5 to $1,000 | 4.9%, $1.50 minimum |

## Debit card

`/get-push-to-card` returns a `redemption_url`. The recipient opens it and enters their debit card, and the money arrives in minutes. Save regular recipients with `POST /payment-recipients` so the agent can pay them again without a new form.

```bash
curl "https://laso.finance/get-push-to-card?amount=200&currency=USD"
```

## Bank account

Register the recipient once with `createBankingRecipient` and `addBankingDestination` (both free), then pay their `destination_id`. ACH normally settles in one to two business days. Sending bank payments requires a banking profile on the paying account. See [Bank accounts](/docs/banking).

```bash
curl "https://laso.finance/send-bank-payment?amount=1200&destination_id=dest_123"
```

## Venmo and PayPal

`/send-payment` pays a Venmo or PayPal account. It requires identity verification on the paying account.

## Before you pay

- Check the fee-inclusive total against the [spend limit](/docs/guardrails). Never split a payment to get under it.
- Send an `Idempotency-Key` on any POST you might retry.
- After a timeout, check `GET /get-payment-status` before paying again.

---

<!-- https://opensolid.ai/docs/banking -->
# Bank accounts

An agent's company needs somewhere for customers to pay it. Open Solid can attach real banking rails to an account:

- **On-ramp account (dollars in).** A virtual US bank account with real ACH and wire details. Dollars sent to it convert and arrive as USDC in the agent wallet. Use it to get paid by processors, marketplaces and customers.
- **Off-ramp (dollars out).** A deposit address that pays out to a registered bank account. Use it to pay someone in dollars.

The agent can run every step itself except one.

> **Identity verification belongs to the human.** Opening a banking profile needs the account owner to verify their identity. The agent sends you the link and waits. It never fills in an identity form on anyone's behalf.

## 1. Create the banking profile

```bash
curl https://laso.finance/createBankingProfile \
  -H "Authorization: Bearer $LASO_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"data":{"userId":"usr_..."}}'
```

If the owner hasn't verified yet, the response is `{ "result": { "kycRequired": true, "kycUrl": "https://..." } }`. Give `kycUrl` to the human, wait for them to finish, then call again. Once they're verified, the same call returns a `profileId` and `applicationStatus`.

## 2. Complete the application

A few non-identity questions remain: employment status, purpose of the account and source of funds. The agent can answer them itself:

1. `getBankingApplication` lists `missingFields`.
2. `updateBankingApplicationDetails` fills them in.
3. `submitBankingApplication` submits.

If `hostedOnly` is `true`, hand `applicationUrl` to the human instead.

## 3. Open the accounts and read the details

`createBankingAccount` opens the on-ramp and off-ramp accounts. `listBankingAccounts` returns routing and account numbers for the on-ramp. Put those wherever the company gets paid.

## 4. Watch money move

- `listBankingTransactions` and `getBankingTransaction` follow deposits and payouts.
- `POST /register-webhook` sends a signed notification when a deposit lands.

## Send a bank payment

Register a recipient with `createBankingRecipient` and `addBankingDestination`, then pay with `GET /send-bank-payment` over x402. The fee is 0.25% with a $1.50 minimum, for $10 to $50,000. See [Payouts](/docs/payouts).

---

<!-- https://opensolid.ai/docs/paid-apis -->
# Paying any x402 API

More and more of the tools an agent's company needs are sold per call over [x402](https://www.x402.org/): generation models, search, scraping, enrichment, market data. A managed wallet pays any of them, not only Open Solid's own routes.

```bash
curl https://laso.finance/agentX402Pay \
  -H "Authorization: Bearer $LASO_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"data":{
        "userId":"usr_...",
        "url":"https://api.example.com/v1/generate",
        "method":"POST",
        "body":{"prompt":"8-second clip of a sunlit nursery"},
        "maxAmountUsdc":0.5,
        "note":"Clip for this week'\''s Pinterest pin"
      }}'
```

The endpoint's own response comes back wrapped:

```json
{ "result": { "status": 200, "body": { "...": "..." }, "txHash": "..." } }
```

## Pin what you agreed to pay

An external endpoint writes its own 402 challenge, and an agent can be steered toward one nobody vetted. Pin the terms on every external payment:

| Field | Effect |
| --- | --- |
| `maxAmountUsdc` | Hard cap on this one payment |
| `expectedAsset` | The token mint or contract you expect |
| `expectedNetwork` | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` or `eip155:8453` (Base) |
| `expectedPayTo` | The receiver address you expect |

If the challenge quotes a higher price, a different asset, another network or another receiver, **the payment is refused and nothing is signed**. Pins can only tighten: `maxAmountUsdc` can lower the owner's spend limit for one call but can never raise it.

## Base and Solana

Endpoints that settle in USDC on Solana or on Base mainnet are both supported, from the same balance. No ETH is needed for gas. If an endpoint offers both, pin `expectedNetwork` to choose.

## Refusal or endpoint error

- **Refusal:** no payment option survived your pins, so nothing was signed. It's safe to retry with a corrected pin.
- **Endpoint error:** the service answered non-2xx. Payment may or may not have settled; a settled one carries `txHash`. Don't blindly repeat a paid request. Check first.

---

<!-- https://opensolid.ai/docs/guardrails -->
# Spend limits and guardrails

Giving an agent a bank account is a trust decision. These controls are enforced by the platform, so they hold even when the agent is confused, wrong or being manipulated.

## Per-payment spend limit

The account owner sets the most any single payment can be, in the dashboard. It defaults to $1,000 and ranges from $1 to $50,000. It applies to every payment the wallet makes: Open Solid routes, bank payments, external x402 endpoints, and transfers out.

The agent can read it and cannot change it:

```bash
curl https://laso.finance/getAgentSpendLimit \
  -H "Authorization: Bearer $LASO_ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"data":{"userId":"usr_..."}}'
```

```json
{ "result": { "maxPerPaymentUsdc": 1000, "min": 1, "max": 50000, "default": 1000 } }
```

Compare the **fee-inclusive** total against it before paying.

> **Never split an over-limit payment.** Two $600 transfers to get under a $1,000 limit is not a workaround. It breaks what the owner asked for. Stop, and tell the human the amount and the limit so they can raise it, approve less, or pay it themselves.

## Pinned prices

Every external payment can pin price, asset, network and receiver. See [Paying any x402 API](/docs/paid-apis).

## Card balances as budgets

A reloadable card only spends what is on it. Keeping near-term spend on the card, rather than the whole treasury, caps what any ad platform can charge before the next top-up.

## Notes and the activity feed

Every payment appears in the owner's activity feed. External payments carry the agent's `note`, one sentence on why it paid and for whom.

## Idempotency

Send an `Idempotency-Key` header, a fresh UUID per intended action, on every POST you might retry. A retry with the same key returns the original response marked `Idempotency-Replayed: true` instead of acting twice.

---

<!-- https://opensolid.ai/docs/human-in-the-loop -->
# Human in the loop

An Open Solid agent runs almost everything itself. A short list of steps always belongs to a person, by design.

| Step | Why it's human | What the agent does |
| --- | --- | --- |
| Claiming a new account | The human owns the account and its funds | Sends the `claim_url` verbatim, then waits |
| Identity verification | Regulation, and it is the human's identity | Sends the `kycUrl` and checks status |
| Saving a personal card | The card belongs to the holder | Sends the save link; never opens it |
| Approving saved-card purchases | The holder approves each order on their own device | Sends the `approval_url` and waits |
| Raising the spend limit | Only the owner can set it | Reports the amount and the limit |

## Handing over a link

Links in these flows are single-use and personal. The agent must:

- send the link exactly as returned, in its next message
- never open it itself
- poll the matching status call, or wait for a webhook, instead of asking the human to report back

## Session links

`GET /get-auth-link` returns a one-time link that signs the human into the dashboard as the agent's account, so they can review activity, top up, or change limits without a password.

---

<!-- https://opensolid.ai/docs/agent-discovery -->
# SKILL.md and llms.txt

Open Solid is designed so an agent can find it, read it and start on its own, with no human clicking through a dashboard first.

| File | What it's for |
| --- | --- |
| [`/SKILL.md`](/SKILL.md) | The agent skill: connection options, setup helper, credential handling, and which reference to load for each task. Save it to your skills directory to keep Open Solid available across sessions. |
| [`/llms.txt`](/llms.txt) | An index of every guide, in the [llms.txt](https://llmstxt.org/) format. |
| [`/llms-full.txt`](/llms-full.txt) | Every guide in one document. |
| `/docs/<page>.md` | Any docs page as raw Markdown. Try [/docs/founder-loop.md](/docs/founder-loop.md). |
| [OpenAPI 3.1](https://laso.finance/openapi.json) | Every route, parameter, response and price. The MCP tools are generated from it. |

## The one-line onboarding

```text
Read https://opensolid.ai/SKILL.md and follow the instructions to set up your Open Solid wallet and start building.
```

This works in any agent that can fetch a URL. Agents with a shell run the setup helper; agents with MCP add the server; agents in a hosted chat use their harness's connector flow.

## Keeping cached copies fresh

`https://laso.finance/.well-known/docs-version.json` is a content hash of the agent docs. If it differs from the version in a cached skill, refetch. API responses also carry `X-Laso-Docs-Version`.

---

<!-- https://opensolid.ai/docs/mcp -->
# MCP server

The full API is available as an MCP server over streamable HTTP:

```text
https://laso.finance/mcp
```

The tools are generated from the live OpenAPI spec at runtime, so the tool set never drifts from the deployed API.

## Connect

There's no key to paste. The first connection opens your browser so you can sign in and approve the agent (OAuth 2.1 with PKCE).

```bash
# Claude Code
claude mcp add --transport http opensolid https://laso.finance/mcp

# Hermes
hermes mcp add opensolid --url https://laso.finance/mcp --auth oauth
```

```json
{ "mcpServers": { "opensolid": { "url": "https://laso.finance/mcp" } } }
```

Clients without OAuth can send an API key as `Authorization: Bearer <key>`.

## What you get

| Tools | Notes |
| --- | --- |
| One tool per API route: `order_card`, `push_to_card`, `send_bank_payment`, `get_account_balance` … | Names are the snake_case of each route's `operationId` |
| `get_agent_wallet`, `create_agent_wallet`, `agent_wallet_transfer`, `pay_x402_endpoint` | The managed-wallet calls, including paying any external x402 endpoint |
| `search_docs` | Searches the live agent docs |

Paid tools settle from the managed wallet automatically, so you never build a payment header. Before the first paid call, check `get_agent_wallet` and fund it.

## Events

The server supports MCP events. Subscribe to `notification.created` to be told about deposits, card issuance, refunds and balance changes, instead of polling.

## Docs-only server

A second, credential-free server covers the documentation alone at `https://docs.laso.finance/mcp`. Use it to work out which call does a job before you hold a key.

---

<!-- https://opensolid.ai/docs/api-reference -->
# API reference

Base URL during the preview: `https://laso.finance`. **x402** routes are paid per call. **Bearer** routes take the session `id_token`. The full machine-readable contract is the [OpenAPI 3.1 spec](https://laso.finance/openapi.json).

## Account

| Route | Auth | Purpose |
| --- | --- | --- |
| `POST /signup` | none | Start an account for a human to claim |
| `GET /signup-status` | none | Poll a pending claim |
| `POST /refresh` | none | Renew an `id_token` |
| `GET /get-account-balance` | Bearer | Wallet and account balances |
| `GET /get-auth-link` | Bearer | One-time dashboard sign-in link for the human |
| `GET /get-pricing` | none | Every product's fee and limits |
| `GET /get-supported-countries` | none | Where each product works |

## Wallet

| Call | Auth | Purpose |
| --- | --- | --- |
| `getAgentWallet` | Bearer | Addresses and balance |
| `agentX402Pay` | Bearer | Pay a route or any x402 URL |
| `agentWalletTransfer` | Bearer | Send USDC out |
| `moveAgentWalletFunds` | Bearer | Move USDC between Solana and Base |
| `getAgentSpendLimit` | Bearer | Read the per-payment cap |

## Cards

| Route | Auth | Purpose |
| --- | --- | --- |
| `POST /create-reloadable-card` | Bearer | New reloadable card, free |
| `GET /fund-card-balance` | Bearer | Top up from the wallet, free |
| `POST /withdraw-card-balance` | Bearer | Move card balance back |
| `GET /get-card` | x402 | USA prepaid card, $5 to $1,000, no fee |
| `GET /order-intl-card` | x402 | International prepaid card |
| `GET /get-card-data` | Bearer | Card number, status and balance |
| `GET /list-card-transactions` | Bearer | Charges on a card |
| `GET /search-merchants` | Bearer | Merchant acceptance database |

## Payouts

| Route | Auth | Purpose |
| --- | --- | --- |
| `GET /get-push-to-card` | x402 | Debit card payout, 4.8% |
| `GET /send-bank-payment` | x402 | ACH payment, 0.25% |
| `GET /send-payment` | x402 | Venmo or PayPal, 4.9% |
| `GET /get-payment-status` | Bearer | Follow a payout |
| `GET/POST/DELETE /payment-recipients` | Bearer | Saved recipients |

## Banking

| Call | Auth | Purpose |
| --- | --- | --- |
| `createBankingProfile` | Bearer | Start; returns a KYC link if needed |
| `getBankingApplication` | Bearer | Outstanding fields |
| `updateBankingApplicationDetails` | Bearer | Answer them |
| `submitBankingApplication` | Bearer | Submit |
| `createBankingAccount` / `listBankingAccounts` | Bearer | Open accounts, read routing numbers |
| `createBankingRecipient` / `addBankingDestination` | Bearer | Register who you pay |
| `listBankingTransactions` | Bearer | Deposits and payouts |

## Gift cards

| Route | Auth | Purpose |
| --- | --- | --- |
| `GET /search-gift-cards` | Bearer | Catalog |
| `GET /order-gift-card` | x402 | Instant code |

## Webhooks and withdrawals

| Route | Auth | Purpose |
| --- | --- | --- |
| `POST /register-webhook` | Bearer | Signed notifications |
| `POST /withdraw` | Bearer | Send unspent account funds home |
| `GET /get-withdrawal-status` | Bearer | Follow a withdrawal |