> ## Documentation Index
> Fetch the complete documentation index at: https://docs.commentify.pro/llms.txt
> Use this file to discover all available pages before exploring further.

# Thread modes

> Per-commentable discussion, reviews, or Q&A. Ratings and accepted answers follow the mode unless you override them.

Each alias in `commentables` is **discussion** until you say otherwise. String entries stay valid. Use the array form when a model should behave as reviews or Q\&A.

```php theme={null}
'commentables' => [
    'articles' => \App\Models\Article::class, // discussion
    'products' => [
        'model' => \App\Models\Product::class,
        'mode' => 'reviews',
    ],
    'lessons' => [
        'model' => \App\Models\Lesson::class,
        'mode' => 'qa',
    ],
],
```

Optional flags override the mode defaults:

```php theme={null}
'lessons' => [
    'model' => \App\Models\Lesson::class,
    'mode' => 'qa',
    'ratings' => false,
    'accepted_answers' => true,
],
```

## What each mode does

| Mode | Top-level `type` | Ratings (1-5) | Accepted answers |
| - | - | - | - |
| `discussion` | `comment` | Off | Off |
| `reviews` | `review` | On. One per author | Off |
| `qa` | `question` | Off | On. Page author or moderator |

Replies stay `type = comment`. Ratings apply only to **top-level** posts on a reviews thread. A second rating from the same author (or guest email) is rejected.

List responses include a `thread` object so Livewire, React, and Vue can show stars, averages, and accept controls without guessing:

```json theme={null}
{
  "mode": "reviews",
  "ratings": true,
  "accepted_answers": false,
  "average_rating": 4.5,
  "rating_count": 12,
  "rating_distribution": { "1": 0, "2": 1, "3": 2, "4": 3, "5": 6 },
  "has_rated": false,
  "duplicate_detection": true
}
```

`duplicate_detection` is an AI flag, not a mode. See [Bring-your-own-key AI](https://docs.commentify.pro/ai.md).

## Ratings

On a reviews thread, the composer shows five stars. Send `rating` (1-5) with `POST {type}/{id}/comments`. Livewire uses `newCommentState.rating`.

List responses expose `thread.average_rating` and `thread.rating_count`. Livewire shows the same via the thread-stats partial.

## Accepted answers

On a Q\&A thread, the **page author** (`badges.author_key`, default `user_id`) or a **moderator** can accept a **reply**. The accepted reply floats to the top of that question. Unaccept clears it.

```bash theme={null}
POST   /commentify/api/v1/comments/{id}/accept
DELETE /commentify/api/v1/comments/{id}/accept
```

Parents cannot be accepted (`cannot_accept_parent`). Accepting on a non-Q\&A thread returns `accepted_answers_disabled`.

Livewire, React, and Vue show **Accept answer** when `comment.can.accept` is true.

## Schema

Pro migrations add `type`, `rating`, `accepted_at`, and `metadata` on `comments`, plus `commentify_embeddings`. The MIT package does not know about those columns. Pro owns the schema and the Livewire UI for modes. The rest of the 1.1 tables are on [Upgrade to Commentify Pro](https://docs.commentify.pro/upgrading.md).

> [!TIP]
>
> Guest commenting is still a [core](https://docs.commentify.pro/guests.md) feature. Modes do not turn guests on or off.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.