Skip to main content

Testing Spending Policies

This guide walks through setting up an agent from scratch and testing that spending policies enforce correctly. By the end, you’ll have an agent with policies that approve, require approval, or deny payments based on amount thresholds.

Prerequisites

What You’ll Build

Amount RangeExpected ResultPolicy
00 - 10Approved automaticallyUnder all thresholds
1010 - 15Requires approvalExceeds approval threshold
$15+DeniedExceeds max transaction amount

Step 1: Create a Wallet

1

Navigate to Wallets

Go to Wallets in the sidebar and click Create Wallet.
2

Configure the wallet

  • Name: e.g., “Test Operations Wallet”
  • Custody Type: PRIVY (recommended - enterprise-grade key management)
  • Chain Type: EVM
3

Provision the wallet

Click Provision to assign an on-chain address. Your wallet is now ready to receive funds.
4

Fund the wallet

For testnet, request pathUSD tokens from the Conto team. For mainnet, send USDC to the wallet address shown on the detail page.

Step 2: Create an Agent

1

Navigate to Agents

Go to Agents in the sidebar and click Create Agent.
2

Set agent details

  • Name: e.g., “Policy Test Agent”
  • Agent Type: Choose your framework (select CUSTOM if unsure)
3

Link a funding wallet

In Step 2 of the wizard, select the wallet you created and configure spending limits:
SettingValue
Delegation TypeLimited
Per Transaction200
Daily Limit1000
Weekly Limit5000
Monthly Limit20000
Do not set Per Transaction to 0. A zero value blocks all payments at the wallet level before policies are evaluated. This is the most common setup mistake.
4

Complete setup

Finish the wizard. Your agent is now active with a linked wallet.

Step 3: Generate an SDK Key

1

Open the agent detail page

Click on your agent to open its detail page.
2

Go to SDK Integration tab

Click the SDK Integration tab.
3

Generate a key

Click Generate SDK Key. Copy the key immediately - it is only shown once.The key looks like: conto_agent_72015200221e...Store it in an environment variable:
export CONTO_API_KEY="conto_agent_your_key_here"

Step 4: Create Policies

Create two policies to test different enforcement behaviors.

Policy A: Spend Limit

1

Create the policy

Go to Policies in the sidebar and click Create Policy.
  • Name: “Manual Spend Test”
  • Description: “Deny transactions over $15”
  • Policy Type: SPEND_LIMIT
2

Add a rule

FieldValue
Rule TypeMAX_AMOUNT
OperatorLTE
Value15
ActionALLOW
This allows transactions up to $15. Anything above is denied.

Policy B: Approval Threshold

1

Create the policy

  • Name: “Manual Approval Test”
  • Description: “Require approval for transactions over $10”
  • Policy Type: APPROVAL_THRESHOLD
2

Add a rule

FieldValue
Rule TypeREQUIRE_APPROVAL_ABOVE
OperatorGREATER_THAN
Value10
ActionREQUIRE_APPROVAL
Transactions over $10 require manual approval in the dashboard before they can execute.

Step 5: Assign Policies to the Agent

1

Open agent detail page

Navigate to your agent’s detail page.
2

Go to the Permissions tab

Click the Permissions tab.
3

Assign both policies

Assign “Manual Spend Test” and “Manual Approval Test” to the agent. All assigned policies are evaluated with AND logic — the most restrictive rule wins.

Step 6: Run Test Transactions

Use curl or any HTTP client to test the three scenarios.

Test 1: $5 Payment (Expect: APPROVED)

curl -X POST https://conto.finance/api/sdk/payments/request \
  -H "Authorization: Bearer $CONTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5,
    "recipientAddress": "0x1234567890abcdef1234567890abcdef12345678",
    "purpose": "Test - under all limits",
    "category": "software"
  }'
Expected response:
{
  "requestId": "cmm...",
  "status": "APPROVED",
  "currency": "pathUSD",
  "wallet": {
    "address": "0x788dD0...",
    "availableBalance": 999822
  }
}

Test 2: $12 Payment (Expect: REQUIRES_APPROVAL)

curl -X POST https://conto.finance/api/sdk/payments/request \
  -H "Authorization: Bearer $CONTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 12,
    "recipientAddress": "0x1234567890abcdef1234567890abcdef12345678",
    "purpose": "Test - over approval threshold"
  }'
