# An AI agent on Instagram

Instagram is an added channel for the agent that already serves your app. You ask for it, talk to the agent from your own Instagram account through a shared preview account, and when it answers well you publish it and connect your professional account. This guide is the task path: what to ask for, what you will see, how to try it and what to check before going live. Every option of the channel is in the [Instagram reference](https://vatio.ai/docs/channels/instagram).

## One agent, every channel

There is no separate Instagram agent. A workspace runs one agent, and the channel only changes how its replies are delivered, so the agent already in your app's web widget or mobile SDK is ready for Instagram. The app is the starting point:

1. **Fastest, from any chat.** Add the remote MCP server `https://vatio.ai/mcp` as a connector in Claude, ChatGPT or Cursor, sign in with a Vatio account and ask for the agent. It is created in a preview to try; nothing reaches users until you publish ([Vatio in Claude and ChatGPT](https://vatio.ai/docs/mcp)).
2. **To build the agent into your app's code.** In the project run `npx @vatio-ai/skills`, then `/vatio-init`, and `/vatio-improve` daily. See [Build an AI agent for your app](https://vatio.ai/docs/guides/build-an-ai-agent).

Then ask your coding agent or chat to add Instagram and prepare the agent for what people send there. Say your app is the online shop of Marlow Home, a furniture and decor brand that sells mostly through its Instagram. This is the kind of `vatio.yml` it writes, for you to review:

```yaml
workspace: marlow-home
agent:
  name: Marlow Home
  personality: Friendly and quick. Short messages, the way people write in DMs.
  instructions: |
    You answer customers of Marlow Home, a furniture and decor shop that
    sells online and from its showroom at 88 Harbor Road.

    Every product has a code like MH-0412, on the image and in the caption
    of each post. When someone asks about a product, look for the code in
    their message or screenshot and call find_products with it. Without a
    code, search by what they describe or what the image shows, and ask
    which one they mean if several match. Give the price, whether it is in
    stock and the product link the tool returned.

    If they send something you cannot read, ask for the product code or
    a screenshot. For shipping, returns and the showroom,
    search knowledge_lookup first.

    Never invent a price, a stock level or a delivery date.
  tools: [find_products, ask_for_a_person, knowledge_lookup]
  knowledge: [shop]
```

## What people send on Instagram

Instagram DMs are short: "price?", "info", "still available?", "do you ship to Denver?", often with a screenshot, because the person wrote from the feed. A typical exchange:

> **Customer:** price? *(screenshot of a post)*
>
> **Agent:** That's the Linden oak side table, MH-0412: $189, and it's in stock. https://marlow-home.example/p/mh-0412
>
> **Customer:** do you ship to denver
>
> **Agent:** We do. Furniture ships for $35 per order and takes 5 to 7 working days to Colorado. You can also pick it up at the showroom for free.

Behind those replies, the agent read "MH-0412" in the screenshot, called `find_products` with it and looked up shipping in the knowledge base. The link came back from the tool, which is what allows the agent to send it. Three habits make this work:

- **Put a code on every post**, on the image and in the caption. The agent reads images, so a screenshot with a code in a corner becomes a lookup by code instead of a guess about which oak table it was.
- **Answer before asking.** "price?" deserves a price; questions come after.
- **Prices and stock come from a tool**, and everything that changes slowly from knowledge.

Your coding agent stores the API address and key as secrets:

```bash
vatio secrets set SHOP_API https://api.marlow-home.example
vatio secrets set SHOP_API_KEY sk_live_...
```

Then it writes the tool, `tools/find_products.yml`:

```yaml
description: Search the catalog by product code or by description.
when_to_use: The customer asks about a product, its price or stock, by code, by description or with a screenshot.
parameters:
  type: object
  properties:
    code: { type: string, description: "Product code, e.g. MH-0412" }
    query: { type: string, description: "What the customer describes or the image shows, e.g. oak side table" }
access: public
request:
  method: GET
  base_url: "$env.SHOP_API"
  path: /products/search
  headers:
    Authorization: "Bearer $env.SHOP_API_KEY"
  query:
    code:
    q: "$params.query"
respond:
  data:
    products: "$.products"
  message:
    when_empty: No product matches that code or description.
    default: "Found {{count}} matching products."
```

Have the endpoint return each product's name, price, stock and page URL, and nothing you would not put on a post: whatever a tool returns, the model can repeat.

Shipping, returns and the showroom go in a [knowledge base](https://vatio.ai/docs/knowledge), one entry per topic. Your coding agent writes them, and supervisors read them from **Knowledge** in the inbox:

```bash
vatio kb create shop
vatio kb write shop shipping shipping.md
vatio kb write shop returns returns.md
vatio kb write shop showroom showroom.md
```

```markdown
# Shipping

## Cost and delivery times
Small items ship for $9 and furniture for $35 per order. Delivery takes
3 to 5 working days on the East Coast and 5 to 7 elsewhere in the
continental US. Pickup at the showroom is free.
```

Vatio does not read websites, and a caption the agent was never sent is not something it knows: put what matters in an entry or behind the tool.

## Test it on the shared preview account

Your coding agent pushes the change to preview and tries it before handing it to you:

```bash
vatio push
vatio chat "how much is MH-0412?"
vatio chat "the lamp I ordered arrived broken"
vatio chat show
```

The second message is a damaged delivery, so it should call `ask_for_a_person`; `chat show` tells you whether it did. `vatio chat` sends text and replies instantly, so screenshots and pacing need Instagram itself, on Vatio's preview account. Open **Try the agent → Instagram** in the inbox, scan the QR code and, from the account you will test with, send the DM the page shows; that proves the account is yours. Keep talking to the agent in that DM and read the conversation under **Tests** in Conversations. Instagram does not let Vatio write first, so your account sends the code instead of receiving one. The steps, `/new`, the limit of five test accounts and how codes work are in [Test with the shared preview](https://vatio.ai/docs/channels/instagram#test-with-the-shared-preview).

A test account reaches `preview`, never live.

Then write the way your followers do: a screenshot with "price?", three short messages in a row, a voice note about delivery.

## Connect your professional account

When the preview is right, publishing is your decision: ask to publish (`vatio publish`). The Free plan includes the owner's own account; see [Pricing](https://vatio.ai/pricing).

Then open **Instagram** in the inbox on live, choose **Connect Instagram** and complete Meta's consent. It has to be a professional account. There is no switch to turn on afterwards: as soon as the account is connected, your live deployment answers its DMs, which is why you publish first. **Verify** checks that the account is receiving DMs. Account limits, token renewal and **Reconnect** are in [Connect your professional account](https://vatio.ai/docs/channels/instagram#connect-your-professional-account).

Before you connect, check that the preview answered the cases you care about, including the one that asks for a person. From then on each version you approve for publication changes what the account answers with, and `vatio rollback` restores the previous one.

## How an Instagram conversation behaves

- **A conversation lasts until eight hours of silence.** After the customer's last message is more than eight hours old, the next one starts a new chat.
- **Fragments become one question.** Vatio groups messages that arrive together, waits for a quiet moment and for media still being processed, then answers once.
- **Edits and unsends follow the customer.** An edited DM shows its new text in the inbox, marked as edited, and the agent reads it from then on; an unsent one disappears from both. Neither is a new message, so the agent does not answer it.
- **Images, voice notes, PDFs and videos are read.** Supported files up to 8 MB each reach the agent, audio is transcribed, and a video up to 14 MB is watched once when it arrives. Anything unsupported or larger stays available to supervisors, and the agent is told it cannot read it.
- **Replies are text, paced like a person typing**: short plain-text messages with typing indicators. The agent cannot send images or files, so the product page carries the photos and the link is what it sends.
- **Links are allowlisted.** The agent only sends URLs it was given, in `links`, its instructions or a tool's result. Any other URL is stripped.

## Who the agent is talking to

An Instagram contact starts out anonymous to your backend: there is no page where it can sign a token saying who they are, so until they sign in only public tools run. A customer's own orders or account belong behind a login, in a tool marked `access: private`. With `sign_in_url` in `auth:`, that tool sends the customer a **Sign in** button that opens your site; your page redirects back with the same token you put on the widget, Vatio asks them to confirm the @handle being connected, and the conversation picks up where it left off ([On WhatsApp and Instagram](https://vatio.ai/docs/authentication/sessions#on-whatsapp)). [An AI chat for your web app or site](https://vatio.ai/docs/guides/ai-chat-widget-for-your-website) shows how to sign the token.

A DM carries no phone number either. On WhatsApp the agent already has the customer's number; on Instagram it has one only if the customer types it. A tool that needs a phone or an email, say to book a showroom visit, takes it as a parameter, and your backend validates it. To check an order for someone who has not signed in, take the order number plus a second detail, such as the email on it, and have your backend verify that they match. The model fills parameters, so that check belongs in code, never in the prompt.

## When a person takes over

Supervisors you invite from **Team** in the inbox see every Instagram conversation in the inbox, with each tool call next to the reply it produced.

- **Replying in the inbox is a takeover.** It pauses the agent on that conversation. **Hand back to agent** releases it, or the takeover expires 8 hours after the last reply from your team; every human reply restarts that clock.
- **The agent can ask for a person.** It calls `ask_for_a_person`, which sends your backend the reason and a link that opens the conversation in the inbox. Your backend alerts whoever should answer: a WhatsApp to the showroom, a Slack channel, an email. Whoever opens the link and replies takes the conversation over.
- **Until then, the agent keeps helping**, and tells the customer it is checking with a colleague. Calling the tool is the model's decision, so try it on the preview account.

`tools/ask_for_a_person.yml`:

```yaml
description: Tell the team that this conversation needs a person.
when_to_use: >
  A damaged delivery or a complaint, a custom order or a trade discount,
  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" }
  required: [reason]
access: public
request:
  method: POST
  base_url: "$env.SHOP_API"
  path: /vatio/ask-for-a-person
  requires: [chat.url]
  headers:
    Authorization: "Bearer $env.SHOP_API_KEY"
  body:
    reason:
    chat_url: "$chat.url"
    name: "$contact.name"
respond:
  message: >
    The team was told. Tell the customer plainly that you are checking this
    with a colleague, who will answer here.
```

When a reply was wrong, choose **Report this reply** on it and write what should have happened. Running `/vatio-improve` in your coding agent fixes the cause, pushes preview and tests the reported cases; you approve publication. See [Improve](https://vatio.ai/docs/improve).

## Comments and outbound messages

The agent answers DMs people send it, because Instagram only lets a business write to someone who wrote first. Vatio sends no broadcasts, campaigns or follow-ups. The one exception is a comment on your post or reel: your backend can answer it with a private DM through the Messages API. See [Comments](https://vatio.ai/docs/channels/instagram#comments). There are no voice calls, and the agent never generates images or files.

WhatsApp works the same way, with a shared preview number and your own number; see [An AI agent on WhatsApp](https://vatio.ai/docs/guides/whatsapp-ai-agent).

## Frequently asked questions

### Can an AI agent answer Instagram DMs automatically?

Yes. You connect your Instagram professional account through Meta's consent screen from Vatio's inbox, and your live agent answers every DM sent to it. It is the same agent that answers in your app, described in the vatio.yml your coding agent writes.

### Do I need to connect my Instagram account to test the agent?

No. Vatio has a shared preview account. You scan a QR code in **Try the agent** in the inbox, send that account the code it shows from your own account, and talk to your agent from there. A workspace can have up to five test accounts, and they never reach live.

### Can the agent read screenshots and voice notes sent on Instagram?

Yes. Supported images, such as a screenshot of a post, are passed to the agent, and voice notes are transcribed, up to 8 MB per file. A video up to 14 MB is watched once when it arrives. Its replies are text only.

### Can the agent send the first DM or run Instagram campaigns?

No. Instagram only lets a business reply to someone who wrote to it, so Vatio sends no broadcasts or follow-ups. The exception is a comment on one of your posts: your backend can answer it with one private DM, within 7 days of the comment ([Comments](https://vatio.ai/docs/channels/instagram#comments)). Reminders and campaigns sent through the Messages API go out on WhatsApp.

### Can my team take over an Instagram conversation from the agent?

Yes. Supervisors see every conversation in the Vatio inbox and take one over by replying there, which pauses the agent on that chat. They hand it back from the inbox, or the takeover expires 8 hours after the last reply from your team.

### Can the agent look up a customer's orders on Instagram?

Yes, once the customer signs in. Public tools run for anyone, and a tool marked access: private runs for a signed-in contact: with a sign_in_url in vatio.yml, Vatio sends them a Sign in button that opens your website, and the conversation picks up when they are back. For customers without an account, the usual pattern is an order number plus a second detail, checked by your backend.

## Related guides

- [An AI agent on WhatsApp](https://vatio.ai/docs/guides/whatsapp-ai-agent): The same agent on WhatsApp: test on a shared number, then connect your own.
- [Orders, deliveries and returns](https://vatio.ai/docs/guides/ai-agent-for-orders): Order status, delivery estimates, changes your rules allow and returns, for each signed-in user.
- [Handoff](https://vatio.ai/docs/handoff): When the agent passes a conversation to your team.
