<!--
Sitemap:
- [Paybox](/index): The non-custodial wallet for AI agents
- [Getting started](/getting-started)
- [Credentials & agents](/concepts/model): The Paybox model
- [Approvals & passkeys](/concepts/approvals)
- [Request lifecycle](/concepts/requests): From intent to result
- [MCP connector](/connect/mcp)
- [OAuth 2.1](/connect/oauth)
- [MCP tools](/reference/mcp-tools): What an agent can call
- [API & endpoints](/api-reference)
- [SDK & CLI](/sdk-cli)
-->

# Request lifecycle \[From intent to result]

Every operation an agent requests — a payment, a signature, a secret, a swap —
runs through the same lifecycle. Understanding it is the difference between an
integration that waits correctly and one that double-charges.

## The shape of every request

An agent submits an **intent** (via an [MCP tool](/reference/mcp-tools)). Paybox
evaluates it against the grant and returns one of:

::::steps

### Allow (autonomous)

The grant's approval mode is *autonomous* and the operation is within its limits.
Payments and secrets complete immediately (`success`). Wallet signs and swaps
move to `pending_signature` — they still need the [signing
window](#the-signing-window) to produce the artifact.

### Needs approval

The grant requires human approval, or the operation crosses a threshold. Paybox
returns `pending_approval` with an `approval_url`. Surface it to the user; they
approve with a passkey in the Paybox app.

### Deny

Policy rejects it outright (e.g. a chain or merchant not in the grant). Paybox
returns `denied` with a `reason`.

::::

## Statuses

| Status | Terminal? | Meaning |
| --- | --- | --- |
| `pending_approval` | no | Waiting on the user's passkey approval. |
| `pending_signature` | no | Approved or autonomous; the signing window is producing the artifact (wallet sign / swap only). |
| `pending_settlement` | no | A cross-chain swap's source tx is broadcast; the bridge is settling on the destination chain. Each poll re-checks and flips it forward. |
| `pending_confirmation` | no | Broadcast but not yet confirmed on-chain. Each poll re-checks and flips to `success` (confirmed) or `error` (dropped or failed). |
| `success` | yes | Done — `output` carries the result. For on-chain operations this means **confirmed on-chain**, never merely broadcast. |
| `denied` | yes | A policy or user decision. Carries a `reason`. |
| `error` | yes | An internal failure (not a decision). Carries a `message`. |

## The poll pattern

The one rule that matters: **submit once, then poll** — never re-issue the
original tool call to "finish" it. Re-calling starts a *new* operation (a second
charge, a second signature).

::::steps

### Submit

Call the `request_*` tool. Keep the `request_id` from the result.

### Surface approval (if pending)

If `status` is `pending_approval`, show the `approval_url`. The user opens it in
the Paybox app and approves with their passkey. Approvals are **operation-bound**
and expire after ~10 minutes — change any parameter and it's a new request, so an
approval can never be replayed against different details.

### Poll

Call [`get_request`](/reference/mcp-tools#get_request) with the `request_id`
until it reaches a terminal status. It walks `pending_approval` →
`pending_signature` → `success` on its own as the user approves and the signing
window completes.

### Use the output

On `success`, read `output` — a payment token, a `0x` signature, a broadcastable
serialized transaction, a swap transaction hash, or a secret token.

::::

## The signing window

Wallet signing never happens in agent code. When a wallet sign or swap is cleared
(`pending_signature`), the MCP host opens the **signing window** — an interactive
UI rendered in the chat (the MCP resource `ui://paybox/wallet-sign`).

* The window signs **client-side** via MoonX MPC. The private key never reaches
  Paybox, the agent, or the model.
* It posts the signed artifact back to Paybox itself. The agent's only job is to
  keep polling `get_request` until `success`.

So a basic wallet flow looks like: `request_wallet_sign` → (`pending_approval`
→ user passkey) → `pending_signature` → *window signs* → `success` with the
signature.

The same window also handles higher-level wallet operations:

* `request_swap` signs the swap transaction or gasless UserOperation envelopes;
  Paybox broadcasts after the window submits the signatures.
* `pay_x402` signs the EIP-3009 typed data; Paybox assembles the x402 payment
  header and, in gateway mode, can re-fetch the paid resource.
* When x402 auto-undelegate is enabled, delegated x402 payers use one composite
  window flow: undelegate first, verify code is gone, then sign the x402 payment.

These operations still follow the same rule: the agent submits once, surfaces
approval if needed, and polls `get_request`.

:::info
The window's own calls back to Paybox use internal tools that are hidden from the
agent. You don't implement or call them — just surface `approval_url` when asked
and poll for the result.
:::

## Audit

Every step — request, approval, denial, completion, revocation — is an audit
event tied to the user, the client, and the request. Users review the trail in
the app; see **[Approvals & passkeys](/concepts/approvals)** for the auth tiers
each action requires.
