Skip to main content
Try Conto without an account, from a terminal or an autonomous agent. A new sandbox starts with default limits of 5perpaymentand5 per payment and 25 per day. A payment within them returns APPROVED, and one above them returns DENIED. The sandbox setup key lets you change those limits and add policies, including merchant and category rules and a rule that holds a payment for human approval. If an organization owner has already invited your agent, register with their token instead. Sandbox signup creates a test-mode organization, one agent, one Tempo Testnet wallet, an agent SDK key, a sandbox organization API key, and a sandbox setup key, with no email verification or human approval. Settlement is simulated: no onchain transfer occurs, a test receipt is not an explorer receipt, and you do not need to fund the wallet.
The anonymous sandbox is for testing only. Returned credentials are shown once and expire after 7 days.

Discovery

Start from the agent manifest:
Read these fields: If your runtime skips manifests, use the endpoint directly:
The descriptor includes environment, simulated-settlement semantics, the default wallet limits, and a machine-readable workflow with setup, request, execute, status, human-claim, and control-configuration actions. Each control action names the credential it needs. Use those links instead of building route names from memory.

Create a sandbox

One command creates the sandbox, writes an owner-only .env.local, updates .gitignore, and adds conto.config.json and a runnable example.mjs to the current directory:
.env.local holds the agent SDK key and the sandbox API key. The CLI writes the setup key to a separate owner-only file, .conto/sandbox-setup.env, and adds .conto/ to .gitignore, so the payment runtime that loads .env.local never receives it. The JSON result reports file locations and environment-variable names (credentials.setupKeyStoredIn and credentials.setupKeyEnv) but prints no secret. If the result has no setupKeyStoredIn, your CLI version predates setup keys. Update the package, or create the sandbox with the API call below. To test from Python 3.10+, run the CLI command above (it needs Node.js 20.19+), then use the Python starter from the same directory. It calls Conto’s HTTP API and needs no Python dependencies.
  1. Download it: curl -fsS https://conto.finance/examples/conto-sandbox.py -o conto-sandbox.py
  2. Run python3 conto-sandbox.py to check setup. It prints the agent name and scopes and creates no payment.
  3. Run python3 conto-sandbox.py --execute to make one test payment. The script executes only in a CLI-created simulated sandbox. It creates one payment intent for 0.01, prints its request ID, and executes only if the policy decision is APPROVED. Success prints Status: completed and Settlement mode: test. The test receipt records the workflow without transferring funds.
  4. Each --execute run creates a new intent. After a timeout, inspect the original request with python3 conto-sandbox.py --status REQUEST_ID instead of executing again. In production, store the request ID before executing.
To create the sandbox without the CLI, call the endpoint directly:
The endpoint’s response includes: Example extraction into one owner-only file per role:
Load agent.env in the payment agent’s runtime and setup.env only where you configure controls. The commands below assume the relevant file is loaded, for example with set -a; . ./setup.env; set +a.

Credential roles

All keys are stored hashed and expire with the sandbox after 7 days. A human claim revokes the setup key. From then on, the owner changes controls in Conto. A coding assistant can apply the test configuration a person asked for with the setup key, then run the payment agent with only the SDK key. The setup key never belongs in the agent’s environment, prompt, or tool configuration.

Configure controls

The setup key works only on these routes, only for its own sandbox, and only until a human claims it. Other organization routes return 403 with code: "SANDBOX_SETUP_SCOPE", and payment routes reject it. An ID from another organization returns 404. These are the same routes, validators, audit log, and policy history that account-backed organizations use. See Policy rules for every rule type.

Change spend limits

The setup key can send spendLimitPerTx, spendLimitDaily, spendLimitWeekly, spendLimitMonthly, allowedHoursStart, allowedHoursEnd, allowedDays, and timezone. Limits accept 0 through 10000, or null for no limit on that window. Other fields, such as isActive or delegationType, return 403. Wallet limits are hard limits: an approval rule cannot override them.

Restrict merchants and categories

Create a policy and assign it to the agent:
Counterparty rules match the payment’s recipientAddress. Category rules match the category the agent sends with the request. That value is agent-supplied, not a verified merchant category. A payment that omits category is denied by any category rule.

Require human approval

Assign it the same way. A rule’s action defaults to ALLOW, so set REQUIRE_APPROVAL explicitly. Keep the per-payment limit above the approval threshold, or the limit denies the payment before review.

Change or turn off a policy

Replace a policy’s rules with PUT /api/policies/{policyId}/rules and a rules array, or turn the policy off with PATCH /api/policies/{policyId} and { "isActive": false }. A change applies to the next evaluation. Policy and rule changes are recorded in the policy’s history and the audit log. Limit and assignment changes are recorded in the audit log.

Quotas and the simulated balance

A sandbox holds up to 25 policies with up to 50 rules each. Reaching a quota returns 409 with code: "SANDBOX_POLICY_QUOTA" or "SANDBOX_RULE_QUOTA". The wallet’s $100 test balance is fixed, and the setup key cannot add to it. A payment larger than the remaining balance is denied with the reason The available balance is insufficient for this payment., not a spending-limit reason.

What the agent sees

The payment agent reads its effective controls with its own SDK key: GET /api/sdk/setup, GET /api/sdk/spending-limits, and GET /api/sdk/policies. It cannot change them.

Inspect the setup

