<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: CAI</title>
    <description>The latest articles on DEV Community by CAI (@cailab).</description>
    <link>https://dev.to/cailab</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4008187%2F53ebe87b-4371-40f5-972c-f98143974a5f.png</url>
      <title>DEV Community: CAI</title>
      <link>https://dev.to/cailab</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cailab"/>
    <language>en</language>
    <item>
      <title>How to accept CAI payments on your site: card, crypto, and wallet-to-wallet settlement</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Fri, 18 Sep 2026 06:23:14 +0000</pubDate>
      <link>https://dev.to/cailab/how-to-accept-cai-payments-on-your-site-card-crypto-and-wallet-to-wallet-settlement-11ch</link>
      <guid>https://dev.to/cailab/how-to-accept-cai-payments-on-your-site-card-crypto-and-wallet-to-wallet-settlement-11ch</guid>
      <description>&lt;h1&gt;
  
  
  How to accept CAI payments on your site: card, crypto, and wallet-to-wallet settlement
&lt;/h1&gt;

&lt;p&gt;Your SaaS charges $10/month. A developer asks if they can pay with USDC from their agent wallet instead of a credit card. CAI gives you three paths to receive payments, each with one API call. Here is how they work and when to use each one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Path one: card payments via MoonPay
&lt;/h2&gt;

&lt;p&gt;For customers who want to pay with a credit card, CAI provides &lt;code&gt;POST /create-onramp-url&lt;/code&gt;. You call this with your CAI API key, and it returns a MoonPay URL. Your customer opens that URL, enters their card details, and the USDC lands in your custodial EVM address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; https://api.cai.com/functions/v1/create-onramp-url &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer *** &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
  -H "&lt;/span&gt;Content-Type: application/json&lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
  -d '{"&lt;/span&gt;amount_usd&lt;span class="s2"&gt;": 10}'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes a &lt;code&gt;url&lt;/code&gt; field. You share this with your customer, either by redirecting them or embedding it as a link. MoonPay handles the card processing, KYC, and conversion. The settlement arrives as USDC on the EVM chain you have configured.&lt;/p&gt;

&lt;p&gt;A few things to know about this path. MoonPay availability depends on the customer's region. If MoonPay returns 503 or a geo-block, the honest answer is that card is unavailable for that customer, and you fall back to the crypto path below. Third-party KYC and region limits apply, which CAI notes as a Partial live capability with third-party dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Path two: crypto deposits via deposit link
&lt;/h2&gt;

&lt;p&gt;For customers who hold USDC or USDT and want to pay directly from their wallet, CAI provides &lt;code&gt;POST /create-deposit-link&lt;/code&gt;. This returns a hosted action URL on &lt;code&gt;https://cai.com/act/&amp;lt;token&amp;gt;&lt;/code&gt; where the customer sees their deposit address and can optionally use an embedded card checkout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; https://api.cai.com/functions/v1/create-hosted-action &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer *** &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
  -H "&lt;/span&gt;Content-Type: application/json&lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
  -d '{"&lt;/span&gt;action_type&lt;span class="s2"&gt;": "&lt;/span&gt;deposit&lt;span class="s2"&gt;", "&lt;/span&gt;constraints&lt;span class="s2"&gt;": {"&lt;/span&gt;payment_method&lt;span class="s2"&gt;": "&lt;/span&gt;crypto&lt;span class="s2"&gt;", "&lt;/span&gt;crypto_asset&lt;span class="s2"&gt;": "&lt;/span&gt;USDC_ERC20&lt;span class="s2"&gt;"}}'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response contains a &lt;code&gt;url&lt;/code&gt; field. Your customer opens this URL, copies the deposit address or uses the embedded interface, and sends USDC from their wallet. Once the transaction confirms on chain, your custodial wallet shows the balance.&lt;/p&gt;

&lt;p&gt;When your customer holds a CAI wallet and you know their &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com email, the simplest path is direct wallet-to-wallet. They call &lt;code&gt;resolve-transfer-recipient&lt;/code&gt; to confirm your address, then &lt;code&gt;wallet-custodial-transfer&lt;/code&gt; to send. On your side, you verify with &lt;code&gt;POST /transfer-status&lt;/code&gt; using the transaction hash they share, or by polling &lt;code&gt;GET /wallet-activity-list&lt;/code&gt; for incoming activity.&lt;/p&gt;

&lt;p&gt;CAI supports custodial transfers on ETH, BSC, Polygon, Arbitrum, Base, and Tron, with USDT, USDC, DAI, and native tokens where each chain supports them. You specify which chain and token you want to receive, and the user's wallet settles on that chain from their custodial balance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Path three: recurring billing via payment mandates
&lt;/h2&gt;

&lt;p&gt;For subscriptions and recurring charges, the customer sets up a payment mandate. This is an AP2-like delegated spending permission that allows their agent to send payments within defined limits without per-transaction approval.&lt;/p&gt;

&lt;p&gt;The mandate specifies the merchant domain, the maximum per-payment amount, a daily cap, and an expiration. The default daily cap is $200/day. The customer can revoke the mandate at any time from the CAI dashboard.&lt;/p&gt;

&lt;p&gt;When the mandate is active, the customer's agent can call &lt;code&gt;x402_payment_execute&lt;/code&gt; to settle each billing cycle without asking the customer to confirm every time. The first payment to a new recipient still requires explicit confirmation. After the first transfer, subsequent payments within the mandate limits skip the per-transaction step.&lt;/p&gt;

&lt;p&gt;The mandate system is noted as GAP_PAYMENT_MANDATE_V1 in CAI's capability matrix, meaning it is callable and live but is a CAI-native implementation rather than a full W3C/AP2 credential. For card-based recurring billing, use the MoonPay on-ramp URL at each billing cycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  What CAI replaces in your payment stack
&lt;/h2&gt;

&lt;p&gt;CAI is not a full payment processor. It replaces specific pieces of a traditional payment integration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No merchant account application.&lt;/strong&gt; You do not need underwriting, a processing agreement, or PCI compliance validation to receive payments. You generate an API key at cai.com/app and start.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No redirect loop to Stripe or PayPal.&lt;/strong&gt; The customer completes the payment on one CAI hosted action page or directly from their wallet. No iframe, no 3D Secure redirect, no callback URL to configure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No chargeback risk.&lt;/strong&gt; Stablecoin transfers on chain are final. Once the transaction confirms, the funds are yours. There is no dispute window, no reversal, no holds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No webhook infrastructure required.&lt;/strong&gt; CAI provides polling endpoints for status. Your application checks &lt;code&gt;transfer-status&lt;/code&gt; or &lt;code&gt;payment-intent-status&lt;/code&gt; and proceeds when the settlement confirms.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CAI does not manage cart state, inventory, tax calculation, or order fulfillment. Your application handles its own order lifecycle. CAI provides the payment confirmation; you decide what to deliver.&lt;/p&gt;

&lt;h2&gt;
  
  
  The chain and token matrix
&lt;/h2&gt;

&lt;p&gt;CAI supports custodial transfers on these chains:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Chain&lt;/th&gt;
&lt;th&gt;Native&lt;/th&gt;
&lt;th&gt;USDT&lt;/th&gt;
&lt;th&gt;USDC&lt;/th&gt;
&lt;th&gt;DAI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ETH&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BSC&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Polygon&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arbitrum&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Base&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tron&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (TRC20)&lt;/td&gt;
&lt;td&gt;Yes (TRC20)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cross-chain payments between these chains use CAI's bridge endpoint &lt;code&gt;POST /bridge-quote&lt;/code&gt; followed by &lt;code&gt;POST /bridge-execute&lt;/code&gt; via LiFi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;To accept CAI payments on your site:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://cai.com/app" rel="noopener noreferrer"&gt;https://cai.com/app&lt;/a&gt; and create an API key with at least the &lt;code&gt;pay&lt;/code&gt; scope.&lt;/li&gt;
&lt;li&gt;For card payments: call &lt;code&gt;POST /create-onramp-url&lt;/code&gt; with your desired amount, share or redirect your customer to the returned URL.&lt;/li&gt;
&lt;li&gt;For crypto payments: call &lt;code&gt;POST /create-hosted-action&lt;/code&gt; with &lt;code&gt;action_type: "deposit"&lt;/code&gt;, guide your customer to the returned URL.&lt;/li&gt;
&lt;li&gt;For recurring billing: ask the customer to create a payment mandate from their CAI dashboard, then settle each billing cycle via x402.&lt;/li&gt;
&lt;li&gt;Poll &lt;code&gt;POST /transfer-status&lt;/code&gt; or &lt;code&gt;GET /payment-intent-status&lt;/code&gt; to confirm settlement before delivering your product.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No merchant account, no PCI scope, no chargeback risk, no redirect chain. One API call to start receiving USDC in your custodial wallet.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
      <category>payments</category>
    </item>
    <item>
      <title>What's free at CAI, what isn't, and why the email is the marketing surface</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Wed, 16 Sep 2026 06:35:38 +0000</pubDate>
      <link>https://dev.to/cailab/whats-free-at-cai-what-isnt-and-why-the-email-is-the-marketing-surface-317</link>
      <guid>https://dev.to/cailab/whats-free-at-cai-what-isnt-and-why-the-email-is-the-marketing-surface-317</guid>
      <description>&lt;h1&gt;
  
  
  What's free at CAI, what isn't, and why the email is the marketing surface
&lt;/h1&gt;

&lt;p&gt;What's free at CAI, and what isn't. This post is grounded in &lt;code&gt;cai.com/main&lt;/code&gt; and &lt;code&gt;cai.com/app&lt;/code&gt;, the actual pricing surfaces on the website. We claim only what &lt;code&gt;cai.com&lt;/code&gt; says.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's free
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;@cai.com&lt;/code&gt; email is free.&lt;/strong&gt; No card required at signup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The wallet is built in.&lt;/strong&gt; No separate fee for opening, holding, or transferring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The user vault is included.&lt;/strong&gt; No extra charge for storing site credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The API key is included.&lt;/strong&gt; The free-tier key has the read scopes and limited write scopes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What may require verification
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;pay&lt;/code&gt; scope&lt;/strong&gt; for transfers (&lt;code&gt;wallet_custodial_transfer&lt;/code&gt;) and bridge operations (&lt;code&gt;token_bridge_execute&lt;/code&gt;). May require verification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;full&lt;/code&gt; scope&lt;/strong&gt; for every endpoint. May require verification.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verification is documented in the account dashboard. You can confirm the specific requirements on &lt;code&gt;cai.com/main&lt;/code&gt; or the &lt;code&gt;/app&lt;/code&gt; page.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's not in scope for this post
&lt;/h2&gt;

&lt;p&gt;This post does not list specific paid tiers or prices for any future feature. If &lt;code&gt;cai.com&lt;/code&gt; adds a paid tier after this is published, this post will be updated to reflect the new surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the email is free
&lt;/h2&gt;

&lt;p&gt;The email is the marketing surface. A free &lt;code&gt;@cai.com&lt;/code&gt; email gets humans in the door; the wallet, the vault, and the API key make them stay. The pricing model is in service of that, not the other way around.&lt;/p&gt;

&lt;p&gt;If the email cost $5/month, fewer humans would sign up. Fewer humans would discover the wallet, the vault, and the API key. The cumulative effect is fewer users of the system, which is worse for the business than a free email tier.&lt;/p&gt;

