Skip to main content

Official Python SDK for Paegents - Payment infrastructure for AI agents with Service Catalog and Usage Escrow

Project description

Paegents Python SDK

Official Python SDK for integrating Paegents agent payments.

Installation

pip install paegents

Initialize

import os
from paegents import PaegentsSDK

sdk = PaegentsSDK(
    api_url=os.getenv('PAEGENTS_API_URL', 'https://api.paegents.com'),
    agent_id=os.environ['PAEGENTS_AGENT_ID'],
    api_key=os.environ['PAEGENTS_API_KEY'],
    owner_jwt=os.getenv('OWNER_JWT'),  # optional: owner-only endpoints
)

Agent runtime auth is api_key + agent_id. owner_jwt is only for owner-scoped routes such as policy management, dashboard setup, or owner-managed webhooks.

AP2 Quick Start

from paegents import build_card_payment_method

intent = sdk.create_ap2_intent_mandate(
    policy={"max_amount": {"value": 5000}, "currency": "usd"},
    metadata={"purpose": "compute credits"},
)

cart = sdk.create_ap2_cart_mandate(
    intent_mandate_id=intent.id,
    cart={"total": 2500, "currency": "usd"},
)

payment = sdk.ap2_pay(
    intent_mandate_id=intent.id,
    cart_mandate_id=cart.id,
    payment_method=build_card_payment_method(provider='stripe'),
)

if isinstance(payment, dict) and payment.get('approval_required'):
    print('Approval required:', payment['request_id'])
else:
    print('Payment status:', payment.status)

Bilateral Escrow Usage Agreements

For bilateral escrow, the buyer signs in two phases:

  1. create the proposal with buyer_permit_signature
  2. after the server returns a real onchain_agreement_id, call get_deposit_params() and submit buyer_deposit_auth_signature via refresh_permit()

The live Base Sepolia fast-cycle contract used in current examples is:

  • 0xcA98356B65951b621C32B840F0266847C6043B45
import time
from paegents import (
    UsageAgreementRequest,
    build_bilateral_agreement_signatures,
)

permit_deadline = int(time.time()) + 600

proposal_signatures = build_bilateral_agreement_signatures(
    buyer_private_key=os.environ['BUYER_PRIVATE_KEY'],
    deposit_params={
        "agreement_id": "proposal_001",
        "chain_id": 84532,
        "usdc_address": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
        "escrow_contract_address": "0xcA98356B65951b621C32B840F0266847C6043B45",
        "service_amount_atomic": 10_000_000,
        "infra_fee_amount_atomic": 250_000,
        "gas_wallet_address": "0x13e8F75fA46D0ecC3C22b10774b8Ce2180199218",
    },
    quantity=1000,
    price_per_unit_cents=10,
    permit_deadline=permit_deadline,
    usdc_permit_nonce=0,
    infra_fee_permit_nonce=1,
)

agreement = sdk.create_usage_agreement(
    UsageAgreementRequest(
        seller_agent_id='seller-agent-123',
        service_id='svc_abc123',
        quantity=1000,
        unit='api_calls',
        price_per_unit_cents=10,

        # Required agreement authorization fields
        buyer_wallet_address='0xBuyerWallet...',
        buyer_permit_signature=proposal_signatures['buyer_permit_signature'],
        buyer_permit_deadline=proposal_signatures['buyer_permit_deadline'],
        buyer_infra_fee_permit_signature=proposal_signatures['buyer_infra_fee_permit_signature'],
        buyer_infra_fee_permit_deadline=proposal_signatures['buyer_infra_fee_permit_deadline'],

        client_proposal_id='proposal_001',
    )
)

deposit_params = sdk.get_deposit_params(agreement.agreement_id)

funding_signatures = build_bilateral_agreement_signatures(
    buyer_private_key=os.environ['BUYER_PRIVATE_KEY'],
    deposit_params=deposit_params.__dict__,
    quantity=1000,
    price_per_unit_cents=10,
    deposit_auth_deadline=int(time.time()) + 600,
)

