DocumentationReply to comments
How to read and reply to comments on your posts
Read the comments under your recent posts and answer them through the account that posted. Your code or your agent writes each reply; BuzzTake reads the comments and posts the replies in the account's browser.
You need a BuzzTake API key and the id of an active account.
1. Find the posts to check
Every post the account published with the post action is in its action history, with its URL in result.url. Filter the history to succeeded posts:
GET/v1/accounts/{id}/actions
curl "https://api.buzztake.com/v1/accounts/$ACCOUNT_ID/actions?type=post&status=succeeded&limit=20" \
-H "Authorization: Bearer $BUZZTAKE_API_KEY"{
"actions": [
{
"id": "0199e5f6-...",
"type": "post",
"status": "succeeded",
"result": { "type": "created", "url": "https://www.instagram.com/p/C0deXyZ/", "id": "C0deXyZ" },
"finished_at": "2026-10-29T09:00:09Z"
}
],
"next_cursor": "0199e5f6-..."
}The history is newest first; pass next_cursor as cursor for older posts. For posts made outside BuzzTake, use their URLs, or the url of comment notifications from read_notifications.
2. Read the comments under a post
POST/v1/accounts/{id}/actions
Run read_post with the post's URL in target. replies is how many comments to read: 20 by default, at most 100. A read costs 4 credits, charged only when it succeeds.
curl https://api.buzztake.com/v1/accounts/$ACCOUNT_ID/actions \
-H "Authorization: Bearer $BUZZTAKE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "type": "read_post", "target": "https://www.instagram.com/p/C0deXyZ/", "replies": 50, "wait": 60 }'{
"type": "read_post",
"status": "succeeded",
"result": {
"type": "post",
"item": { "url": "https://www.instagram.com/p/C0deXyZ/", "text": "Dark mode is live.", "replies": "12" },
"replies": [
{
"url": "https://www.instagram.com/p/C0deXyZ/c/18034.../",
"id": "18034...",
"author_handle": "jamie.codes",
"author_name": "Jamie",
"text": "Where do I turn it on?",
"published_at": "2026-10-29T10:14:00Z",
"likes": "3",
"media_urls": []
}
]
},
"credits": 4
}item is the post and replies are its comments, each with url, id, author_handle, author_name, text, published_at and the counts as the page shows them. A field the page does not show is null.
3. Choose what each reply answers
reply takes a target. Whether that can be one comment depends on the platform:
| Platform | Reply target |
|---|---|
| X, Threads, Bluesky, Mastodon | The comment's url. Comments are posts, so you can reply to a reply. |
| Instagram, Facebook, Reddit, YouTube | The comment's url. The reply answers that comment. |
| The post's URL. A reply adds a comment on the post; it cannot answer one comment. | |
| TikTok, Pinterest | The post's URL. Their comments come back with no url or id, and a reply adds a comment on the post. |
| Telegram | No reply action. read_post returns no replies. |
4. Reply to each comment
A reply needs target, and text, media or both; comments on LinkedIn, Reddit and Pinterest take text only. It costs 8 credits, charged when it starts. Use an Idempotency-Key made from the comment's id: if your script runs twice, the second run returns the first reply and posts nothing new.
curl
curl https://api.buzztake.com/v1/accounts/$ACCOUNT_ID/actions \
-H "Authorization: Bearer $BUZZTAKE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: reply-18034..." \
-d '{
"type": "reply",
"target": "https://www.instagram.com/p/C0deXyZ/c/18034.../",
"text": "Thanks, @jamie.codes. It is under Settings, Appearance.",
"wait": 60
}'JavaScript
const api = "https://api.buzztake.com/v1";
const accountId = process.env.ACCOUNT_ID;
const ownHandle = "acme_demo";
const headers = {
Authorization: `Bearer ${process.env.BUZZTAKE_API_KEY}`,
"Content-Type": "application/json",
};
// Runs one action, waits for it, and returns its result. Throws unless it succeeded.
async function run(body, idempotencyKey) {
const res = await fetch(`${api}/accounts/${accountId}/actions`, {
method: "POST",
headers: idempotencyKey ? { ...headers, "Idempotency-Key": idempotencyKey } : headers,
body: JSON.stringify({ ...body, wait: 90 }),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const action = await res.json();
if (action.status !== "succeeded") {
throw new Error(`${body.type} ${action.status}: ${action.error?.message ?? ""}`);
}
return action.result;
}
const postUrl = "https://www.instagram.com/p/C0deXyZ/";
const { replies } = await run({ type: "read_post", target: postUrl, replies: 50 });
for (const comment of replies) {
if (!comment.url || comment.author_handle === ownHandle) continue;
const text = `Thanks, @${comment.author_handle}. It is under Settings, Appearance.`;
const created = await run(
{ type: "reply", target: comment.url, text },
`reply-${comment.id ?? comment.url}`,
);
console.log(comment.url, "->", created.url);
}Python
import os
import requests
api = "https://api.buzztake.com/v1"
account_id = os.environ["ACCOUNT_ID"]
own_handle = "acme_demo"
headers = {"Authorization": f"Bearer {os.environ['BUZZTAKE_API_KEY']}"}
def run(body, idempotency_key=None):
"""Runs one action, waits for it, and returns its result. Raises unless it succeeded."""
extra = {"Idempotency-Key": idempotency_key} if idempotency_key else {}
resp = requests.post(
f"{api}/accounts/{account_id}/actions",
headers={**headers, **extra},
json={**body, "wait": 90},
timeout=100,
)
if not resp.ok:
raise SystemExit(f"{resp.status_code}: {resp.text}")
action = resp.json()
if action["status"] != "succeeded":
raise SystemExit(f"{body['type']} {action['status']}: {action.get('error')}")
return action["result"]
post_url = "https://www.instagram.com/p/C0deXyZ/"
result = run({"type": "read_post", "target": post_url, "replies": 50})
for comment in result["replies"]:
if not comment.get("url") or comment.get("author_handle") == own_handle:
continue
text = f"Thanks, @{comment['author_handle']}. It is under Settings, Appearance."
created = run(
{"type": "reply", "target": comment["url"], "text": text},
f"reply-{comment.get('id') or comment['url']}",
)
print(comment["url"], "->", created["url"])The scripts skip the account's own comments and comments with no URL. Replace the fixed text with your own, or with a reply your model writes from comment.text.
read_post and draft
replies for you to confirm. Each reply it sends is a reply tool call at the same
price.
Common errors
- 422 invalid_input
- "reply needs
text,media, or both" - 422 invalid_input
- "
repliesmust be a whole number from 0 to 100" - 422 unsupported
- "Telegram accounts cannot reply. They can: ..." Telegram has no replies.
- Action error not_found
- The post or comment was deleted, or the account cannot see it.
- Action error rate_limited
- The platform asked the account to slow down. Space out the replies and try later.
See also
- The read_post action
- The reply action
- How to monitor mentions of your brand and reply
- How to read and send direct messages with an API
- How to post a thread on X, Threads, Bluesky or Mastodon
To run this on your own accounts, create a BuzzTake account, then add an account and an API key.