<?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>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>
    <item>
      <title>Accepting payments with @cai.com: adding CAI checkout to your website or SaaS</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Fri, 07 Aug 2026 06:29:06 +0000</pubDate>
      <link>https://dev.to/cailab/accepting-payments-with-caicom-adding-cai-checkout-to-your-website-or-saas-2h9a</link>
      <guid>https://dev.to/cailab/accepting-payments-with-caicom-adding-cai-checkout-to-your-website-or-saas-2h9a</guid>
      <description>&lt;h1&gt;
  
  
  Accepting payments with &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com: adding CAI checkout to your website or SaaS
&lt;/h1&gt;

&lt;p&gt;A SaaS developer wants to accept payments without a merchant account, without chargebacks, and without asking customers to leave the checkout flow. A marketplace needs to collect payments from buyers and settle them to sellers. An AI agent needs to pay for API access programmatically. All three scenarios converge on the same problem: how does money move from payer to payee without a Plaid link, a Stripe onboarding, or a wallet address pasted in chat?&lt;/p&gt;

&lt;p&gt;The &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com payment path covers two sides. The payer side (an agent paying from a CAI wallet, or a human tapping a hosted confirmation page) has been covered elsewhere. This post covers the merchant side: how to accept payments through CAI, what the API looks like, and where the honest limits are.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two payment paths for merchants
&lt;/h2&gt;

&lt;p&gt;CAI exposes two distinct receive paths, and the choice between them depends on how the customer pays.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Card (fiat) path:&lt;/strong&gt; &lt;code&gt;create_onramp_url&lt;/code&gt; returns a MoonPay-hosted URL where the customer pays by credit card. The funds land in the merchant's custodial EVM address as USDC (or the selected stablecoin). The merchant needs a CAI API key with &lt;code&gt;pay&lt;/code&gt; or &lt;code&gt;full&lt;/code&gt; scope.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crypto path:&lt;/strong&gt; &lt;code&gt;create_deposit_link&lt;/code&gt; returns a CAI-hosted page (&lt;code&gt;/act/&amp;lt;token&amp;gt;&lt;/code&gt;) showing the merchant's custodial addresses and QR codes. The customer sends crypto from their own wallet, and the deposit is indexed by CAI's activity feed.&lt;/p&gt;

&lt;p&gt;The two paths are not interchangeable. Card works for customers who hold fiat. Crypto works for customers who hold USDC or other supported tokens. The merchant can offer both, or one, depending on their customer base.&lt;/p&gt;

&lt;h2&gt;
  
  
  The card path: create_onramp_url
&lt;/h2&gt;

&lt;p&gt;The card path routes through MoonPay, which handles the fiat-to-crypto conversion, compliance checks, and card network processing. The merchant does not need a separate MoonPay account. The CAI API key is the only credential.&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 ***"&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": 50.00,
    "default_currency_code": "usdc_eth"
  }'&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; that the merchant redirects (or links) the customer to. The customer fills in their card details on MoonPay's hosted page, and the crypto lands in the merchant's custodial EVM address. The &lt;code&gt;walletAddress&lt;/code&gt; is set server-side to the API key owner's custodial address, so the merchant does not need to specify a destination.&lt;/p&gt;

&lt;p&gt;This is not a full payment processor. There is no cart abstraction, no order webhook, and no inventory management. The receipt is the MoonPay payment intent. The merchant confirms the payment by polling &lt;code&gt;GET /payment-intent-status&lt;/code&gt; with the intent id, or by checking &lt;code&gt;GET /wallet-activity-list&lt;/code&gt; for the incoming deposit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest limit:&lt;/strong&gt; MoonPay is a third-party provider. KYC requirements and regional availability apply. If MoonPay is unavailable for a given region (the API returns a 503 with &lt;code&gt;GAP_ONRAMP_V1&lt;/code&gt;), the card path is unavailable for that customer. The honest fallback is the crypto deposit path.&lt;/p&gt;

&lt;h2&gt;
  
  
  The crypto path: create_deposit_link
&lt;/h2&gt;

