---
title: Instagram
description: Instagram Direct Messages adapter using Meta's Instagram Messaging API.
tagline: Build Instagram DM bots with media, quick replies, reactions, and story replies.
package: @chat-adapter/instagram
---

# Instagram



<Callout type="info">
  Building for Facebook Messenger? Use the [Messenger adapter](/adapters/official/messenger) instead. It connects through the Messenger Platform API and uses a Facebook Page access token.
</Callout>

## Install

<PackageInstall package="@chat-adapter/instagram" />

## Quick start

<Callout type="info">
  The adapter auto-detects `INSTAGRAM_ACCESS_TOKEN`, `INSTAGRAM_APP_SECRET`, `INSTAGRAM_VERIFY_TOKEN`, `INSTAGRAM_ACCOUNT_ID`, and the optional `INSTAGRAM_API_VERSION` from the environment.
</Callout>

```typescript title="lib/bot.ts" lineNumbers
import { Chat } from "chat";
import { createInstagramAdapter } from "@chat-adapter/instagram";

export const bot = new Chat({
  userName: "mybot",
  adapters: {
    instagram: createInstagramAdapter(),
  },
});

bot.onDirectMessage(async (thread, message) => {
  await thread.post("Hello from Instagram!");
});
```

```typescript title="app/api/webhooks/instagram/route.ts" lineNumbers
import { bot } from "@/lib/bot";

export async function GET(request: Request) {
  return bot.webhooks.instagram(request);
}

export async function POST(request: Request) {
  return bot.webhooks.instagram(request);
}
```

## Configuration

<TypeTable
  type={{
  accessToken: {
    type: "string",
    description:
      "Instagram access token for the Messaging API. Auto-detected from `INSTAGRAM_ACCESS_TOKEN`.",
  },
  appSecret: {
    type: "string",
    description:
      "Meta app secret for `X-Hub-Signature-256` verification. Auto-detected from `INSTAGRAM_APP_SECRET`.",
  },
  verifyToken: {
    type: "string",
    description:
      "Webhook verification secret. Auto-detected from `INSTAGRAM_VERIFY_TOKEN`.",
  },
  accountId: {
    type: "string",
    description:
      "Instagram professional account ID. Auto-detected from `INSTAGRAM_ACCOUNT_ID`.",
  },
  apiVersion: {
    type: "string",
    default: '"v26.0"',
    description:
      "Optional Meta Graph API version override. Auto-detected from `INSTAGRAM_API_VERSION`.",
  },
  userName: {
    type: "string",
    default: '"bot"',
    description:
      "Bot username. Defaults to the connected Instagram account username after initialization.",
  },
  logger: {
    type: "Logger",
    default: "ConsoleLogger",
    description: "Logger used for adapter diagnostics.",
  },
}}
/>

## Meta app setup

<Callout type="info">
  This adapter uses **Instagram API with Instagram Login** and
  `graph.instagram.com`. It does not require a Facebook Page. The connected
  Instagram account must be a public professional Business or Creator account;
  personal and private accounts cannot use the Messaging API.
</Callout>

### 1. Create a Business app and add Instagram