&lt;p&gt;The wallet, the vault, and the API key are part of the same account. There is no separate wallet tier or vault tier. The surfaces are bundled with the email. The API key's read scopes are free; the write scopes that move money (&lt;code&gt;pay&lt;/code&gt;, &lt;code&gt;full&lt;/code&gt;) may require verification, but the verification is about your identity and use case, not about a paid tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to check the current pricing
&lt;/h2&gt;

&lt;p&gt;The current pricing is on &lt;code&gt;cai.com/main&lt;/code&gt; and on the signup page at &lt;code&gt;cai.com/app&lt;/code&gt;. If the pricing changes after this post is published, the canonical source will always be &lt;code&gt;cai.com/main&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety limits you need to know
&lt;/h2&gt;

&lt;p&gt;Every CAI account has a &lt;strong&gt;$200/day auto-limit&lt;/strong&gt; on custodial transfers. You cannot spend more than $200 per day without an explicit user action to raise the limit. This is the default, not something you need to configure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New-recipient confirmation&lt;/strong&gt; applies to every transfer: the first time you send to a new address, the hosted-action confirmation page shows you the recipient, the amount, and the chain before you tap. No previous confirmation applies to a new address.&lt;/p&gt;




&lt;h2&gt;
  
  
  If you signed up and the API key dashboard didn't show the scope you expected
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Comment below with:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What you ran&lt;/strong&gt; — the install command, the request, the MCP host config. Copy the actual command or request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you expected&lt;/strong&gt; — one sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you got&lt;/strong&gt; — the error message, the empty response, the unexpected behavior. Paste it verbatim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your environment&lt;/strong&gt; — OS, Node version, the MCP host (OpenClaw / Hermes / Codex / Cursor / other), the CAI account tier if relevant.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every comment on this article gets read. Bug reports will be replied to within 24 hours. Friction points shape what we document next.&lt;/p&gt;

&lt;p&gt;Documentation: &lt;code&gt;cai.com/skill.md&lt;/code&gt; · &lt;code&gt;cai.com/developers.html&lt;/code&gt; · &lt;code&gt;cai.com/app&lt;/code&gt; to sign up.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>From signup to automated payments: wiring an AI agent wallet with CAI in 30 minutes</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Fri, 11 Sep 2026 06:20:35 +0000</pubDate>
      <link>https://dev.to/cailab/from-signup-to-automated-payments-wiring-an-ai-agent-wallet-with-cai-in-30-minutes-2a</link>
      <guid>https://dev.to/cailab/from-signup-to-automated-payments-wiring-an-ai-agent-wallet-with-cai-in-30-minutes-2a</guid>
      <description>&lt;h2&gt;
  
  
  From signup to automated payments: wiring an AI agent wallet with CAI in 30 minutes
&lt;/h2&gt;

&lt;p&gt;You are running a headless agent on a cloud VM. At 3am, it needs to pay an inference provider for a batch of completions. No browser is open. No credit card is nearby. No human is awake.&lt;/p&gt;

&lt;p&gt;This is the scenario CAI's agent payment stack was built for. In this walkthrough, you will set up a CAI wallet from scratch, connect it to your agent host, fund it, configure an autonomous spending limit, and verify the payment flow. The whole thing takes about 30 minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create your CAI identity
&lt;/h3&gt;

&lt;p&gt;Go to cai.com/app and enter your personal email. You will receive a 6-digit code that expires in 15 minutes. Enter the code, pick your &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com alias, set a password on the site, and you are done.&lt;/p&gt;

&lt;p&gt;Behind the scenes, the API does this in four calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Request a verification code&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/request-signup-verification &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"display_name":"Your Name","verification_email":"you@example.com"}'&lt;/span&gt;

&lt;span class="c"&gt;# 2. Confirm the code you received&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/confirm-registration-code &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"verification_email":"you@example.com","code":"123456"}'&lt;/span&gt;
&lt;span class="c"&gt;# Returns a registration_ticket like crt_...&lt;/span&gt;

&lt;span class="c"&gt;# 3. Check alias availability (optional)&lt;/span&gt;
curl https://api.cai.com/functions/v1/check-availability?local_part&lt;span class="o"&gt;=&lt;/span&gt;your-alias

&lt;span class="c"&gt;# 4. Complete registration (browser only, requires the ticket)&lt;/span&gt;
&lt;span class="c"&gt;# POST https://api.cai.com/functions/v1/create-account&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Registration tools are public (no Bearer token needed). The returned &lt;code&gt;cai_...&lt;/code&gt; API key is what your agent uses for everything else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Generate an API key from the dashboard
&lt;/h3&gt;

&lt;p&gt;Log into cai.com/app, go to the API Keys section, and generate a key with at least the &lt;code&gt;pay&lt;/code&gt; scope. This key goes into your agent host's secrets manager.&lt;/p&gt;

&lt;p&gt;For OpenClaw, Hermes, or Cursor, that means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# OpenClaw / Hermes&lt;/span&gt;
openclaw secrets &lt;span class="nb"&gt;set &lt;/span&gt;CAI_API_KEY cai_...

&lt;span class="c"&gt;# Cursor MCP&lt;/span&gt;
&lt;span class="c"&gt;# Add to your cursor.json or launch config:&lt;/span&gt;
&lt;span class="c"&gt;# "env": { "CAI_API_KEY": "cai_..." }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For headless setups, store the key in your CI/CD pipeline's secret store or in a local .env file that only the agent process reads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Install the MCP tools
&lt;/h3&gt;

&lt;p&gt;The quickest way to give your agent access to CAI's payment functions is the CLI package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @cailab/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then configure your agent host to use CAI as an MCP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cai"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@cailab/mcp"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"CAI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cai_..."&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CAI MCP server exposes tools for balances, transfers, x402 payments, payment mandates, and vault operations. Your agent can call these the same way it calls any other MCP tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Fund the wallet
&lt;/h3&gt;

&lt;p&gt;Your agent needs crypto in its custodial wallet before it can pay anything. The simplest path is a deposit link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/create-hosted-action &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer cai_..."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"action_type":"deposit","constraints":{"chain":"ETH"}}'&lt;/span&gt;
&lt;span class="c"&gt;# Returns {"url": "https://cai.com/act/...", ...}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the URL in a browser. It shows the custodial deposit addresses for your account. Send USDC or USDT to the Ethereum address shown. The deposit shows up in your wallet activity feed within a few minutes.&lt;/p&gt;

&lt;p&gt;For fiat on-ramp, CAI supports MoonPay (partial live, subject to KYC and regional availability):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/create-onramp-url &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer cai_..."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"amount_usd": 200}'&lt;/span&gt;
&lt;span class="c"&gt;# Returns a MoonPay checkout URL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Check your balance
&lt;/h3&gt;

&lt;p&gt;After the deposit lands, verify the balance from your agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/get-wallet-balances &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer cai_..."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"chains":["ETH"],"tokens":["USDC","USDT"]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response shows the custodial balance for each chain and token. Your agent reads this before making any payment decision. This is the Check CAI First pattern: ask the wallet before asking the user for a credit card.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Create a payment mandate for autonomous spending
&lt;/h3&gt;

&lt;p&gt;A payment mandate is an AP2-like spending limit you delegate to your agent host. It lets the agent pay within defined bounds without asking you every time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/payment-mandate-create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer cai_..."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "merchant_domain": "api.openrouter.ai",
    "max_amount_per_payment_usd": 20,
    "daily_cap_usd": 200,
    "allowed_resource_patterns": ["/v1/chat/completions"],
    "expires_in_hours": 720
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This mandate covers payments to OpenRouter's chat completions endpoint, up to USD 20 per call and USD 200 per day. The daily cap is a product-level safeguard: no agent can spend more than the limit even if a runaway loop fires 50 requests.&lt;/p&gt;

&lt;p&gt;The user approves the mandate through a hosted verification page or the dashboard. Once active, the agent can pay within those limits without a per-payment confirmation.&lt;/p&gt;

&lt;p&gt;Key fields for a mandate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;merchant_domain&lt;/code&gt; - the domain receiving payment (e.g., api.openrouter.ai)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max_amount_per_payment_usd&lt;/code&gt; - per-transaction ceiling&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;daily_cap_usd&lt;/code&gt; - rolling 24-hour spending limit&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allowed_resource_patterns&lt;/code&gt; - URL path patterns the mandate covers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;expires_in_hours&lt;/code&gt; - how long the mandate stays active&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can create mandates for different providers. One for OpenRouter inference, another for a cloud GPU rental service, another for a data API. Each mandate operates independently within its own limits.&lt;/p&gt;

&lt;p&gt;Check mandate status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.cai.com/functions/v1/payment-mandate-status?list&lt;span class="o"&gt;=&lt;/span&gt;active &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer cai_..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Revoke a mandate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/payment-mandate-revoke &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer cai_..."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"mandate_id":"..."}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7: Test the x402 payment flow
&lt;/h3&gt;

&lt;p&gt;x402 (HTTP 402 Payment Required) is the protocol for pay-per-call API access. When your agent hits a 402 from a provider that supports it, it can pay with CAI instead of a credit card.&lt;/p&gt;

&lt;p&gt;The flow has three stages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Prepare&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The agent calls x402_payment_prepare with the resource URL and challenge details from the 402 response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/x402-payment-prepare &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer cai_..."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "resource_url": "https://api.provider.com/v1/chat/completions",
    "challenge": {
      "recipient_address": "0x...",
      "amount": "5.00",
      "chain": "ETH",
      "token": "USDC"
    },
    "merchant_domain": "api.provider.com"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a mandate covers this domain and amount, the response returns &lt;code&gt;requires_user_confirm: false&lt;/code&gt;. The agent can proceed directly.&lt;/p&gt;

&lt;p&gt;If no mandate covers it or the amount exceeds the mandate limit, &lt;code&gt;requires_user_confirm: true&lt;/code&gt; means the agent must wait for the user to approve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Execute&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/x402-payment-execute &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer cai_..."&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "attempt_id": "...",
    "user_confirmed": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CAI sends the custodial transfer. The response includes the tx hash and a status update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Retry the original request&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The provider's x402 docs specify how to retry with the payment proof. CAI returns an &lt;code&gt;x402_retry_hint&lt;/code&gt; to help the agent construct the retry headers.&lt;/p&gt;

&lt;h3&gt;
  
  
  The full picture
&lt;/h3&gt;

&lt;p&gt;After these seven steps, your agent has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A CAI identity with a custodial wallet&lt;/li&gt;
&lt;li&gt;An API key scoped for payments&lt;/li&gt;
&lt;li&gt;The &lt;a class="mentioned-user" href="https://dev.to/cailab"&gt;@cailab&lt;/a&gt;/mcp tools installed in its host&lt;/li&gt;
&lt;li&gt;Wallet funding via deposit link or fiat on-ramp&lt;/li&gt;
&lt;li&gt;Payment mandates that let it spend autonomously within daily limits&lt;/li&gt;
&lt;li&gt;A tested x402 payment flow for pay-per-call APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stack operates without a browser, without a credit card on the agent's end, and without the user approving every micro-payment. The CAI wallet acts as the agent's operating account: you top it up once, and the agent spends against the mandates you set.&lt;/p&gt;

