Engagement
Like Facebook Page posts and manage comments as the Page.
Facebook engagement is likes. The connection likes a published post as the Page, and likes are idempotent. Liking an already liked post succeeds without error. Pass post as described in Analytics. Use the internal id for Onepostly posts. Use the native post id plus accountId for outside posts.
Likes
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": "1699f415-7fb6-43f4-9d2a-c447491f32a8"
},
});
console.log(response);{
"postId": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
"destinationId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
"platform": "facebook",
"kind": "like",
"active": true
}import { Configuration, EngagementApi } from "@onepostly/sdk";
const engagementApi = new EngagementApi(
new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);
const response = await engagementApi.unlike({
post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
});
console.log(response);{
"postId": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
"destinationId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
"platform": "facebook",
"kind": "like",
"active": false
}Unliking returns the same shape with active: false.
Successful calls emit the engagement.liked and engagement.unliked webhooks.
Bookmarks, retweets and quotes do not exist on Facebook.
Comments
Manage comments on a published Facebook Page post. Works on text posts, photos, videos and multi-photo posts. Stories have no comments. Comments are posted as the Page.
List
Returns the post comments. 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": "facebook",
"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.facebook.com/page/posts/17895695668004550"
}
]
}
}| Query | Required | Notes |
|---|---|---|
post | Yes | Internal post id or native post id. Native ids require accountId |
accountId | For native ids | Disambiguates the target account. Also narrows internal posts with several destinations |
destinationId | No | Globally unique. Resolves on its own or narrows one destination inside an internal post |
limit | No | 1-50, default 25 |
cursor | No | Pagination 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"
}
}| Body | Required | Notes |
|---|---|---|
post | Yes | Internal post id or native post id. Native ids require accountId |
text | Yes | Comment text |
accountId | For native ids | Target account for native ids. Also disambiguates internal posts |
destinationId | No | Globally unique. Resolves on its own or targets one destination inside an internal post |
parentCommentId | No | Reply to a comment. Omit to comment on the post itself |
Delete
Deletes a comment made by the Page. commentId is the comment id on Facebook. Get it from List above (comments[].id). The same id works for hide, like, 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": "facebook",
"commentId": "c0",
"deleted": true
}
}If you get a permission error on any of these, reconnect the Facebook connection once.
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": "facebook",
"commentId": "string",
"hidden": false
}
}Like or unlike a comment
Likes a comment as the Page, or removes the like. Unliking a comment that was never liked succeeds with liked: false.
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": "c0"
},
});
console.log(response);{
"liked": {
"postId": "string",
"destinationId": "string",
"platform": "facebook",
"commentId": "string",
"liked": false
}
}import { Configuration, CommentsApi } from "@onepostly/sdk";
const commentsApi = new CommentsApi(
new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);
const response = await commentsApi.unlikeComment({
post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
commentId: "c0",
});
console.log(response);{
"liked": {
"postId": "string",
"destinationId": "string",
"platform": "facebook",
"commentId": "string",
"liked": false
}
}Private reply
Sends a text Messenger DM 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": "facebook",
"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": "welcome_dm",
"name": "Welcome message",
"keywords": [
"string"
],
"dmMessage": "Thanks for reaching out! We reply within a day."
},
});
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
Posts published outside Onepostly work the same way once they are 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.facebook.com/page/posts/987654321"
},
});
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": "facebook",
"externalPostId": "987654321",
"externalUrl": "https://www.facebook.com/page/posts/987654321",
"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": "facebook",
"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.facebook.com/page/posts/17895695668004550"
}
]
}
}Errors
| Code | Cause | Fix |
|---|---|---|
MISSING_EXTERNAL_ID | Destination not published yet | Wait for publish |
ENGAGEMENT_PERMISSION | Connection lacks pages_manage_engagement | Reconnect the Page |
LIKE_FAILED or UNLIKE_FAILED | Facebook rejected the action | Check the error message for the Facebook reason |
COMMENTS_PERMISSION | Connection lacks pages_manage_engagement | Reconnect the Page |
TEXT_REQUIRED | Empty comment text | Add message text |
COMMENT_CREATE_FAILED | Facebook rejected the comment | Check the error message for the Facebook reason |
COMMENT_HIDE_FAILED | Facebook rejected the hide toggle | Check the error message for the Facebook reason |
COMMENT_LIKE_FAILED / COMMENT_UNLIKE_FAILED | Facebook rejected the like toggle | Check the error message for the Facebook reason |
PRIVATE_REPLY_FAILED | Facebook rejected the private reply | Reconnect with messaging access; respect the 7-day window |