> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Metaculus/metaculus/llms.txt
> Use this file to discover all available pages before exploring further.

# Comments

> Create and retrieve comments on posts

## Overview

Comments allow users to discuss questions, share insights, and explain their reasoning. Comments can be public or private, can include forecasts, and support threading (replies).

***

## List Comments

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://www.metaculus.com/api/comments/?post=3530&limit=50" \
    -H "Authorization: Token YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://www.metaculus.com/api/comments/",
      headers={"Authorization": "Token YOUR_TOKEN"},
      params={
          "post": 3530,
          "limit": 50
      }
  )
  print(response.json())
  ```
</CodeGroup>

`GET /api/comments/`

Retrieve comments with filtering options. Either `post` or `author` parameter is required.

### Query Parameters

<ParamField query="post" type="integer">
  Filter comments by post ID (required if `author` not provided)
</ParamField>

<ParamField query="author" type="integer">
  Filter comments by author user ID (required if `post` not provided)
</ParamField>

<ParamField query="is_private" type="boolean" default="false">
  Show private comments (for authenticated user only) or public comments
</ParamField>

<ParamField query="parent_isnull" type="boolean">
  Filter to only root comments (`true`) or only replies (`false`)
</ParamField>

<ParamField query="sort" type="string">
  Sort order: `created_at` (oldest first) or `-created_at` (newest first)
</ParamField>

<ParamField query="focus_comment_id" type="integer">
  Place a specific comment at the top of results
</ParamField>

<ParamField query="include_deleted" type="boolean" default="false">
  Include soft-deleted comments in results
</ParamField>

<ParamField query="use_root_comments_pagination" type="boolean">
  If true, pagination applies only to root comments, and all replies are included
</ParamField>

<ParamField query="limit" type="integer" default="50">
  Number of comments to return
</ParamField>

<ParamField query="offset" type="integer" default="0">
  Pagination offset
</ParamField>

### Response

<ResponseField name="total_count" type="integer">
  Total number of comments (including replies)
</ResponseField>

<ResponseField name="count" type="integer">
  Number of root comments only
</ResponseField>

<ResponseField name="next" type="string">
  URL for next page, or null
</ResponseField>

<ResponseField name="previous" type="string">
  URL for previous page, or null
</ResponseField>

<ResponseField name="results" type="array">
  Array of comment objects
</ResponseField>

### Comment Object

<ResponseField name="id" type="integer">
  Unique comment identifier
</ResponseField>

<ResponseField name="author" type="object">
  Author information

  <ResponseField name="id" type="integer">
    User ID
  </ResponseField>

  <ResponseField name="username" type="string">
    Username
  </ResponseField>

  <ResponseField name="is_bot" type="boolean">
    Whether the author is a bot
  </ResponseField>

  <ResponseField name="is_staff" type="boolean">
    Whether the author is Metaculus staff
  </ResponseField>
</ResponseField>

<ResponseField name="parent_id" type="integer">
  ID of the comment being replied to, or null if root comment
</ResponseField>

<ResponseField name="root_id" type="integer">
  ID of the root comment in this thread
</ResponseField>

<ResponseField name="created_at" type="string (datetime)">
  When the comment was created
</ResponseField>

<ResponseField name="text_edited_at" type="string (datetime)">
  When the comment text was last edited
</ResponseField>

<ResponseField name="text" type="string">
  Comment content in markdown
</ResponseField>

<ResponseField name="on_post" type="integer">
  ID of the post this comment belongs to
</ResponseField>

<ResponseField name="on_post_data" type="object">
  Basic post information

  <ResponseField name="id" type="integer">
    Post ID
  </ResponseField>

  <ResponseField name="title" type="string">
    Post title
  </ResponseField>
</ResponseField>

<ResponseField name="included_forecast" type="object">
  Forecast data if user included their prediction with the comment

  <ResponseField name="question" type="integer">
    Question ID
  </ResponseField>

  <ResponseField name="probability_yes" type="number">
    For binary questions: probability value
  </ResponseField>

  <ResponseField name="continuous_cdf" type="array">
    For continuous questions: CDF array
  </ResponseField>
</ResponseField>

<ResponseField name="is_private" type="boolean">
  Whether this is a private comment
</ResponseField>

<ResponseField name="is_soft_deleted" type="boolean">
  Whether the comment has been deleted
</ResponseField>

<ResponseField name="is_pinned" type="boolean">
  Whether the comment is pinned by moderators
</ResponseField>

<ResponseField name="vote_score" type="integer">
  Total vote score (upvotes - downvotes)
</ResponseField>

<ResponseField name="user_vote" type="integer">
  Current user's vote: `1` (upvote), `-1` (downvote), or `null`
</ResponseField>

<ResponseField name="changed_my_mind" type="object">
  "Changed my mind" indicators

  <ResponseField name="count" type="integer">
    Number of users who marked this comment as changing their mind
  </ResponseField>

  <ResponseField name="for_this_user" type="boolean">
    Whether current user marked this as changing their mind
  </ResponseField>
</ResponseField>

<ResponseField name="mentioned_users" type="array">
  Users mentioned with @ in the comment
</ResponseField>

<ResponseField name="author_staff_permission" type="string">
  Author's staff permission level on the post
</ResponseField>

<ResponseField name="key_factors" type="array">
  Key factors associated with this comment (advanced feature)
</ResponseField>

***

## Create Comment

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://www.metaculus.com/api/comments/create/" \
    -H "Authorization: Token YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "on_post": 3530,
      "text": "Great analysis! I agree with the reasoning.",
      "included_forecast": false,
      "is_private": false
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://www.metaculus.com/api/comments/create/",
      headers={
          "Authorization": "Token YOUR_TOKEN",
          "Content-Type": "application/json"
      },
      json={
          "on_post": 3530,
          "text": "Great analysis! I agree with the reasoning.",
          "included_forecast": False,
          "is_private": False
      }
  )
  comment = response.json()
  print(f"Comment created with ID: {comment['id']}")
  ```
