A/ Agentonomy Developers
Integration documentationv0.1
AGENT COMMERCE / INTEGRATION GUIDE

Give your agent
the ability to transact.

Agentonomy provides MCP tools, not another agent. Your application connects its existing agents to service discovery, authorized purchases and results. Your agents choose when to use a tool; Agentonomy handles payment policy, execution, settlement and delivery within the user's authorization.

TRANSPORTStreamable HTTP
AUTHENTICATIONOAuth + PKCE S256
CURRENT ONBOARDINGRead runtime configuration
Check runtime availability and real-wallet acceptance separately. This guide describes the supported integration flow. Always read the actual issuer metadata: DCR is available only when its registration_endpoint is published. Existing pre-registered clients remain compatible. Supported networks, a healthy server, or successful OAuth do not prove a particular user's financial readiness. Base uses real funds; Amoy uses test assets. Connect only the networks permitted for your client.
Your agent platform→OAuth / MCP tools→Shared Marketplace & Core→Settlement / delivery

Keep three boundaries separate: the agent selects a tool; OAuth identifies the client and the user's permitted connection; wallet proof, Mandate and finite allowance authorize money movement. A public client_id is neither a user identity nor a payment credential. Your platform keeps its own login, tasks and product approvals; it does not build another payment ledger. Embedded applications and Agentonomy Connect retain their own contracts; their tokens and grants cannot be substituted here.

THE USER JOURNEY

From a request to a delivered result

Your platform keeps its login, Agent and conversation. Agentonomy supplies tools, not another Agent. Your team implements the connection once; each user connects their own account and controls what it may spend. Do not send users through application registration or ask them to copy tokens.

  1. Connect in the existing app

    The user opens your Agent's supported connector settings and chooses Agentonomy. Your app starts OAuth and receives the callback. Show the connected account and a clear route back to the original conversation; connection success does not mean payments are ready.

  2. Set a spending boundary

    The Agentonomy account page guides the owner through only the missing wallet, network, spending-limit and expiry steps. Any required first token approval is finite and confirmed by the owner. Reuse valid authorization. Purchases within its permitted limits do not need another wallet confirmation each time.

  3. Ask for a service

    Return to your Agent and describe the result you want, the network and the maximum price. The host checks the selected network's readiness; the Agent discovers the actual service, checks its terms and executes its fixed quote within the existing authorization. Viewing this guide or connecting an account never starts a purchase.

  4. Get the result in the same conversation

    Your app returns the original purchase reference, payment state and available delivery result. Show pending, paid but not yet delivered, and complete separately. Only verified payment, settled budget and available delivery count as completion. The purchase tool sequence below implements this handoff.

A first task the user can adapt

On [network], find [the service I need] and buy it for no more than [amount] USDC under my current authorization. Return the delivered result and purchase status. If setup is missing, show me the required next step. If a result is delayed, check the original purchase instead of buying again.

Replace the brackets with the user's actual request. This is an example, not a consent record or permission to spend; runtime authorization and the actual service terms still apply.

Interrupted? Find the existing purchase; do not buy again. Keep the original request and purchase identifiers in the host. For a lost response, query get_clink_purchase_preview with the original client_request_id and follow that record's recovery actions. For existing purchases, use list_clink_purchases and query the selected original record. If payment is complete but delivery is missing, recover that delivery only. A missing response or reconnect never authorizes a second payment. Follow the recovery contract; never ask the user to paste a token, signature or complete account link into chat.

01 / GET CONNECTED

From registration to your first purchase

  1. Discover and register once. Read the issuer metadata. If it advertises registration_endpoint, submit the public metadata below or run the self-service example. Save the returned client_id for this application/environment, not per agent. If registration is not advertised, use an existing pre-registered client; do not guess an endpoint or ID. No shared client secret is required.
  2. Connect one user. Start authorization-code OAuth with PKCE S256, a cryptographically random state and the exact resource. The issuer page waits for the original platform-admission operation when necessary; standard clients do not poll a private qualification API. The user proves their wallet and consents. Validate state and issuer on callback; exchange the code once.
  3. Complete financial setup. Open the Agentonomy account page. The user chooses a funding source, signs a bounded Mandate and performs a finite approve only if Core requires it. Reuse still-valid authorization without resetting its limits or usage.
  4. Discover, preview, execute and query. Use the tools below. Persist original identifiers before mutation. A purchase is complete only after payment verification, settlement, delivery and budget reconciliation agree.