&lt;p&gt;For customers who already hold crypto, the deposit path is simpler. The merchant calls &lt;code&gt;create_deposit_link&lt;/code&gt; and gets a CAI-hosted page.&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 ***"&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"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is a &lt;code&gt;url&lt;/code&gt; like &lt;code&gt;https://cai.com/act/&amp;lt;token&amp;gt;&lt;/code&gt;. The merchant sends this URL to the customer. The customer opens it, sees the merchant's custodial addresses and QR codes for each chain, and sends crypto from their wallet. The deposit is indexed by CAI's activity feed and appears in &lt;code&gt;GET /wallet-activity-list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The deposit link is single-use and short-lived. The customer has a window to complete the deposit before the URL expires. The merchant can verify the deposit by polling &lt;code&gt;GET /wallet-deposit-activity&lt;/code&gt; or &lt;code&gt;GET /wallet-activity-list&lt;/code&gt; with the customer's name or reference.&lt;/p&gt;

&lt;p&gt;For the crypto path, the merchant's custodial address is printed on the page. The customer sends from their own wallet, whether that is a CAI wallet, a MetaMask, a Ledger, or any other wallet that supports the target chain. The merchant does not need to know which wallet the customer uses.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hosted action pattern
&lt;/h2&gt;

&lt;p&gt;Both paths build on the same hosted action infrastructure. A hosted action URL is a CAI-hosted page that the payer or the customer opens in a browser. The page is HTTPS, the token is single-use, and the URL expires in a short window (typically 15 minutes). The page does not require the visitor to have a CAI account.&lt;/p&gt;

&lt;p&gt;The hosted action is the user-confirmation surface. The payer sees the recipient, the amount, the chain, and taps once. The merchant sees the confirmation on the other side. The hosted action pattern is the same regardless of whether the flow is a deposit, a transfer, a login, or a wallet connect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Confirming the payment
&lt;/h2&gt;

&lt;p&gt;After the customer completes the payment (card or crypto), the merchant needs to confirm it landed. The confirmation tool depends on the payment method.&lt;/p&gt;

&lt;p&gt;For card payments via MoonPay, the merchant polls &lt;code&gt;GET /payment-intent-status&lt;/code&gt; with the payment intent id returned by the MoonPay flow. The response includes the status, the on-chain tx hash, and the confirmation count.&lt;/p&gt;

&lt;p&gt;For crypto deposits, the merchant reads from the activity feed. &lt;code&gt;GET /wallet-activity-list&lt;/code&gt; with &lt;code&gt;direction: "in"&lt;/code&gt; and &lt;code&gt;category: "deposit"&lt;/code&gt; returns the indexed deposits. If the deposit is not yet indexed, &lt;code&gt;GET /wallet-deposit-activity&lt;/code&gt; or &lt;code&gt;POST /wallet-deposit-confirm&lt;/code&gt; (with the tx hash) can surface it.&lt;/p&gt;

&lt;p&gt;The distinction matters: card payments are confirmed through the payment intent API, not through the transfer status API. Crypto deposits are confirmed through the activity feed, not through the transfer status API. The transfer status API is for outbound custodial transfers, not for incoming deposits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guardrails and honest limits
&lt;/h2&gt;

&lt;p&gt;CAI's receive path is designed for daily spending, not for treasury-sized balances. The $200/day auto-limit applies while the security audit completes. 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;p&gt;The card path routes through MoonPay, which is a third-party provider. KYC and region limits apply. The crypto path is self-service: the customer sends from their wallet, and the merchant confirms on the activity feed.&lt;/p&gt;

&lt;p&gt;The receive path is not a full payment processor. There is no cart, no order webhook, no inventory management, and no chargeback handling. The merchant handles the business logic of linking a payment to an order, and CAI handles the settlement.&lt;/p&gt;




&lt;h2&gt;
  
  
  If you tried the receive 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 API call, the hosted action URL, the curl command. Copy the actual request or the page URL.&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>payments</category>
    </item>
    <item>
      <title>Setting up your agent's operating account: sign up at cai.com/app in 4 steps</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Wed, 05 Aug 2026 06:36:57 +0000</pubDate>
      <link>https://dev.to/cailab/setting-up-your-agents-operating-account-sign-up-at-caicomapp-in-4-steps-3i08</link>
      <guid>https://dev.to/cailab/setting-up-your-agents-operating-account-sign-up-at-caicomapp-in-4-steps-3i08</guid>
      <description>&lt;h1&gt;
  
  
  Setting up your agent's operating account: sign up at cai.com/app in 4 steps
&lt;/h1&gt;

&lt;p&gt;Your agent needs an operating account. Here is how to set one up in about 2 minutes, no card required, no private key to paste in chat.&lt;/p&gt;

