Overview

Comments and Engagement

Endpoints for reading and writing comments, likes, reposts, bookmarks and quotes, with the webhooks each action sends.

Read and reply to comments, moderate them, and like, repost, bookmark or quote posts from your connected accounts. Every endpoint targets its post with post, accountId or destinationId, described in Targeting a Post.

Support by Platform

PlatformList and reply to commentsDelete own commentHide commentLike commentPrivate replyLike postRepost and quoteBookmark
XYesYesNoNoNoYesYesYes
InstagramYesYesYesNoYesNoNoNo
FacebookYesYesYesYesYesYesNoNo
ThreadsYesYesYesNoNoNoYesNo
YouTubeYesYesNoNoNoYesNoNo
BlueskyYesYesNoNoNoYesYesYes
LinkedInNoNoNoNoNoNoNoNo
TikTokNoNoNoNoNoNoNoNo
PinterestNoNoNoNoNoNoNoNo

Calling an action a platform does not support returns UNSUPPORTED_PLATFORM. Platform specifics are on each platform's Engagement page, for example X.

On X, write actions are billed to your wallet like other X usage. When the wallet is empty they return INSUFFICIENT_WALLET.

Comments

List Comments

GET /v1/comments returns one entry in subjects per destination, each with its comments, nextCursor and error. Replies are nested under their parent in replies.

Prop

Type

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
      }
    ]
  }
}

Reply to a Post or Comment

POST /v1/comments publishes a comment from the account that owns the targeted destination. Returns 201 with the new comment.

Prop

Type

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": "Thanks for watching!",
    "parentCommentId": "17858893269000001",
    "accountId": "YOUR_INSTAGRAM_ACCOUNT_ID"
  },
});
console.log(response);
{
  "comment": {
    "id": "c1",
    "text": "Love this!",
    "username": "jane_doe",
    "likeCount": 12,
    "timestamp": "2026-08-25T10:05:00.000Z"
  }
}

Delete a Comment

DELETE /v1/comments deletes a comment your account wrote. Pass the selector and commentId as query parameters.

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",
  accountId: "YOUR_BLUESKY_ACCOUNT_ID",
  commentId: "at://did:plc:abc123/app.bsky.feed.post/3kq2c4x7v2s2a",
});
console.log(response);
{
  "deleted": {
    "postId": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "destinationId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
    "platform": "x",
    "commentId": "c0",
    "deleted": true
  }
}

On X, Instagram, Facebook and Threads, a commentId that is one of your published posts is refused with NOT_A_COMMENT. Use remote delete for posts.

Hide or Unhide a Comment

POST /v1/comments/hide with commentId and hidden (true to hide, false to unhide).

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": "122104567890123456_987654321",
    "hidden": true,
    "accountId": "YOUR_FACEBOOK_ACCOUNT_ID"
  },
});
console.log(response);
{
  "hidden": {
    "postId": "string",
    "destinationId": "string",
    "platform": "string",
    "commentId": "string",
    "hidden": false
  }
}

Like a Comment

POST /v1/comments/like with commentId likes a comment. DELETE /v1/comments/like with the same parameters as query parameters removes the like. Facebook only.

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

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

const response = await commentsApi.likeComment({
  commentTargetBody: {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "commentId": "122104567890123456_987654321",
    "accountId": "YOUR_FACEBOOK_ACCOUNT_ID"
  },
});
console.log(response);
{
  "liked": {
    "postId": "string",
    "destinationId": "string",
    "platform": "string",
    "commentId": "string",
    "liked": false
  }
}

Send a Private Reply

POST /v1/comments/private-reply sends a direct message to the person who wrote commentId. text is up to 2,000 characters. Instagram and Facebook only; details are on the Instagram and Facebook pages.

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": "17858893269000001",
    "text": "Thanks! Check your DMs.",
    "accountId": "YOUR_INSTAGRAM_ACCOUNT_ID"
  },
});
console.log(response);
{
  "reply": {
    "postId": "string",
    "destinationId": "string",
    "platform": "string",
    "commentId": "string",
    "reply": {
      "id": "string",
      "text": "string",
      "timestamp": "string"
    }
  }
}

Likes, Reposts, and Bookmarks

All of these take only the selector. Create with POST (selector in the body, returns 201), undo with DELETE (selector as query parameters, returns 200).

ActionCreateUndoResponse fields
Like a postPOST /v1/likesDELETE /v1/likeskind: "like", active
Bookmark a postPOST /v1/bookmarksDELETE /v1/bookmarkskind: "bookmark", active
RepostPOST /v1/retweetsDELETE /v1/retweetsretweeted, retweetId

Each response also contains postId, destinationId and platform. The repost endpoints are named /v1/retweets on every platform.

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

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