Published endpoints

Loading the runtime's public endpoint configuration…

URLs come from the fixed runtime issuer, not the incoming Host header. Download public configuration. OAuth metadata is authoritative for discovery.

02 / SELF-SERVICE APPLICATIONS

Register an application, not every agent

This integration supports Dynamic Client Registration (DCR) at POST /oauth/register when enabled by the runtime and advertised in OAuth metadata. Existing static registration remains supported. URL-shaped Client ID Metadata Documents are not supported by this profile; use an assigned opaque client ID. Public names and callback domains are self-reported metadata, not verified branding or permission to spend.

You provide

  • An application name and exact public HTTPS callback URI(s), with no query, fragment, wildcard, localhost or private-address callback.
  • token_endpoint_auth_method=none, authorization-code grant, optional refresh grant, and response_types=["code"].
  • The required scopes; purchase uses the complete bundle below. Add offline_access only when refresh is needed.
  • Optional agentonomy_networks restricted to the runtime's published allowed networks. Optional trusted subject verification public key for a multi-user host.

Agentonomy returns

  • A durable public client_id, issuance time and normalized public registration metadata.
  • A registration status and original admission operation reference for optional diagnostics.
  • No client secret, user token, wallet credential, budget or financial authorization.
  • A normal OAuth authorization path; the issuer handles admission waiting.
POST /oauth/register
Content-Type: application/json
# Optional recovery header; save the original request and key before sending:
Idempotency-Key: <32-to-128-character-high-entropy-base64url-key>

{
  "client_name": "My MCP integration",
  "redirect_uris": ["https://your-app.example/oauth/agentonomy/callback"],
  "token_endpoint_auth_method": "none",
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "scope": "account:read marketplace:read purchases:read",
  "agentonomy_networks": ["eip155:80002"]
}

This is a read-only example. Use the complete purchase scope bundle when your application needs purchases; registration never supplies a user's Mandate. Replace placeholder callbacks with your real controlled HTTPS endpoint. Do not send tokens, codes, signatures, secrets or wallet material. The optional Idempotency-Key allows the exact original request to recover a lost registration response: same key and request return the original registration; a changed request conflicts. Without that header, standard initial registration still works, but an unknown result must not trigger a loop of new registrations or name-based adoption.

Registration is not readiness. Core first persists and verifies the exact immutable application metadata, environment, resource, scope and network boundaries; the original client epoch must then be acknowledged. The issuer's authorization page waits on this operation and resumes the same authorization transaction. An invalid ACK cannot authorize consent or issue tokens. No private polling extension is required of a standard client. If the authorization transaction expires, restart OAuth at the user's direction with the same registered application, not another registration.

Defaults per registration namespace: 1000 applications, 100 pending, 60 new registrations per hour, 10 per source peer per hour, 16 KiB request body and 5 callbacks. Global bounds apply as well as peer limits. Respect rejection and backoff; these are protection limits, not a throughput promise. Registration does not support anonymous in-place callback, scope or public-key changes. Use the supported controlled change process or a separately authorized new client; never inherit old permissions or revive a disabled registration. Existing clients can still be disabled or recovered when new registration is paused.

Self-service public configuration ↓ · Self-service example ↓. The legacy pre-registration schema and template remain for existing reviewed integrations; they are not an extra form required by DCR. Runtime metadata determines whether self-service registration is enabled in your environment.

03 / DELEGATED ACCESS

OAuth that belongs to the user

The current runtime accepts public clients with token_endpoint_auth_method=none. Use Authorization Code + PKCE S256; never use client credentials as a substitute for user consent. This profile deliberately has no shared client secret.

The example below requests the complete purchase scope bundle and requires an approved purchase client profile plus user consent. A read-only client requests only the read scopes in the table and cannot continue to preview or execute. Add offline_access only when approved and needed; it is not included implicitly.