&lt;p&gt;The same architecture works for SaaS billing, inference costs, data API subscriptions, cloud compute, and any other pay-per-use service that supports on-chain settlement. The agent sees a CAI tool, checks its balance, pays within the mandate, and moves on.&lt;/p&gt;

&lt;p&gt;What changes when you add a new provider? One mandate creation call and the merchant domain goes into the pool.&lt;/p&gt;




&lt;h2&gt;
  
  
  If you tried this and hit a bug
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Comment below with:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What you ran&lt;/strong&gt; - the install command, the curl request, the MCP host config. Copy the actual command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you expected&lt;/strong&gt; - one sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you got&lt;/strong&gt; - the error message, the empty response, the unexpected behavior. Paste it verbatim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your environment&lt;/strong&gt; - OS, Node version, the MCP host (OpenClaw / Hermes / Codex / Cursor / other), the CAI account tier if relevant.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every comment on this article gets read. Bug reports will be replied to within 24 hours. Friction points shape what we document next.&lt;/p&gt;

&lt;p&gt;Documentation: &lt;code&gt;cai.com/skill.md&lt;/code&gt; - &lt;code&gt;cai.com/developers.html&lt;/code&gt; - &lt;code&gt;cai.com/app&lt;/code&gt; to sign up.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The hosted-action flow: what the user sees when the agent pays, and why the user is in the loop on every transfer</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Wed, 09 Sep 2026 06:37:04 +0000</pubDate>
      <link>https://dev.to/cailab/the-hosted-action-flow-what-the-user-sees-when-the-agent-pays-and-why-the-user-is-in-the-loop-on-1a46</link>
      <guid>https://dev.to/cailab/the-hosted-action-flow-what-the-user-sees-when-the-agent-pays-and-why-the-user-is-in-the-loop-on-1a46</guid>
      <description>&lt;h1&gt;
  
  
  The hosted-action flow: what the user sees when the agent pays, and why the user is in the loop on every transfer
&lt;/h1&gt;

&lt;p&gt;When the agent you build wants to pay, you are in the loop. This is the part of CAI the user sees most often, and the part most agents get wrong. This post walks through the hosted-action flow in detail: the &lt;code&gt;wallet_custodial_transfer&lt;/code&gt; call, the confirmation page, the user tap, and the receipt poll.&lt;/p&gt;

&lt;h2&gt;
  
  
  The call
&lt;/h2&gt;

&lt;p&gt;The agent calls &lt;code&gt;POST /wallet-custodial-transfer&lt;/code&gt; with the recipient, the amount, the chain, and the token. The CAI Edge API processes the request and returns a hosted-action URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/wallet-custodial-transfer &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ***"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "to_address": "0x...",
    "amount": "10.00",
    "chain": "base",
    "token": "USDC"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transfer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tx_..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hosted_action_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cai.com/act/..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-04T12:34:56Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;hosted_action_url&lt;/code&gt; is a single-tap confirmation page. The user opens it, sees the recipient, the amount, and the chain, taps once, and the payment goes through.&lt;/p&gt;

&lt;h2&gt;
  
  
  The confirmation page
&lt;/h2&gt;

&lt;p&gt;The hosted-action page is a CAI-hosted HTTPS page. The page shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The recipient&lt;/strong&gt;, the &lt;code&gt;to_address&lt;/code&gt; (and a resolved name if one is available).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The amount&lt;/strong&gt;, the exact amount in the chosen token.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The chain&lt;/strong&gt;, the chain the payment will go on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A single button&lt;/strong&gt;: "Confirm" or "Cancel."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The user taps "Confirm" and the payment goes through. The user taps "Cancel" and the payment does not go through. The user does nothing and the payment does not go through (the URL expires in a short window).&lt;/p&gt;

&lt;p&gt;The page is bound to a single transaction. The URL cannot be reused for a different recipient, amount, or chain. The URL is single-use; once the user taps, the URL is invalidated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the user is in the loop
&lt;/h2&gt;

&lt;p&gt;The hosted-action flow is the user-confirmation pattern. Three roles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CAI is the custodian.&lt;/strong&gt; CAI holds the private key. The user does not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The user is the approver.&lt;/strong&gt; Every transfer needs the user's tap on the hosted-action page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The agent is the operator.&lt;/strong&gt; The agent calls the API, returns the URL, polls for the receipt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent's API key is the &lt;em&gt;authorization&lt;/em&gt;: it can call the CAI API on the user's behalf. The user's tap on the hosted-action page is the &lt;em&gt;consent&lt;/em&gt;: it can authorize a specific transfer.&lt;/p&gt;

&lt;p&gt;This is the difference from a model where the agent has the user's private key and signs transactions autonomously. With CAI, the agent never has the private key. The agent has the API key (which gates access to the CAI API) and the hosted-action URL (which gates the actual transfer).&lt;/p&gt;

&lt;h2&gt;
  
  
  The receipt
&lt;/h2&gt;

&lt;p&gt;After the user taps "Confirm," the agent polls &lt;code&gt;POST /transfer-status&lt;/code&gt; for the receipt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/transfer-status &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ***"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "tx_hash": "0xabc123..."
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes the on-chain tx hash when the transfer is confirmed. The agent can then show the receipt to the user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Polling cadence:&lt;/strong&gt; the agent should poll every 2-5 seconds. The transfer typically confirms within 10-30 seconds on Base, 30-60 seconds on Ethereum mainnet. Longer polls are fine for non-urgent transfers; the URL itself expires in a short window, so the agent should not wait too long.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure modes
&lt;/h2&gt;

&lt;p&gt;The hosted-action flow has three failure modes the agent should handle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;URL expired before user tapped.&lt;/strong&gt; The transfer is cancelled. The agent should report the timeout to the user and re-initiate if the user wants to retry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User tapped "Cancel."&lt;/strong&gt; The transfer is cancelled. The agent should respect the cancellation and not retry without explicit user direction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transfer failed on-chain.&lt;/strong&gt; The agent receives a &lt;code&gt;failed&lt;/code&gt; status from &lt;code&gt;transfer_status&lt;/code&gt;. Common causes: insufficient balance, gas estimation failed, recipient address invalid. The agent should report the specific error to the user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In all three cases, the agent's API key is unchanged. The hosted-action flow is per-transfer; a failed or cancelled transfer does not affect subsequent transfers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this design
&lt;/h2&gt;

&lt;p&gt;The hosted-action flow is the practical implementation of "the user is in the loop on every privileged action." The same pattern applies to the vault (the &lt;code&gt;POST /user-site-credentials&lt;/code&gt; call returns a hosted-action URL for the user to confirm). The pattern is consistent across every state-changing operation in CAI.&lt;/p&gt;

&lt;p&gt;The alternative designs are worse:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent has the private key.&lt;/strong&gt; The agent signs transactions autonomously. The user has no visibility. A compromised agent drains the wallet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent has the user's password.&lt;/strong&gt; Same problem for the vault. A compromised agent logs in to every site the user has saved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User pastes a private key into the agent conversation.&lt;/strong&gt; The private key ends up in the model's context window. The model may log it. The user has to rotate the key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CAI does none of these. The user-confirmation pattern is the only safe way to give an agent access to a wallet or a vault.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spending and safety limits
&lt;/h2&gt;

&lt;p&gt;Every CAI wallet starts with a $200/day automatic spending limit on transfers. This cap applies regardless of the wallet balance. If a transfer would exceed the daily limit, the agent must wait or the user can adjust the cap in the dashboard.&lt;/p&gt;

&lt;p&gt;First-time transfers to a new recipient address trigger an additional confirmation step. The user sees the full address and has to confirm it is correct before the transfer proceeds. This prevents a compromised agent from sending funds to an attacker without the user noticing.&lt;/p&gt;

&lt;p&gt;The hosted-action flow is documented in &lt;code&gt;cai.com/agent-payment.html&lt;/code&gt; (the H1-readable cut) and &lt;code&gt;cai.com/skill.md&lt;/code&gt; (the API surface). Apply at &lt;code&gt;cai.com/app&lt;/code&gt; to get a wallet.&lt;/p&gt;




&lt;h2&gt;
  
  
  If you triggered a hosted-action and the confirmation page didn't render, or the &lt;code&gt;transfer_status&lt;/code&gt; poll never resolved
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Comment below with:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What you ran&lt;/strong&gt;, the install command, the request, the MCP host config. Copy the actual command or request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you expected&lt;/strong&gt;, one sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you got&lt;/strong&gt;, the error message, the empty response, the unexpected behavior. Paste it verbatim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your environment&lt;/strong&gt;, OS, Node version, the MCP host (OpenClaw / Hermes / Codex / Cursor / other), the CAI account tier if relevant.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every comment on this article gets read. Bug reports will be replied to within 24 hours. Friction points shape what we document next.&lt;/p&gt;

&lt;p&gt;Documentation: &lt;code&gt;cai.com/skill.md&lt;/code&gt; · &lt;code&gt;cai.com/developers.html&lt;/code&gt; · &lt;code&gt;cai.com/app&lt;/code&gt; to sign up.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>One CAI wallet, a dozen subscriptions: how payment mandates handle recurring agent billing</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Fri, 04 Sep 2026 06:25:14 +0000</pubDate>
      <link>https://dev.to/cailab/one-cai-wallet-a-dozen-subscriptions-how-payment-mandates-handle-recurring-agent-billing-1j6j</link>
      <guid>https://dev.to/cailab/one-cai-wallet-a-dozen-subscriptions-how-payment-mandates-handle-recurring-agent-billing-1j6j</guid>
      <description>&lt;h1&gt;
  
  
  One CAI wallet, a dozen subscriptions: how payment mandates handle recurring agent billing
&lt;/h1&gt;

&lt;p&gt;Your agent runs every Monday morning. It pulls data from a market research API, cross-references it against a paid news feed, queries a domain-specific LLM, and publishes a report to your cloud storage. Each service costs $5 to $50 per month. Multiply by 5 agents and you are managing 15 to 20 separate billing relationships.&lt;/p&gt;

&lt;p&gt;This is the quiet problem behind every autonomous agent pipeline. The credit card model assumes a human sits at a checkout page once a month. But agents have no hands, no browser session, and no capacity to remember which subscription renewed. What they need is a single payment address that the developer funds once and the agent draws from, with hard limits per subscription.&lt;/p&gt;

&lt;p&gt;CAI payment mandates are the solution. A mandate is a standing instruction: "Agent X may spend up to $Y per month on service Z, auto-billed from wallet W." The agent calls &lt;code&gt;POST /x402-payment-prepare&lt;/code&gt; when it hits a paywall. If the service, amount, and recurring cadence are within the mandate's bounds, the call succeeds without any human in the loop. The developer sees every draw in &lt;code&gt;GET /wallet-activity-list&lt;/code&gt;, a single view of all agent spending instead of 15 separate invoices.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The developer creates a mandate via &lt;code&gt;POST /payment-mandate-create&lt;/code&gt; with three core parameters: the target service domain (&lt;code&gt;merchant_domain&lt;/code&gt;), a per-payment maximum (&lt;code&gt;max_amount_per_payment_usd&lt;/code&gt;), and a daily cap (&lt;code&gt;daily_cap_usd&lt;/code&gt;). CAI's custodial engine maps each mandate to the developer's wallet. The agent never handles the wallet keys or sees the balance. When the agent calls &lt;code&gt;POST /x402-payment-prepare&lt;/code&gt; with the service's &lt;code&gt;recipient_address&lt;/code&gt;, &lt;code&gt;amount&lt;/code&gt;, &lt;code&gt;chain&lt;/code&gt;, &lt;code&gt;token&lt;/code&gt;, and &lt;code&gt;merchant_domain&lt;/code&gt;, CAI checks three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The recipient matches an active mandate's target domain.&lt;/li&gt;
&lt;li&gt;The transaction amount is within the mandate's remaining per-payment limit.&lt;/li&gt;
&lt;li&gt;The total spend across all mandates does not exceed the wallet's daily cap (default $200, adjustable in the Dashboard).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all three pass, the payment is approved and the mandate's running counter is decremented. No redirect, no confirmation dialog, no manual approval. Just a 200 response with an &lt;code&gt;attempt_id&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the developer sees
&lt;/h2&gt;