const response = await engagementApi.like({
  engagementTargetBody: {
    "post": "1960956321831854280",
    "accountId": "YOUR_X_ACCOUNT_ID"
  },
});
console.log(response);
{
  "postId": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  "destinationId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
  "platform": "x",
  "kind": "like",
  "active": true
}

List Reposts

GET /v1/retweets lists the accounts that reposted a post, in subjects[].actors, with limit (1 to 100, default 25) and cursor. Available on X and Bluesky.

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

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

const response = await engagementApi.listRetweeters({
  post: "3kq2c4x7v2s2a",
  accountId: "YOUR_BLUESKY_ACCOUNT_ID",
  limit: 25,
});
console.log(response);
{
  "retweets": {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "subjects": [
      {
        "scope": "destination",
        "subjectId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
        "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
        "platform": "x",
        "externalPostId": "1960956321831854280",
        "status": "ready",
        "actors": [
          {
            "id": "u1",
            "username": "jane_doe",
            "displayName": "Jane Doe",
            "avatarUrl": "https://cdn.onepostly.com/avatars/jane.jpg"
          }
        ],
        "nextCursor": null
      }
    ]
  }
}

Quote a Post

POST /v1/quotes with the selector and text publishes a new post from the same account that quotes the targeted post. Available on X, Threads and Bluesky. The response contains sourcePostId, sourceDestinationId and the new post. To quote while creating a regular post, see Threads and Quotes.

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

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

const response = await engagementApi.quote({
  quoteBody: {
    "post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
    "text": "Worth a read",
    "accountId": "YOUR_THREADS_ACCOUNT_ID"
  },
});
console.log(response);
{
  "sourcePostId": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
  "sourceDestinationId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
  "post": {
    "id": "b3e1a7c2-8f4d-4e6a-9c1b-2d3e4f5a6b7c",
    "text": "Worth a read",
    "mediaUrls": [
      "https://cdn.onepostly.com/media/product.jpg"
    ],
    "mediaKind": "image",
    "status": "queued",
    "scheduledFor": null,
    "timezone": null,
    "destinations": [
      {
        "id": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
        "accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
        "platform": "x",
        "status": "draft",
        "externalPostId": "17895695668004550",
        "externalUrl": "https://x.com/you/status/17895695668004550",
        "errorCode": null,
        "errorMessage": null,
        "publishedAt": "2026-08-25T10:00:00.000Z",
        "metrics": null
      }
    ],
    "createdAt": "2026-08-25T10:00:00.000Z",
    "updatedAt": "2026-08-25T10:00:00.000Z"
  }
}

Webhooks

ActionWebhook event
Reply with POST /v1/commentscomment.created
Delete with DELETE /v1/commentscomment.deleted
New comment on an Instagram or Facebook postcomment.received
Like or unlike a postengagement.liked, engagement.unliked
Bookmark or remove a bookmarkengagement.bookmarked, engagement.unbookmarked
Repost or undo a repostengagement.retweeted, engagement.unretweeted
Quote a postengagement.quoted and post.platform.published

Except comment.received, these events fire only for actions you take through the API, not for other people's likes or reposts. Hiding, liking a comment and private replies send no webhook. Payloads are in Comment Events and Engagement Events.

Errors

Selector errors (ACCOUNT_REQUIRED, NOT_PUBLISHED, AMBIGUOUS_TARGET and others) are listed in Targeting a Post.

CodeCauseFix
UNSUPPORTED_PLATFORMThe platform does not support this action through Onepostly.Check Support by Platform.
VALIDATION_ERRORA required field such as commentId or text is missing.Send the required fields.
TEXT_TOO_LONGtext exceeds the platform's limit.Shorten the text to the Text Limits.
NOT_A_COMMENTcommentId is one of your published posts.Delete the post with remote delete.
INSUFFICIENT_WALLETAn X action needs wallet balance.Top up the wallet, then try again.
CONNECTION_INACTIVEThe account is disconnected or needs reconnecting.Reconnect the account.
TOKEN_INVALIDThe platform rejected the account's authorization.Reconnect the account.
PERMISSION_DENIEDThe account lacks the permission for this action.Reconnect and grant all requested permissions.
COMMENT_CREATE_FAILED, COMMENT_DELETE_FAILED, COMMENT_HIDE_FAILED, COMMENT_LIKE_FAILED, COMMENT_UNLIKE_FAILED, PRIVATE_REPLY_FAILED, ENGAGEMENT_FAILED, RETWEET_FAILED, UNRETWEET_FAILED, QUOTE_FAILEDThe platform refused the action without a specific reason.Read message, then try again later.

A 429 response means a rate limit was reached; see Handle 429 Responses.