</CodeGroup>

`POST /api/comments/create/`

Create a new comment on a post.

### Request Body

<ParamField body="on_post" type="integer" required>
  The post ID to comment on
</ParamField>

<ParamField body="text" type="string" required>
  Comment text in markdown format. Can be empty if key\_factors are provided.
</ParamField>

<ParamField body="is_private" type="boolean" default="false">
  Whether this is a private comment (visible only to you)
</ParamField>

<ParamField body="included_forecast" type="boolean" default="false">
  Include your most recent forecast on this question
</ParamField>

<ParamField body="parent" type="integer">
  ID of the comment to reply to (omit for root comments)
</ParamField>

<ParamField body="key_factors" type="array">
  Advanced: Key factors to attach to this comment
</ParamField>

### Response

Returns the created comment object.

<Note>
  **Comment Formatting**

  Comments support markdown formatting:

  * **Bold**: `**text**`
  * *Italic*: `*text*`
  * Links: `[text](url)`
  * Lists: `- item` or `1. item`
  * Code: `` `code` ``
  * Mentions: `@username`
  * LaTeX math: `$equation$` or `$$block$$`
</Note>

***

## Edit Comment

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH "https://www.metaculus.com/api/comments/12345/edit/" \
    -H "Authorization: Token YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"text": "Updated comment text"}'
  ```

  ```python Python theme={null}
  import requests

  response = requests.patch(
      "https://www.metaculus.com/api/comments/12345/edit/",
      headers={
          "Authorization": "Token YOUR_TOKEN",
          "Content-Type": "application/json"
      },
      json={"text": "Updated comment text"}
  )
  print(response.json())
  ```
</CodeGroup>

`PATCH /api/comments/{commentId}/edit/`

Edit your own comment.

### Path Parameters

<ParamField path="commentId" type="integer" required>
  The comment ID to edit
</ParamField>

### Request Body

<ParamField body="text" type="string" required>
  Updated comment text
</ParamField>

<Note>
  You can only edit your own comments. The edit timestamp is tracked in `text_edited_at`.
</Note>

***

## Delete Comment

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE "https://www.metaculus.com/api/comments/12345/delete/" \
    -H "Authorization: Token YOUR_TOKEN"
  ```

  ```python Python theme={null}
  import requests

  response = requests.delete(
      "https://www.metaculus.com/api/comments/12345/delete/",
      headers={"Authorization": "Token YOUR_TOKEN"}
  )
  print(response.status_code)
  ```