GET /oauth/authorize
  response_type=code
  client_id=<assigned-client-id>
  redirect_uri=<exact-registered-https-callback>
  scope=account:read marketplace:read marketplace:purchase purchases:read purchases:recover
  state=<random-one-time-value-bound-to-this-login>
  code_challenge=<BASE64URL(SHA256(code_verifier))>
  code_challenge_method=S256
  resource=<exact-MCP-resource-URL>

Construct this URL with a URL encoder. Keep the verifier, state and pending transaction in your backend's protected per-user storage. On callback, require the exact expected state and issuer (iss), honor cancellation/error, and consume the pending transaction only once. Do not accept an arbitrary redirect destination or user ID supplied by the agent.

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
client_id=<assigned-client-id>
code=<returned-code>
redirect_uri=<the-same-registered-callback>
code_verifier=<original-verifier>
resource=<the-same-MCP-resource-URL>

Send the access token only to the exact MCP resource as Authorization: Bearer …. Tokens are not Core credentials and must never be forwarded to merchants, the model prompt, embedded-application routes or Agentonomy Connect routes. One tenant/user connection must never borrow another user's token.

Scopes

AccessScopesMeaning
Readaccount:read marketplace:read purchases:readRead this connection's readiness, catalog and original purchases.
PurchaseRead scopes + marketplace:purchase purchases:recoverPreview, execute and recover within independent Core spending authority.
Longer connectionoffline_accessRequest rotating refresh tokens; not a budget or payment permission.

Refresh and revoke

Access tokens expire after 300 seconds. Refresh tokens are issued only when offline_access is both approved and consented. Refresh uses the same client and resource; scopes cannot increase. Tokens rotate and reuse is detected: serialize refresh per connection and persist the replacement atomically. Refresh-token idle expiry is 7 days and absolute expiry is 30 days; reauthorization is still required after expiry or revocation.

POST /oauth/token
grant_type=refresh_token
client_id=<assigned-client-id>
refresh_token=<current-refresh-token>
resource=<exact-MCP-resource-URL>

POST /oauth/revoke
client_id=<assigned-client-id>
token=<current-token>
token_type_hint=refresh_token

Both requests are form encoded. A lost code-exchange or refresh response is not permission to replay a one-use credential blindly: mark the connection as needing reauthorization and retain purchase recovery identifiers. Revoking an access token affects that token; revoking a refresh token invalidates its token family. Neither is a full connection disconnect or a Mandate revocation. Use the issuer-owned disconnect flow for the connection and follow its original operation to completion. None of these actions refunds settled payments or cancels already accepted chain operations.

In the base profile, the same application, environment and verified wallet reuse a stable connection; different platform login accounts do not automatically create isolated payment accounts. Your trusted backend must select the user's connection and enforce task/workspace access; the model cannot supply the payer or token. If your platform promises account isolation, it must enforce trusted account-to-wallet binding before consent changes the connection, credentials or Core admission. The optional subject_context extension binds a stable opaque platform subject to the original OAuth transaction, callback, nonce and expiry. Register its Ed25519 verification public key explicitly through subject_context_public_key; the trusted host signs the context using its own protected signing facility. This is not a payment signature or a requirement for standard single-user MCP clients. Deduplicating only after token exchange is too late; optional does not mean platform-account isolation can be ignored. Never downgrade an existing stronger binding or adopt another user's connection to simplify onboarding.

04 / MONEY AUTHORITY

Connecting an agent is not authorizing spending

The OAuth account page links to the issuer-owned financial setup UI. After returning from OAuth, the user can reopen the account page to complete setup or resume original records. The account page requires a current verified Agentonomy browser session. If it returns PROOF_REQUIRED after session expiry, reconnect through OAuth as the same owner/client to restore the original stable connection, then return to the account page. This is not a request to re-sign an already-valid Mandate. Partners display a link; they do not reconstruct messages or call private Cookie/CSRF business endpoints with an OAuth token.

  1. Wallet proof: Core generates the challenge and message; the owner signs using their wallet. This does not export a private key.
  2. Source and Mandate: the owner chooses the source, chain, Marketplace scope, total/hourly/per-payment limits and expiry. Core owns used/reserved amounts; a client cannot reset them.
  3. Conditional finite approve: Core supplies the exact chain, token, spender and target amount. An attempt is claimed once before wallet submission. Unknown outcomes recover the same attempt/hash, never a replacement transaction.
  4. Readiness: wallet proof, Mandate, allowance, Hosted readiness, platform admission and available funds are checked separately. A successful OAuth callback or an active Mandate is not sufficient.

