1
Request the payment
request_wallet_payment is the default way to pay within your policy. An over-threshold payment normally returns status: pending and a request_id: a human decides, then Reinx runs the payment automatically. Keep polling the same request; do not submit a second payment after approval.amount_cents and idempotency_key are required. The input recipient is an address string. caip2 accepts a CAIP-2 id or a network name such as base; it is required for your first payment to a new EVM address. Do not guess the network: ask your human or the recipient. See network selection for history and Solana inference. asset defaults to USDC.Use submit_approval_request only when you deliberately want a human to review before anything is spent, even below your auto-approve threshold. It needs only the approval:request scope and can include justification. The same network selection, budget, and policy limits apply. Approval runs the payment automatically.2
Poll until terminal
Pass the returned The wallet-payment status vocabulary is the same on the two write tools and the poll tool. The poll tool also returns If you cannot change your client’s timeout, choose a shorter wait. A client timeout does not establish a payment outcome; retry the read with the same
request_id to get_payment_status:not_found.wait_seconds is an optional integer from 0 to 60, default 0. With a positive value, get_payment_status waits up to that many seconds and returns early when status or step changes, or immediately for a terminal result. This is an agent-side long-poll, not a payment submission. A timeout is not proof of success or failure: retry the read with the same request_id.Keep the wait shorter than your MCP client’s request deadline. The TypeScript SDK defaults to a 60-second client timeout; use at most wait_seconds: 45 with that default. Before requesting a full 60-second wait, configure the client timeout to 90 seconds, for example:request_id.settled means the payment is confirmed final on chain and normally carries on_chain_tx_hash. In the rare case that confirmation was recorded but the provider’s hash could not be captured, on_chain_tx_hash is null and the payment is still final. Do not keep polling a settled payment, including when its hash is null. Settlement is never reported before confirmation.retry_after_seconds is non-null only for pending and executing; honor it rather than polling on a fixed schedule. It is about 10 seconds for a new executing payment (under 60 seconds old), then 30 seconds; pending starts at 30 seconds and backs off to 60, 120, then 300 seconds the longer it waits (or long-poll with wait_seconds). It is null for every terminal status. expires_at is the human-decision deadline and is non-null only while pending.While executing, step can describe the recorded phase. These are phases, not a strict sequence: submitting can appear before converting, and a step may repeat. For every phase, keep polling the same request_id, honoring retry_after_seconds or using wait_seconds.step_since is the recorded entry time for that step. Either field can be null; null means no recorded detail. An executing payment has not settled, including while it is converting. resolved_at is the terminal resolution time, not the submission time.provider_tx_id is the provider’s opaque payment identifier; on_chain_tx_hash identifies the destination-chain transaction. They are different identifiers.3
Learn from denials
Use
get_denial_feedback to read recent automatic denials and human feedback before changing a request. Budget and limit denials explain the binding cap or limit. When recorded, limited_by names that gate and remaining_cents gives its remaining capacity. Historical denials without recorded context return null for both fields; funding refusals can also return null.Check capacity before requesting
check_balance and get_agent_status return nullable spendable_now_cents and limited_by. When capacity is available, these describe the enforced budget, per-payment, daily-spend, and payment-count gates. limited_by is then one of agent_budget, team_cap, project_cap, per_payment_limit, daily_spend_limit, or payment_count_limit.
If capacity cannot be read, both fields are null and the optional boolean capacity_unavailable is true; it is omitted after a successful capacity read. Wallet holdings in check_balance and status and budget in get_agent_status are read separately from capacity. Null means capacity is unknown, not zero. Retry the capacity read later; do not infer capacity from wallet holdings.
A $0 agent wallet does not block payments: wallet payments are funded just in time. The wallet balance is not the affordability gate. A payment sent for human review must also fit after requests already awaiting approval.
For a coarse treasury pre-flight, pass the intended amount_cents to check_balance:
funding_check: { amount_cents, org_can_fund, reason, checked_at }. org_can_fund is true when the treasury can currently fund that amount, false with reason: org_treasury_insufficient when it cannot, or null when the amount exceeds spending capacity (over_spending_capacity) or the check is unavailable (unavailable). This exposes no treasury balance, shortfall, or headroom number. The check is coarse, does not reserve funds, and does not net in-flight sibling commitments. Funding is re-checked at execution: ORG_TREASURY_INSUFFICIENT is still possible after a positive check. If the probe itself cannot be read, including from an older API without this route, funding_check is null; that means unknown, not an empty treasury.
Idempotency and replay
Persist a stableidempotency_key (8–200 characters) per logical payment before calling a write tool.
- After a timeout or upstream error, resend the complete request with the same key and unchanged fields.
- After
CHAIN_REQUIRED, ask for the network and retry withcaip2and the sameidempotency_key. This refusal happens before a key is consumed. Do not use a new key afterCHAIN_REQUIRED, a timeout, orUPSTREAM_ERROR. - Reusing a key for a different payment or request context returns a conflict. Keep the complete request unchanged for retries.
409 request_in_progressmeans the original request is still being processed. Wait and retry with the same key and payload; do not generate a new key.- A replay reports the payment’s current
statusand setsreplayed: true. Keep the samerequest_idfor polling. - A write response can be
pendingorexecuting; acceptance and human approval do not establish settlement.
CHAIN_REQUIRED instead of a replay: supply the original chain and keep the same key. History covers 365 days; if old history ages out and a retry resolves to a different chain, it can return 409 idempotency_key_reuse. Retry with the original chain explicitly, not a new key.
Push to your backend
Developer webhooks are today’s push option for your backend: subscribe toapproval.completed to learn when a human decision resolves; expired approvals produce no such webhook. A human approval alone does not establish settlement; the agent must continue get_payment_status with the same request_id to a final result, optionally using wait_seconds.
transaction.completed can notify your backend about successful transactions, but the payload lacks the payment’s request_id, and failure, expiry, and reversal outcomes do not have transaction webhooks today. Do not use webhooks as a complete per-payment status stream; the agent owns reconciliation, and an organization key cannot call get_payment_status. See current webhook limits. MCP resource subscriptions are a later design path and are not available today; there is no promised release date.
When the owner removes Reinx’s signing access
Auto-approve is suspended while Reinx’s signing access is removed. Payments that pass policy checks returnstatus: pending, pending_reason: owner_signature_required, and this pending_message:
This organization has removed Reinx’s signing access. Every payment now needs the owner’s approval and passkey signature, regardless of your auto-approve limit.Only the organization owner can approve and sign. Each transfer hop needs its own passkey signature. Keep polling the same
request_id; get_payment_status includes the same pending reason. Once approved, a payment waiting for the next signature remains executing, with step: awaiting_owner_signature. Hard policy and budget denials still apply.
get_spending_rules and get_agent_status report auto_approve_suspended: true and auto_approve_suspended_reason: owner_signature_required. The configured auto-approve threshold is unchanged. These additive fields are omitted when signing is not suspended.
org_signer_revoked means the owner removed Reinx’s signing access. Ask the owner to approve and sign with their passkey or re-add Reinx; retrying cannot restore signing access.
Response fields
The poll response also includes
agent_id, approved_amount_cents, approved_merchant, recipient, denial_feedback, applied_rule_types, resolved_at, and fetched_at. An output recipient is { "address": "…", "chain_caip2": "…" } when recorded, otherwise null.
Networks and assets
get_spending_rules and get_agent_status return allowed_networks, sorted alphabetically, with { name, display_name, caip2 } for each environment-allowed network. No network is marked as a default or recommendation. If the list cannot be read, it is null with allowed_networks_unavailable: true: retry the read rather than inventing a list. UNSUPPORTED_CHAIN refusals also name the allowed networks.
Production examples, in alphabetical order: Arbitrum (arbitrum, eip155:42161), Base (base, eip155:8453), Optimism (optimism, eip155:10), Polygon (polygon, eip155:137), Solana (solana, solana:mainnet). Use the returned environment list; staging can use testnets. Plain names are case-insensitive and resolve to an allowed CAIP-2 id.
History is per agent, limited to settled payments in the last 365 days. EVM address matching is case-insensitive; Solana matching is exact. Pending or failed payments and other agents’ histories do not choose your network. Both write tools use this same rule. A payment’s response and
get_payment_status include chain_caip2, chain_name, and the selection’s chain_source; recipient_history also includes chain_source_request_id and chain_source_settled_at for the payment it used. Older records can have null selection context.
A missing or ambiguous network returns HTTP 422 with a flat body, for example:
ambiguous_history response can also include previous_networks in the same network-entry shape. The refusal writes no payment event and does not consume your idempotency key. Do not guess or generate a new key: ask, then retry with the confirmed network and the same key.
get_spending_summary adds by_recipient entries with recipient, chain_caip2, chain_name, spent_cents, transaction_count, and last_settled_at. Each entry groups a wallet recipient and network within the summary window; the same address on two networks has separate entries. EVM addresses group case-insensitively and are returned lowercase; Solana case is preserved. The list contains the top 20 recipient/network pairs by spend, not a complete recipient directory. Wallet recipients also remain in by_merchant for compatibility. This summary is useful context, not the full 365-day history used for network selection.
asset defaults to USDC. Gas is sponsored; agents do not need ETH or SOL. Recipient addresses are validated for the selected chain family. An EVM address by itself does not establish which EVM network the recipient expects.
Purpose, errors, and limits
Every tool call requires apurpose of 3–500 characters explaining why the agent is acting. It is recorded for audit and scoring. Reuse a stable purpose across polls for one payment.
Invalid or revoked keys return 401. A manually paused agent cannot start a payment, but can use allowed read tools to reconcile an existing request. Archiving revokes its key.
General tool calls use the plan’s rate limits. Payment tools have tighter caps: 10/min per key and 30/min per organization. Honor the delay on a 429 response.