Changelog · October 19–25, 2026

Replies never invent a price

Every agent now checks the amounts of money in its replies against what your tools and prompt said. API keys became one concept, quiet hours let you choose when the agent stays silent, and a few surfaces were removed so the CLI and the MCP are the way in.

The way in has not changed: npx @vatio-ai/skills and /vatio-init in your app’s project. What is new is a check on every reply: the Safeguards page lists what it catches and what the agent says when an amount is not confirmed.

Keys are now publishable or secret, and the CLI and the MCP are the surfaces to work from: the HTTP developer API behind them is no longer documented, and people’s data is exported or erased with vatio contacts. To choose when the agent stays silent, see Human in the loop; for photos and visitor files, Tools.

Releases

Vatio 0.94.0, 0.95.0, 0.96.0, 0.97.0, 0.98.0, 0.99.0, 0.99.1, 0.100.0, 0.100.1, 0.100.2, 0.100.3, 0.101.0, 0.102.0, 0.103.0, 0.104.0, 0.105.0 and 0.106.0. The CLI and the platform are released together; every entry is also in the full changelog in the docs.

0.106.0 — 2026-10-25

vatio chat list no longer talks to your agent. A lone word that reads like a subcommand (list, search, open, history…) is refused and nothing is sent; the error points at vatio chat show [CHAT_ID] and vatio chat export --from DATE. Before, it went to the agent as a message and started a chat.

Secret keys name their environment. A new one is vsk_live_… or vsk_preview_…; keys from before are plain vsk_… and keep working. The inbox creates a secret key as a live and preview pair, for one VATIO_SERVER_KEY variable with a different value per environment. vatio keys create secret --env live|preview still makes one at a time.

The vatio-add-to-app skill is gone (@vatio-ai/skills 1.27.0). To put the agent in your app, ask your coding agent to add the web widget or the iOS, Android or Flutter SDK. Running npx @vatio-ai/skills again removes the old copy.

0.105.0 — 2026-10-25

Agents no longer state amounts nobody gave them. A new safeguard, no_invented_amounts, runs on every reply of every agent: an amount of money in a draft ($25.000, US$49.99, 25 lucas) must be a number a tool returned in the conversation, an amount written in the prompt, or a quote that adds up from those (a quantity times a unit price, plus up to two other amounts, such as shipping). Any other amount sends the draft back to the model, as an unauthorized link does; if the model keeps writing it, the reply says the amount is not confirmed. A price the visitor proposed is never one, a price the owner gives in a conversation with one of the business’s own numbers is. send_image refuses a caption with an invented price. The inbox and vatio chat show name the policy on a discarded draft. See Safeguards.

0.104.0 — 2026-10-25

vatio whatsapp mine: your numbers from the CLI, before a number is connected. vatio whatsapp mine NUMBER... sets the business’s own numbers (the inbox’s Your numbers), --clear empties the list, and with no arguments it prints them; plain vatio whatsapp prints them too. They now belong to the workspace rather than to the connected number, so they can be set first and they outlive reconnecting one. On the preview number the list decides who is the business: list your test phone to try access: owner tools, leave it off to talk to the agent as a customer. See Your numbers.

0.103.0 — 2026-10-25

Owner tools and photos on WhatsApp.

  • access: owner gives a tool only to the business itself: a WhatsApp conversation with one of Your numbers (Channels → WhatsApp). Anyone else is never shown the tool, a call that names it anyway is refused with owner_only, and in an owner conversation the agent is told it is talking with the business. Run the business from WhatsApp with it: update stock, confirm a payment, add a product from a photo. In preview, while Your numbers is empty, every phone verified on Try the agent counts as one. See Access.
  • send_image, a new built-in tool, sends a WhatsApp contact a photo one of your tools returned in the conversation, with a caption, right after the reply: a product from your catalog, say. A URL the agent wrote or a visitor typed is refused. JPEG or PNG over https, up to 5 MB and 10 a turn; the photos show in the inbox. See Photos.

