On this page

#An AI agent for order status, changes and returns in your app

An AI agent for orders lives in your app's chat and answers a signed-in user about their own orders: where an order is and when it should arrive, as your API says; changing the address or cancelling while your rules still allow it; starting a return; and shipping and return questions, answered from your policy. Refunds, disputes and damaged items go to a person. It fits any app that sells or delivers something: a store, a marketplace, food delivery, a tracking app. With Vatio you start it from your app's project with two lines, your coding agent writes it against your own orders API, and you try a preview before any user sees it.

#What the agent does

  • Where is my order. The status, the carrier, the tracking link and the delivery estimate, exactly as your API returns them.
  • Delivery estimates. What the estimate means and why it moved, when your API says why. Never a date it worked out itself.
  • Changes your rules allow. A new address before the order ships, a cancellation before it is dispatched. Your API refuses the rest, and the agent explains why.
  • Returns. It checks the policy, asks which items and why, starts the return and sends the instructions link your API returns.
  • Policy questions. Shipping times and costs, return windows, exchanges, from knowledge entries you own.
  • Everything else goes to a person. Refunds, charge disputes, damaged or wrong items, a "delivered" order that never arrived, and anyone who asks for a person.

A typical exchange in your app's widget, with a signed-in user:

User: where's my order? it was supposed to come yesterday

Agent: Your order LK-20931, the linen duvet cover, shipped on Monday with Parcelway. It was scanned at their Columbus depot this morning, and their new estimate is Thursday. You can follow it here: https://track.parcelway.example/LK20931

User: can you send it to my office instead?

Agent: I can't change the address anymore: it can only be changed until an order ships, and this one left on Monday.

Behind the first reply was one call to my_orders: the estimate and the tracking link came from your API, which is what allows the agent to send that link. The second needed no call, because my_orders had already said the order shipped; had the agent tried change_address, your API would have refused it too. Every tool call is visible in the inbox, next to the reply it produced.

#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-init

The first line installs the Vatio skills in your project. The second runs in Claude Code; in Cursor or Codex, ask your coding agent to use vatio-init. You can say what you have in mind:

/vatio-init an agent that answers order status and starts returns for signed-in users through our orders API

vatio-init reads your app first: its orders endpoints, how users sign in, any shipping or returns page. The first time it pushes the agent, your browser opens to sign in with email, Google or GitHub, and that creates your Vatio account.

#What vatio-init will ask you

It asks only what your code can't answer:

  1. What may the agent change, and until when? For example, the address until the order ships and cancellation until it is dispatched, and nothing after that. If an action has no endpoint yet, say whether your coding agent should add one or whether your team keeps doing it.
  2. What are your return rules, in your words? How many days, in what condition, who pays the return shipping, exchange or refund. They become a knowledge entry.
  3. What must it never promise? Usually a refund, a credit, or a delivery date your API didn't return. And it never asks for card details.
  4. When does a person take over? Damaged or wrong items, refunds and disputed charges, orders marked delivered that never arrived, complaints.

The answers become the agent's instructions, its tools, including when it asks for a person, and its knowledge.

#How it reaches your orders

The agent can only show someone their own orders if it knows who they are, and that comes from your app's sign-in, never from what someone types in the chat.

  • Your users sign in with Supabase. This is common in apps built with Lovable or Bolt. A Supabase Edge Function reads the Supabase session and signs the token (Supabase apps).
  • Your own backend signs users in. Your backend signs a short-lived token for whoever is signed in, and the widget carries it. Your coding agent can add that to your backend (Authentication): a keypair whose public half stays with the agent and whose private half goes into your backend's secrets, so Vatio can check a token but never create one.

Tools that read or change orders are marked access: private and forward that token to your API. Your endpoint verifies it and takes the user from it. A private tool can't take the user's id as a parameter: one that declares user_id or customer_id fails the deploy, because the model fills parameters and can be talked into filling that one with someone else's id. An order number is fine as a parameter, because your API looks it up only among that user's orders and answers 404 for anyone else's. See Private tools.

On Supabase, the same tools call your Edge Functions with the Vatio token, and each function reads the orders of $auth.subject. Never give a tool the service-role key.

Keep the rules themselves in your API too: "only before it ships" belongs in the endpoint, not only in the instructions. When it refuses, answer with a status like 409 and a message that says why ("This order has already shipped, so the address can no longer be changed"), and the agent passes that reason on instead of guessing one.

#What your coding agent writes

You don't edit these files by hand, but they live in your project and they are yours to review. An excerpt of vatio.yml:

workspace: larkspur-home
agent:
name: Larkspur
instructions: |
You help Larkspur customers with their own orders: where an order is,
when it arrives, changing it while that is still possible, returns, and
questions about shipping and returns.
Orders: call my_orders before saying anything about an order. Give the
status, the delivery estimate and the tracking link it returned. If it
returned no estimate, say there isn't one yet.
Changes: the address can change until the order ships, and an order can
be cancelled until it is dispatched. Read the change back to the
customer before calling change_address or cancel_order. If the tool
refuses, give its reason.
Returns: check the policy with knowledge_lookup, ask which items and
why, call start_return and send the instructions link it returns.
If an order tool says it could not confirm who the customer is, they
are not signed in: ask them to sign in to the app, and do not guess.
Rules you never break:
- Never promise a refund, a credit or a delivery date a tool did not return.
- Never ask for card numbers, passwords or codes, and never take a payment.
tools: [my_orders, change_address, cancel_order, start_return, ask_for_a_person, knowledge_lookup]
knowledge: [orders]
auth:
public_key: identity.pub