Purchases inside a valid Mandate's network, use, time and spending limits do not require another wallet confirmation for every payment. Platform OAuth scope is an additional ceiling, not a replacement for the user's Mandate. This does not prevent a partner from offering a review UI for its own product.

The same EOA may also be used in an embedded application or Agentonomy Connect, but third-party identities and grants are not copied from those paths. Physical balance and token allowance may still be shared on-chain. Core applies shared-funds and unresolved-operation protection; do not work around a conflict by creating a new connection.

Read readiness for the intended chain in networks[], including its next_action and continuation_path. Top-level payment_ready summarizes any ready network: Amoy readiness is not Base readiness. Follow the returned reason; Hosted or platform admission failures need platform handling, not another wallet signature. Unknown chain state requires a later read, not zero allowance, a new approval or a promise that execution will succeed.

One application, many users and agents

LevelIdentity and authority
Application / environmentRegister once for a client_id, not once per user or agent. This public application ID is not a shared access token.
Verified userRoute each trusted user to their own connection and owner-approved Source / Mandate, subject to the account-binding rules above. Never borrow another user's connection or authorization.
Business agentsOne or many agents may use that user's connection within the same authorization. They share its budget; each agent does not receive a fresh budget. Agentonomy's stable internal agent_id identifies the payment principal; it is not your business agent's ID.

A shared agent template may serve many users. For every call, your trusted backend must validate the logged-in user and task ownership before selecting that user's connection and credentials; never use a platform-wide token or let the model choose the payer. Approved and consented OAuth scopes still restrict the tools available: multi-agent access does not mean every tool is enabled. Independent per-business-agent sub-budgets, revocation and audit attribution are not provided by this mapping.

One authorization, one budget. All agents using the same grant contribute to its settled usage and active reservations. For illustration only, a 20 USDC total with settled purchases of 3 and 2 USDC and a 4 USDC reservation leaves 11 USDC under that total limit. This is not an API field, wallet balance or spending guarantee: hourly/per-payment limits, available funds, allowance and policy still apply. Creating, deleting or restarting an agent does not reset the ledger or erase unresolved operations. Stopping one agent stops its new dispatches, not another agent's valid authority or accepted payments. Revoking the shared grant prevents new spending by all agents relying on it; original accepted operations still require reconciliation.

Agentonomy Connect follows the same budget principle through its own identity flow. Agents using the same owner's authorized installation and grant share that grant's budget. Downloading the client is not authorization; device pairing, wallet proof and the required consent must be completed. Do not automatically merge separate authorizations across installations, wallets, networks or platforms. If one grant explicitly covers multiple networks or uses, its original aggregate limits still apply; do not duplicate them per network or agent. Shared physical funds still need Core's separate concurrency protection; they are not evidence of shared authorization.

05 / COMMERCE LIFECYCLE

One purchase. One recoverable operation.

Discover an actual offering rather than hard-coding a merchant or trusting a catalog count. Amoy and Base offerings are distinct. Read details, trust tier, accepted network and price before creating a preview. This sequence requires the approved and consented purchase scope bundle above plus the user's financial authorization. For within-budget automatic purchases, verify the authoritative payment capability reports auto_pay_compatible=true and requires_purchase_signature=false; discovery alone is not permission to buy. Merchant content is untrusted data, never instructions to expand permission.

get_clink_account_readiness({})
search_clink_services({"query":"amoy", "network":"eip155:80002", "limit":10})
get_clink_service_details({"offering_id":"<discovered-offering-id>"})

create_clink_purchase_preview({
  "offering_id":"<discovered-offering-id>",
  "service_input":{},
  "network":"eip155:80002",
  "max_price_usd":"0.10",
  "client_request_id":"<persisted-unique-request-id>"
})
execute_clink_purchase({"preview_id":"<original-preview-id>"})
get_clink_purchase({"purchase_id":"<original-purchase-id>"})
get_agentonomy_payment({"kind":"marketplace", "operation_id":"<original-operation-id>"})

