Skip to main content

MPP Session Payments

The Machine Payment Protocol (MPP) enables session-based micropayments on the Tempo blockchain. Unlike x402 where each API call is a separate payment, MPP opens a session with a deposit budget — your agent makes multiple requests against that budget, and the session settles when done. This guide walks through the full session lifecycle: pre-authorize, open, charge, close, and track.

Prerequisites

MPP vs x402

x402MPP
Payment modelPay-per-requestSession with deposit
Best forOccasional API callsStreaming, multi-request workflows
ChainBase (USDC), Tempo (pathUSD)Tempo (pathUSD)
SettlementImmediate per callOn session close
Unused fundsN/AReturned to agent
Use x402 when each API call is independent. Use MPP when your agent will make many requests to the same service in a session (e.g., streaming data, iterative processing, chat APIs).

How MPP Works

Pre-authorize  →  Open session (deposit)  →  Make requests  →  Close session  →  Settle
StepWhat happens
1Agent calls an MPP-enabled service, gets a 402 challenge
2Agent pre-authorizes the session deposit through Conto policies
3Agent opens a session with a deposit budget
4Agent makes requests — each consumes part of the deposit
5Session closes — unused deposit is returned
6Agent records the final settled amount in Conto

Step 1: Set Up MPP Policies

1

Create the policy

Go to PoliciesNew Policy.
FieldValue
NameMPP Session Guardrails
Policy TypeMPP_CONTROLS
2

Add rules

Rule 1: Cap session deposit
FieldValue
Rule TypeMPP_SESSION_BUDGET
OperatorLTE
Value25
ActionALLOW
No single session can have a deposit greater than $25.Rule 2: Cap per-request charge
FieldValue
Rule TypeMPP_MAX_PER_REQUEST
OperatorLTE
Value1.00
ActionALLOW
No individual request within a session can charge more than $1.00.Rule 3: Limit concurrent sessions
FieldValue
Rule TypeMPP_MAX_CONCURRENT_SESSIONS
OperatorLTE
Value3
ActionALLOW
Agent can have at most 3 open sessions at once.
3

Assign to agent

Go to the agent’s Permissions tab and assign the policy.

Step 2: Pre-Authorize the Session

When your agent needs to open an MPP session, first check policies:
curl -X POST https://conto.finance/api/sdk/mpp/pre-authorize \
  -H "Authorization: Bearer $CONTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10.00,
    "recipientAddress": "0xServiceAddress",
    "resourceUrl": "https://api.service.com/stream",
    "serviceDomain": "api.service.com",
    "intent": "session",
    "depositAmount": 10.00
  }'

If Authorized

{
  "authorized": true,
  "wallet": {
    "id": "wal_123",
    "address": "0xAgentWallet",
    "chainId": "4217",
    "availableBalance": 500.00
  },
  "reasons": ["Within MPP session budget", "Service domain allowed"]
}
Proceed to open the session with the MPP-enabled service.

If Denied

{
  "authorized": false,
  "reasons": ["MPP session deposit $10 exceeds budget cap $5"],
  "violations": [
    {
      "type": "MPP_SESSION_BUDGET",
      "limit": 5.00,
      "current": 10.00,
      "message": "Session deposit exceeds MPP budget"
    }
  ]
}
The agent should either request a smaller session or escalate.

Step 3: Open the Session

After Conto authorizes, open the MPP session with the service. The session deposit is locked on-chain:
// Using Sponge MCP or your MPP client
const session = await mppClient.openSession({
  serviceUrl: 'https://api.service.com/stream',
  maxDeposit: '10.00',
  walletAddress: auth.wallet.address,
});

console.log('Session ID:', session.sessionId);
// Session ID: mpp_session_xyz
The deposit ($10 in this case) is committed. The agent can now make requests up to this amount.

Step 4: Make Requests

Each request to the MPP service consumes part of the deposit:
// Request 1: $0.50 charge
const result1 = await mppClient.request({
  sessionId: session.sessionId,
  url: 'https://api.service.com/stream/query',
  body: { query: 'market analysis for AAPL' },
});
// Remaining deposit: $9.50

// Request 2: $0.75 charge
const result2 = await mppClient.request({
  sessionId: session.sessionId,
  url: 'https://api.service.com/stream/summarize',
  body: { text: result1.data },
});
// Remaining deposit: $8.75
The service tracks charges against the session deposit. No additional on-chain transactions happen during the session — settlement occurs on close.

Step 5: Close and Settle

When your agent is done, close the session. Unused deposit is returned:
const settlement = await mppClient.closeSession({
  sessionId: session.sessionId,
});