1. Open the [Meta App Dashboard](https://developers.facebook.com/apps) and
   click **Create App**.
2. For the use case, select **Other**, then click **Next**.
3. Select the **Business** app type, then click **Next**.
4. Enter the app name and contact email and finish creating the app. Connecting
   a verified business is required before publishing, but can be completed
   later under **App settings > Basic**.
5. In the new app dashboard, find the **Instagram** product and click **Set
   up**.

Meta automatically adds **API setup with Instagram login**. Do not select
**API setup with Facebook login** for this adapter; that setup uses Facebook
or Page tokens and `graph.facebook.com`.

### 2. Add the test account and generate a token

1. In the left menu, open **Instagram > API setup with Instagram login**.
2. Under **Generate access tokens**, click **Add account** and sign in to
   the public Instagram professional account the bot will use.
3. Once the account appears, click **Generate token**, sign in again, and copy
   the token to `INSTAGRAM_ACCESS_TOKEN`.

Tokens generated in the App Dashboard are long-lived and valid for 60 days.
They are suitable for development and for accounts you own or manage. Refresh
or rotate the token before it expires.

For an app that connects other businesses' accounts, configure **Instagram
business login** and request these scopes in the login flow:

* `instagram_business_basic`
* `instagram_business_manage_messages`

Business Login returns a one-hour token. Exchange it server-side for a
60-day token through `https://graph.instagram.com/access_token`.

### 3. Get the Instagram professional account ID

The account ID is not the app ID or the app-scoped user ID. Query the
professional account associated with the token:

```bash
curl "https://graph.instagram.com/v26.0/me?fields=user_id,username&access_token=$INSTAGRAM_ACCESS_TOKEN"
```

Copy the returned `data[0].user_id` value to `INSTAGRAM_ACCOUNT_ID`.

Set the remaining secrets:

* In **App settings > Basic**, copy the Meta app's **App Secret** to
  `INSTAGRAM_APP_SECRET`. Meta uses this secret to sign webhook requests.
* Generate your own private random string for `INSTAGRAM_VERIFY_TOKEN`. This
  value is only shared with Meta during webhook verification.

### 4. Configure and activate webhooks

Deploy the GET and POST route shown above to a public HTTPS URL first, then:

1. Return to **Instagram > API setup with Instagram login**.
2. Under **Configure webhooks**, click **Configure**.
3. Set **Callback URL** to
   `https://your-domain.com/api/webhooks/instagram`.
4. Set **Verify token** to the same value as `INSTAGRAM_VERIFY_TOKEN`, then
   click **Save**.
5. Click **Manage** and keep these fields enabled:
   `messages`, `message_reactions`, `messaging_postbacks`, and
   `messaging_seen`.

Configuring the callback does not subscribe an Instagram account by itself.
Subscribe the account represented by the access token:

```bash
curl -X POST \
  "https://graph.instagram.com/v26.0/me/subscribed_apps?subscribed_fields=messages,message_reactions,messaging_postbacks,messaging_seen&access_token=$INSTAGRAM_ACCESS_TOKEN"
```

Send the professional account a DM from another Instagram account to verify
the `messages` webhook. Meta first verifies the callback with GET, then sends
event notifications with POST.

### 5. Prepare for production

Standard Access works for professional accounts you own or have added to the
App Dashboard. To connect accounts you do not own, complete Business
Verification and App Review for Advanced Access to
`instagram_business_basic` and `instagram_business_manage_messages`.
Request the **Human Agent** feature only if real support agents will use the
seven-day response window.

See Meta's current
[app creation guide](https://developers.facebook.com/docs/instagram-platform/create-an-instagram-app),
[Business Login guide](https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/business-login/),
and [webhook subscription guide](https://developers.facebook.com/docs/instagram-platform/webhooks/)
for dashboard changes and production review requirements.

## Supported messaging

* Send and receive Instagram direct messages.
* Send images, video, audio, and files using binary data or publicly accessible HTTPS URLs.
* Render supported card buttons as Instagram quick replies. Quick-reply taps are delivered to action handlers.
* Send typing indicators while work is in progress.
* Receive reaction events through `onReaction`.
* Receive replies to Instagram stories as direct messages. The original webhook remains available on `message.raw` when story-specific context is needed.

<Callout type="warn">
  Instagram's standard messaging window lasts 24 hours after the user's most recent message. `sendHumanAgentMessage` uses the `HUMAN_AGENT` tag for human-support replies within seven days, but Meta does not allow it for automated messages and may require approval.
</Callout>

### Buffered streaming

Instagram does not expose message editing, so streamed responses are buffered and sent as one message when the stream completes.

### Thread ID format

```
instagram:{accountId}:{userId}
```

Example: `instagram:17841400000000000:1234567890`.

## Feature support

<FeatureSupport />
