codespar_wallet
The agent's governed funds. Read the balance and Pix key, read the wallet ledger, mint a Pix copia-e-cola to top the wallet up, or manage the account's Pix keys. Buy-side companion to codespar_pay.
The agent's governed funds: balance, statement, top-up; per-currency slots.
codespar_wallet8 actionsmoves no moneyalways required actionThis is the wallet the agent spends FROM. Fund it with receive, then spend with codespar_pay. It is distinct from codespar_ledger, the double-entry books.
Actions
action | What it does | Money | Needs |
|---|---|---|---|
balanceexample below | Read the spendable balance and the Pix key bound to the wallet (the default action) | no | — |
pix_keys_delete | Delete one Pix key by key_id, only with confirm=true; without it answers requires_confirmation and sends nothing | no | key_id |
pix_keys_list | List the account's Pix keys as key_id, key_type and key_tail (never the full key), with can_register and can_delete and why not | no | — |
pix_keys_register | Register one Pix key on the consumer's own account: always a random key (EVP) in test; key_type and key in live | no | — |
receipt_document | Download the comprovante of a confirmed payment by receipt_id, pdf (default) or png; answers filename, sha256 and the authenticated path, never a public URL | no | receipt_id |
receive | Mint a Pix copia-e-cola a payer settles to top the wallet up; the credit lands when the inbound webhook confirms | no | — |
statement | Read the wallet ledger: funds, holds and debits, newest first | no | — |
statement_document | Download the account statement (extrato) of from..to as an A4 PDF: opening, inflows, outflows, closing, reserves apart; at most 92 days | no | fromto |
Unknown action: refused; nothing is read or minted. Measured 2026-09-09.
Names come from the published tool document (/v1/meta-tools.json, the same list the MCP server answers to tools/list); the one-line summaries and the money class are kept in the docs repository and checked against it on every build.
Example
action: "balance", the default: the spendable funds and the Pix key bound to the wallet.
{
"name": "codespar_wallet",
"arguments": {
"action": "balance",
"consumer_id": "consumer_0000"
}
}const result = await session.execute("codespar_wallet", {
action: "balance",
consumer_id: "consumer_0000"
});result = session.execute("codespar_wallet", {
"action": "balance",
"consumer_id": "consumer_0000"
})codespar tool codespar_wallet \
-i '{
"action": "balance",
"consumer_id": "consumer_0000"
}'{
"wallet_id": "wlt_0000000000000000",
"balances": [
{
"currency": "BRL",
"balance_minor": 1000,
"available_minor": 1000,
"updated_at": "2026-09-10T12:00:00.000Z"
}
],
"funding_sources": [
{
"funding_source_id": "cfs_0000000000000000",
"rail": "pix-celcoin",
"currency": "BRL",
"status": "active",
"provider": "celcoin",
"provider_balance_minor": 999999,
"provider_error": null,
"as_of": "2026-09-10T12:00:01.000Z",
"pix_key": "a1b2c3d4-0000-4000-8000-000000000000",
"pix_key_type": "EVP",
"account_masked": "****1234"
}
]
}balances[] is the balance: one entry per currency (currency, balance_minor, available_minor, updated_at), read from the same row GET /v1/wallets/:id returns and the figure every spend is validated against. wallet_id is null and balances is empty when the consumer has no wallet in this project yet; balance never creates one.
funding_sources[] lists the project's funding sources, each with provider (celcoin), provider_balance_minor (the provider's live balance, for reconciliation only, never the figure to decide a spend on), provider_error and as_of, plus the registered Pix key (pix_key, pix_key_type, account_masked). When the provider could not be read, provider_balance_minor is null and provider_error says why: provider_unavailable (asked, no readable answer) or source_inactive (the source is not active or has no account, so the provider was not asked); balances[] is unaffected either way. A funding source no longer carries balance_minor: that name used to hold the provider figure and read as the balance, and it was removed on purpose.
When to use
- Before a spend, to know whether the wallet can cover it:
balance. - To fund the wallet:
receivemints a Pix copia-e-cola (static by default, dynamic withdynamic: true) that a payer settles; the credit lands when the inbound webhook confirms. Show the code to the payer and re-readbalanceafterwards. - To reconcile:
statementis the wallet ledger (funds, holds, debits), newest first, up tolimitentries. With a period (fromandto, ordays) it answers the statement the dashboard shows instead: one line per operation, the period's opening, inflows, outflows and closing, andnext_cursorfor the next page. - To manage the account's Pix keys from a conversation:
pix_keys_list,pix_keys_register,pix_keys_delete(see Pix keys below). None of them moves money.
Every action is scoped to one consumer; consumer_id defaults to the session user and is the same id codespar_shop and codespar_pay use.
Arguments
| Field | Type | Required | Description |
|---|---|---|---|
action | string | No | balance | statement | receive | pix_keys_list | pix_keys_register | pix_keys_delete | receipt_document | statement_document. Defaults to balance. |
consumer_id | string | No | Whose wallet; defaults to the session user |
amount | number | No | Top-up amount in minor units (centavos for BRL), for receive |
description | string | No | Charge description shown to the payer (receive) |
dynamic | boolean | No | receive: mint a dynamic copia-e-cola (location URL) instead of a static QR. Default false |
limit | number | No | statement: lines per page. With a period, 1..200, default 200; without one, the latest raw ledger entries, 1..100, default 20 |
days | number | No | statement: the last N days up to today (1..92), instead of from and to |
cursor | string | No | statement with a period: the next_cursor of the previous page |
key_id | string | For pix_keys_delete | The key to delete, as pix_keys_list answered it (pk_…); never the key value |
confirm | boolean | No | pix_keys_delete: true only after the person confirmed in the conversation; absent or false answers requires_confirmation and sends nothing |
key_type | string | No | pix_keys_register, live only: EVP | CPF | CNPJ | EMAIL | PHONE. Ignored in test (always a random key) |
key | string | No | pix_keys_register, live only: the key value for every type but EVP |
receipt_id | string | For receipt_document | The receipt (rcpt_…) of the payment, as codespar_pay or the payments list answered it |
format | string | No | receipt_document: pdf (default) or png (the same page as an image, to share) |
from | string | For statement_document; optional for statement | First day of the period, YYYY-MM-DD (America/São Paulo). With a period, statement answers one line per operation (payment, receipt, fund, fee, reversal; reserves are not lines), the period's opening, inflows, outflows and closing as the dashboard statement shows them, and next_cursor |
to | string | For statement_document; optional for statement | Last day, inclusive; not after today; at most 92 days after from |
Errors and what to do
| Error | Cause | What to do |
|---|---|---|
invalid_args | An unknown action. Nothing is read or minted. | Fix the call against the Arguments table. |
| A wallet with no funding source | The consumer has no payment account yet (in live, an account comes from codespar_kyc onboarding). | Onboard the consumer first. In the test environment the sandbox wallet ships pre-connected. |
pix_key_only_key | pix_keys_delete on the account's only key: the account keeps at least one. Nothing is sent. | Register another key first, then delete this one. |
pix_key_account_blocked, customer_account_suspended | The account's space or binding is closed, or the customer account is paused; details.reason is space_closed, binding_closed or blocked_paused. Nothing is sent. | The keys do not change until the account is resumed or bound again. pix_keys_list still answers while paused. |
no_provider_account | The consumer named has no account this project can act on. | Pass the consumer whose account it is (a test project's own account is sbx_<projectId>), or onboard the consumer. |
project_access_call_cap | A test project's call budget for the window is used up. Nothing is sent. | Wait for the window; the response names it. |
Money and mandate
Nothing on this tool moves money by itself. receive creates an instrument (the copia-e-cola) that a payer settles later; the wallet is credited only when the inbound webhook confirms the payment. Spending out of the wallet happens on codespar_pay, and every spend is mandate-gated server-side (per-currency caps, per-transaction caps, allowlists, expiry). The wallet holds the funds; the mandate holds the permission.
Related
codespar_pay: spend out of the walletcodespar_shop: buy at real stores; the checkout's Pix is paid from this walletcodespar_kyc:onboardingprovisions the account this wallet is funded from- Wallets concept: account wallets vs consumer wallets, invariants, reconciliation
cs.wallet.pixKeys: the same Pix key operations over the REST routes, in the SDK- Consumer wallet API: REST endpoints, including slot transfer
- Shopping Agent cookbook: the balance a shopper's agent spends from
Notes
The multi-slot wallet. A consumer's wallet is one wallet with per-currency slots (for example BRL and USDC) minted from a single mandate signature. There is no FX inside the wallet: each slot has its own cap and settled-spend ledger, and the payee type routes a payment to the matching slot (a URL or 0x address routes to USDC; a Pix key or copia-e-cola routes to BRL). Moving balance between slots is a REST operation, documented in the consumer wallet API.
Fund, check, spend. receive with an amount → the payer settles the copia-e-cola → the webhook credits the wallet → balance shows the funds → codespar_pay spends them under the signed mandate. The settlement's receipt is the Control Record, mandate, payment and delivery bound in one signed document:
Pix keys
The account's Pix keys, shaped for a conversation. pix_keys_list answers each key as key_id, key_type and key_tail (its last four characters), with count, can_register and can_delete; the full key never travels in a result, the person copies it on the dashboard page panel_url names (the Wallet page of the project, or the customer account's page). pix_keys_register registers one key: in the test environment always a random key (EVP), whatever key_type says; in live, key_type and key as the REST route takes them. pix_keys_delete takes a key_id from the list and confirm: without confirm: true it answers status: "requires_confirmation" with the key's tail and the consequence sentence (consequence, in Portuguese: once deleted, the key no longer points to this account), and sends nothing; the agent asks the person and calls again with confirm: true.
{
"action": "pix_keys_list",
"status": "ok",
"consumer_id": "sbx_prj_0000000000000000",
"account_masked": "••••27",
"keys": [{ "key_id": "pk_0000000000000000abcd", "key_type": "EVP", "key_tail": "e0e4" }],
"count": 1,
"can_register": true,
"register_type": "EVP",
"can_delete": false,
"delete_reason": "only_key",
"panel_url": "/dashboard/projects/prj_0000000000000000/wallets"
}The rules the dashboard panel applies hold here too. The account keeps at least one key (can_delete: false with delete_reason: "only_key", and pix_key_only_key on a delete). A customer account paused in CodeSpar still lists and refuses the writes (blocked_paused); a closed binding or a closed space refuses both (binding_closed, space_closed). status: "not_found" (not this account's key now) and status: "already_deleted" (the bank says the entry was already gone) are answers, never errors, so a repeated deletion is harmless. Every bank call for a test project's own account counts in the project's call budget, as the panel's calls do.
consumer_id defaults to the session user; in a test project whose session user has no account of its own, to the project's own account (sbx_<projectId>), the one the Wallet page shows. The same three operations exist as REST routes (/v1/consumers/:consumerId/pix-keys), in the SDK (cs.wallet.pixKeys) and in the CLI (codespar pix-keys); those answer the key value, because the caller there is the account's operator and not a model reading a tool result.
Documents
Documents on demand, generated from confirmed data and never from a new operation. receipt_document takes the receipt_id of a payment and answers the reference of its comprovante: filename, content_type, sha256 (the hash of the structured data the page was rendered from, the same value the REST route sends in X-CodeSpar-Document-Sha256) and path, the authenticated API path of the bytes (/v1/consumers/receipts/{id}/document?format=pdf|png); the chat and the dashboard turn that path into a download, and nothing in the result is a public link. format: "png" answers the same page as an image, for a conversation. Before the payment is confirmed the action answers status: "refused" with document_not_final: the receipt reflects the confirmed state and the data available, not a promise. statement_document takes from and to (YYYY-MM-DD, at most 92 days, to not after today) and answers the reference of the account statement (extrato) as an A4 PDF: totals with opening_minor, inflows_minor, outflows_minor, closing_minor and reserved_minor, where the first four close the identity opening + inflows − outflows = closing (asserted on the server against an independent reading of the ledger; a period that does not close answers statement_not_reconciled, never a wrong page) and the reserves (holds) stay apart from it. A test project's documents carry the Test mark once, in the header; a statement is always pdf.
{
"action": "receipt_document",
"status": "ok",
"document": {
"kind": "receipt",
"format": "pdf",
"filename": "comprovante-rcpt_0000000000000000.pdf",
"content_type": "application/pdf",
"sha256": "9f2c…",
"path": "/v1/consumers/receipts/rcpt_0000000000000000/document?format=pdf",
"environment": "test",
"receipt_id": "rcpt_0000000000000000",
"amount_minor": 12500,
"currency": "BRL"
}
}The same two documents exist as REST routes (GET /v1/consumers/receipts/{id}/document, GET /v1/account/statement), in the SDK (cs.receipts.document, cs.account.statement), in the CLI (codespar receipts document, codespar account statement) and, in the stdio server, as the codespar_documents tool; those answer the bytes, because the caller there is the account's operator. The renderer is the platform's own headless browser, with no network and no scripts; while it is down the routes answer 503 document_renderer_unavailable and the dashboard keeps the download links in place.
codespar_shop
Buy-side shopping. Act as the shopper, search a store's live catalog and buy, minting the store's real Pix copia-e-cola to settle from the governed wallet. VTEX guest checkout and Mercado Livre.
codespar_pay
Outbound spend. Money leaves the wallet or account your agent governs, under a signed mandate. Pix, card, boleto settlement, TED and wire, plus the reads around them (status, boleto quote, DDA, DICT keys and claims, Pix devolution).