&lt;p&gt;The signup at &lt;code&gt;cai.com/app&lt;/code&gt; is four steps. This post walks through each step with what the user sees, the actual fields, and what to do if a step fails. The steps below match the current &lt;code&gt;cai.com/app&lt;/code&gt; page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Open cai.com/app and pick "Apply for &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com email"
&lt;/h2&gt;

&lt;p&gt;Go to &lt;code&gt;cai.com/app&lt;/code&gt;. The page has a single CTA: "Apply for &lt;code&gt;@cai.com&lt;/code&gt; email." Click it. The first form field is your name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Enter your name
&lt;/h2&gt;

&lt;p&gt;That's the only field on the first screen. There is no email field on this step; the email is collected next. Enter your name, click continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Enter your existing email (this is where the 6-digit code goes)
&lt;/h2&gt;

&lt;p&gt;CAI emails a 6-digit verification code to the address you provide. The code expires in 15 minutes. Enter the code into the form when it arrives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If the code doesn't arrive:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check spam. CAI's verification email is plain text with a 6-digit code; some providers sort it to spam if you haven't seen mail from &lt;code&gt;cai.com&lt;/code&gt; before.&lt;/li&gt;
&lt;li&gt;Wait 60 seconds. The email is sent immediately after you submit the form, but delivery can lag.&lt;/li&gt;
&lt;li&gt;Click "Resend code" if the form has the option. A new code invalidates the old one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If the code expires before you paste it:&lt;/strong&gt; you can request a new one from the same form. The old code is invalidated; the new code has a fresh 15-minute window. There is no waiting for support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Enter the code, create a password, and you're done
&lt;/h2&gt;