0.102.0 — 2026-10-24

Fewer surfaces: the CLI and the MCP. The HTTP developer API behind them (/api/developer/v1, vat_ tokens) is no longer documented and is not a supported surface: it can change without notice. What your own backend calls stays documented and stable: messages with a secret key, webhooks and errors.

  • vatio contacts export ID and vatio contacts delete ID replace the Contacts API for access, portability and erasure requests. export prints the JSON (or writes it with --out FILE); delete shows what goes and asks you to type the id, and needs --yes without a terminal. See Contacts. The MCP gets the same two as export_contact and erase_contact; erasing needs confirm_contact_id to repeat the id.
  • Routines are gone. vatio routines and the routine: tool file no longer exist. To hand work to Claude from WhatsApp, use an ordinary tool that calls your own backend, which checks who is asking and fires the routine’s API trigger. See Give Claude a WhatsApp number.
  • Supabase sign-in is gone. vatio auth --supabase and auth: supabase: in vatio.yml no longer exist, and the widget no longer reads the page’s Supabase session. An app on Supabase signs the visitor token in an Edge Function like any other stack; see Authentication. Nothing in production used it.

0.101.0 — 2026-10-23

One concept, API keys, of two kinds. What was a publishable token and what was a server key are now the publishable key (vatpub_…, for a page or an app) and the secret key (vsk_…, for your backend). The values and prefixes of the keys you already have do not change, and neither do the widget’s data-token, the SDKs’ token or the Authorization: Bearer header. In the inbox they are one page, Settings → API keys, with a single New key button at the top right that asks the kind.

This breaks Vatio’s own commands and REST paths, with no aliases:

  • vatio tokens is gone. vatio tokens create --env live --label website --origin URL is now vatio keys create publishable --env live --label website --origin URL, and vatio tokens origins PREFIX URL... is vatio keys origins PREFIX URL....
  • vatio keys create needs publishable or secret. There is no default kind: what used to be vatio keys create --env live is vatio keys create secret --env live. --origin is only for a publishable key.
  • vatio keys list shows both kinds, with a kind column and the keys Vatio manages marked. --json prints the list.
  • The developer API replaces publishable_tokens and server_keys with api_keys: GET and POST /api_keys (the body names the kind), PATCH /api_keys/:prefix for a publishable key’s origins and DELETE /api_keys/:prefix. The create response carries the full key once and the new api_key. An unknown kind answers 422 invalid_key_kind. See API keys.

0.100.3 — 2026-10-23

Security fixes.

  • Signing in from the CLI. The approval page no longer emails a sign-in link. To sign in with your email there, you get the regular code by email, type it in the same browser, and come back to approve the terminal. Google and GitHub work as before.
  • Inviting from the CLI. vatio team invite now needs two-step verification on your account. Without it, invite from the inbox, under Team.
  • Two-step verification for the riskiest changes. In the inbox, inviting a member, minting a server key, offering the workspace to a new owner and deleting it now need two-step verification on your account. Security lists who on the team doesn’t have it yet.
  • MCP tokens. A token issued to an MCP client over OAuth now works only at /mcp, not on the rest of the developer API.
  • Credentials in the CLI. The file that holds your token is created readable only by you.
  • Opening your browser on Windows. The CLI no longer opens it through cmd.exe.

0.100.2 — 2026-10-22

Vatio no longer triages or fixes reports itself. It used to read each report as it was filed, say where the fix lived and, for the agent’s instructions or a knowledge entry, change preview and test the change on its own. Every open report is now your developer’s, to fix with their coding agent through /vatio:vatio-improve, and Vatio changes nothing on preview by itself. Continuous improvement lists the reports by state, with the latest test, and vatio flags no longer has a What Vatio did section.

“Connect Supabase” is gone from the inbox. No workspace used it. Your Supabase project is named in vatio.yml (auth: supabase:), and vatio auth --supabase reads it from the .env of your project or from the URL you pass. Nothing changes for a project that already declares it.