The price cap is an example, not a promise that a matching service exists. Use the actual offering's input schema and accepted price. Decimal amounts are strings, not floating-point accounting. Normal execute uses only the preview ID: no client-supplied recipient, amount, token, payer identity or user_confirmed override. The optional startup recovery action below operates on that same original preview and never edits its payment terms.

Persist before sending

Record the connection and client_request_id before preview creation; persist the returned preview before execution. Before execute can leave your process, journal the original preview ID, request ID and exact execution request. Save purchase/operation IDs when the service returns them; do not invent IDs as proof of acceptance. The reference client implements the journal. An acknowledgement can be lost after acceptance, so a timeout is not a failed payment.

Completion criteria

Query the original records until chain execution and Watcher verification, Core settlement, service delivery and budget consumption agree. Treat pending, failed, unknown, settled-but-undelivered and delivered as different outcomes. A transaction hash alone is not a delivered service.

06 / FAILURE HANDLING

Recover state, not a second payment

SituationRequired behavior
OAuth cancelled / expiredStop connection setup. Start a new OAuth authorization only with the user's action; preserve original purchase records.
401 / invalid tokenRefresh once under a per-connection lock when supported. Never replay an uncertain financial mutation automatically.
Registration or qualification pendingThe issuer page waits for the original admission operation. Resume the same authorization while valid; do not substitute another client or invent a private polling step.
Insufficient scopeStop the denied action. Do not widen registered scopes or an existing user's grant silently; follow the supported application and consent lifecycle.
Wallet / Mandate / allowance not readyOpen the official account UI. It determines necessary steps; do not repeatedly request already-valid signatures.
Unknown preview responseQuery get_clink_purchase_preview by the original client_request_id. Do not create another preview with a new key.
Unknown execute responseQuery the original preview and its startup descriptor. Follow only authoritative recovery actions on that original preview; if admitted, recover its purchase and payment operation. A missing result is not evidence of non-submission.
Payment settled, delivery failedUse the authorized recover_clink_purchase_delivery path on the original purchase. Never execute a new payment to recover delivery. Independent disconnected history is read-only and cannot perform this recovery.
Approve claim/hash unknownRecover the original attempt/hash in the official account UI. No automatic resend, even after timeout or empty hash.
429 / 503 / RPC outageBack off read-only status checks. Preserve unknown states; never coerce unavailable balances or allowance to zero.

The tool schema below defines the exact structured error envelope and result schemas. Read structuredContent and isError; do not parse prose as authorization. Return only non-sensitive request/operation identifiers and error codes to support. Redact tokens, cookies, signatures, callback query strings and authorization headers.

Recover the original startup

The preview and purchase projection may contain startup.protocol=original_preview_startup_v1, a state and allowed next actions. Only when the authoritative original record allows it, your trusted host may request execute_clink_purchase({"preview_id":"<original-preview-id>","startup_action":"resume"}) or use "terminate" for safe closure. The same request/preview and fixed payment terms are retained. Atomic termination fences late execute; already-admitted or unknown legacy payments cannot be turned into “never sent.” If a recovery response is lost, query the original record again. Closing a browser, timing out or receiving an empty result never grants another send. Do not expose these trusted recovery controls as a model-chosen way to replace purchases.

Read old purchases after disconnect

Open the issuer-owned /third-party/account/connections/{connection_id}/history page with the original connection ID. It requests a new independent wallet proof and checks the stored owner against fresh Core evidence on every read. The page reads only original purchase/payment IDs, settlement and existing delivery results; it does not reactivate OAuth, grant new consent, require a new Mandate or mutate delivery. This remains distinct from Source/Mandate history. A disabled application or disconnected token must not be revived to view old purchases. Missing ownership evidence fails closed; expired or unavailable delivery remains explicitly unresolved, not a new purchase or an implied refund.

07 / REFERENCE

The complete Marketplace tool surface

This reference is rendered from the same frozen contract the runtime validates. The actual tools/list is filtered by the current token's scopes. Tools marked read-only are not payment authority. Direct transfers, deposits and prediction-market trading are outside this third-party v0.1 surface.