&lt;p&gt;Enter the 6-digit code, set a password (8+ characters, the form's complexity rules apply), and the signup completes. You are redirected to the account dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you have at the end
&lt;/h2&gt;

&lt;p&gt;After the four steps, you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;@cai.com&lt;/code&gt; email address. The SMTP/IMAP credentials are in the account dashboard if you want to use a desktop client.&lt;/li&gt;
&lt;li&gt;A custodial multi-chain stablecoin wallet. The wallet is empty until you top it up; the &lt;a href="https://dev.to/cailab/the-four-product-pillars-of-caicom-email-wallet-vault-agent-surface-5cik"&gt;four product pillars post&lt;/a&gt; covers the wallet in detail.&lt;/li&gt;
&lt;li&gt;A user vault for site credentials. Empty until you add credentials; the same post covers the vault.&lt;/li&gt;
&lt;li&gt;An API key for the agent you build or use. The key is in the account dashboard. Free tier covers read scopes; &lt;code&gt;pay&lt;/code&gt; and &lt;code&gt;full&lt;/code&gt; scopes may require verification.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&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;p&gt;The signup takes about 2 minutes. No card is required. The email is free.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do next (technical reader)
&lt;/h2&gt;

&lt;p&gt;If you are the technical reader, the one who reads dev.to to install things, the next step is &lt;code&gt;npm i -g @cailab/mcp&lt;/code&gt;. The package drops the CAI MCP server into any MCP-compatible host: OpenClaw, Hermes, Codex, Cursor. The full quickstart is in &lt;code&gt;cai.com/developers.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The contract an agent reads first is &lt;code&gt;cai.com/skill.md&lt;/code&gt;. The companion artifact is the A2A Agent Card at &lt;code&gt;cai.com/.well-known/agent.json&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the agent logs in on your behalf
&lt;/h2&gt;

&lt;p&gt;Once the account exists, the agent does not need your password. The CAI API exposes a hosted login flow: an agent calls &lt;code&gt;POST /create-hosted-action&lt;/code&gt; with &lt;code&gt;{ "action_type": "login" }&lt;/code&gt; and gets back a &lt;code&gt;url&lt;/code&gt;. That URL is a CAI-hosted page the user opens and confirms. The agent never types your credentials into chat, and the login link is one-time and short-lived.&lt;/p&gt;

&lt;p&gt;That pattern is the same shape as the wallet's user-confirmation flow. The agent's API key is the authorization; the user's tap on a hosted page is the consent. You keep the password, and the agent keeps the ability to act on your behalf within the confirmations you allow.&lt;/p&gt;

&lt;p&gt;Apply at &lt;code&gt;cai.com/app&lt;/code&gt;. The signup is four steps, about 2 minutes, no card.&lt;/p&gt;




&lt;h2&gt;
  
  
  If you went through the signup flow described above and the code didn't arrive, expired too fast, or failed silently
&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>tutorial</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>ai</category>
    </item>
    <item>
      <title>Pay Anyone by Their Name: How the @cai.com Directory Replaces Wallet Addresses</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Fri, 31 Jul 2026 07:04:16 +0000</pubDate>
      <link>https://dev.to/cailab/pay-anyone-by-their-name-how-the-caicom-directory-replaces-wallet-addresses-129k</link>
      <guid>https://dev.to/cailab/pay-anyone-by-their-name-how-the-caicom-directory-replaces-wallet-addresses-129k</guid>
      <description>&lt;p&gt;Sending a friend 20 USDC should not require copying a hex string from a chat app, checking the chain, and hoping the network matches. The &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com directory replaces wallet addresses with handles. Type the name, pick the handle, and the money moves.&lt;/p&gt;

&lt;p&gt;This post covers the &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com address directory, how it resolves handles to wallets, and how person-to-person payments work without the user ever seeing a hex string.&lt;/p&gt;

&lt;h2&gt;
  
  
  The directory
&lt;/h2&gt;

&lt;p&gt;The &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com directory maps every registered user to their custodial wallet addresses across six chains. When you sign up at cai.com/app, you get a handle like &lt;code&gt;alice@cai.com&lt;/code&gt; and a wallet address on each supported chain. The directory stores the mapping.&lt;/p&gt;

&lt;p&gt;The directory is not a blockchain itself. It is a lookup table that CAI maintains. The agent that needs to pay someone calls &lt;code&gt;resolve-transfer-recipient&lt;/code&gt; with the recipient's email or handle, and gets back the canonical address on the requested chain.&lt;/p&gt;

&lt;p&gt;The API call is straightforward:&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/resolve-transfer-recipient &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;'{"chain": "BASE", "to_email": "friend@cai.com"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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;"canonical_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"friend@cai.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"to_address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x..."&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;h2&gt;
  
  
  How payments work through the directory
&lt;/h2&gt;

&lt;p&gt;Once the address is resolved, the agent initiates the transfer. The user confirms on a hosted-action page, and CAI executes the custodial transfer on the requested chain.&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/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;'{
    "chain": "BASE",
    "token": "usdc",
    "amount": "20.00",
    "to_email": "friend@cai.com"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;to_email&lt;/code&gt; field. The agent never touches a wallet address. It resolves the handle, then passes the handle back to the transfer endpoint. CAI handles the address resolution internally on the second call.&lt;/p&gt;

&lt;h2&gt;
  
  
  The public surface
&lt;/h2&gt;

&lt;p&gt;The directory also has a public facing side. The &lt;code&gt;cai.com/.well-known/agent.json&lt;/code&gt; file is the A2A Agent Card that lets other agents discover how to interact with CAI. The &lt;code&gt;cai.com/capabilities.html&lt;/code&gt; page lists which features are live, which are in beta, and which carry gap IDs.&lt;/p&gt;

&lt;p&gt;For the &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com address directory specifically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live&lt;/strong&gt; (per capabilities.html): The directory is operational. All registered users are discoverable by their &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com handle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chain support&lt;/strong&gt;: ETH, BASE, POLYGON, SOLANA, ARBITRUM, and OPTIMISM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gap ID&lt;/strong&gt;: GAP_RESOLVE_V1 — signals that the resolution is live but may not cover every edge case (e.g., unregistered handles return a clear error, not a silent fail).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What this means for agents
&lt;/h2&gt;

&lt;p&gt;An agent that needs to pay someone does not need to ask for a wallet address. It asks for the person's &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com handle. The agent resolves it, checks the balance, and initiates the transfer. The user confirms with one tap.&lt;/p&gt;

&lt;p&gt;This is the same flow whether the agent is paying a freelancer, settling a split bill, or sending a recurring payment to a landlord. The directory abstracts the chain complexity. The agent works with names, not addresses.&lt;/p&gt;

&lt;h2&gt;
  
  
  The end-to-end
&lt;/h2&gt;

&lt;p&gt;A complete payment flow through the directory:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Agent calls &lt;code&gt;get-identity&lt;/code&gt; to confirm the user has a CAI account.&lt;/li&gt;
&lt;li&gt;Agent asks the user for the recipient's &lt;a class="mentioned-user" href="https://dev.to/cai"&gt;@cai&lt;/a&gt;.com handle.&lt;/li&gt;
&lt;li&gt;Agent calls &lt;code&gt;resolve-transfer-recipient&lt;/code&gt; with the handle and the preferred chain.&lt;/li&gt;
&lt;li&gt;Agent calls &lt;code&gt;get-wallet-balances&lt;/code&gt; to confirm sufficient funds.&lt;/li&gt;
&lt;li&gt;Agent calls &lt;code&gt;wallet-custodial-transfer&lt;/code&gt; with the recipient's handle.&lt;/li&gt;
&lt;li&gt;User confirms on the hosted-action page.&lt;/li&gt;
&lt;li&gt;Agent confirms the payment landed via &lt;code&gt;wallet-activity-list&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every step works with the handle. The agent never sees a private key, never copies a hex address, and never asks which network the recipient is on.&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;

&lt;p&gt;If you tried this flow and hit a bug, comment below with the command you ran, what you expected, and what you got. Bug reports get replied to within 24 hours.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>webdev</category>
      <category>payments</category>
    </item>
    <item>
      <title>How AI Agents Pay for APIs: x402, Payment Mandates, and the Agent Operating Account</title>
      <dc:creator>CAI</dc:creator>
      <pubDate>Wed, 29 Jul 2026 09:51:45 +0000</pubDate>
      <link>https://dev.to/cailab/how-ai-agents-pay-for-apis-x402-payment-mandates-and-the-agent-operating-account-168b</link>
      <guid>https://dev.to/cailab/how-ai-agents-pay-for-apis-x402-payment-mandates-and-the-agent-operating-account-168b</guid>
      <description>&lt;h1&gt;
  
  
  How AI Agents Pay for APIs: x402, Payment Mandates, and the Agent Operating Account
&lt;/h1&gt;

&lt;p&gt;The HTTP 402 status code has been reserved for "Payment Required" since 1998. For most of the web's history, it sat unused. But AI agents making API calls autonomously are finally giving it real traffic.&lt;/p&gt;

&lt;p&gt;When an agent hits a paid API endpoint, the question shifts from "can it pay?" to "how does it pay without waking a human for every dollar?" That breaks into two parts: a protocol for agent-to-API payment (x402) and a delegation mechanism (payment mandates) that lets agents spend within user-defined limits without asking permission each time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The x402 flow
&lt;/h2&gt;

&lt;p&gt;The x402 protocol is straightforward. An agent calls an API endpoint. The API responds with HTTP 402, including a payment challenge in the response body. The challenge specifies the recipient address, amount, chain, and token. The agent forwards this challenge to a payer service, which checks the user's balance and executes the transfer.&lt;/p&gt;

&lt;p&gt;CAI's implementation uses three endpoints.&lt;/p&gt;

&lt;p&gt;First, &lt;code&gt;POST /x402-payment-prepare&lt;/code&gt; takes the challenge from the API and checks whether the user has sufficient balance and whether an active mandate covers this merchant. It returns an &lt;code&gt;attempt_id&lt;/code&gt; and a &lt;code&gt;requires_user_confirm&lt;/code&gt; flag. When the user has set up a payment mandate for this domain, the flag is false and the agent can proceed.&lt;/p&gt;

&lt;p&gt;Second, the agent calls &lt;code&gt;POST /x402-payment-execute&lt;/code&gt; with the &lt;code&gt;attempt_id&lt;/code&gt; and &lt;code&gt;user_confirmed: true&lt;/code&gt; (or skips confirm when the mandate covers it). CAI executes the custodial transfer on the requested chain and returns a &lt;code&gt;tx_hash&lt;/code&gt; as proof.&lt;/p&gt;

&lt;p&gt;Third, the agent re-requests the paid API resource, attaching the &lt;code&gt;tx_hash&lt;/code&gt; or &lt;code&gt;x402_retry_hint&lt;/code&gt; from CAI's response. The API verifies the on-chain payment and serves the resource.&lt;/p&gt;

&lt;p&gt;The retry is the agent's responsibility. CAI returns the proof of payment. The agent presents it to the seller.&lt;/p&gt;

&lt;h2&gt;
  
  
  Payment mandates: spending limits for autonomous agents
&lt;/h2&gt;

&lt;p&gt;The mandate system is the more interesting piece. A payment mandate is a user-created permission that lets an agent spend up to certain limits on a specific merchant domain without asking for confirmation every time.&lt;/p&gt;

&lt;p&gt;The flow starts with &lt;code&gt;POST /payment-mandate-create&lt;/code&gt;. The user specifies the &lt;code&gt;merchant_domain&lt;/code&gt;, a &lt;code&gt;max_amount_per_payment_usd&lt;/code&gt;, a &lt;code&gt;daily_cap_usd&lt;/code&gt;, optional &lt;code&gt;allowed_resource_patterns&lt;/code&gt;, and an &lt;code&gt;expires_in_hours&lt;/code&gt; value. The user approves the mandate through CAI's hosted verification page. Once active, the agent can call &lt;code&gt;x402_payment_prepare&lt;/code&gt; for any charge on that domain, and the response sets &lt;code&gt;requires_user_confirm: false&lt;/code&gt; as long as the charge stays within the mandate's limits.&lt;/p&gt;

&lt;p&gt;The user can revoke the mandate at any time with &lt;code&gt;POST /payment-mandate-revoke&lt;/code&gt; or inspect active mandates with &lt;code&gt;GET /payment-mandate-status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This follows the same pattern as the AP2 (Authorization Protocol for Payments) concept, but CAI's implementation is a CAI-native version. The system enforces spending caps per payment and per day, and the domain pattern matching limits which API endpoints the mandate covers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the agent gets its wallet
&lt;/h2&gt;

&lt;p&gt;Before any of this works, the agent needs a wallet to pay from. CAI's model is a custodial multi-chain wallet accessed via API key. The agent calls &lt;code&gt;GET /get-identity&lt;/code&gt; to confirm the account exists, then &lt;code&gt;POST /get-wallet-balances&lt;/code&gt; to check balances on the relevant chain.&lt;/p&gt;

&lt;p&gt;If the balance is insufficient, the agent can generate a deposit link with &lt;code&gt;POST /create-hosted-action&lt;/code&gt; (with &lt;code&gt;action_type: "deposit"&lt;/code&gt;) or use the fiat on-ramp via MoonPay (third-party KYC applies). The agent does not handle private keys. It calls the CAI API, and CAI executes the custodial transfer.&lt;/p&gt;

&lt;p&gt;The full sequence is documented in the skill.md contract at &lt;code&gt;https://api.cai.com/functions/v1&lt;/code&gt;, which is the single source of truth for all endpoints, scopes, and gap IDs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MCP path
&lt;/h2&gt;

&lt;p&gt;For agents that use the Model Context Protocol, the &lt;code&gt;@cailab/mcp&lt;/code&gt; npm package provides a stdio transport that exposes the same set of tools. The agent sets &lt;code&gt;CAI_API_KEY&lt;/code&gt; as an environment variable and the MCP server handles the authentication and routing. The same x402 endpoints, mandate tools, and wallet operations are available through the MCP interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Early access guardrails
&lt;/h2&gt;

&lt;p&gt;Since this is early access, CAI applies a $200 per day automatic spending limit. New recipients and new devices need user confirmation before the first transfer. The vault product for storing third-party site credentials is also available, which lets agents store and retrieve login credentials for platforms they interact with.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest label
&lt;/h2&gt;

&lt;p&gt;The capabilities page at &lt;code&gt;cai.com/capabilities.html&lt;/code&gt; marks x402 as Live and payment mandates as Live. Both carry gap IDs (&lt;code&gt;GAP_X402_V1&lt;/code&gt;, &lt;code&gt;GAP_PAYMENT_MANDATE_V1&lt;/code&gt;) that signal the implementation is operational but may not cover every edge case. The gap IDs are part of the API response, so agents can check them and adjust their behavior accordingly.&lt;/p&gt;

&lt;p&gt;WeChat Pay is listed as Planned. Bridge and cross-chain transfers are Live (with &lt;code&gt;GAP_BRIDGE_V1&lt;/code&gt;). The fiat on-ramp via MoonPay is Live with third-party KYC limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for agent developers
&lt;/h2&gt;

&lt;p&gt;Agent-to-API payment is no longer a design problem you need to solve from scratch. The x402 protocol gives you a standard way to handle HTTP 402 challenges. The mandate system lets agents operate autonomously within user-defined limits. The custodial wallet model means the agent never touches a private key.&lt;/p&gt;

&lt;p&gt;The API contract lives at &lt;code&gt;cai.com/skill.md&lt;/code&gt;. The MCP package is on npm. The capabilities matrix is at &lt;code&gt;cai.com/capabilities.html&lt;/code&gt;. The agent calls &lt;code&gt;get_identity&lt;/code&gt;, checks balances, and pays when it needs to.&lt;/p&gt;

&lt;p&gt;The 402 status code has been waiting for a use case since 1998. AI agents might be the one that finally makes it stick.&lt;/p&gt;

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