Expected response:
{
  "requestId": "cmm...",
  "status": "REQUIRES_APPROVAL",
  "violations": [
    {
      "type": "PER_TX_LIMIT",
      "message": "[Policy: Manual Approval Test] Amount $12 exceeds approval threshold $10",
      "source": "policy_rule",
      "policyName": "Manual Approval Test"
    }
  ]
}

Test 3: $20 Payment (Expect: DENIED)

curl -X POST https://conto.finance/api/sdk/payments/request \
  -H "Authorization: Bearer $CONTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 20,
    "recipientAddress": "0x1234567890abcdef1234567890abcdef12345678",
    "purpose": "Test - over max amount"
  }'
Expected response:
{
  "requestId": "cmm...",
  "status": "DENIED",
  "violations": [
    {
      "type": "PER_TX_LIMIT",
      "message": "[Policy: Manual Approval Test] Amount $20 exceeds approval threshold $10",
      "source": "policy_rule"
    }
  ]
}

Step 7: Execute an Approved Payment

If Test 1 returned APPROVED, you can execute it on-chain:
curl -X POST https://conto.finance/api/sdk/payments/REQUEST_ID/execute \
  -H "Authorization: Bearer $CONTO_API_KEY"
Response includes the txHash and an explorer URL to verify on-chain.

Using the SDK Instead of curl

The same tests using the TypeScript SDK:
import { Conto } from '@conto/sdk';

const conto = new Conto({ apiKey: process.env.CONTO_API_KEY });

// Test 1: Should approve
const test1 = await conto.payments.request({
  amount: 5,
  recipientAddress: '0x1234567890abcdef1234567890abcdef12345678',
  purpose: 'Test - under all limits',
});
console.log('Test 1:', test1.status); // APPROVED

// Test 2: Should require approval
const test2 = await conto.payments.request({
  amount: 12,
  recipientAddress: '0x1234567890abcdef1234567890abcdef12345678',
  purpose: 'Test - over approval threshold',
});
console.log('Test 2:', test2.status); // REQUIRES_APPROVAL

// Test 3: Should deny
const test3 = await conto.payments.request({
  amount: 20,
  recipientAddress: '0x1234567890abcdef1234567890abcdef12345678',
  purpose: 'Test - over max amount',
});
console.log('Test 3:', test3.status); // DENIED

Editing Wallet Limits After Setup

If you need to change wallet spending limits after the initial setup:
  1. Go to the agent detail page
  2. Open the Overview or Wallets tab
  3. Click the pencil icon next to the wallet
  4. Update per-transaction, daily, weekly, or monthly limits
  5. Click Save Changes
If the per-transaction limit is set to $0, all payments will be denied at the wallet level with the message “Amount exceeds per-transaction limit of $0”. Update it to a value that makes sense for your use case.

How Policy Evaluation Works

When a payment request comes in, Conto evaluates in this order:
  1. Wallet-level limits — per-transaction, daily, weekly, monthly caps set on the agent-wallet link
  2. Policy rules — all assigned policies are evaluated with AND logic
  3. First DENY stops — if any rule denies, the request is immediately denied
  4. REQUIRE_APPROVAL — if any rule requires approval, the request is held for manual review
  5. All pass — if everything passes, the request is approved
Organization-level policies (assigned to the org, not directly to the agent) also apply. These stack with agent-level policies. Check the Permissions tab on the agent detail page to see all effective policies.

Troubleshooting

The wallet-level per-transaction limit is set to 0. Edit the wallet limits on the agent detail page (pencil icon) and set it to a non-zero value.
Multiple policies are evaluated with AND logic. If one policy denies while another would require approval, the denial takes priority. Check which policies are assigned in the Permissions tab.
Policies at the same priority level are all evaluated. If your approval threshold (>$10) fires before your spend limit (>$15), it’s because the approval threshold is checked first. Both are still enforced — the most restrictive outcome wins.
SDK keys are only shown once when generated. If you’ve lost it, generate a new one from the agent detail page under SDK Integration.
Org-level policies apply to all agents. If a Starter policy caps transactions at 25andyouragentpolicyallowsupto25 and your agent policy allows up to 100, the $25 cap wins. Check with your org admin.

Next Steps