Payments and Agent accounts
Supported funding methods, Agent wallet confirmation, and spending controls.
Supported payments
Use USDC · Base or USDG · Robinhood Chain when that asset is available for your account. RH payments support USDG only. Read GET /v1/payments/options with the current account's bearer token; availability depends on the active network configuration. Wallet payment and the compatible payment window are separate options.
Before connecting or confirming a wallet transaction, check the prominent “Adding Credits to: [user]” label and account ID. The credited Xenodia account is fixed when the order is created. Switching wallets or signing in as another user does not redirect an existing order. A funding owner's account and its Agent accounts have separate balances; select the intended account before creating a payment.
Ordinary wallet payment
Use a verified wallet linked to the signed-in account. Xenodia supports a direct ERC-20 transfer from that wallet, including a delegated signing wallet; exchange withdrawals, arbitrary contract wallets and gas sponsorship are not supported. You need the selected stablecoin and sufficient ETH on the same network to pay network fees. Connecting or proving wallet ownership does not grant permission to spend tokens.
Wallet top-ups are credited after a successful transaction is verified in the current chain, without waiting for Ethereum finalization. Pending or failed transactions do not credit. Arrival is usually within seconds but depends on the network and verification availability.
- Create an order with
POST /v1/payments/orders, providingasset_id(base_usdcorrh_usdg), integeramount_microas a decimal string, and a uniqueidempotency_key. Reuse the key only to recover the identical request. - Verify the returned recipient account, network, token,
credit_micro,amount_micro,rate_ppmand receiving address. The current rate for new orders is returned aswallet_pricing.stablecoin_per_credit_ratebyGET /v1/payments/options; each order keeps its original quote after later rate changes. Before asking the wallet to send, callPOST /v1/payments/orders/{id}/attemptswith{}and keep the returnedattempt_id. Only the successful claimant may send exactly the order's transfer from its specified wallet. A conflict means another attempt is already active; do not send. Do not reuse a receiving address copied from a historical order. - Submit the resulting hash to
POST /v1/payments/orders/{id}/transactionsastx_hash. A hash alone is not payment proof: Xenodia verifies the actual transfer and its account relationship. - Read
GET /v1/payments/orders/{id}or list your orders withGET /v1/payments/orders. Onlycompletedconfirms delivery. Submitted and confirming payments are still pending; do not pay again just because a page closes or confirmation takes time.
The order keeps its original account, wallet and amount. Credits are posted once after the required confirmation. An ambiguous, incorrect or late transfer may require review; order expiry cannot reverse a transaction already sent. Payment history is available at GET /v1/payments/history. Historical card payments use a generic card-payment label; implementation identifiers are not part of this public contract.
The send reservation covers other tabs and devices. Only an explicit wallet rejection before any transfer permits POST /v1/payments/orders/{id}/attempts/{attemptId}/reject with {}. A timeout, disconnected wallet or unknown result must not release the reservation or trigger another payment. Recover using the original transaction hash or contact support.
If an unpaid order has expired, first confirm that no transaction was sent, then call POST /v1/payments/orders/{id}/resume with an empty body or {}. This extends the same order by 30 minutes and records the extension; it never sends funds or changes the user, wallet, amount, network, token or receiving address. If you already paid, register the transaction hash and query the original order instead. An order with a recorded transaction, an active send attempt, a completed payment or a payment under review cannot be resumed. An unresolved existing order can block a new order for the same wallet and asset; contact support for a review instead of paying again.
Compatible payment window and x402 clients
The existing x402 protocol remains available for compatible clients when enabled. In the browser, obtain an account-bound context from POST /v1/payments/context before opening the payment window. Display the returned recipient and preserve the signed context when using the returned payment URL; do not construct an account ID in the URL yourself. The context fixes the credited account and requested amount.
Retain the payment_id from an accepted x402 response and query GET /v1/payments/x402/{id} with the credited account's bearer token. accepted acknowledges submission; only credited confirms that Credits have been added. Inspect the existing payment before signing another transfer. An Agent's ordinary self-funding protocol request remains separate from browser funding of the signed-in user.
Infini and AXON are permanently retired. Their old quote, checkout, order, reconciliation, redemption, and webhook routes return HTTP 410 with payment_method_retired. Do not transfer funds to historical payment addresses or attempt to redeem a legacy transaction. Historical financial records remain available in authenticated payment history and the ledger.
Bind an Agent
Open Settings → My Agents → Add Agent. For a browser wallet, select Connect & add Agent, connect the wallet your Agent uses, and confirm the message signature. Binding completes automatically.
For an external Agent wallet, select Agent on another device, enter its address, and select Get instruction. Send the complete instruction to your Agent, paste its returned signature, and select Add Agent. Names are optional. New Agents use their own Credits first, then the owner's Credits, with no spending limits by default. Never provide a private key.
The authenticated owner requests a challenge from POST /v1/me/agents/challenge with wallet_address. The response contains challenge_id, message, wallet_address, and expires_at (Unix seconds). Submit POST /v1/me/agents with wallet_address, alias, challenge_id, and the wallet's EIP-191 signature. Confirmation expires after five minutes and can be used once. It is bound to the requesting owner and the Agent address.
Binding preserves separate balances and establishes the trusted relationship. New bindings default to self_then_owner with owner funding enabled and all limits set to zero (unlimited). The signed-in owner can change the name, payment mode, or limits of an existing binding directly, without another wallet signature. Historical legacy_pending bindings support the same settings changes; this marker does not require a new signature to edit. Existing settings remain unchanged until the owner edits them.
Control owner funding
In My Agents → Edit, choose Pay with. Spending limits are optional:
self_only: use the Agent's Credits.self_then_owner: use the Agent's Credits first, then use the owner's Credits when owner funding is enabled.owner_only: use only the owner's Credits; a paused owner-funding switch rejects new requests.
A successful binding is sufficient to manage owner funding. Settings save directly using the owner's authenticated session. The API exposes these controls through GET and PUT /v1/me/agents/{address}/billing-policy, under data.
Policy fields are billing_mode, owner_funding_enabled, per_request_limit_micro, daily_limit_micro, monthly_limit_micro, and max_concurrent. One Credit is 1,000,000 microcredits. Each limit is independent: leave its field blank or enter 0 for unlimited. Positive credit limits apply only where configured; a positive concurrency limit must be between 1 and 1000. The UI sends blank limits as zero. Omitting a field in an API update preserves its previous value; send zero to remove an existing limit. Unlimited spending still requires sufficient available Credits.
Requests still in progress count toward the applicable limits. Pausing or unlinking prevents new owner-funded requests; already accepted work may still settle. A timeout does not by itself prove that an accepted task did no work or incurred no cost. Retain the request ID when contacting support about a reservation under review.
When a media task returns billing.status: review or error.review_required: true, its outcome is unknown and the reserved Credits remain held. This is not a refund: keep the task ID for review and do not resubmit the same work.
Pending charges and payment reviews
In Credits → Pending charges and payment reviews, an owner can inspect a completed request whose verified cost exceeded its original authorization. Review the displayed total and explicitly authorize that exact request. Reserved credits count toward the total; the confirmation does not raise future Agent budgets and does not execute the original request again. A recorded authorization may still await sufficient available credits or payment review. Refresh to see the current settlement state.
GET /v1/credits/settlements accepts an Owner or Agent access token. Owners see eligible funding relationships; Agents can read only their own requests, without other payers' available balances or authorization rights. The list includes verified pending charges and holds with billing_state: usage_unknown. An unknown actual amount is not zero cost: retain the request ID and contact support for review. Such a hold cannot be authorized or automatically released on timeout.
POST /v1/credits/settlements/authorize still requires an owner browser access token, the original request ID, verified actual_amount_micro and confirm: true. An independent self-paying Agent without an owner should contact support when explicit settlement authorization is required; binding an owner does not itself approve a historical charge. Changing an Agent's future limit is not authorization for a past request.
Refund and dispute notifications are recorded independently of delivery retries. A successful reversal recovers only available wallet credits, preserving other requests' reservations; a remaining amount is tracked for recovery and can restrict new usage. A later top-up first covers outstanding recovery. Open disputes and contradictory or incomplete evidence remain under review. Historical referral rewards without an order link require manual reconciliation. GET /v1/payments/reversals exposes the signed-in account's review state. These operations do not initiate an external refund or transfer.
Retrieving a completed chat after a disconnect
Keep the original Idempotency-Key and send the identical request body. When a verified JSON result or complete stream has been saved, the API returns it without a new model call or duplicate charge. Results whose stored JSON representation is at most 4 MiB are retained for seven days. Incomplete, uncertain or oversized uncached results return 409; expired saved bodies return 410 and must not trigger automatic execution with a new key. A valid result can be delivered while accounting is pending; inspect X-Billing-Status and Idempotent-Replayed. For a fresh SSE response, billing state is sent as a declared HTTP trailer, which some clients and proxies do not expose. Prices are fixed when the request is accepted.
Original payers and historical charges
GET /v1/credits/settlements?limit=50 filters pending charges before pagination. When next_cursor is present, pass it as before_id to load older charges. Unlinking an Agent preserves the original funding owner's ability to inspect and approve its historical charges. Only the Agent's original reservation and the original owner's funds can settle those charges; the detached Agent's new credits and a new owner's funds are not added.
Each charge returns funding_accounts and shortfall_micro. Add any missing credits to an original payer with supplemental_allowed: true. A combined displayed balance may include accounts that cannot fund this particular request. For self_then_owner, a request originally reserved entirely from the Agent keeps that original payer even after explicit amount confirmation; confirmation does not silently enable owner fallback.
Agent access to GET /v1/credits/ledger includes its own credit movements and original-payer reserve, commit, release, and refund entries for that Agent's requests. It does not expose the owner's unrelated topups or other Agents' activity.
Ledger pagination uses page (starting at 1) and per_page (1–100, default 20), not limit or before_id. For example, use /v1/credits/ledger?page=1&per_page=100. Read entries, total, page and per_page from the response, and continue until all pages have been read. Unknown query parameters are ignored.
Ledger entries expose a generic description and omit internal metadata and idempotency_key for every account. For entries paid by another account, balance_after is also omitted; the request-specific amount and payer remain visible. Public payment history uses card for historical card payments and wallet for wallet payments, including compatible protocol payments.
When payment_review_required is true, an original payer is under payment review: sufficient available credits and amount approval alone cannot finish the charge. The payment review must be resolved first.