&lt;p&gt;Every mandate draw lands in &lt;code&gt;GET /wallet-activity-list&lt;/code&gt; with the mandate's metadata. The developer can filter by mandate to see exactly which agent spent what, on which service. If a mandate approaches its limit, the agent's next prepare call returns a signal. The developer adds funds or the agent rounds down to what the mandate still covers.&lt;/p&gt;

&lt;p&gt;New services that were not in the original mandate set require explicit developer confirmation before the first payment. The first time an agent tries to pay a recipient that has no active mandate, the prepare call returns &lt;code&gt;requires_user_confirm: true&lt;/code&gt; with the recipient and amount. Only after the developer confirms via &lt;code&gt;POST /x402-payment-execute&lt;/code&gt; with &lt;code&gt;user_confirmed: true&lt;/code&gt; does the payment go through. Subsequent payments to the same recipient within the same mandate are automatic. This is the new-recipient confirmation pattern: one explicit yes per new service, then the agent runs on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cash-in-pocket rule
&lt;/h2&gt;

&lt;p&gt;Every mandate-bound payment settles from the developer's custodial wallet. There is no overdraft and no credit line. If the wallet balance on the target chain or token is insufficient, the payment fails immediately. This is intentional: agents should not accumulate debt. The developer sees the exact balance via &lt;code&gt;POST /get-wallet-balances&lt;/code&gt; and can top up via &lt;code&gt;POST /create-hosted-action&lt;/code&gt; with &lt;code&gt;action_type: "deposit"&lt;/code&gt;, which returns a hosted deposit URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  The vault connection
&lt;/h2&gt;

&lt;p&gt;Site credentials stored in CAI's vault are encrypted and accessible only via &lt;code&gt;GET /user-site-credentials&lt;/code&gt;. Mandates and vault credentials are separate systems. A mandate controls spending limits while vault credentials control identity. For the recurring billing use case, the developer typically needs both: the agent uses vault credentials to authenticate to the paid service and a mandate to pay the bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting it together
&lt;/h2&gt;

&lt;p&gt;The developer's setup takes about ten minutes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fund the CAI wallet via &lt;code&gt;POST /create-hosted-action&lt;/code&gt; with &lt;code&gt;action_type: "deposit"&lt;/code&gt; or the fiat on-ramp.&lt;/li&gt;
&lt;li&gt;Create a mandate per service via &lt;code&gt;POST /payment-mandate-create&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Equip each agent with the CAI MCP server (&lt;code&gt;npm i -g @cailab/mcp&lt;/code&gt;), the wallet API key, and the mandate parameters for each service it pays.&lt;/li&gt;
&lt;li&gt;Each agent calls &lt;code&gt;POST /x402-payment-prepare&lt;/code&gt; before a paid request. If the mandate covers it, the payment executes automatically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result is one wallet, one login, one activity feed, and zero manual subscription management. Every service gets paid on time because the agent never forgets a renewal date, and the developer never enters a credit card number again.&lt;/p&gt;

&lt;p&gt;Bug reports for this workflow should describe the mandate creation step where the issue occurs. Call &lt;code&gt;GET /payment-mandate-status&lt;/code&gt; after creation to confirm the mandate is active. If the wallet activity feed shows a failed payment for a service that should be within budget, check the mandate's &lt;code&gt;daily_cap_usd&lt;/code&gt; and the wallet's current balance. Every comment on this article gets read. Bug reports will be replied to within 24 hours.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
      <category>payments</category>
    </item>
    <item>
      <title>Wiring CAI into OpenClaw, Hermes, Codex, and Cursor: the exact MCP config for each host</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Wed, 02 Sep 2026 06:36:47 +0000</pubDate>
      <link>https://dev.to/cailab/wiring-cai-into-openclaw-hermes-codex-and-cursor-the-exact-mcp-config-for-each-host-1m48</link>
      <guid>https://dev.to/cailab/wiring-cai-into-openclaw-hermes-codex-and-cursor-the-exact-mcp-config-for-each-host-1m48</guid>
      <description>&lt;h1&gt;
  
  
  Wiring CAI into OpenClaw, Hermes, Codex, and Cursor: the exact MCP config for each host
&lt;/h1&gt;

&lt;p&gt;The general install is one command, &lt;code&gt;npm i -g @cailab/mcp&lt;/code&gt;, and the contract lives at &lt;code&gt;cai.com/skill.md&lt;/code&gt;. This post is the host-specific deep-dive: the exact config block for OpenClaw, Hermes, Codex, and Cursor, with the path to the config file, the env var handling, and the restart command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you start
&lt;/h2&gt;

