Comments API Reference
The Comments API allows you to retrieve, create, delete, hide/unhide, and like/unlike comments on published posts. All write operations are processed asynchronously.
Endpoints
Section titled “Endpoints”| Method | Endpoint | Description |
|---|---|---|
GET | /api/posts/:post_id/comments | List comments |
GET | /api/posts/:post_id/comments/:id | Get a single comment |
POST | /api/posts/:post_id/comments | Create a comment or reply |
DELETE | /api/posts/:post_id/comments/:id | Delete a comment |
POST | /api/posts/:post_id/comments/:id/hide | Hide a comment |
POST | /api/posts/:post_id/comments/:id/unhide | Unhide a comment |
POST | /api/posts/:post_id/comments/:id/like | Like a comment |
POST | /api/posts/:post_id/comments/:id/unlike | Unlike a comment |
All endpoints require the profile_id query parameter to identify which platform profile’s comments to interact with.
Comment ID resolution
Section titled “Comment ID resolution”Endpoints that accept a comment :id in the path (get, delete, hide, unhide, like, unlike) accept either:
- Postproxy ID: The comment’s hashid (e.g.
abc123xyz) - External ID: The platform’s native comment ID (e.g.
17858893269123456)
Platform support
Section titled “Platform support”Not all platforms support all comment actions. Attempting an unsupported action returns 405 Method Not Allowed.
| Action | Threads | YouTube | |||
|---|---|---|---|---|---|
| List | Yes | Yes | Coming soon | Coming soon | Coming soon |
| Reply | Yes | Yes | Coming soon | Coming soon | Coming soon |
| Delete | Yes | Yes | Coming soon | Coming soon | Coming soon |
| Hide/Unhide | Yes | Yes | Coming soon | Coming soon | Coming soon |
| Like/Unlike | No | Yes | Coming soon | Coming soon | Coming soon |
List comments
Section titled “List comments”GET /api/posts/:post_id/comments
Retrieves a paginated list of top-level comments for a published post on a specific profile. Each top-level comment includes a flat replies array containing all nested replies sorted by creation date.
Query parameters
Section titled “Query parameters”| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
profile_id | string | Yes | - | Profile ID |
page | integer | No | 0 | Page number (zero-indexed) |
per_page | integer | No | 20 | Number of top-level comments per page |
Example
Section titled “Example”curl -X GET "https://api.postproxy.dev/api/posts/POST_ID/comments?profile_id=PROFILE_ID&page=0&per_page=20" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const comments = await client.comments.list("POST_ID", "PROFILE_ID");console.log(`Total comments: ${comments.total}`);for (const comment of comments.data) { console.log(`${comment.author_username}: ${comment.body}`); for (const reply of comment.replies) { console.log(` ${reply.author_username}: ${reply.body}`); }}package main
import ( "context" "fmt" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.NewClient("YOUR_API_KEY") comments, _ := client.Comments.List(context.Background(), "POST_ID", "PROFILE_ID", nil) fmt.Printf("Total comments: %d\n", comments.Total) for _, c := range comments.Data { fmt.Printf("%v: %s\n", c.AuthorUsername, c.Body) for _, r := range c.Replies { fmt.Printf(" %v: %s\n", r.AuthorUsername, r.Body) } }}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")comments = client.comments.list("POST_ID", profile_id: "PROFILE_ID")puts "Total comments: #{comments.total}"comments.data.each do |comment| puts "#{comment.author_username}: #{comment.body}" comment.replies.each do |reply| puts " #{reply.author_username}: #{reply.body}" endenduse PostProxy\Client;
$client = new Client("YOUR_API_KEY");$comments = $client->comments()->list("POST_ID", "PROFILE_ID");echo "Total comments: {$comments->total}\n";foreach ($comments->data as $comment) { echo "{$comment->authorUsername}: {$comment->body}\n"; foreach ($comment->replies as $reply) { echo " {$reply->authorUsername}: {$reply->body}\n"; }}import dev.postproxy.sdk.PostProxy;
var client = PostProxy.builder("YOUR_API_KEY").build();var comments = client.comments().list("POST_ID", "PROFILE_ID");System.out.println("Total comments: " + comments.total());for (var comment : comments.data()) { System.out.println(comment.authorUsername() + ": " + comment.body()); for (var reply : comment.replies()) { System.out.println(" " + reply.authorUsername() + ": " + reply.body()); }}using PostProxy;
var client = PostProxyClient.Builder("YOUR_API_KEY").Build();var comments = await client.Comments.ListAsync("POST_ID", "PROFILE_ID");Console.WriteLine($"Total comments: {comments.Total}");foreach (var comment in comments.Data){ Console.WriteLine($"{comment.AuthorUsername}: {comment.Body}"); if (comment.Replies is not null) { foreach (var reply in comment.Replies) { Console.WriteLine($" {reply.AuthorUsername}: {reply.Body}"); } }}Response:
{ "total": 42, "page": 0, "per_page": 20, "data": [ { "id": "abc123xyz", "external_id": "17858893269123456", "body": "Great post!", "status": "synced", "author_username": "someuser", "author_avatar_url": null, "author_external_id": "12345", "parent_external_id": null, "like_count": 3, "is_hidden": false, "permalink": null, "platform_data": null, "posted_at": "2026-03-25T10:00:00.000Z", "created_at": "2026-03-25T10:01:00.000Z", "replies": [ { "id": "def456abc", "external_id": "17858893269123457", "body": "Thanks!", "status": "synced", "author_username": "author", "author_avatar_url": null, "author_external_id": "67890", "parent_external_id": "17858893269123456", "like_count": 1, "is_hidden": false, "permalink": null, "platform_data": null, "posted_at": "2026-03-25T10:05:00.000Z", "created_at": "2026-03-25T10:05:00.000Z" } ] } ]}Response fields
Section titled “Response fields”| Field | Type | Description |
|---|---|---|
total | integer | Total number of top-level comments |
page | integer | Current page number |
per_page | integer | Items per page |
data | array | Array of top-level comment objects, each with a replies array |
Reply nesting
Section titled “Reply nesting”Pagination applies to top-level comments only. All replies (regardless of nesting depth) are flattened into the replies array of their root top-level comment, sorted by created_at ascending. Each reply retains its parent_external_id so the client can reconstruct the tree if needed.
Get comment
Section titled “Get comment”GET /api/posts/:post_id/comments/:id
Retrieves a single comment with its direct replies.
Path parameters
Section titled “Path parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
post_id | string | Yes | Post ID |
id | string | Yes | Comment ID or external ID |
Example
Section titled “Example”curl -X GET "https://api.postproxy.dev/api/posts/POST_ID/comments/COMMENT_ID?profile_id=PROFILE_ID" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const comment = await client.comments.get("POST_ID", "COMMENT_ID", "PROFILE_ID");console.log(comment);package main
import ( "context" "fmt" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.NewClient("YOUR_API_KEY") comment, _ := client.Comments.Get(context.Background(), "POST_ID", "COMMENT_ID", "PROFILE_ID") fmt.Println(comment)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")comment = client.comments.get("POST_ID", "COMMENT_ID", profile_id: "PROFILE_ID")puts commentuse PostProxy\Client;
$client = new Client("YOUR_API_KEY");$comment = $client->comments()->get("POST_ID", "COMMENT_ID", "PROFILE_ID");print_r($comment);import dev.postproxy.sdk.PostProxy;
var client = PostProxy.builder("YOUR_API_KEY").build();var comment = client.comments().get("POST_ID", "COMMENT_ID", "PROFILE_ID");System.out.println(comment);using PostProxy;
var client = PostProxyClient.Builder("YOUR_API_KEY").Build();var comment = await client.Comments.GetAsync("POST_ID", "COMMENT_ID", "PROFILE_ID");Console.WriteLine(comment);Response:
{ "id": "abc123xyz", "external_id": "17858893269123456", "body": "Great post!", "status": "synced", "author_username": "someuser", "author_avatar_url": null, "author_external_id": "12345", "parent_external_id": null, "like_count": 3, "is_hidden": false, "permalink": null, "platform_data": null, "posted_at": "2026-03-25T10:00:00.000Z", "created_at": "2026-03-25T10:01:00.000Z", "replies": [ { "id": "def456abc", "external_id": "17858893269123457", "body": "Thanks!", "status": "synced", "author_username": "author", "author_avatar_url": null, "author_external_id": "67890", "parent_external_id": "17858893269123456", "like_count": 1, "is_hidden": false, "permalink": null, "platform_data": null, "posted_at": "2026-03-25T10:05:00.000Z", "created_at": "2026-03-25T10:05:00.000Z" } ]}Create comment
Section titled “Create comment”POST /api/posts/:post_id/comments
Creates a new comment on a published post. The comment is stored immediately and published to the platform asynchronously.
Request body
Section titled “Request body”| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | Yes | Comment text content |
parent_id | string | No | ID of comment to reply to (Postproxy ID or external ID). Omit to comment on the post itself. |
Example: Comment on post
Section titled “Example: Comment on post”curl -X POST "https://api.postproxy.dev/api/posts/POST_ID/comments?profile_id=PROFILE_ID" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "Thanks for the feedback everyone!" }'import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const comment = await client.comments.create("POST_ID", "PROFILE_ID", "Thanks for the feedback everyone!");console.log(comment);package main
import ( "context" "fmt" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.NewClient("YOUR_API_KEY") comment, _ := client.Comments.Create(context.Background(), "POST_ID", "PROFILE_ID", "Thanks for the feedback everyone!", nil) fmt.Println(comment)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")comment = client.comments.create("POST_ID", "Thanks for the feedback everyone!", profile_id: "PROFILE_ID")puts commentuse PostProxy\Client;
$client = new Client("YOUR_API_KEY");$comment = $client->comments()->create("POST_ID", "PROFILE_ID", "Thanks for the feedback everyone!");print_r($comment);import dev.postproxy.sdk.PostProxy;
var client = PostProxy.builder("YOUR_API_KEY").build();var comment = client.comments().create("POST_ID", "PROFILE_ID", "Thanks for the feedback everyone!");System.out.println(comment);using PostProxy;
var client = PostProxyClient.Builder("YOUR_API_KEY").Build();var comment = await client.Comments.CreateAsync("POST_ID", "PROFILE_ID", "Thanks for the feedback everyone!");Console.WriteLine(comment);Response (201 Created):
{ "id": "ghi789def", "external_id": null, "body": "Thanks for the feedback everyone!", "status": "pending", "author_username": null, "author_avatar_url": null, "author_external_id": null, "parent_external_id": null, "like_count": 0, "is_hidden": false, "permalink": null, "platform_data": null, "posted_at": null, "created_at": "2026-03-25T12:00:00.000Z"}The comment is created with status: "pending" and external_id: null. Once the async job publishes it to the platform, the status updates to "published" and external_id is populated. If publishing fails, the status becomes "failed".
Example: Reply to a comment
Section titled “Example: Reply to a comment”curl -X POST "https://api.postproxy.dev/api/posts/POST_ID/comments?profile_id=PROFILE_ID" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "Glad you liked it!", "parent_id": "COMMENT_ID" }'import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");const reply = await client.comments.create("POST_ID", "PROFILE_ID", "Glad you liked it!", { parentId: "COMMENT_ID",});console.log(reply);package main
import ( "context" "fmt" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.NewClient("YOUR_API_KEY") parentID := "COMMENT_ID" reply, _ := client.Comments.Create(context.Background(), "POST_ID", "PROFILE_ID", "Glad you liked it!", &postproxy.CommentCreateOptions{ParentID: &parentID}) fmt.Println(reply)}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")reply = client.comments.create("POST_ID", "Glad you liked it!", profile_id: "PROFILE_ID", parent_id: "COMMENT_ID")puts replyuse PostProxy\Client;
$client = new Client("YOUR_API_KEY");$reply = $client->comments()->create("POST_ID", "PROFILE_ID", "Glad you liked it!", parentId: "COMMENT_ID");print_r($reply);import dev.postproxy.sdk.PostProxy;
var client = PostProxy.builder("YOUR_API_KEY").build();var reply = client.comments().create("POST_ID", "PROFILE_ID", "Glad you liked it!", "COMMENT_ID");System.out.println(reply);using PostProxy;
var client = PostProxyClient.Builder("YOUR_API_KEY").Build();var reply = await client.Comments.CreateAsync("POST_ID", "PROFILE_ID", "Glad you liked it!", parentId: "COMMENT_ID");Console.WriteLine(reply);Error responses
Section titled “Error responses”Post not published (422):
{ "error": "Post is not published"}Unsupported platform (405):
{ "error": "Unsupported method for pinterest"}Parent comment not found (404):
{ "error": "Parent comment not found"}Delete comment
Section titled “Delete comment”DELETE /api/posts/:post_id/comments/:id
Deletes a comment from the platform asynchronously.
Path parameters
Section titled “Path parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
post_id | string | Yes | Post ID |
id | string | Yes | Comment ID or external ID |
Example
Section titled “Example”curl -X DELETE "https://api.postproxy.dev/api/posts/POST_ID/comments/COMMENT_ID?profile_id=PROFILE_ID" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");await client.comments.delete("POST_ID", "COMMENT_ID", "PROFILE_ID");package main
import ( "context" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.NewClient("YOUR_API_KEY") client.Comments.Delete(context.Background(), "POST_ID", "COMMENT_ID", "PROFILE_ID")}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")client.comments.delete("POST_ID", "COMMENT_ID", profile_id: "PROFILE_ID")use PostProxy\Client;
$client = new Client("YOUR_API_KEY");$client->comments()->delete("POST_ID", "COMMENT_ID", "PROFILE_ID");import dev.postproxy.sdk.PostProxy;
var client = PostProxy.builder("YOUR_API_KEY").build();client.comments().delete("POST_ID", "COMMENT_ID", "PROFILE_ID");using PostProxy;
var client = PostProxyClient.Builder("YOUR_API_KEY").Build();await client.Comments.DeleteAsync("POST_ID", "COMMENT_ID", "PROFILE_ID");Response (200 OK):
{ "accepted": true}Error responses
Section titled “Error responses”Unsupported platform (405):
{ "error": "Unsupported method for threads"}Comment not yet published (422):
{ "error": "Comment has not been published yet"}Hide comment
Section titled “Hide comment”POST /api/posts/:post_id/comments/:id/hide
Hides a comment on the platform asynchronously. Hidden comments are not visible to the public.
Example
Section titled “Example”curl -X POST "https://api.postproxy.dev/api/posts/POST_ID/comments/COMMENT_ID/hide?profile_id=PROFILE_ID" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");await client.comments.hide("POST_ID", "COMMENT_ID", "PROFILE_ID");package main
import ( "context" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.NewClient("YOUR_API_KEY") client.Comments.Hide(context.Background(), "POST_ID", "COMMENT_ID", "PROFILE_ID")}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")client.comments.hide("POST_ID", "COMMENT_ID", profile_id: "PROFILE_ID")use PostProxy\Client;
$client = new Client("YOUR_API_KEY");$client->comments()->hide("POST_ID", "COMMENT_ID", "PROFILE_ID");import dev.postproxy.sdk.PostProxy;
var client = PostProxy.builder("YOUR_API_KEY").build();client.comments().hide("POST_ID", "COMMENT_ID", "PROFILE_ID");using PostProxy;
var client = PostProxyClient.Builder("YOUR_API_KEY").Build();await client.Comments.HideAsync("POST_ID", "COMMENT_ID", "PROFILE_ID");Response (200 OK):
{ "accepted": true}Unhide comment
Section titled “Unhide comment”POST /api/posts/:post_id/comments/:id/unhide
Unhides a previously hidden comment on the platform asynchronously.
Example
Section titled “Example”curl -X POST "https://api.postproxy.dev/api/posts/POST_ID/comments/COMMENT_ID/unhide?profile_id=PROFILE_ID" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");await client.comments.unhide("POST_ID", "COMMENT_ID", "PROFILE_ID");package main
import ( "context" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.NewClient("YOUR_API_KEY") client.Comments.Unhide(context.Background(), "POST_ID", "COMMENT_ID", "PROFILE_ID")}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")client.comments.unhide("POST_ID", "COMMENT_ID", profile_id: "PROFILE_ID")use PostProxy\Client;
$client = new Client("YOUR_API_KEY");$client->comments()->unhide("POST_ID", "COMMENT_ID", "PROFILE_ID");import dev.postproxy.sdk.PostProxy;
var client = PostProxy.builder("YOUR_API_KEY").build();client.comments().unhide("POST_ID", "COMMENT_ID", "PROFILE_ID");using PostProxy;
var client = PostProxyClient.Builder("YOUR_API_KEY").Build();await client.Comments.UnhideAsync("POST_ID", "COMMENT_ID", "PROFILE_ID");Response (200 OK):
{ "accepted": true}Like comment
Section titled “Like comment”POST /api/posts/:post_id/comments/:id/like
Likes a comment on the platform asynchronously.
Example
Section titled “Example”curl -X POST "https://api.postproxy.dev/api/posts/POST_ID/comments/COMMENT_ID/like?profile_id=PROFILE_ID" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");await client.comments.like("POST_ID", "COMMENT_ID", "PROFILE_ID");package main
import ( "context" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.NewClient("YOUR_API_KEY") client.Comments.Like(context.Background(), "POST_ID", "COMMENT_ID", "PROFILE_ID")}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")client.comments.like("POST_ID", "COMMENT_ID", profile_id: "PROFILE_ID")use PostProxy\Client;
$client = new Client("YOUR_API_KEY");$client->comments()->like("POST_ID", "COMMENT_ID", "PROFILE_ID");import dev.postproxy.sdk.PostProxy;
var client = PostProxy.builder("YOUR_API_KEY").build();client.comments().like("POST_ID", "COMMENT_ID", "PROFILE_ID");using PostProxy;
var client = PostProxyClient.Builder("YOUR_API_KEY").Build();await client.Comments.LikeAsync("POST_ID", "COMMENT_ID", "PROFILE_ID");Response (200 OK):
{ "accepted": true}Unlike comment
Section titled “Unlike comment”POST /api/posts/:post_id/comments/:id/unlike
Removes a like from a comment on the platform asynchronously.
Example
Section titled “Example”curl -X POST "https://api.postproxy.dev/api/posts/POST_ID/comments/COMMENT_ID/unlike?profile_id=PROFILE_ID" \ -H "Authorization: Bearer YOUR_API_KEY"import PostProxy from "postproxy-sdk";
const client = new PostProxy("YOUR_API_KEY");await client.comments.unlike("POST_ID", "COMMENT_ID", "PROFILE_ID");package main
import ( "context" postproxy "github.com/postproxy/postproxy-go")
func main() { client := postproxy.NewClient("YOUR_API_KEY") client.Comments.Unlike(context.Background(), "POST_ID", "COMMENT_ID", "PROFILE_ID")}require "postproxy"
client = PostProxy::Client.new("YOUR_API_KEY")client.comments.unlike("POST_ID", "COMMENT_ID", profile_id: "PROFILE_ID")use PostProxy\Client;
$client = new Client("YOUR_API_KEY");$client->comments()->unlike("POST_ID", "COMMENT_ID", "PROFILE_ID");import dev.postproxy.sdk.PostProxy;
var client = PostProxy.builder("YOUR_API_KEY").build();client.comments().unlike("POST_ID", "COMMENT_ID", "PROFILE_ID");using PostProxy;
var client = PostProxyClient.Builder("YOUR_API_KEY").Build();await client.Comments.UnlikeAsync("POST_ID", "COMMENT_ID", "PROFILE_ID");Response (200 OK):
{ "accepted": true}Comment object fields
Section titled “Comment object fields”| Field | Type | Description |
|---|---|---|
id | string | Unique comment identifier (ID) |
external_id | string|null | Platform’s native comment ID (null for pending comments) |
body | string | Comment text content |
status | string | Comment status: synced, pending, published, failed |
author_username | string|null | Author’s display name or username |
author_avatar_url | string|null | Author’s profile image URL |
author_external_id | string|null | Author’s platform-specific ID |
parent_external_id | string|null | Parent comment’s external ID (null for top-level comments) |
like_count | integer | Number of likes on the comment |
is_hidden | boolean | Whether the comment is hidden |
permalink | string|null | Direct URL to the comment on the platform (when available) |
platform_data | object|null | Platform-specific metadata |
posted_at | string|null | ISO 8601 timestamp when the comment was posted on the platform |
created_at | string | ISO 8601 timestamp of record creation |
Comment statuses
Section titled “Comment statuses”| Status | Description |
|---|---|
synced | Comment was fetched from the platform during sync |
pending | Comment was created via API and is being published to the platform |
published | Comment was successfully published to the platform |
failed | Comment failed to publish to the platform |
Common error responses
Section titled “Common error responses”Missing profile_id (400):
{ "status": 400, "error": "Bad Request", "message": "param is missing or the value is empty: profile_id"}Post not found (404):
{ "error": "Not found"}Comment not found (404):
{ "error": "Not found"}Unsupported method (405):
{ "error": "Unsupported method for {network}"}