The Test page is gone: Try the agent, Tests and versions moved. Try the agent, a button at the top of Conversations, opens the web chat, the shared WhatsApp number and the shared Instagram account over the list. Conversations has a Customers | Tests switch, and Tests holds what the team said to the agent on preview. The version cards are at the top of Continuous improvement, read-only: Publish, Run tests and the knowledge-conflict page left the inbox. You publish with vatio publish, run tests with vatio test and resolve a knowledge conflict by reading the entry from live (vatio kb cat BASE ENTRY --env live) and writing your change on top (vatio kb write), or by asking your coding agent; vatio kb publish publishes knowledge alone. review_url and knowledge_url are now always null. Old /<workspace>/test links redirect, and the link vatio push prints opens Try the agent. On Channels, the packages card became one card that points at /vatio-add-to-app and the documentation.

The Contacts page and the inbox’s contact export are gone. The inbox no longer lists or searches every person, and it no longer exports one. A person is seen and forgotten from their conversation: the contact pane beside it keeps their name, channels, memories and other conversations, and Forget this contact (owner and developers). The per-person export and delete stay in the developer API (GET /contacts/:id/export, DELETE /contacts/:id), with a token and recorded in Activity. Old /<workspace>/contacts links land on Conversations.

0.100.1 — 2026-10-22

vatio share-session no longer sends another session when it cannot find the one it runs in. Run from inside Claude Code or Codex, it takes that session. When that session’s file was not where it looked, it used to fall back, without a word, to the newest session for the directory: another conversation. It now stops and says so, and --list and --id ID pick one. From a terminal it still takes the newest session for the directory.

vatio test no longer fails a case only because a replay is not signed in. A replay never has a signed-in visitor, so an access: private tool it calls for real answers not_authenticated. A case that failed because of that is now marked not tested (a tool needs a signed-in visitor) with the tool, like a case that needed the test phone’s contact, instead of reading as a regression of your agent. Calls the reported turn made still get the answer your backend gave then.

0.100.0 — 2026-10-22

vatio team: see who is in the workspace and invite someone. vatio team lists the owner and everyone invited, and who has not signed in yet; vatio team invite EMAIL --role viewer|supervisor|developer invites them and emails them, the same invitation as the inbox’s Team page. It is the owner’s alone, as there, and the role has to be named. When the owner’s account has a second factor, the invite takes a fresh code from it (--code), as the inbox asks the owner to confirm. Removing someone and changing a role stay in the inbox. See Team.

vatio whatsapp test-phones lists the phones verified on the Test page. A coding agent that needs a number to send a preview message to no longer has to ask the developer for it. Plain vatio whatsapp prints them too, whether or not the workspace has a number of its own. Adding a phone is still only in the inbox. See Channels.

0.99.1 — 2026-10-22

vatio share-session says what to do when you run it after ! in Claude Code. Typed at Claude Code’s ! prompt, it has no terminal to ask from, so it refused with a message addressed to a coding agent, and nothing was sent. It now also tells the person to add --yes. Nothing else changes: it still sends only after a yes, or with --yes.

0.99.0 — 2026-10-22

A push says who can see it, not which environment it landed in. Until someone outside your team talks to your agent the workspace is a draft and live follows every push, so vatio push said to preview about a version that was already answering people. It now says what happened instead: Your agent is answering with this now while the workspace is a draft, and once it is published, which deployment visitors still get and what is left before they get this one. The environment is named only when the push is waiting for a vatio publish. The docs follow the same order: Draft and published comes first, and preview appears where it starts to mean something. staging and sandbox are still accepted as names for preview and are no longer documented.