Use the SDK key returned by sandbox signup:
This returns the authenticated agent, available wallets, spend limits, granted scopes, and versioned setup diagnostics. Call it as the runtime probe before any payment operation. In a new sandbox, diagnostics.environment.kind is anonymous_sandbox, and the SANDBOX_UNCLAIMED issue tells you a person has not claimed it yet. After a claim, the kind is claimed_sandbox. In a CLI-created project, npx @conto_finance/create-conto-agent doctor --json prints the same diagnostics.

Run a policy-checked payment

Request a small test payment. Conto evaluates it and returns the decision in status:
If the status is APPROVED, execute it:
Success is an execute response with "status": "completed" and receipt.settlementMode: "test". The receipt includes a Conto transactionId and omits txHash and the explorer URL. Status and transaction endpoints repeat the settlement mode. test never proves an onchain transfer. GET /api/sdk/transactions includes the transaction, which counts against the configured spend limits. With the default limits, a request over 5,orover5, or over 25 in a day, returns DENIED with a reason. A denied request never executes and never spends. To make retries safe, send an idempotencyKey with each purchase. The same request with the same key returns the original request. The same key with different input returns 409. Give a changed purchase, including a retry after you change a control, a new key. If an execute call ends without a response, check GET /api/sdk/payments/{requestId} before doing anything else. Do not execute again blindly.

Human review

A payment that matches a REQUIRE_APPROVAL rule returns "status": "REQUIRES_APPROVAL" and an approvalRequestId. It stays pending and does not execute. No machine credential can approve it: the review routes refuse the SDK key, the setup key, and the sandbox API key. To finish the review, a person claims the sandbox:
  1. Create a claim link with the handoff below and send verificationUrl to the person.
  2. The person signs in, claims the sandbox, switches to the sandbox organization in Conto, and opens Alerts & Approvals, then Approvals.
  3. The person approves or rejects the payment.
The agent polls GET /api/sdk/payments/{requestId} with its SDK key. It does not call execute while the payment waits.
  • Approved. Conto rechecks the payment against the current controls and records a simulated test payment. The agent sees "status": "completed" and "settlementMode": "test".
  • Rejected. The agent sees "status": "declined". Nothing is spent.
  • Controls changed while it waited. The recheck applies the current controls, so an approved payment can still end as declined.
  • No decision. The request expires after 24 hours.
An unclaimed sandbox has no reviewer, so a held payment stays pending until someone claims it.

Simulation boundary

Every payment executed in a sandbox is simulated, whatever wallet it uses. No custody provider is called, and receipts carry settlementMode: "test" with no transaction hash or explorer link. Spend counters and the test balance use the same reservation and accounting as live payments. Claiming does not change this: a sandbox organization cannot create managed wallets, set up Conto Pay, or change plans, and connected cards are not available in a sandbox. To use real funds, create a Conto organization. The optional external signer flow below is separate: your own wallet signs that transfer, and Conto never executes it.

Bring your own signer (optional)

If your agent controls a real Tempo Testnet wallet, call POST /api/sdk/payments/approve with amount, recipientAddress, your wallet as senderAddress, and chainId: 42431. An approved response returns approvalToken and confirmUrl:
Conto registers your wallet with the external-wallet defaults, not the 5and5 and 25 sandbox limits. Send the transfer from your wallet, then post the txHash and approvalToken to confirmUrl:
See the external-wallet flow for token expiry and the SDK methods.

Hand off to a person from a remote agent

Use this flow when your agent runs on a server, in CI, or on another device. It requires no localhost callback and never places the sandbox API key in a browser link. In a CLI-created project, one command creates the link and keeps the polling token in an owner-only file:
See sandbox handoff for its exit codes. The API calls below do the same without the CLI.
Send only verificationUrl to the person who will own the sandbox. Treat that URL and the returned token as temporary secrets: keep them out of logs and public messages. The URL expires in at most 15 minutes. The person signs in, verifies their email, reviews the sandbox name and ownership permission, and explicitly chooses Claim sandbox. Poll statusUrl using the handoff token (not the SDK or sandbox key). Wait at least the returned intervalSeconds between checks. Stop on claimed or on expiry. Do not repeatedly create grants.
status: "claimed" completes the handoff and revokes the setup key. It does not enable production payments, fund a wallet, change spending limits, or extend the sandbox credentials. Delete the handoff file when done. Review production readiness before using real funds.

Agent checklist

  1. Fetch /.well-known/agent.json.
  2. Read machineReadable.agentSandboxQuickstart and machineReadable.agentSandboxSignup.
  3. POST /api/agents/sandbox.
  4. Store returned keys securely. They are shown once. Give the payment runtime only credentials.sdkKey. Keep credentials.setupKey with the setup step.
  5. Optionally configure limits and policies with the setup key.
  6. Call GET /api/sdk/setup with credentials.sdkKey.
  7. POST /api/sdk/payments/request with an idempotencyKey, then POST /api/sdk/payments/{requestId}/execute for an APPROVED result.
  8. Verify status: "completed" and receipt.settlementMode: "test". Expect no hash or explorer URL in a new simulated receipt.
  9. For REQUIRES_APPROVAL, hand off to a person and poll the payment status.
  10. Before the credentials expire, POST /api/agents/sandbox/handoff, or run sandbox claim with the CLI, and send the returned verificationUrl to a person.

Next steps

Code examples

SDK, OpenAI, Anthropic, Python, and server examples

Payments API

Request, approve, execute, confirm, and inspect payment state

Custody modes

Choose managed execution or external-wallet approval flows

OpenAPI

Generate clients and inspect request and response schemas