Engagement

List, create, delete, and hide comments on published Instagram media.

Manage comments on published Instagram media. Works on feed images, carousels and Reels. Stories have no durable comments. The list returns UNSUPPORTED_MEDIA for Stories. Pass post as described in Analytics. Use the internal id for Onepostly posts. Use the native media id plus accountId for outside media.

Likes, bookmarks and reposts do not exist on Instagram.

Comments

List, create, delete, and hide comments on feed images, carousels and Reels.

List

Returns newest first. Top level comments include their replies.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.listComments({
  post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  limit: 25,
});
console.log(response);
{
  "comments": {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "subjects": [
      {
        "scope": "destination",
        "subjectId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
        "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
        "platform": "instagram",
        "externalPostId": "17895695668004550",
        "status": "ready",
        "comments": [
          {
            "id": "c1",
            "text": "Love this!",
            "username": "jane_doe",
            "likeCount": 12,
            "timestamp": "2026-08-25T10:05:00.000Z",
            "parentId": null
          }
        ],
        "nextCursor": null,
        "error": null,
        "externalUrl": "https://www.instagram.com/p/17895695668004550/"
      }
    ]
  }
}
QueryRequiredNotes
postYesInternal post id or native post id. Native ids require accountId
accountIdFor native idsDisambiguates the target account. Also narrows internal posts with several destinations
destinationIdNoGlobally unique. Resolves on its own or narrows one destination inside an internal post
limitNo1-50, default 25
cursorNoPagination cursor from the previous response nextCursor. Requires a single resolved target

Create

Creates a top level comment, or a reply when parentCommentId is set.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.createComment({
  createCommentBody: {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "text": "Love this!",
    "parentCommentId": "c0"
  },
});
console.log(response);
{
  "comment": {
    "id": "c1",
    "text": "Love this!",
    "username": "jane_doe",
    "likeCount": 12,
    "timestamp": "2026-08-25T10:05:00.000Z"
  }
}
BodyRequiredNotes
postYesInternal post id or native post id. Native ids require accountId
textYesComment text
accountIdFor native idsTarget account for native ids. Also disambiguates internal posts
destinationIdNoGlobally unique. Resolves on its own or targets one destination inside an internal post
parentCommentIdNoReply to a comment. Omit to comment on the media itself

Delete

Deletes a comment owned by the connected account. commentId is the comment id on Instagram. Get it from List above (comments[].id). The same id works for hide and private reply below.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.deleteComment({
  post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  commentId: "c0",
});
console.log(response);
{
  "deleted": {
    "postId": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "destinationId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
    "platform": "instagram",
    "commentId": "c0",
    "deleted": true
  }
}

Already deleted comments count as success.

Hide or unhide

Hides a comment so only its author still sees it, or reveals it again with hidden: false.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.hideComment({
  body: {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "commentId": "c0",
    "hidden": true
  },
});
console.log(response);
{
  "hidden": {
    "postId": "string",
    "destinationId": "string",
    "platform": "instagram",
    "commentId": "string",
    "hidden": false
  }
}

Private reply

Sends a direct message in response to a comment. One private reply per comment, 7-day window. Requires messaging access on the connection.

import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.createPrivateReply({
  body: {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "commentId": "c0",
    "text": "Thanks! Check your DMs."
  },
});
console.log(response);
{
  "reply": {
    "postId": "string",
    "destinationId": "string",
    "platform": "instagram",
    "commentId": "string",
    "reply": {
      "id": "string",
      "text": "string",
      "timestamp": "string"
    }
  }
}

Automations

Keyword auto-replies per connection, evaluated best-effort on inbound webhooks (max 20 rules). comment_to_dm answers matching comments with a private reply; story_reply and welcome_dm answer matching DMs. keywords are case-insensitive substring matches (at least one is required), and use excludeKeywords to skip messages that contain any of them:

import { Configuration, EngagementApi } from "@onepostly/sdk";