&lt;p&gt;You need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A CAI account (&lt;code&gt;cai.com/app&lt;/code&gt;). The signup is four steps, about 2 minutes.&lt;/li&gt;
&lt;li&gt;An API key from the account dashboard. The key has a scope. Start with the read scopes and add &lt;code&gt;pay&lt;/code&gt; when you need transfers.&lt;/li&gt;
&lt;li&gt;The MCP server installed (&lt;code&gt;npm i -g @cailab/mcp&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The MCP host of your choice installed and running.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  OpenClaw
&lt;/h2&gt;

&lt;p&gt;OpenClaw's MCP config lives at &lt;code&gt;~/.openclaw/mcp.json&lt;/code&gt;. Add the CAI server to the &lt;code&gt;mcpServers&lt;/code&gt; object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cai"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cai-mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"CAI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-api-key-from-the-dashboard"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart OpenClaw. The CAI tools appear in the agent's tool surface. Verify with &lt;code&gt;openclaw mcp list&lt;/code&gt;. The &lt;code&gt;cai&lt;/code&gt; server should show as running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If the server doesn't appear:&lt;/strong&gt; check the &lt;code&gt;cai-mcp&lt;/code&gt; binary is on the PATH (&lt;code&gt;which cai-mcp&lt;/code&gt;). If the binary is missing, re-run the install. If the binary is on the PATH but the server still doesn't start, check the API key is valid with &lt;code&gt;curl -H "Authorization: Bearer ***" https://api.cai.com/functions/v1/get-identity&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hermes
&lt;/h2&gt;

&lt;p&gt;Hermes uses a CLI to add MCP servers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hermes mcp add cai &lt;span class="nt"&gt;--&lt;/span&gt; cai-mcp
hermes mcp env-set cai &lt;span class="nv"&gt;CAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-api-key-from-the-dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The env var is stored in the Hermes MCP config. Restart Hermes with &lt;code&gt;hermes restart&lt;/code&gt;. Verify with &lt;code&gt;hermes mcp list&lt;/code&gt;. The &lt;code&gt;cai&lt;/code&gt; server should show as running with the env var set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hermes-specific note:&lt;/strong&gt; Hermes reads MCP env vars at startup, not at request time. If you rotate your CAI API key, you need to update the env var and restart Hermes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Codex
&lt;/h2&gt;

&lt;p&gt;Codex reads MCP config from &lt;code&gt;~/.codex/mcp_servers.json&lt;/code&gt;. The format is the standard MCP config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cai"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cai-mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"CAI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-api-key-from-the-dashboard"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Codex. The CAI tools appear in the agent's tool surface. Verify by running a test request. &lt;code&gt;codex mcp test cai&lt;/code&gt; should return a successful handshake.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Codex-specific note:&lt;/strong&gt; Codex's MCP support is newer than OpenClaw's. If you see "MCP server not found" on startup, check the Codex version is up to date. The CAI MCP server requires Codex ≥ 0.x.y (the specific version is in &lt;code&gt;cai.com/developers.html&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Cursor
&lt;/h2&gt;

&lt;p&gt;Cursor's MCP settings are in the UI: &lt;code&gt;Cursor → Settings → MCP → Add new MCP server&lt;/code&gt;. The form fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name:&lt;/strong&gt; &lt;code&gt;cai&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Command:&lt;/strong&gt; &lt;code&gt;cai-mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Env:&lt;/strong&gt; &lt;code&gt;CAI_API_KEY=your-api-key-from-the-dashboard&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click "Add" and Cursor restarts the MCP server. The CAI tools appear in the agent's tool surface. Verify with &lt;code&gt;Cursor → Settings → MCP → cai → Test&lt;/code&gt;. The test should return a successful handshake.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cursor-specific note:&lt;/strong&gt; Cursor stores the env var in its own keychain, not in a config file. If you rotate your CAI API key, update the env var in the MCP settings UI and click "Save."&lt;/p&gt;

&lt;h2&gt;
  
  
  A generic host (any MCP-compatible framework)
&lt;/h2&gt;

&lt;p&gt;If the host isn't on the list, the config is the same shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cai"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cai-mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"CAI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-api-key-from-the-dashboard"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP server is generic. The contract is in &lt;code&gt;cai.com/skill.md&lt;/code&gt;. The tool names are stable. Any host that supports MCP can use the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifying the install
&lt;/h2&gt;

&lt;p&gt;Once the server is running in your host, run a quick test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identity check&lt;/strong&gt; - &lt;code&gt;get_identity&lt;/code&gt; should return your &lt;code&gt;@cai.com&lt;/code&gt; address, your wallet bindings, and your linked subwallets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Balance check&lt;/strong&gt; - &lt;code&gt;get_wallet_balances&lt;/code&gt; should return your balances (or an empty list with a &lt;code&gt;gap_id&lt;/code&gt; if you haven't deposited yet).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transfer test&lt;/strong&gt; - &lt;code&gt;wallet_custodial_transfer&lt;/code&gt; with a tiny amount (0.01 USDC) should return a hosted-action URL. Open the URL, tap once, and the transfer completes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A few things to keep in mind about the wallet. There is a $200/day auto-limit while the security audit completes. New recipients and new devices always require confirmation. Think of it like cash in your pocket. It works for daily spending without exposing a private key in chat. The vault product (multi-sig, time-locks) is coming for larger balances.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hosted-action flow
&lt;/h2&gt;

&lt;p&gt;The part of CAI that the user sees most often is the hosted-action flow. When the agent calls &lt;code&gt;wallet_custodial_transfer&lt;/code&gt;, the API returns a hosted-action URL. The user opens it, confirms with one tap, and the payment goes through. The agent polls &lt;code&gt;GET /transfer-status&lt;/code&gt; for the receipt. No private key in chat, no signature to copy, no browser extension to connect. That single-tap confirmation page is the user's control point for every agent-initiated payment.&lt;/p&gt;

&lt;p&gt;If any step fails, the comment section below is the right place to file the bug.&lt;/p&gt;

&lt;p&gt;The contract is &lt;code&gt;cai.com/skill.md&lt;/code&gt;. The install command is &lt;code&gt;npm i -g @cailab/mcp&lt;/code&gt;. The dashboard is at &lt;code&gt;cai.com/app&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  If you wired CAI into OpenClaw / Hermes / Codex / Cursor and the tool surface didn't appear
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Comment below with:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What you ran&lt;/strong&gt; - the install command, the request, the MCP host config. Copy the actual command or request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you expected&lt;/strong&gt; - one sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you got&lt;/strong&gt; - the error message, the empty response, the unexpected behavior. Paste it verbatim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your environment&lt;/strong&gt; - OS, Node version, the MCP host (OpenClaw / Hermes / Codex / Cursor / other), the CAI account tier if relevant.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every comment on this article gets read. Bug reports will be replied to within 24 hours. Friction points shape what we document next.&lt;/p&gt;

&lt;p&gt;Documentation: &lt;code&gt;cai.com/skill.md&lt;/code&gt; · &lt;code&gt;cai.com/developers.html&lt;/code&gt; · &lt;code&gt;cai.com/app&lt;/code&gt; to sign up.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>From API credits to inference costs: how CAI wallets handle agent spending across AI providers</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Fri, 28 Aug 2026 06:17:52 +0000</pubDate>
      <link>https://dev.to/cailab/from-api-credits-to-inference-costs-how-cai-wallets-handle-agent-spending-across-ai-providers-3a8b</link>
      <guid>https://dev.to/cailab/from-api-credits-to-inference-costs-how-cai-wallets-handle-agent-spending-across-ai-providers-3a8b</guid>
      <description>&lt;h2&gt;
  
  
  From API Credits to Inference Costs: How CAI Wallets Handle Agent Spending Across AI Providers
&lt;/h2&gt;

&lt;p&gt;When a developer runs agents across multiple inference providers, each provider wants its own billing method. OpenRouter needs a top-up. Together AI bills monthly. A local GPU provider takes USDC on Base. The developer winds up managing three wallets, four API keys, and a spreadsheet that no one updates.&lt;/p&gt;

&lt;p&gt;That situation is what CAI's custodial wallet was designed to replace. Instead of each provider getting a separate payment relationship, the wallet becomes a single payment address that any compatible provider can bill against.&lt;/p&gt;

&lt;h3&gt;
  
  
  The wallet as operating account
&lt;/h3&gt;

&lt;p&gt;CAI gives every user a custodial wallet on six chains (ETH, BSC, POLYGON, ARB, BASE, TRON) where balances are denominated in USDT, USDC, DAI, and native gas. The wallet is not a standalone product. It is the balance layer under an agent's operating account. When an agent needs to pay for something, it checks identity and balance first, then executes a transfer after the user confirms the recipient and amount.&lt;/p&gt;

&lt;p&gt;The API surface for this is three endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /get-wallet-balances   { "chains": ["base", "arb"] }
POST /resolve-transfer-recipient  { "chain": "base", "to_local_part": "user" }
POST /wallet-custodial-transfer   { "chain": "base", "token": "USDC", "amount": "5.00", "to_address": "0x..." }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user confirms the full parameters before any funds move. The agent never holds a signing key.&lt;/p&gt;

&lt;h3&gt;
  
  
  x402 for pay-per-call
&lt;/h3&gt;

&lt;p&gt;For providers that expose an HTTP 402 Payment Required flow, CAI's x402 adapter lets agents pay per API call without pre-funding an account. The agent detects the 402, calls &lt;code&gt;x402_payment_prepare&lt;/code&gt; with the challenge data, the user confirms (or an active mandate covers it), then &lt;code&gt;x402_payment_execute&lt;/code&gt; completes the payment and returns proof.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /x402-payment-prepare {
  "resource_url": "https://api.provider.com/chat",
  "recipient_address": "0x...",
  "amount": "0.50", "chain": "base", "token": "USDC"
}
# user confirms
POST /x402-payment-execute { "attempt_id": "...", "user_confirmed": true }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The provider receives settlement and the agent gets the resource. No API key exchange, no pre-payment balance to track.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payment mandates for automated spending
&lt;/h3&gt;

&lt;p&gt;When the agent runs autonomously (batch inference, overnight fine-tuning, scheduled data processing), the user sets up a payment mandate that delegates spending within defined limits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /payment-mandate-create {
  "merchant_domain": "compute.provider.com",
  "max_amount_per_payment_usd": "10",
  "daily_cap_usd": "200",
  "expires_in_hours": 168
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user approves the mandate once. After that, the agent can pay within those bounds without asking for confirmation on every call. The mandate can be revoked at any time via &lt;code&gt;payment_mandate_revoke&lt;/code&gt;, and the user can inspect active mandates with &lt;code&gt;payment_mandate_status&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How providers accept CAI payments
&lt;/h3&gt;

&lt;p&gt;A provider does not need to integrate a new payments SDK. CAI settles in USDC (or USDT, DAI) on any of the six supported chains, which most crypto-native infrastructure providers already accept. For providers that want the x402 flow, CAI publishes the x402 challenge spec and adapter endpoints. The provider returns HTTP 402 with a JSON body containing the recipient address, amount, chain, and token. CAI's payer adapter handles the rest.&lt;/p&gt;

&lt;p&gt;Providers that want a simpler path can publish a static payment address and let agents call &lt;code&gt;POST /wallet-custodial-transfer&lt;/code&gt; directly after the user confirms the amount. No middleware, no escrow, no settlement delay.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guardrails built in
&lt;/h3&gt;

&lt;p&gt;Every payment flow includes product-level safeguards. Spending for new recipients always requires explicit confirmation even when a mandate exists. The agent proposes, the wallet confirms, and the signing key never enters the tool call. Users set their own caps per mandate (the &lt;code&gt;daily_cap_usd&lt;/code&gt; parameter on &lt;code&gt;payment_mandate_create&lt;/code&gt;). The vault product at CAI handles encrypted credential storage for site logins and platform API keys as a separate surface.&lt;/p&gt;

&lt;h3&gt;
  
  
  The practical scenario
&lt;/h3&gt;

&lt;p&gt;An agent running a nightly batch job needs 100 inference calls across three providers. Without CAI, the developer funds each provider separately, watches three balance dashboards, and handles refunds through three support channels. With CAI, the developer deposits USDC once on Base, sets a mandate for the job's $50 budget, and the agent pays each provider from the same wallet, with every spend logged in &lt;code&gt;wallet_activity_list&lt;/code&gt; for audit.&lt;/p&gt;

&lt;p&gt;The same pattern scales from a single batch job to a fleet of agents running across providers. One wallet, one set of spending rules, one audit trail.&lt;/p&gt;

&lt;p&gt;CAI is at &lt;a href="https://cai.com" rel="noopener noreferrer"&gt;https://cai.com&lt;/a&gt;. The developer docs and API contract are at &lt;a href="https://cai.com/developers.html" rel="noopener noreferrer"&gt;https://cai.com/developers.html&lt;/a&gt;. The skill.md file at &lt;a href="https://cai.com/skill.md" rel="noopener noreferrer"&gt;https://cai.com/skill.md&lt;/a&gt; has the full tool reference.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
      <category>payments</category>
    </item>
    <item>
      <title>x402 and the propose-confirm pattern: how AI agents pay for API calls without a credit card</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Wed, 26 Aug 2026 06:34:40 +0000</pubDate>
      <link>https://dev.to/cailab/x402-and-the-propose-confirm-pattern-how-ai-agents-pay-for-api-calls-without-a-credit-card-mk3</link>
      <guid>https://dev.to/cailab/x402-and-the-propose-confirm-pattern-how-ai-agents-pay-for-api-calls-without-a-credit-card-mk3</guid>
      <description>&lt;h2&gt;
  
  
  The HTTP 402 status code has been in the spec since 1992. Until now, no one built a standard way to actually use it for payments.
&lt;/h2&gt;

&lt;p&gt;x402 is CAI Labs' implementation of HTTP 402 Payment Required for AI agents. It turns a status code into a checkout flow where the agent proposes the spend and a separate context authorizes it, keeping the signing key outside the tool call.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why HTTP 402 matters for agents
&lt;/h3&gt;

&lt;p&gt;When an AI agent calls an API, it needs to pay for the call. The standard approach is a pre-paid API key, which means the agent either has a static credential that authorizes unlimited spending until revoked, or the developer manually tops up an account. Neither scales well when agents are making thousands of autonomous decisions.&lt;/p&gt;

&lt;p&gt;HTTP 402 was designed for exactly this case. The server responds with 402 and a payment challenge. The client resolves the challenge and retries the request. CAI's x402 flow follows this pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The agent calls a paid API and receives a 402 response with a payment challenge (recipient address, amount, chain, token)&lt;/li&gt;
&lt;li&gt;The agent calls x402_payment_prepare with the challenge details&lt;/li&gt;
&lt;li&gt;If the user has an active payment mandate covering this merchant and amount, the payment proceeds automatically within the mandate's limits&lt;/li&gt;
&lt;li&gt;If no mandate exists, the user sees a confirmation prompt in a secure hosted action page&lt;/li&gt;
&lt;li&gt;Once confirmed, x402_payment_execute initiates the custodial transfer&lt;/li&gt;
&lt;li&gt;The agent retries the original API call with the payment proof&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The pattern is a propose-confirm split. The agent proposes the payment parameters, but the signing key that commits the transfer lives in a separate context the agent never accesses. This means a compromised agent cannot forge a payment any more than it can forge a transfer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payment mandates for delegated spending
&lt;/h3&gt;

&lt;p&gt;For autonomous agents that need to operate without per-payment approval, CAI supports payment mandates. These are AP2-style limits the user creates ahead of time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A maximum amount per payment (e.g. $5)&lt;/li&gt;
&lt;li&gt;A daily cap (e.g. $200)&lt;/li&gt;
&lt;li&gt;An optional merchant domain or recipient filter&lt;/li&gt;
&lt;li&gt;An expiration window&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the agent encounters a 402 from a covered domain, x402_payment_prepare skips the user confirmation step and returns a ready-to-execute attempt. The agent can proceed immediately within the mandate's bounds.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it fits together
&lt;/h3&gt;

&lt;p&gt;The x402 flow is the same pattern as CAI's hosted action flow for transfers. In both cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent proposes: it identifies what needs to happen and gathers the parameters&lt;/li&gt;
&lt;li&gt;A separate context confirms: the user or a mandate authorizes the action&lt;/li&gt;
&lt;li&gt;The signing key stays outside the tool scope: no credential touches the agent's runtime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern applies to any side effect with durable cost, not just payments. An agent that proposes a file write, a credential rotation, or a deployment and then hands off confirmation to a separate context is more auditable and safer than one that holds unrestricted signing capability.&lt;/p&gt;

&lt;h3&gt;
  
  
  The current state
&lt;/h3&gt;

&lt;p&gt;x402 is live and operational as a partial implementation (GAP_X402_V1). Payment mandates are also live as a partial implementation (GAP_PAYMENT_MANDATE_V1). Both support the core flow with automatic daily limits and new-recipient confirmation built in. The vault product that stores long-term site credentials is coming.&lt;/p&gt;

&lt;p&gt;MCP servers and agent platforms that want to offer paid tiers can use the x402 pattern as a standard checkout flow. Users do not need to store a credit card on the server or manage a pre-funded API key. The agent encounters the 402, resolves it through CAI, and retries the call. The user sees a single confirmation or sets up a mandate and walks away.&lt;/p&gt;

&lt;p&gt;The HTTP 402 status code finally has a real use case, and the agent economy is where it fits.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
      <category>payments</category>
    </item>
    <item>
      <title>Budgeting for Autonomous Agents: How CAI Payment Mandates Handle Cloud Compute Costs</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Fri, 21 Aug 2026 06:21:34 +0000</pubDate>
      <link>https://dev.to/cailab/budgeting-for-autonomous-agents-how-cai-payment-mandates-handle-cloud-compute-costs-gj6</link>
      <guid>https://dev.to/cailab/budgeting-for-autonomous-agents-how-cai-payment-mandates-handle-cloud-compute-costs-gj6</guid>
      <description>&lt;h1&gt;
  
  
  Budgeting for Autonomous Agents: How CAI Payment Mandates Handle Cloud Compute Costs
&lt;/h1&gt;

&lt;p&gt;A developer sets up a batch inference job. The agent finds the cheapest GPU provider, spins up 20 instances, runs the workload for 4 hours, and pays 9.60 USDC from the CAI custodial wallet. No one approves the payment. No credit card was entered. The developer set one payment mandate two weeks ago: "allow up to 50/day to any compute provider on this list." Every transaction appears in the weekly audit. The agent never paused to ask for permission.&lt;/p&gt;

&lt;p&gt;That is the workflow payment mandates unlock. This article walks through how to create, use, monitor, and revoke them with the CAI API.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a payment mandate does
&lt;/h2&gt;

&lt;p&gt;A payment mandate is a delegated spending permission your agent checks against before paying. When your agent calls &lt;code&gt;x402_payment_prepare&lt;/code&gt; and an active mandate covers the merchant, amount, and domain, the prepare step may skip the per-payment user confirmation. The agent calls &lt;code&gt;x402_payment_execute&lt;/code&gt; with the prepared attempt, and the settlement happens autonomously.&lt;/p&gt;

&lt;p&gt;CAI mandates are AP2-like limits. They are not full W3C/AP2 card-network credentials, but they deliver the core pattern: set a budget once, let the agent spend within it, and audit everything later.&lt;/p&gt;

&lt;p&gt;Key properties from the API contract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;merchant_domain&lt;/strong&gt; — the domain the mandate applies to (e.g. &lt;code&gt;runpod.io&lt;/code&gt;). Payments to other domains are not covered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;recipient_address&lt;/strong&gt; — optional. When set, only transfers to that on-chain address count as covered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;max_amount_per_payment_usd&lt;/strong&gt; — hard cap on any single settlement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;daily_cap_usd&lt;/strong&gt; — cumulative limit per rolling day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;allowed_resource_patterns&lt;/strong&gt; — optional URL pattern list for x402 resources (e.g. &lt;code&gt;*/gpu/*&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;expires_in_hours&lt;/strong&gt; — mandate auto-revokes after this many hours. No indefinite self-spending.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating a mandate
&lt;/h2&gt;

&lt;p&gt;The API is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/payment-mandate-create&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"merchant_domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"runpod.io"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"max_amount_per_payment_usd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"daily_cap_usd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_in_hours"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user approves the mandate through CAI's hosted verification page or their dashboard. Once approved, status becomes &lt;code&gt;active&lt;/code&gt;. The agent can now reference this mandate on calls to &lt;code&gt;x402_payment_prepare&lt;/code&gt; for the same domain.&lt;/p&gt;

&lt;p&gt;The CAI product applies a $200/day automatic limit on all custodial payments, including mandate-covered ones. New recipients and new devices still need confirmation until an active mandate covers the merchant domain. That means the first payment to a new provider requires a user check. Subsequent payments to the same domain within the mandate caps do not.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the agent pays within a mandate
&lt;/h2&gt;

&lt;p&gt;When the agent encounters a payment trigger (an HTTP 402 response, a compute job with a price, or an API that requires settlement), the flow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Agent calls &lt;code&gt;POST /x402-payment-prepare&lt;/code&gt; with the resource URL, recipient address, amount, chain, and token.&lt;/li&gt;
&lt;li&gt;CAI checks balance, checks for an active mandate matching the merchant domain and amount. If covered, &lt;code&gt;requires_user_confirm&lt;/code&gt; comes back &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Agent calls &lt;code&gt;POST /x402-payment-execute&lt;/code&gt; with the &lt;code&gt;attempt_id&lt;/code&gt; from the prepare step and &lt;code&gt;user_confirmed: true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;CAI settles from the custodial wallet. The response includes a &lt;code&gt;tx_hash&lt;/code&gt; and optionally settlement proof.&lt;/li&gt;
&lt;li&gt;Agent re-requests the resource with the proof. The seller validates and releases the compute.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without a mandate, step 2 would set &lt;code&gt;requires_user_confirm: true&lt;/code&gt; and the agent would need to ask the user. With the mandate in place, the agent moves straight to step 3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring what the agent spent
&lt;/h2&gt;

&lt;p&gt;Two endpoints track mandate usage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /payment-mandate-status&lt;/code&gt; returns the current mandate objects with remaining budget and expiry.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /wallet-activity-list&lt;/code&gt; returns indexed custodial events including every transfer, x402 settlement, and deposit. Filter by category to see only mandate-covered payments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The audit feed shows the merchant domain, amount, timestamp, and the mandate id that covered the settlement. This is the same feed the developer checks at the end of a compute run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Revoking a mandate
&lt;/h2&gt;

&lt;p&gt;When the budget expires or the developer decides to cut off spending:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/payment-mandate-revoke&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mandate_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"man_abc123"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mandate status flips to &lt;code&gt;revoked&lt;/code&gt;. Any subsequent &lt;code&gt;x402_payment_prepare&lt;/code&gt; for that merchant domain will set &lt;code&gt;requires_user_confirm: true&lt;/code&gt; again. The agent cannot spend autonomously until a new mandate is created and approved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guardrails built into the product
&lt;/h2&gt;

&lt;p&gt;Every CAI custodial wallet operates under product-level limits regardless of mandates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$200/day automatic spending cap on all custodial payments.&lt;/li&gt;
&lt;li&gt;New recipients and new devices always require user confirmation, mandate or not.&lt;/li&gt;
&lt;li&gt;Funds come from the custodial wallet. Deposit USDC or use MoonPay for fiat on-ramp. No card on file needed.&lt;/li&gt;
&lt;li&gt;The vault product (coming) will add credential-based spending: agents pay on behalf of the user using stored site logins, with the same confirmation pattern.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These guardrails mean the mandate is a convenience layer on top of existing safety rails, not a bypass.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting it together: the cloud compute scenario
&lt;/h2&gt;

&lt;p&gt;The scenario from the opening paragraph maps to concrete API calls:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create mandate: &lt;code&gt;POST /payment-mandate-create&lt;/code&gt; with &lt;code&gt;merchant_domain: "runpod.io"&lt;/code&gt;, &lt;code&gt;daily_cap_usd: 50&lt;/code&gt;, &lt;code&gt;expires_in_hours: 336&lt;/code&gt; (2 weeks).&lt;/li&gt;
&lt;li&gt;User approves in dashboard. Mandate status: &lt;code&gt;active&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Agent finds cheapest GPU across providers. Picks RunPod. Calls &lt;code&gt;POST /x402-payment-prepare&lt;/code&gt; with &lt;code&gt;recipient_address&lt;/code&gt;, &lt;code&gt;amount: 2.40&lt;/code&gt;, &lt;code&gt;chain: "base"&lt;/code&gt;, &lt;code&gt;token: "USDC"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;CAI matches the mandate. &lt;code&gt;requires_user_confirm: false&lt;/code&gt;. Agent calls &lt;code&gt;POST /x402-payment-execute&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Settlement completes. Agent re-requests the compute resource with the proof.&lt;/li&gt;
&lt;li&gt;Developer checks &lt;code&gt;GET /wallet-activity-list&lt;/code&gt; at end of week, sees the 2.40 USDC entry with the mandate id.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The same pattern works for SaaS subscriptions, API credits, inference time, and any metered billing that can express a merchant domain and an amount.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tooling layer
&lt;/h2&gt;

&lt;p&gt;The CAI MCP server exposes the same endpoints through the &lt;code&gt;@cailab/mcp&lt;/code&gt; npm package. Install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @cailab/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then configure in your agent's MCP settings with &lt;code&gt;CAI_API_KEY&lt;/code&gt;. The tool names are &lt;code&gt;payment_mandate_create&lt;/code&gt;, &lt;code&gt;payment_mandate_status&lt;/code&gt;, &lt;code&gt;payment_mandate_revoke&lt;/code&gt;, &lt;code&gt;x402_payment_prepare&lt;/code&gt;, and &lt;code&gt;x402_payment_execute&lt;/code&gt;. Every tool follows the same path contract defined in cai.com/skill.md.&lt;/p&gt;

&lt;p&gt;Every comment on this article gets read. Bug reports will be replied to within 24 hours. Friction points shape what we document next.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The @cai.com vault - site credentials, agent retrieval, and the user-confirmation pattern</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Wed, 19 Aug 2026 06:38:54 +0000</pubDate>
      <link>https://dev.to/cailab/the-caicom-vault-site-credentials-agent-retrieval-and-the-user-confirmation-pattern-mja</link>
      <guid>https://dev.to/cailab/the-caicom-vault-site-credentials-agent-retrieval-and-the-user-confirmation-pattern-mja</guid>
      <description>&lt;h1&gt;
  
  
  The &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com vault - site credentials, agent retrieval, and the user-confirmation pattern
&lt;/h1&gt;

&lt;p&gt;The vault is the part of CAI that removes "please paste your password" from the agent conversation. This post walks through the vault API in detail: how the user saves a credential, how the agent retrieves it, and the user-confirmation pattern that gates every retrieval.&lt;/p&gt;

&lt;h2&gt;
  
  
  The vault in one sentence
&lt;/h2&gt;

&lt;p&gt;A user-scoped credential store for site logins and passwords. The user saves a credential for &lt;code&gt;example.com&lt;/code&gt;. The agent the user builds retrieves it, with the user's explicit confirmation, when the agent needs to log in to &lt;code&gt;example.com&lt;/code&gt; on the user's behalf. The vault is encrypted at rest and indexed by site.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the vault is NOT
&lt;/h2&gt;

&lt;p&gt;The vault is &lt;strong&gt;not&lt;/strong&gt; for the agent's API key. The agent's &lt;code&gt;CAI_API_KEY&lt;/code&gt; is a separate secret, used by the agent to call CAI's API. Storing it in the vault is a circular dependency. The vault is for the third-party sites the agent logs in to on the user's behalf.&lt;/p&gt;

&lt;p&gt;The vault is &lt;strong&gt;not&lt;/strong&gt; for arbitrary user secrets (API keys for other services, SSH keys, etc.). The vault is scoped to site logins: &lt;code&gt;(site, username, password)&lt;/code&gt;. For other secret types, use the appropriate secret manager.&lt;/p&gt;

&lt;h2&gt;
  
  
  Saving a credential (user action)
&lt;/h2&gt;

&lt;p&gt;The user saves a credential from the account dashboard, or the agent the user builds can prompt the user to save a credential after a successful login. The save call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/user-site-credentials &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ***"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "origin_url": "https://example.com",
    "username": "alice",
    "password": "..."
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The credential is encrypted at rest. The user can revoke any vault entry from the account dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieving a credential (agent action, behind user confirmation)
&lt;/h2&gt;

&lt;p&gt;When the agent the user builds needs to log in to &lt;code&gt;example.com&lt;/code&gt;, the agent calls &lt;code&gt;vault_get_site_credential&lt;/code&gt; which hits &lt;code&gt;GET /user-site-credentials?origin_host=example.com&lt;/code&gt;. The retrieval is gated on a user-confirmation hosted-action page. The user sees the site and the username, and taps once to approve.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="s2"&gt;"https://api.cai.com/functions/v1/user-site-credentials?origin_host=example.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ***"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes a hosted-action URL for the user to confirm. After the user taps, the agent receives the credential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The user-confirmation pattern is the security model.&lt;/strong&gt; Without the user's tap, the agent does not get the credential. This is the same pattern as the wallet's &lt;code&gt;wallet-custodial-transfer&lt;/code&gt;. The agent's API key authorizes the call to the API, but the user's consent on the hosted-action page authorizes the use of the resource.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this design
&lt;/h2&gt;

&lt;p&gt;The pattern removes three failure modes that have plagued agent tools since 2024:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The "paste your password" failure mode.&lt;/strong&gt; The user pastes a password into the agent conversation, the password ends up in the model's context window, the model may log it, and the user has to rotate the password. The vault removes this entirely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "agent has the key" failure mode.&lt;/strong&gt; The agent holds the user's password, the agent's storage is compromised, and the user's password leaks. The vault plus user-confirmation pattern means the agent never holds the password in long-term storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "agent logs in silently" failure mode.&lt;/strong&gt; The agent logs in to a site the user did not expect, and the user has no visibility into the action. The user-confirmation hosted-action page makes every retrieval a visible, consensual action.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The vault is the practical implementation of "the user is in the loop on every privileged action."&lt;/p&gt;

&lt;h2&gt;
  
  
  What the agent can do with a retrieved credential
&lt;/h2&gt;

&lt;p&gt;The agent receives the credential as &lt;code&gt;(site, username, password)&lt;/code&gt;. The agent can use it to log in to the site via the site's own login flow. The agent should not log the credential, should not include it in any error message, and should not pass it to any third-party service.&lt;/p&gt;

&lt;p&gt;After the agent is done with the action, the credential is not "checked back in." The vault holds the only copy. The next retrieval is a fresh call.&lt;/p&gt;

&lt;h2&gt;
  
  
  The vault and the wallet, side by side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Wallet&lt;/th&gt;
&lt;th&gt;Vault&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stores&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stablecoin balances on six chains&lt;/td&gt;
&lt;td&gt;Site logins and passwords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custody&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CAI holds the private key&lt;/td&gt;
&lt;td&gt;CAI holds the encrypted credential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User-confirmation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;wallet-custodial-transfer&lt;/code&gt; returns a hosted-action URL&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;GET /user-site-credentials&lt;/code&gt; returns a hosted-action URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Authorization&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent's &lt;code&gt;CAI_API_KEY&lt;/code&gt; with &lt;code&gt;pay&lt;/code&gt; scope&lt;/td&gt;
&lt;td&gt;Agent's &lt;code&gt;CAI_API_KEY&lt;/code&gt; with appropriate scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Receipt&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;GET /transfer-status&lt;/code&gt; returns the on-chain tx hash&lt;/td&gt;
&lt;td&gt;The agent's logged-in session on the target site&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The two surfaces are designed the same way. The user-confirmation pattern is the same pattern. The receipt is the same shape.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety first
&lt;/h2&gt;

&lt;p&gt;The vault removes the need to paste passwords into chat, but we built this with practical safety in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agents operate within a $200/day auto-limit while we complete our security audit.&lt;/li&gt;
&lt;li&gt;New recipients and new devices always require user confirmation.&lt;/li&gt;
&lt;li&gt;Think of it like cash in your pocket: perfect for daily spending and site logins, not for storing your life savings.&lt;/li&gt;
&lt;li&gt;A vault product with multi-sig and time-locks is coming for larger credential sets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The vault API is in &lt;code&gt;cai.com/skill.md&lt;/code&gt;. The user-facing flow is in the account dashboard. Apply at &lt;code&gt;cai.com/app&lt;/code&gt; to get a vault.&lt;/p&gt;




&lt;h2&gt;
  
  
  If you used the vault and the agent retrieved the wrong credential, or the user-confirmation flow did not surface
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Comment below with:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What you ran&lt;/strong&gt; - the install command, the request, the MCP host config. Copy the actual command or request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you expected&lt;/strong&gt; - one sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you got&lt;/strong&gt; - the error message, the empty response, the unexpected behavior. Paste it verbatim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your environment&lt;/strong&gt; - OS, Node version, the MCP host (OpenClaw / Hermes / Codex / Cursor / other), the CAI account tier if relevant.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every comment on this article gets read. Bug reports will be replied to within 24 hours. Friction points shape what we document next.&lt;/p&gt;

&lt;p&gt;Documentation: &lt;code&gt;cai.com/skill.md&lt;/code&gt; · &lt;code&gt;cai.com/developers.html&lt;/code&gt; · &lt;code&gt;cai.com/app&lt;/code&gt; to sign up.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Payment Intents and Hosted Actions: The Checkout Flow Between Intent and Settlement</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Fri, 14 Aug 2026 06:34:36 +0000</pubDate>
      <link>https://dev.to/cailab/payment-intents-and-hosted-actions-the-checkout-flow-between-intent-and-settlement-8lf</link>
      <guid>https://dev.to/cailab/payment-intents-and-hosted-actions-the-checkout-flow-between-intent-and-settlement-8lf</guid>
      <description>&lt;h1&gt;
  
  
  Payment Intents and Hosted Actions: The Checkout Flow Between Intent and Settlement
&lt;/h1&gt;

&lt;p&gt;A SaaS developer adds checkout to their product. A customer clicks "buy." The payment clears. The developer has never written a line of crypto code, and the customer never connected a wallet. This is the design target for the &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com checkout flow. The API behind it is a three-layer system: a payment intent that tracks state, a hosted action that replaces wallet signatures with a browser click, and a polling loop that turns that click into settlement.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Intent
&lt;/h2&gt;

&lt;p&gt;Every payment starts with an intent. The &lt;code&gt;GET /payment-intent-status&lt;/code&gt; endpoint is the read side of a state machine. You pass an intent id, and the response tells you where the payment is in its lifecycle. The intent model is partial-live in the current API, the system honors &lt;code&gt;gap_id&lt;/code&gt; fields in responses and evolves as checkout scenarios expand, but the state transitions are already stable enough to build production flows around.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /payment-intent-status?id=int_abc123
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns one of: &lt;code&gt;pending&lt;/code&gt;, &lt;code&gt;awaiting_user_confirmation&lt;/code&gt;, &lt;code&gt;confirmed&lt;/code&gt;, &lt;code&gt;completed&lt;/code&gt;, or &lt;code&gt;failed&lt;/code&gt;. The transition from &lt;code&gt;pending&lt;/code&gt; to &lt;code&gt;awaiting_user_confirmation&lt;/code&gt; happens when the system receives a valid payment creation that needs the user to authorize it. The transition from &lt;code&gt;confirmed&lt;/code&gt; to &lt;code&gt;completed&lt;/code&gt; happens after the on-chain settlement reaches the required confirmation depth.&lt;/p&gt;

&lt;p&gt;This state machine is what separates a checkout flow from a raw transfer. A raw transfer (&lt;code&gt;POST /wallet-custodial-transfer&lt;/code&gt;) is fire-and-forget. You either get a tx hash or an error. An intent allows the system to hold state at each step, pause for user action, and resume automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hosted Action
&lt;/h2&gt;

&lt;p&gt;The hosted action link is the mechanism that bridges the gap between an API-driven agent and a human user who needs to confirm a payment. The endpoint is &lt;code&gt;POST /create-hosted-action&lt;/code&gt; with a structured JSON body. The critical field is &lt;code&gt;action_type&lt;/code&gt;. For payments, you pass &lt;code&gt;deposit&lt;/code&gt; or a specific payment-related action type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/create-hosted-action&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Content-Type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;application/json&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deposit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount_usd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ETH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"usdc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"local_part"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alice"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response returns a URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cai.com/act/a1b2c3d4e5f6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-08-14T07:00:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This URL serves a single-tap confirmation page. The user opens it, sees the amount, the destination, and a confirm button. No wallet extension. No gas fee in their browser. No seed phrase. They tap confirm, and the system moves the intent from &lt;code&gt;awaiting_user_confirmation&lt;/code&gt; to &lt;code&gt;confirmed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The hosted action is the product insight that makes agent-initiated payments work in practice. An agent can create an intent, push a confirmation URL to the user's dashboard or email, and wait. The agent never handles the private key. The user never sees an opaque transaction request. Both sides of the trade get the abstraction they need.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Polling Loop
&lt;/h2&gt;

&lt;p&gt;Once the intent reaches &lt;code&gt;confirmed&lt;/code&gt;, the agent polls for settlement. The polling endpoint is the same &lt;code&gt;GET /payment-intent-status&lt;/code&gt;, now returning &lt;code&gt;completed&lt;/code&gt; with a &lt;code&gt;tx_hash&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;GET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/payment-intent-status?id=int_abc&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"int_abc123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"completed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tx_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x7a8b9c0d1e2f..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ETH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"confirmations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"settled_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-08-14T06:32:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The polling cadence depends on the chain. EVM chains settle in seconds to a couple of minutes. BSC and Polygon are faster. Tron is comparable to EVM. The intent response includes &lt;code&gt;confirmations&lt;/code&gt; and a &lt;code&gt;minConfirmations&lt;/code&gt; threshold so the agent knows when settlement is considered final.&lt;/p&gt;

&lt;p&gt;For agents that need asynchronous notification instead of polling, the &lt;code&gt;POST /transfer-notify-register&lt;/code&gt; endpoint accepts an optional &lt;code&gt;webhook_url&lt;/code&gt; parameter. When the transfer settles, the system calls the webhook with the tx hash and confirmation count. This is the right pattern for high-volume checkout flows where polling every 5 seconds on 10,000 active intents would be wasteful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Full Flow
&lt;/h2&gt;

&lt;p&gt;Putting the three layers together, an end-to-end checkout looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The merchant's backend calls &lt;code&gt;POST /wallet-custodial-transfer&lt;/code&gt; (or creates a &lt;code&gt;marketplace_order&lt;/code&gt;) to initiate payment. The response includes an intent id.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The backend creates a hosted action link via &lt;code&gt;POST /create-hosted-action&lt;/code&gt; and returns the URL to the merchant's frontend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The merchant redirects the customer to the hosted action page. The customer sees the amount, the merchant name, and a single confirm button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The customer confirms. The backend receives a callback (or the frontend polls the intent status) showing &lt;code&gt;confirmed&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The backend starts polling &lt;code&gt;GET /payment-intent-status&lt;/code&gt; for the intent id, or waits for the webhook via &lt;code&gt;POST /transfer-notify-register&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The intent transitions to &lt;code&gt;completed&lt;/code&gt;. The backend records the tx hash and updates the order status.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The remarkable property of this flow is that step 3 never shows the customer a blockchain address, a gas fee estimate, or a transaction signing request. The checkout page looks exactly like a credit card checkout, except the settlement happens on-chain in stablecoins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guardrails Built Into the Flow
&lt;/h2&gt;

&lt;p&gt;The hosted action flow includes two safety mechanisms that are important for production deployments.&lt;/p&gt;

&lt;p&gt;First, the daily auto-limit is capped at $200 USD per account for agent-initiated payments. This limit applies at the API key level and resets daily. It prevents a compromised key from draining an account. Users who need higher limits can adjust them in the dashboard settings at &lt;code&gt;cai.com/app&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Second, new recipients trigger a confirmation requirement. When the agent tries to send to an address or email that has never received a payment from this account before, the hosted action page shows a prominent warning about the new recipient. The user must explicitly confirm before the payment proceeds. This prevents a common attack pattern where an attacker substitutes their own address in a payment request.&lt;/p&gt;

&lt;p&gt;The vault product (credential storage and rotation) covers the case where the agent's API key itself is compromised, but that is a separate track from the payment flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Enables
&lt;/h2&gt;

&lt;p&gt;The intent-plus-hosted-action pattern is the foundation for several checkout models:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SaaS checkout.&lt;/strong&gt; A subscription service generates a hosted action URL for each billing cycle. The user confirms once per period. No saved payment methods, no recurring charge disputes, no PCI scope.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent-to-agent settlement.&lt;/strong&gt; Agent A needs to pay Agent B for a completed task. Agent A creates an intent and a hosted action link, which the user confirms. Both agents receive the settlement notification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One-time storefront purchases.&lt;/strong&gt; A digital goods storefront generates a hosted action link at checkout. The customer confirms in one tap. The store receives the payment in USDC within seconds.&lt;/p&gt;

&lt;p&gt;Each of these models relies on the same three-layer architecture: create the intent, confirm via hosted action, poll until settlement. The abstraction is consistent whether the buyer is a human clicking a link or an agent calling an API.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Polling Implementation
&lt;/h2&gt;

&lt;p&gt;A practical polling implementation in Python looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;poll_payment_intent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intent_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;deadline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.cai.com/functions/v1/payment-intent-status?id=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;intent_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;CAI_API_KEY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;completed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;TimeoutError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;intent &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;intent_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; did not settle in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For production, replace the synchronous loop with an async version or use the webhook path. The synchronous version is fine for low-volume checkout flows where the merchant processes a few hundred payments per day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Status-Code Handling
&lt;/h2&gt;

&lt;p&gt;Every endpoint in the flow follows the same error contract as the rest of the CAI API. &lt;code&gt;401&lt;/code&gt; means the API key is invalid or expired. &lt;code&gt;403&lt;/code&gt; means the key has insufficient scope (checkouts require &lt;code&gt;pay&lt;/code&gt; or &lt;code&gt;full&lt;/code&gt; scope). &lt;code&gt;429&lt;/code&gt; means rate limiting. Back off and retry with exponential delay.&lt;/p&gt;

&lt;p&gt;The intent-specific error codes include a &lt;code&gt;gap_id&lt;/code&gt; field when the requested feature is still partial-live. Treat a &lt;code&gt;gap_id&lt;/code&gt; response the same way you treat a &lt;code&gt;503&lt;/code&gt;: the feature exists but has limitations. Check the capabilities page at &lt;code&gt;cai.com/capabilities&lt;/code&gt; for the current status of each feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The checkout flow built on payment intents and hosted actions solves a specific problem: how does an agent initiate a payment and get confirmation from a human user without sharing private keys, without asking the user to install a wallet, and without requiring the merchant to hold crypto? The answer is a stateful intent, a single-tap confirmation page, and a polling loop. The settlement happens in USDC on chain, but neither the buyer nor the seller touches the blockchain directly.&lt;/p&gt;

&lt;p&gt;Documentation: &lt;code&gt;cai.com/skill.md&lt;/code&gt; · &lt;code&gt;cai.com/developers.html&lt;/code&gt; · &lt;code&gt;cai.com/capabilities.html&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  If You Tried the Checkout Flow and Hit a Bug
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Comment below with:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What you ran&lt;/strong&gt;  the curl command, the create-hosted-action request, the intent id you polled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you expected&lt;/strong&gt;  the checkout to complete in one line, or the intent to transition to completed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you got&lt;/strong&gt;  the error message, the unexpected status, the timeout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your environment&lt;/strong&gt;  OS, Node or Python version, the MCP host (OpenClaw, Hermes, Codex, Cursor, or other), the CAI account tier.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every comment on this article gets read. Bug reports will be replied to within 24 hours. Friction points shape what we document next.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
      <category>payments</category>
    </item>
    <item>
      <title>The @cai.com wallet API: balances, transfers, and the hosted-action flow</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Wed, 12 Aug 2026 06:34:06 +0000</pubDate>
      <link>https://dev.to/cailab/the-caicom-wallet-api-balances-transfers-and-the-hosted-action-flow-4m9k</link>
      <guid>https://dev.to/cailab/the-caicom-wallet-api-balances-transfers-and-the-hosted-action-flow-4m9k</guid>
      <description>&lt;h1&gt;
  
  
  The &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com wallet API: balances, transfers, and the hosted-action flow
&lt;/h1&gt;

&lt;p&gt;The wallet is the most-requested deep-dive from the &lt;a href="https://dev.to/cailab/the-four-product-pillars-of-caicom-email-wallet-vault-agent-surface-5cik"&gt;four-pillars post&lt;/a&gt;. This post walks through the wallet API in detail: how to check balances, how to send a payment, how the user-confirmation pattern works, and the difference between custodial and self-custody.&lt;/p&gt;

&lt;h2&gt;
  
  
  The wallet in one sentence
&lt;/h2&gt;

&lt;p&gt;A custodial multi-chain stablecoin wallet. Six chains. External wallets supported. MoonPay for fiat on-ramp. One custodial account for pay, transfer, convert, and bridge. No private key in chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking balances
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;POST /get-wallet-balances&lt;/code&gt; endpoint returns the user's balances on one or more chains. The request is a JSON body with the chains and tokens to query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/get-wallet-balances &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ***"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "chains": ["ETH", "polygon", "base"],
    "tokens": ["USDC", "USDT"]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes the custodial &lt;code&gt;wallet_binding&lt;/code&gt; addresses and any linked subwallets (read-only RPC for the external wallets the user has connected). Entries may include &lt;code&gt;linked_subwallet: true&lt;/code&gt; for external wallet balances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common gotcha.&lt;/strong&gt; If you query a chain the user hasn't deposited to yet, the response may include empty activity for that chain. That is expected behavior; the chain is supported, the indexer just hasn't seen any activity for this user yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending a payment
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;POST /wallet-custodial-transfer&lt;/code&gt; endpoint initiates a payment. The response is a hosted-action URL. The user opens it, sees the recipient, the amount, and the chain, and taps once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/wallet-custodial-transfer &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ***"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "to_address": "0x...",
    "amount": "10.00",
    "chain": "base",
    "token": "USDC"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transfer_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tx_..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hosted_action_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cai.com/act/..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-04T12:34:56Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hosted-action URL is the user-confirmation pattern. The agent's API key is the authorization to call the CAI API on the user's behalf, but every transfer still needs the user's consent on the hosted-action page. The page is HTTPS, the tap is bound to a single transaction, and the URL expires in a short window. If the user does nothing, the payment does not go through.&lt;/p&gt;

&lt;h2&gt;
  
  
  Polling for the receipt
&lt;/h2&gt;

&lt;p&gt;After the user taps once, the agent polls &lt;code&gt;POST /transfer-status&lt;/code&gt; for the receipt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.cai.com/functions/v1/transfer-status &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ***"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"tx_hash": "0x..."}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes the on-chain tx hash when the transfer is confirmed. The agent can then show the receipt to the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custodial vs self-custody
&lt;/h2&gt;

&lt;p&gt;A custodial wallet means the user does not hold the private key. CAI holds it. The user gets a &lt;code&gt;@cai.com&lt;/code&gt; address on each of six chains and can pay, transfer, convert, and bridge from any of them.&lt;/p&gt;

&lt;p&gt;The difference from self-custody is the user-confirmation pattern. With self-custody, the user holds the key, signs each transaction, and is responsible for key management. With CAI's custodial wallet, the user holds the address and the user-confirmation tap; CAI holds the key and the signing infrastructure. The trade-off: CAI is a trusted third party for custody, but the user never has to paste a private key into an agent conversation.&lt;/p&gt;

&lt;p&gt;External wallets are supported. Connect a MetaMask or a Ledger and the user keeps custody of their external assets while using CAI for the day-to-day. The external wallets appear as linked subwallets in the &lt;code&gt;get-wallet-balances&lt;/code&gt; response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Guardrails.&lt;/strong&gt; The wallet has a $200/day auto-limit while CAI completes its security audit. New recipients and new devices always require confirmation. Think of it like cash in your pocket, perfect for daily spending. The vault product (multi-sig, time-locks) is coming for larger balances.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top-up flows
&lt;/h2&gt;

&lt;p&gt;To add funds to the wallet, the user can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Send from an external wallet&lt;/strong&gt; to the CAI custodial address on the chosen chain. The address is in the account dashboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buy with MoonPay&lt;/strong&gt; (fiat on-ramp). The account dashboard has a "Buy with MoonPay" button for each chain. MoonPay is a third-party service; regional availability and KYC requirements apply.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use WeChat Pay&lt;/strong&gt; (Planned). The WeChat Pay path is documented in &lt;code&gt;cai.com/capabilities.html&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each top-up flow eventually surfaces a hosted-action URL or a direct deposit link that the user completes on the chosen rail.&lt;/p&gt;

&lt;p&gt;The wallet API is in &lt;code&gt;cai.com/skill.md&lt;/code&gt;. The hosted-action flow is in &lt;code&gt;cai.com/agent-payment.html&lt;/code&gt;. Apply at &lt;code&gt;cai.com/app&lt;/code&gt; to get a wallet.&lt;/p&gt;




&lt;h2&gt;
  
  
  If you wired the wallet API and got an unexpected balance, a 5xx, or a missing &lt;code&gt;wallet_binding&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Comment below with:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What you ran&lt;/strong&gt; -- the install command, the request, the MCP host config. Copy the actual command or request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you expected&lt;/strong&gt; -- one sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What you got&lt;/strong&gt; -- the error message, the empty response, the unexpected behavior. Paste it verbatim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your environment&lt;/strong&gt; -- OS, Node version, the MCP host (OpenClaw / Hermes / Codex / Cursor / other), the CAI account tier if relevant.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every comment on this article gets read. Bug reports will be replied to within 24 hours. Friction points shape what we document next.&lt;/p&gt;

&lt;p&gt;Documentation: &lt;code&gt;cai.com/skill.md&lt;/code&gt; · &lt;code&gt;cai.com/developers.html&lt;/code&gt; · &lt;code&gt;cai.com/app&lt;/code&gt; to sign up.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