An unknown command suggests the closest one. vatio puhs offers push, a subcommand on its own (vatio show) lists the commands it belongs to, a sentence (vatio "do you deliver?") offers vatio chat, and the package name used as a command — npx @vatio-ai/cli @vatio-ai/cli push, the commonest way to get the invocation wrong — says so and prints the command to run. It used to answer all of them with the whole help text, which is where the reader had already failed to find what they wanted.

vatio secrets set KEY --from-env takes the value from your shell or the .env beside your vatio.yml and sends it without printing it, so a coding agent can set a secret it is not allowed to read instead of stopping to ask you to run the command. Only the key you name is read. --from-env NAME reads a different local name. See Secrets.

One http://localhost origin covers every port. A publishable token that lists http://localhost:3000 now works on :5173 or whatever port your dev server picked today, the way a loopback OAuth redirect URI already did (RFC 8252 §7.3). A changed PORT was silently a blank widget. Only http loopback: https://localhost:5000 is still its own origin. See Tokens.

vatio test explains how to start a suite. With nothing to replay it pointed at reporting a reply that went wrong, which is no help on a workspace where nothing has gone wrong yet; it now shows vatio chat --new plus vatio test add, which is how a reply that is already right is kept. A test run’s report no longer fails with an uncaught timeout when it takes a while to render: it says the run is still on Vatio’s servers and to ask again.

vatio changelog says what a newer release would bring. It prints which release is current, the headline of every change between the version you have and that one, and the npm command that installs it; --full prints each entry whole. npm still does the updating, so vatio update is still not a command — its refusal names this one now. That refusal was the only answer a coding agent could get, because the “a new release is available” notice prints only to a terminal and an agent has none. The automatic jump to the current release (426 cli_outdated) names the command as well.

0.98.0 — 2026-10-22

The plan belongs to an organization. Every workspace now sits in an organization, and the plan, the subscription and the monthly conversations belong to it: its workspaces share one plan, and the conversations of all of them count against it. Whoever has one workspace sees no difference. The owner of an organization can add more workspaces to it, each one an agent for a different workflow, with vatio init SLUG --org ORG or the create_workspace tool’s organization argument. A workspace transferred to someone else leaves for an organization of its own unless it was the only one in its organization, which then goes along with its plan. Contacts and conversations stay in the workspace they belong to.

0.97.0 — 2026-10-21

Choose when the agent does not answer. A weekly schedule, with any number of ranges per day and a time zone, in which the agent stays silent on every channel. A message that arrives inside a range is not answered afterwards: it waits for your team in the inbox. Set it in the inbox under Channels → Quiet hours, or with vatio quiet-hours. Without one the agent answers around the clock. See Human in the loop.

0.96.0 — 2026-10-20

Tools can send the visitor’s files. A tool parameter declared with format: vatio-attachment takes a file the visitor sent in the conversation, such as the screenshot on a support ticket. The agent picks the file by the attachment id it now sees next to each one. Your backend gets a link that expires after 1 hour, with the filename, type and size. Only files the visitor sent in that conversation can be sent; any other value goes back to the agent as invalid_argument. Each file sent appears on the Activity page. $params.<name>.<field> reads a field of an object argument, such as $params.screenshot.url. See Visitor files.

0.95.0 — 2026-10-19

One request, bounded retries. Vatio retries confirmed WhatsApp send and delivery failures for developer messages in every mode. A request keeps the same message ID and idempotency key through four total attempts; the API and inbox show the attempt count and next retry time. In a conversation, the message’s receipt says which attempt got it through, and its tooltip when each retry ran and after which error. The developer receives a failure webhook when Vatio has no safe attempts left. Opt-outs and uncertain send outcomes stop immediately to avoid unwanted or duplicate messages. vatio messages failed lists final failures; the separate resend command and API are removed.

0.94.0 — 2026-10-19

Review failed WhatsApp messages. The inbox groups failures by cause, the server API and vatio messages failed filter them by error and date, and a channel.issue webhook reports account-level problems. This version also introduced separate resend attempts, which 0.95.0 replaces with retries on the original request.

October 12–18, 2026 →