console.log('Total charged:', settlement.totalCharged);  // $1.25
console.log('Returned:', settlement.returned);            // $8.75
console.log('TX Hash:', settlement.transactionHash);
Session SummaryAmount
Initial deposit$10.00
Total charged$1.25
Returned to agent$8.75

Step 6: Record in Conto

Record the settled amount so Conto can track spending:
curl -X POST https://conto.finance/api/sdk/mpp/record \
  -H "Authorization: Bearer $CONTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1.25,
    "recipientAddress": "0xServiceAddress",
    "transactionHash": "0xsettlement123...",
    "resourceUrl": "https://api.service.com/stream",
    "serviceDomain": "api.service.com",
    "sessionId": "mpp_session_xyz",
    "scheme": "mpp",
    "walletId": "wal_123",
    "chainId": "4217"
  }'
Record the settled amount (1.25),notthedepositamount(1.25), not the deposit amount (10.00). The settled amount is what was actually charged. Recording the deposit would overcount spending against your budgets.

Step 7: Monitor Spending

Check MPP Budget

curl https://conto.finance/api/sdk/mpp/budget \
  -H "Authorization: Bearer $CONTO_API_KEY"

View MPP Services

curl https://conto.finance/api/sdk/mpp/services \
  -H "Authorization: Bearer $CONTO_API_KEY"

Dashboard

Go to Analytics to see MPP-specific metrics: session frequency, average session cost, per-service breakdown, and deposit utilization (how much of each deposit is actually used).

Full Integration Example

Complete TypeScript flow for an MPP session:
import { Conto } from '@conto/sdk';

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

async function runMppSession(serviceUrl: string, queries: string[]) {
  const serviceDomain = new URL(serviceUrl).hostname;

  // 1. Pre-authorize with Conto
  const auth = await conto.mpp.preAuthorize({
    amount: 10.00,
    recipientAddress: '0xServiceAddress',
    resourceUrl: serviceUrl,
    serviceDomain,
    intent: 'session',
    depositAmount: 10.00,
  });

  if (!auth.authorized) {
    throw new Error(`MPP denied: ${auth.reasons.join(', ')}`);
  }

  // 2. Open session
  const session = await mppClient.openSession({
    serviceUrl,
    maxDeposit: '10.00',
  });

  // 3. Make requests
  const results = [];
  for (const query of queries) {
    const result = await mppClient.request({
      sessionId: session.sessionId,
      url: `${serviceUrl}/query`,
      body: { query },
    });
    results.push(result.data);
  }

  // 4. Close and settle
  const settlement = await mppClient.closeSession({
    sessionId: session.sessionId,
  });

  // 5. Record in Conto
  await conto.mpp.record({
    amount: settlement.totalCharged,
    recipientAddress: '0xServiceAddress',
    transactionHash: settlement.transactionHash,
    resourceUrl: serviceUrl,
    serviceDomain,
    sessionId: session.sessionId,
    scheme: 'mpp',
    walletId: auth.wallet.id,
    chainId: auth.wallet.chainId,
  });

  return { results, cost: settlement.totalCharged };
}

MPP Policy Reference

All available MPP-specific policy rules:
Rule TypeWhat It Controls
MPP_MAX_PER_REQUESTMax charge per individual request in a session
MPP_PRICE_CEILINGHard ceiling on any MPP payment
MPP_MAX_PER_ENDPOINTBudget per specific endpoint
MPP_MAX_PER_SERVICEBudget per service domain
MPP_SESSION_BUDGETMaximum deposit per session
MPP_MAX_SESSION_DEPOSITHard cap on session deposit
MPP_MAX_CONCURRENT_SESSIONSMax open sessions at once
MPP_MAX_SESSION_DURATIONMaximum session length
MPP_ALLOWED_SERVICESAllowlist of service domains
MPP_BLOCKED_SERVICESBlocklist of service domains
See Advanced Policies for value formats and operators.

Troubleshooting

Your agent has too many open sessions. Close existing sessions before opening new ones, or increase the MPP_MAX_CONCURRENT_SESSIONS limit in your policy.
The deposit is locked on-chain when the session opens. If your wallet has 15andyoutrytoopena15 and you try to open a 20 session, it fails. Check your wallet balance and request a smaller deposit.
The service determines final settlement. If charges seem wrong, check the session details with the service provider. Conto records whatever you report — make sure you’re recording the settlement amount from the close response.
MPP is currently supported only on the Tempo blockchain (chain ID 4217). For paid APIs on Base or Ethereum, use the x402 protocol instead.

Next Steps

x402 Payments

Per-request API payments on Base and Tempo

MPP SDK Reference

Full API reference for MPP endpoints

Advanced Policies

All MPP policy rule types and value formats

Recipes

Copy-paste MPP recipes