</CodeGroup>

`DELETE /api/comments/{commentId}/delete/`

Soft-delete your comment. The comment text is replaced with "deleted" but the comment remains visible.

### Path Parameters

<ParamField path="commentId" type="integer" required>
  The comment ID to delete
</ParamField>

***

## Vote on Comment

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://www.metaculus.com/api/comments/12345/vote/" \
    -H "Authorization: Token YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"direction": 1}'
  ```

  ```python Python theme={null}
  import requests

  # Upvote
  response = requests.post(
      "https://www.metaculus.com/api/comments/12345/vote/",
      headers={
          "Authorization": "Token YOUR_TOKEN",
          "Content-Type": "application/json"
      },
      json={"direction": 1}
  )

  # Remove vote
  response = requests.post(
      "https://www.metaculus.com/api/comments/12345/vote/",
      headers={
          "Authorization": "Token YOUR_TOKEN",
          "Content-Type": "application/json"
      },
      json={"direction": 0}
  )
  ```
</CodeGroup>

`POST /api/comments/{commentId}/vote/`

Vote on a comment.

### Path Parameters

<ParamField path="commentId" type="integer" required>
  The comment ID to vote on
</ParamField>

### Request Body

<ParamField body="direction" type="integer" required>
  Vote direction:

  * `1`: Upvote
  * `-1`: Downvote
  * `0`: Remove vote
</ParamField>

***

## Report Comment

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://www.metaculus.com/api/comments/12345/report/" \
    -H "Authorization: Token YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"reason": "Spam content"}'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://www.metaculus.com/api/comments/12345/report/",
      headers={
          "Authorization": "Token YOUR_TOKEN",
          "Content-Type": "application/json"
      },
      json={"reason": "Spam content"}
  )
  print(response.status_code)
  ```
</CodeGroup>

`POST /api/comments/{commentId}/report/`

Report a comment for moderator review.

### Path Parameters

<ParamField path="commentId" type="integer" required>
  The comment ID to report
</ParamField>

### Request Body

<ParamField body="reason" type="string" required>
  Reason for reporting
</ParamField>

***

## Example: Comment Thread

```python theme={null}
import requests

headers = {"Authorization": "Token YOUR_TOKEN"}

# Get all comments on a post
response = requests.get(
    "https://www.metaculus.com/api/comments/",
    headers=headers,
    params={"post": 3530, "limit": 100}
)

comments = response.json()["results"]

# Organize into threads
root_comments = [c for c in comments if c["parent_id"] is None]
replies = [c for c in comments if c["parent_id"] is not None]

print(f"Root comments: {len(root_comments)}")
print(f"Replies: {len(replies)}")

# Display thread structure
for root in root_comments:
    print(f"\n{root['author']['username']}: {root['text'][:50]}...")
    print(f"  Votes: {root['vote_score']}")
    
    # Find replies to this comment
    comment_replies = [r for r in replies if r["parent_id"] == root["id"]]
    for reply in comment_replies:
        print(f"  ↳ {reply['author']['username']}: {reply['text'][:50]}...")
```

## Example: Comment with Forecast

```python theme={null}
import requests

headers = {"Authorization": "Token YOUR_TOKEN"}

# First, submit a forecast
requests.post(
    "https://www.metaculus.com/api/questions/forecast/",
    headers=headers,
    json=[{"question": 1, "probability_yes": 0.75}]
)

# Then create a comment that includes the forecast
response = requests.post(
    "https://www.metaculus.com/api/comments/create/",
    headers=headers,
    json={
        "on_post": 1,
        "text": "I predict 75% because recent data shows...",
        "included_forecast": True,
        "is_private": False
    }
)

comment = response.json()
print(f"Forecast included: {comment['included_forecast']}")
```