Asking for a person is a tool too, tools/ask_for_a_person.yml. It sends your backend the reason and a link that opens the conversation in the inbox, and your backend alerts whoever should answer: a WhatsApp to your support lead, a Slack channel, a ticket in your helpdesk (Hand off to a person):

description: Tell the team that this conversation needs a person.
when_to_use: >
An item arrived damaged, wrong or incomplete, the customer asks for a
refund or disputes a charge, tracking says delivered and the customer
says it never arrived, a complaint about an order or the service, or the
customer asks to talk to a person.
parameters:
type: object
properties:
reason: { type: string, description: "Why it needs a person, in one line, with the order number" }
required: [reason]
access: public
request:
method: POST
base_url: "$env.LARKSPUR_API"
path: /vatio/ask-for-a-person
requires: [chat.url]
body:
reason:
chat_url: "$chat.url"
name: "$contact.name"
phone: "$contact.phone_number"
respond:
message: >
The team was told. Tell the customer plainly that you are checking this
with a colleague, who will answer here.

The agent keeps helping until someone on your team replies from the inbox, which takes the conversation over. Calling the tool is the model's decision, not a guarantee, so try it on preview.

One of the order tools, tools/start_return.yml:

description: Start a return for items in one of the signed-in customer's orders.
when_to_use: The customer wants to return items, has said which ones and why, and the policy allows it.
parameters:
type: object
properties:
order_number: { type: string, description: "From my_orders, e.g. LK-20931" }
items: { type: string, description: "Which items, as my_orders names them" }
reason: { type: string, enum: [changed_mind, wrong_size, not_as_described, other] }
required: [order_number, items, reason]
access: private
request:
method: POST
base_url: "$env.LARKSPUR_API"
path: /me/returns
headers:
Authorization: "Bearer $auth.token"
body:
order_number:
items:
reason:
respond:
data:
return: "$.return"

Your endpoint finds the order among the token's user's orders, checks the return window, creates the return and answers with its code and a link to the instructions. my_orders is a private GET to /me/orders with the same header and no parameters at all. If one action needs several calls in your backend, your coding agent puts them behind one endpoint, so the agent makes one call.

#Try it before your users do

vatio-init ends by pushing a preview and giving you the link to the inbox, with Try the agent open, where you chat with it before anyone else can. The order questions need a signed-in user, so also ask your coding agent to put preview's widget in your app's development version, sign in as a test user, and try:

  • "Where's my last order?" The status, estimate and tracking link should be what your API returned, with nothing added.
  • Change the address of an order that already shipped. It should refuse with your API's reason, and not promise anything else.
  • "I want a refund." It should call ask_for_a_person without promising one, and say it is checking with a colleague.
  • Another test user's order number. It should get nothing: your API answers 404.

Preview calls your API for real, and a cancellation is a cancellation, so point it at a staging copy of your API: your coding agent gives the API's secret a test value (--tests). When the agent answers the way you want, approve publication: tell your coding agent to publish. Nothing goes live until you do.

#After launch

Your team reads conversations in the inbox, with every tool call next to the reply it produced. When a reply is wrong, they choose Report this reply and write what should have happened, for example: "Should have said the return window closed on October 2 instead of offering a return." A stale policy can also be fixed right there, in its knowledge entry; every edit is kept as a version.

Then, once a day, run /vatio-improve in your coding agent. It reads the open reports, fixes each cause where it lives (the instructions, a knowledge entry, a tool or the endpoint it calls) and pushes a preview, and Vatio replays every reported case against it. You review which cases pass and approve the update; publication is refused if a case that passes on live fails on preview. The daily email brings the command when new reports arrive. Replays call your tools too, so the staging value matters here as well. See Improve your agent.

#WhatsApp and Instagram

The same agent also answers on your WhatsApp number and Instagram account (Pricing). There is no page there to carry the user's token, so add your login page as sign_in_url: when an order tool runs for someone who isn't signed in, Vatio sends them a Sign in button, they sign in the way your app already works, and the conversation picks up where it left off. Your coding agent adds it; it is the sign_in_url under auth:. On WhatsApp, Vatio asks the person to confirm the number being connected unless the account's phone matches it, so a forwarded link can't connect someone else's account (On WhatsApp and Instagram). Until they sign in, the agent can still answer policy questions from knowledge.

#Frequently asked questions

#Can an AI agent tell a user where their order is?

Yes, when the user is signed in to your app. The agent calls a private tool that forwards their token to your orders API, your API returns only that user's orders, and the agent answers with the status, the delivery estimate and the tracking link your API returned. It never works out a date on its own.

#Can the agent cancel an order or change the delivery address?

Only what your API allows. You decide the rules, such as changing the address until the order ships or cancelling until it is dispatched, and your endpoint enforces them. The agent reads the change back before making it, and when your API refuses, it explains the reason your API gave.

#Does Vatio connect to Shopify or my store platform?

There is no built-in connector for any store platform. A tool is one HTTP request to your app's own API, described in YAML. If your orders live in a platform, your backend calls it behind one endpoint of yours, and the agent calls that endpoint.

#Can someone see another customer's order by typing its order number?

Not if your API scopes each lookup to the signed-in user. A private tool cannot take a user id as a parameter, so your API reads the user from the verified token, looks the order number up only among that user's orders, and answers 404 for anyone else's.

#Does the agent give refunds?

No. Refunds, charge disputes and damaged or wrong items go to a person: the agent calls a tool that alerts your team with a link to the conversation, where the order is already looked up. The agent's instructions forbid promising a refund, and it never asks for card details or takes a payment.

  • 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.
  • 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.
  • Support for signed-in users: Answer from your docs, check the user's own account, troubleshoot and open a ticket with what was tried.

Last updated:

Latest CLI version: 0.114.0 · Changelog · The whole contract as Markdown: /docs/docs.md · or vatio docs