const engagementApi = new EngagementApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await engagementApi.createAutomation({
  createAutomationBody: {
    "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
    "kind": "comment_to_dm",
    "name": "Price questions",
    "keywords": [
      "price",
      "cost"
    ],
    "dmMessage": "Thanks! Check your DMs for details.",
    "excludeKeywords": [
      "priceless"
    ]
  },
});
console.log(response);
{
  "accountId": "string",
  "rule": {
    "id": "string",
    "name": "Free guide giveaway",
    "kind": "comment_to_dm",
    "keywords": [
      "guide",
      "free"
    ],
    "excludeKeywords": [
      "guidelines"
    ],
    "dmMessage": "Thanks for your interest! Here is your guide.",
    "enabled": false
  }
}
import { Configuration, EngagementApi } from "@onepostly/sdk";

const engagementApi = new EngagementApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await engagementApi.listAutomations({
  accountId: "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
  name: "guide",
});
console.log(response);
{
  "rules": [
    {
      "id": "string",
      "name": "Free guide giveaway",
      "kind": "comment_to_dm",
      "keywords": [
        "guide",
        "free"
      ],
      "excludeKeywords": [
        "guidelines"
      ],
      "dmMessage": "Thanks for your interest! Here is your guide.",
      "enabled": false,
      "accountId": "string"
    }
  ]
}

Outside Posts

Media published outside Onepostly works the same way once it is synced. Sync by URL then use the native id plus accountId in every comments call. Omit url and postId to refresh the recent posts of the account in bulk.

import { Configuration, PostsApi } from "@onepostly/sdk";

const postsApi = new PostsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await postsApi.syncExternal({
  syncExternalBody: {
    "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
    "url": "https://www.instagram.com/p/ABCdef123/"
  },
});
console.log(response);
{
  "synced": {
    "postsFound": 1,
    "postsSynced": 1,
    "skipped": false
  },
  "found": true,
  "post": {
    "id": "e8f9a0b1-c2d3-4e5f-8a6b-c7d8e9f0a1b2",
    "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
    "platform": "instagram",
    "externalPostId": "ABCdef123",
    "externalUrl": "https://www.instagram.com/p/ABCdef123/",
    "mediaKind": "text",
    "publishedAt": "2026-08-25T10:00:00.000Z",
    "syncedAt": "2026-08-25T10:00:00.000Z",
    "analyticsStatus": "ready"
  }
}
import { Configuration, CommentsApi } from "@onepostly/sdk";

const commentsApi = new CommentsApi(
  new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);

const response = await commentsApi.listComments({
  post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  limit: 25,
});
console.log(response);
{
  "comments": {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "subjects": [
      {
        "scope": "destination",
        "subjectId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
        "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
        "platform": "instagram",
        "externalPostId": "17895695668004550",
        "status": "ready",
        "comments": [
          {
            "id": "c1",
            "text": "Love this!",
            "username": "jane_doe",
            "likeCount": 12,
            "timestamp": "2026-08-25T10:05:00.000Z",
            "parentId": null
          }
        ],
        "nextCursor": null,
        "error": null,
        "externalUrl": "https://www.instagram.com/p/17895695668004550/"
      }
    ]
  }
}

Errors

CodeCauseFix
MISSING_EXTERNAL_IDDestination not published yetWait for publish
UNSUPPORTED_MEDIAStories have no durable commentsUse feed, carousel or Reels media
COMMENTS_PERMISSIONConnection lacks instagram_business_manage_commentsReconnect the account
TEXT_REQUIREDEmpty comment textAdd message text
COMMENT_CREATE_FAILEDInstagram rejected the commentCheck the error message for the Instagram reason
COMMENT_HIDE_FAILEDInstagram rejected the hide toggleCheck the error message for the Instagram reason
PRIVATE_REPLY_FAILEDInstagram rejected the private replyReconnect with messaging access; respect the 7-day window

See Also