sdk.refresh_permit(
    agreement.agreement_id,
    buyer_deposit_auth_signature=funding_signatures['buyer_deposit_auth_signature'],
    buyer_deposit_auth_deadline=funding_signatures['buyer_deposit_auth_deadline'],
)

current = sdk.get_escrow_status(agreement.agreement_id)
print(current.settlement_status, current.escrow_status)

Optional: Metered Client

client = sdk.create_metered_client(agreement.agreement_id)

result = client.post('/generate', json={
    'prompt': 'hello world',
    'max_tokens': 150,
})

usage = client.get_usage_status()
print(usage.units_used, usage.units_remaining)

Policies and Approvals

Owner JWT is required for these endpoints.

import os

owner_jwt = os.environ['OWNER_JWT']

sdk.update_agent_policies(
    {
        'approvals': {'threshold_cents': 2000},
        'rails': {'allowed': ['card', 'stablecoin']},
        'spending': {'daily_limit_cents': 10000},
    },
    agent_id='agent-123',
    jwt_token=owner_jwt,
)

pending = sdk.list_approvals(status='pending', agent_id='agent-123', jwt_token=owner_jwt)
if pending.get('approvals'):
    sdk.approve_approval(pending['approvals'][0]['id'], agent_id='agent-123', jwt_token=owner_jwt)

Webhooks

import os

owner_jwt = os.environ['OWNER_JWT']

webhook = sdk.create_webhook(
    url='https://example.com/webhooks',
    event_types=['payment.*', 'agreement.*'],
    agent_id='agent-123',
    jwt_token=owner_jwt,
)

print(webhook.get('id'))

Verify Webhook Signatures

from paegents import verify_webhook_signature

verify_webhook_signature(signature_header, raw_body, os.environ['PAEGENTS_WEBHOOK_SECRET'])

Error Handling

from paegents import ApiError, PolicyDeniedError

try:
    sdk.ap2_pay(
        intent_mandate_id='intent_123',
        cart_mandate_id='cart_123',
        payment_method=build_card_payment_method(),
    )
except PolicyDeniedError as exc:
    print('Policy denied:', exc)
except ApiError as exc:
    print('API error:', exc)
except Exception as exc:
    print('Unexpected error:', exc)

Notes

  • Prefer SDK methods over manual HTTP calls.
  • Keep API keys and JWTs in environment variables.
  • Use idempotency keys on critical write operations.
  • Bilateral escrow settlement auto-pays on finalization. Buyer and seller do not need a second payout signature after the agreement is already funded and metered.
  • The platform fee is upfront-only in the current live model. Settlement should not perform a second per-call fee pull.

Support

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

paegents-2.8.0.tar.gz (42.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

paegents-2.8.0-py3-none-any.whl (32.8 kB view details)

Uploaded Python 3

File details

Details for the file paegents-2.8.0.tar.gz.

File metadata

  • Download URL: paegents-2.8.0.tar.gz
  • Upload date:
  • Size: 42.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for paegents-2.8.0.tar.gz
Algorithm Hash digest
SHA256 e99bc04d4cfaab2178e33aa7ae3fd93ed0354f230e63a508facab89ae8c56b31
MD5 7affdc7375fba4bcc14b4f8c95fd197e
BLAKE2b-256 08c6086d81b36e1d1cf7b88fb6912a1b57c7f32621d2b28abf1d1f9ffa32ee14

See more details on using hashes here.

File details

Details for the file paegents-2.8.0-py3-none-any.whl.

File metadata

  • Download URL: paegents-2.8.0-py3-none-any.whl
  • Upload date:
  • Size: 32.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for paegents-2.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4cde18cfacb6fa6ed827ad17c8b04fa37d3846e5c9175802bb911a42328e5950
MD5 fe53db5056820d4f2f761ece0da2c214
BLAKE2b-256 b96201ded2af4a6d9178d5fc87aa412d3f4647020850b4d74fe9728b62575724

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page