UCM Python SDK
Python SDK for the UCM Agent Commerce Protocol.
Installation
pip install ucm-sdk
For development:
pip install ucm-sdk[dev]
Quick Start
API Key mode (simplest)
import asyncio
from ucm import UCMClient
async def main():
# Register and get an API key
async with UCMClient('https://registry.ucm.ai', api_key='ucm_key_...') as client:
# Discover services
result = await client.discover('I need web search API')
for svc in result['services']:
print(f"{svc['name']} - {svc['price']}")
# Buy a service
receipt = await client.buy('acme/web-search')
print(receipt['access_token'])
# Check balance
balance = await client.balance()
print(balance)
asyncio.run(main())
Ed25519 mode (provider operations)
import asyncio
from ucm import UCMClient, generate_keypair
async def main():
private_key, public_key = generate_keypair()
async with UCMClient('https://registry.ucm.ai', private_key, public_key) as client:
# Publish a service (requires Ed25519)
result = await client.publish({
'acp_version': '0.1',
'service_id': 'myorg/my-api',
'name': 'My API',
'description': 'Does something useful',
'provider': {'wallet': public_key, 'name': 'My Org'},
'base_url': 'https://api.example.com',
'endpoints': [{'path': '/v1/query', 'method': 'POST'}],
'tags': ['search'],
'pricing': {
'model': 'per-call',
'price': '0.01',
'currency': 'USDT',
'unit': 'call',
},
'sla': {'uptime': '99.9%', 'latency_p95': '500ms'},
})
print(result['service_id'], result['status'])
asyncio.run(main())
Self-registration flow
import asyncio
from ucm import UCMClient
async def main():
# Start without any auth — register to get an API key
async with UCMClient('https://registry.ucm.ai', api_key='placeholder') as client:
pass # placeholder needed for constructor
# Better: use register which auto-sets the api_key
client = UCMClient('https://registry.ucm.ai', api_key='_')
reg = await client.register('my-agent', description='A helpful agent')
# client.api_key is now automatically set
print(f"Agent ID: {reg['agent_id']}")
print(f"API Key: {reg['api_key']}")
# Now use authenticated endpoints
balance = await client.balance()
print(balance)
await client.close()
asyncio.run(main())
Error handling
from ucm import UCMClient, ACPError, WalletRequiredError, BudgetError
async def safe_buy(client: UCMClient, service_id: str):
try:
return await client.buy(service_id)
except WalletRequiredError:
print("Need to bind a wallet first!")
except BudgetError as e:
print(f"Budget issue: {e.message}")
except ACPError as e:
print(f"ACP error [{e.code}]: {e.message} (HTTP {e.status_code})")
API Reference
generate_keypair() -> tuple[str, str]
Generate a new Ed25519 keypair. Returns (private_key_hex, public_key_hex).
UCMClient
Async client for interacting with the UCM registry.
Constructor
UCMClient(
registry_url: str,
private_key: str | None = None,
public_key: str | None = None,
api_key: str | None = None,
timeout: float = 30.0,
)
At least one of (private_key, public_key) or api_key must be provided.
Public endpoints (no auth)
| Method | Description |
|---|---|
discover(need, tags?, limit?) |
Search services by natural language |
service_info(service_id) |
Get service details |
verify_token(token) |
Verify an access token |
deposit_info() |
Get Solana escrow information |
get_onboarding_md() |
Fetch agent onboarding guide |
Agent management
| Method | Description |
|---|---|
register(name, description?) |
Self-register, get API key |
bind_wallet(wallet, signature) |
Bind Solana wallet |
recover(wallet, timestamp, signature) |
Recover account via wallet |
Authenticated endpoints (Ed25519 or API key)
| Method | Description |
|---|---|
buy(service_id, plan?) |
Purchase service access |
balance() |
Check budget and usage |
history(limit?) |
Get transaction history |
Ed25519-only endpoints (provider/operator)
| Method | Description |
|---|---|
publish(descriptor) |
List a new service |
update_service(service_id, update) |
Update a service |
delete_service(service_id) |
Delist a service |
authorize(agent, rules, operator?) |
Create budget authorization |
Exceptions
All ACP errors are mapped to typed exceptions:
| Exception | ACP Error Codes |
|---|---|
ACPError |
Base class for all errors |
InvalidRequestError |
INVALID_REQUEST, INVALID_DESCRIPTOR |
AuthenticationError |
INVALID_SIGNATURE, NONCE_REUSED, TIMESTAMP_EXPIRED |
BudgetError |
BUDGET_RULE_VIOLATED, INSUFFICIENT_BUDGET, AUTHORIZATION_EXPIRED, APPROVAL_REQUIRED |
NotFoundError |
SERVICE_NOT_FOUND, AGENT_NOT_FOUND |
ConflictError |
SERVICE_ALREADY_EXISTS, WALLET_ALREADY_BOUND, WALLET_IN_USE |
WalletRequiredError |
WALLET_REQUIRED |
RateLimitError |
RATE_LIMITED |
Each exception has .code, .message, .status_code, and .detail attributes.
Authentication
The SDK supports two authentication modes:
-
Ed25519 signatures — Required for provider operations (publish, authorize, delete). Headers:
X-ACP-Pubkey,X-ACP-Timestamp,X-ACP-Nonce,X-ACP-Signature. -
API Key (Bearer token) — Simpler auth for agent operations (buy, balance, history). Header:
Authorization: Bearer ucm_key_....
When both are configured, Ed25519 is preferred. API key is used as fallback.
License
MIT
Metadata
Release files for ucm-sdk 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ucm_sdk-0.2.1.tar.gz | 11.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ucm_sdk-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 20.8 kB
Release files / ucm_sdk-0.2.1.tar.gz
| Download URL | ucm_sdk-0.2.1.tar.gz |
|---|---|
| Size | 11.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a0aca6a6abb54351290b7179eb744a3c333fa69ea6ab1bf1add06946fd05eadf
|
|
BLAKE2b-256 checksum How to use checksums |
06cc76c43c94633550f2089e6bfdfccb15ec9bbbecc1ea4502e66bd60a37b84a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|
Release files / ucm_sdk-0.2.1-py3-none-any.whl
| Download URL | ucm_sdk-0.2.1-py3-none-any.whl |
|---|---|
| Size | 9.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
679435533e6a1ef2eb0c5e8ea46f599778d5b47a4c7ce24f5930b4afc4e7bf50
|
|
BLAKE2b-256 checksum How to use checksums |
8545738976983b2d24061e47a36e2293a80dc34a9f80e7c0c43286f12034b5bf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.3
|