Wallets
Every body gets a wallet when it is created. It is not decoration: it is the account the agent pays out of, and the address anyone can check against the chain.
curl $BASE/agents/$AGENT/wallet -H "Authorization: Bearer $INCARNA_KEY"
{
"address": "0x2f0866E100C990A0A39DD4Bbb75a1CBDf71c8732",
"chain": "base-sepolia",
"usdc": null,
"native": null
}
usdcandnativearenullwhen the balance lookup is unavailable. Null means unknown, never zero. Only one of those is worth alarming anybody about.
Provisioning happens in the background with the persona, which is why a body is
provisioning for a few seconds before it is ready. POST /agents/{id}/wallet
provisions one for a body that somehow has none; it is idempotent with an
Idempotency-Key and normally unnecessary.
Who holds the key
Not us. The private key is held by the wallet provider; Incarna asks it for a
signature over one specific payment and gets one back, or does not. So the from
address on chain is the body's own, and "the agent paid" is a fact rather than a
description of our invoice.
The address is the same on every EVM chain, which means moving a body's network later does not change an address already published on its public page.
Funding
Send USDC on the wallet's chain to the address. That is the whole procedure, and it is the owner's action from the owner's own wallet. Nothing in the API or the Playground moves money into a body — a button that appeared to do it for you would be a lie about who holds the keys.
Withdrawal is not built. Deposits work; there is no endpoint that sends funds back out. Fund a body with what it needs to work, not with a balance.
Who pays for what
One line decides it:
A body pays for what it consumes as an identity in the world. Incarna's own suppliers are paid by Incarna.
Residential presence and inboxes are bought in bulk and cannot be attributed to one body honestly, so they are ours. Inference sits on the body's side, because the body is what consumes it.
That last one is the interesting case, and the first answer we gave was wrong. Inference is only our cost if we pay it. When a body buys its own thinking, token spend never touches our books — we do not carry model price rises, and one runaway retry loop is not our bill. It is not double-charging, it is unbundling. It also deletes an entire subsystem: the payment is the meter. There is no per-org token accounting to build and no monthly reconciliation to argue about.
The reasoning and the rejected alternatives are written down in the repository, at
docs/design/wallets.md.
Ceilings
A body's spending is bounded per call and per day.
curl $BASE/agents/$AGENT/spending -H "Authorization: Bearer $INCARNA_KEY"
{
"enabled": true,
"spent_24h_usd": "0.031400",
"max_per_day_usd": "5.000000",
"max_per_call_usd": "0.250000",
"network": "eip155:84532"
}
Read the numbers from this endpoint rather than from documentation. They are set per
deployment, and enabled: false means this body is not spending at all yet.
network is the CAIP-2 id of whatever chain the body's wallet is on.
Three properties are deliberate:
- The window is a rolling 24 hours, not a calendar day. A calendar cap resets at midnight in a timezone nobody agreed on, and the useful question is always "how much in the last day".
- The daily figure counts what was authorised, not what settled. Conservative in the right direction for a limit whose job is bounding a retry loop.
- Ceilings are checked before signing, never after. The thing deciding whether to retry a call is a language model. A refusal has to cost nothing.
How a body pays without us holding an org key
POST /x402/authorize signs a payment as a named body. It is authenticated by a
short-lived grant, not by an organization API key, and that is the point: the caller
is a runtime that holds one credential and serves every customer. An org key there
would let a turn taken for one customer spend another's money the moment an agent id
was wrong. The grant names exactly one body, carries a ceiling, and expires in
minutes.
You do not call this route. It exists between our own pieces, and it is documented here because "the agent's own wallet" is a claim, and this is the mechanism that makes it true.
Two different networks
chain on a wallet and the network Incarna's own paid routes settle on are separate
settings, and they are allowed to differ.
| A body spending | Whatever chain its wallet reports. Read it; do not assume. |
| Paying Incarna over x402 | eip155:84532 — Base Sepolia — today. See x402. |
Bodies paying Incarna's own action fees out of their wallets is designed and not built. Today those fees are paid by the customer over x402, and the body's wallet is for what the body buys.
What shows publicly
A published body page shows the wallet address and its chain, and nothing else about it. That is intentional — the address is the part a stranger can verify for themselves, on a chain we do not control. See The public page.