#An AI support agent for your app's signed-in users
An AI support agent for your app answers your users inside the app, where they are already signed in. It answers how-to questions from what your team has written, reads the user's own account (their plan, the status of something they started, their recent activity), troubleshoots one step at a time and reads screenshots of errors. When the steps don't fix the problem, it opens a ticket with what was tried, and billing disputes, cancellations and security concerns go to a person. With Vatio, your coding agent builds it from your app's project; Vatio runs the conversations, your team supervises them in the inbox, and nothing reaches your users until you approve it.
The same shape fits a SaaS product (plan, usage, a failed export), a fintech or insurance app (a payment, a policy, where a claim stands) or a job or admissions portal (where an application is).
#What the agent does
- How-to questions. "How do I invite my team?" It searches your knowledge and answers from it, or says it doesn't know.
- The user's own account. Their plan, whether a payment went through, the status of an application or a policy, their recent activity, the ticket they opened last week.
- "It's not working." It checks your status page for an incident first, then walks through the fix one step at a time, waiting for each answer.
- Screenshots of errors. It reads the message on the screenshot and searches your knowledge with it.
- A ticket with what was tried. When the steps didn't work, it opens one with a category, a summary and the steps already tried, so your team doesn't start from zero.
- Everything else goes to a person. Disputed charges, refunds and credits, cancellations, someone who thinks their account was accessed by someone else.
A typical exchange in your app's widget, with a signed-in user:
User: the export button does nothing since this morning
Agent: Sorry about that. There's no incident on our side right now, and your workspace is on the Team plan, which includes exports. When you click it, does anything appear, even for a second?
User: (sends a screenshot) just this
Agent: It says "Pop-up blocked". The export opens in a new tab and your browser stopped it. Click the icon at the right of the address bar, choose "Always allow" for this site, and try again.
Behind the first reply were a call to the status check and one to the user's account; behind the second, the screenshot and a troubleshooting entry in knowledge. In the inbox, each reply shows the calls the agent made, with their arguments and what your API answered.
#Start in your app's project
From a chat, the fastest start: add https://vatio.ai/mcp as a connector in Claude, ChatGPT or Cursor, sign in with your Vatio account and ask for this agent. It is created in a preview you can try; nothing reaches your users until you publish (Vatio in Claude and ChatGPT).
To build it into your app's code, run this in the app's project:
npx @vatio-ai/skills/vatio-initRun the first line in your app's project, then the second in Claude Code. In Cursor or Codex, ask it to use vatio-init. If you built the app in Lovable or Bolt, connect its project to GitHub and open it in Claude Code or Cursor first. You can say what you want right away:
/vatio-init a support agent for our signed-in users: answer from our docs, check their account and open a ticket when it can't fix itvatio-init reads your app: what it does, the API an agent could call, how your users sign in and the docs it could answer from. It tells you what it found, asks only what the code can't answer, writes the agent and pushes a preview. The first push opens your browser to sign in with email, Google or GitHub, and signing in creates your account. Nothing is published until you approve it.
#What vatio-init will ask you
- What do users contact you about? Usually a few how-to questions, something that stopped working, and their plan or billing.
- What does your team already answer? The replies and the troubleshooting steps your team repeats every week. They become the agent's knowledge.
- What must it never do? Ask for a password or a verification code, promise a credit or a refund, change a plan or close an account.
- When does a person take over? Billing disputes, cancellations, security concerns, a bug the steps didn't fix and the user won't wait for.
- Which systems does it read from? Your status page or incident feed, the API behind the user's account, and your ticketing system.
Your answers become the instructions, the rules it never breaks, the tools, including the one that asks for a person, and the knowledge. A vague answer gets a question back rather than a guess.
#How it reads the user's account
The agent knows who it is talking to the same way your app does:
- Your users sign in with Supabase. A Supabase Edge Function reads the Supabase session and signs the token (Supabase apps).
- Any other sign-in. Your backend signs a short-lived token for whoever is logged in and passes it to the widget; ask your coding agent to add that to your backend (Authentication). Vatio holds only the public key, so it can check who someone is but can never claim it.
Add a metadata claim to the token with a profile link and badges such as the plan or the payment status, and whoever takes over a conversation sees them at the top of it in the inbox, without opening your admin. A user who signs in halfway through keeps the same conversation, so the question that made them sign in doesn't need retyping.
Tools that read or change a user's own data are marked access: private. They run only for a signed-in user, and they forward that user's token to your API.
The security point is where the user comes from. A private tool cannot take user_id, customer_id or account_id as a parameter, and the deploy fails if one tries, because the model fills parameters and can be talked into filling in someone else's. Your API verifies the token and reads the user from it, so "show me the account of jane@example.com" cannot reach anyone else's data. See Private tools.
#What your coding agent writes
You don't edit these files by hand, but they live in your repository and you can review them like any other code. An excerpt of vatio.yml:
workspace: acme-appagent: name: Acme Support personality: Patient, clear and brief. One step at a time. instructions: | You support signed-in users of Acme. Answer how-to questions from knowledge_lookup; if it does not answer, say so.
Problems: call service_status first. If there is an incident, say so and do not open a ticket. Otherwise read my_account, then give the steps from knowledge one at a time, waiting for each answer. If my_account says it could not confirm who the user is, they are not signed in: send the sign_in link.
Tickets: call open_ticket only after the steps did not fix it, with what was tried. Only give a ticket number open_ticket returned.
Rules you never break: - Never ask for a password, a verification code or a card number. - Never promise a credit, a refund or a date. - Never change a plan or close an account; a person does that. tools: [knowledge_lookup, service_status, my_account, open_ticket, ask_for_a_person] knowledge: [help] links: sign_in: https://acme-app.example/loginauth: public_key: identity.pubtools/open_ticket.yml, a private tool:
description: Open a support ticket on the signed-in user's account.when_to_use: The steps did not fix the problem, there is no incident, and the user agreed to a ticket.parameters: type: object properties: category: { type: string, enum: [bug, account, billing, other] } summary: { type: string, description: "The problem in one or two sentences, with any error message word for word" } steps_tried: { type: string, description: "Each step tried and what happened" } required: [category, summary, steps_tried]access: privaterequest: method: POST base_url: "$env.ACME_API" path: /me/tickets headers: Authorization: "Bearer $auth.token" body: category: summary: steps_tried:respond: data: ticket: "$.ticket"tools/ask_for_a_person.yml, a public tool:
description: Tell the support team that this conversation needs a person.when_to_use: > The user disputes a charge or asks for a refund or credit, wants to cancel or downgrade, thinks someone else accessed their account, or asks to talk to a person.parameters: type: object properties: reason: { type: string, description: "Why it needs a person, in one line" } required: [reason]access: publicrequest: method: POST base_url: "$env.ACME_API" path: /vatio/ask-for-a-person requires: [chat.url] body: reason: chat_url: "$chat.url" name: "$contact.name" email: "$contact.email"respond: message: > The team was told. Tell the user plainly that you are checking this with a colleague, who will answer here.- No user id anywhere. Your endpoint opens the ticket on the account the token names.
my_accountis the same kind of privateGETwith no parameters at all;service_statusis public, because an incident is nobody's private data. - With Supabase, the same tool calls an Edge Function, forwarding the Vatio token the same way.
- Your API's address is a secret your coding agent stores in Vatio, never in the repository.
$chat.urlopens the conversation in the inbox. Your endpoint alerts whoever should answer, a Slack channel, an email or a ticket in your helpdesk, and their reply from the inbox takes the conversation over.- The agent keeps helping until then, and tells the user it is checking with a colleague. Calling the tool is the model's decision, so try a request for a person on preview and check the call in the inbox.
#Knowledge: what your team already answers
vatio-init turns what your team already answers into knowledge entries: Markdown, one topic per entry, each section able to answer a question on its own. Write troubleshooting steps so they work in words, because the agent replies only in text.
Vatio doesn't crawl your help center. If an answer lives on a page, what the agent needs goes into an entry. Once the agent is live, a supervisor who sees an outdated step reports the reply that used it, and the fix is tested on preview before it is published; every change is kept as a numbered version with who made it. More in Knowledge base.
#Try it before your users do
The link vatio-init gives you opens the inbox with Try the agent open, where you chat with the preview. Try what your users will:
- "The export button does nothing." It should check for an incident first, then give one step at a time, and open a ticket only after the steps fail.
- A screenshot of a real error message. It should read the message and answer from your knowledge.
- "This is broken, give me a month free." No promise: it should call
ask_for_a_personand say it is checking with a colleague. - "What plan is jane@example.com on?" It should read nothing: no tool takes an email or an id.
Questions about an account need a real signed-in user, so ask your coding agent to put the preview's widget in your app's development build, sign in as a test user and ask from there. When the answers are right, approve publication by asking your coding agent to publish.
#After launch
Your team reads real conversations in the inbox and takes one over by replying. When a reply is wrong, they report it and write what should have happened; that note becomes a test case.
Your daily routine is /vatio-improve in your coding agent. It takes every open report, fixes the cause where it lives (the instructions, a knowledge entry, a tool, or your backend), and pushes it to the preview. Vatio replays the reported cases against the preview, and you review the results and approve the update. Publishing is refused for a version that breaks a case live gets right, unless you explicitly override it. On mornings with new reports, a daily email brings the command.
A replay is a real agent turn, and its tool calls reach your backend. Give your API's secret a test value that points at a staging backend, and a replay's open_ticket or ask_for_a_person goes there; without one, the call is not sent at all. See Improve your agent.
#WhatsApp and Instagram
The same agent answers on WhatsApp and Instagram. There is no page there to carry a token, so your coding agent adds a sign_in_url to the auth: block: when a private tool needs a signed-in user, Vatio sends a Sign in button that opens your app's login page, and the conversation picks up where it left off once they are back (On WhatsApp and Instagram). Without it, people there get answers from knowledge and the status check, and the sign-in link for anything on their account. See Pricing.
#Frequently asked questions
#Can an AI support agent read a signed-in user's account in my app?
Yes, through tools marked private. Your backend signs a short-lived token for whoever is logged in. Vatio verifies it and forwards it to your API, which reads the user from the token. A private tool cannot take a user id as a parameter, so nobody can ask the agent for someone else's account.
#Where does a support agent get its answers to how-to questions?
From knowledge entries: Markdown your team writes, one topic per entry, which the agent searches before it answers. Vatio does not crawl your help center, so what the agent needs goes into an entry. Supervisors can fix an entry from the inbox the day a step changes, and every edit is kept as a version.
#Can users send a screenshot of an error to the support agent?
Yes. The agent reads images up to 8 MB, so a screenshot of an error message becomes text it can search your knowledge with and write into a ticket. It replies only in text, so troubleshooting steps should work in words.
#What should an AI support agent hand to a person?
Whatever you list in the when_to_use of the tool it uses to ask for a person: usually billing disputes, refunds and credits, cancellations, anyone who thinks their account was accessed by someone else, and anyone who asks for a person. The tool calls your backend with a link to the conversation, your backend alerts your team, and the agent keeps helping, saying it is checking with a colleague, until someone replies from the inbox.
#How do I fix a support reply that was wrong?
A supervisor reports the reply in the inbox and writes what should have happened. Then you run /vatio-improve in your coding agent: it fixes the cause in your project, Vatio replays every reported case against the preview, and you approve the update before your users get it.
#Related guides
- Connect your backend: Give the agent your API as tools, and let signed-in users reach their own data with a token your backend signs.
- Knowledge base: What the agent answers from: Markdown entries your coding agent writes and your team edits, versioned, tried in preview and published with the agent.
- Hand off to a person: When the agent passes a conversation to your team, what happens inside and outside office hours, and how it comes back.
- Your daily improvement routine: Report mistakes in the inbox, /vatio-improve has your coding agent fix them, and you approve the update.