Download full tool + result JSON Schemas ↓

Loading tool definitions…
08 / REFERENCE IMPLEMENTATION

Run a real client, not a mocked success screen

The Python reference backend uses the official MCP Python SDK, an actual OAuth callback and a durable local journal. self_service.py registers an application through discovery and DCR, then runs the existing single-user backend. generic_adapter.py supplies reusable trusted user/task/intent dispatch for a multi-user host; it does not replace your login, credential store or agents. Run the example only in a dedicated integration environment behind your HTTPS callback proxy.

Download all examples ↓ · self_service.py ↓ · generic_adapter.py ↓ · Self-service public configuration ↓

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
# Fill ONLY public values in self-service.public-config.example.json:
# issuer, resource, client name, exact HTTPS callback, scopes and networks.
# Use separate private directories outside your checkout. Never print their contents.
.venv/bin/python self_service.py --config self-service.public-config.example.json \
  --registration-state-dir /absolute/private/registration-state \
  --state-dir /absolute/private/reference-state --port 8787
# Reverse-proxy your registered HTTPS host to 127.0.0.1:8787.
# Preserve Host, disable access logging for callback queries, and open that HTTPS host.
# For a lost DCR response, rerun the SAME configuration and directories with:
# --recover-registration
# This reuses the persisted request/key; it does not create a replacement application.

If the issuer does not advertise DCR, use a pre-registered ID with app.py and the static public configuration instead. The self-service CLI is single-user and deliberately rejects the optional multi-user subject key; a trusted host must implement that signing/context port itself. A standard MCP client can use ordinary discovery and OAuth without this example or a private admission poll.

Use dedicated directories with restricted permissions. The backend consumes its own tokens without displaying them. Registration state is separate from token storage; the latter is bound to the exact issuer, resource, client ID, callback and scope configuration. Use a separate private directory for a different configuration; do not reuse or migrate a token database by editing public config. Keep these directories, callback queries and OAuth request material out of Git, logs, analytics and AI prompts. The browser must not receive refresh tokens. Do not expose the loopback service directly to the internet.

For a multi-user platform, retain your existing login and task system. Supply authenticated user-to-connection mapping, protected storage, callback routing and task ownership; no particular vendor adapter is required. Never make an agent-supplied user identifier the authority for token selection, and use a stable business intent rather than a new request key for each model retry. Local combined tests cover two users and multiple agents sharing each user's original grant, cumulative budget and fail-closed SQLite lock conflicts. Chain/Hosted boundaries are synthetic; this is not PostgreSQL full-stack concurrency, real wallet acceptance or multiple real merchant deliveries. Complete the live criteria below before advertising the integration as ready.

09 / INTEGRATION ACCEPTANCE

What to verify before calling it integrated

  • Register an application absent from every preconfigured list; complete issuer-managed admission without an operator editing that client into configuration.
  • Exact callback, resource, scopes and networks; cancellation, expiry/refresh, disconnect and cross-user isolation.
  • Owner-completed wallet proof, Source, bounded Mandate and conditional finite approve; valid previous authorization is not reset.
  • Two users, each with multiple agents: each user's same grant shares settled usage and reservations, without copied limits or cross-user credential selection.
  • Live discovery and offering details from the same Marketplace runtime.
  • Authorized purchase: Watcher verified, Core settled, delivery content available to the original task, budget correct.
  • Lost execute response, original startup resume/termination, restart recovery and delivery retry without a second debit; disconnected owner can read history without new spending authority.

Implementation and automated tests do not replace real-wallet acceptance. Live availability comes from the target runtime, not this page. For support, retain only the public client ID, environment, contract version, network and redacted request/operation identifiers; never send a token, signature or complete account/session link. A real public support channel and retention terms must be published before general availability; no contact address or service-level guarantee is implied here.

Self-service acceptance target — still pending: an independent integrator follows these public materials, registers through the standard flow, authorizes a new user and completes a recoverable purchase without undocumented setup or a vendor-specific adapter. Local DCR/admission, shared-budget and recovery regressions are not that live result. Amoy and Base payment evidence must be recorded separately; documentation, a healthy endpoint, or OAuth success is not a completed purchase.