# Comments

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## GET /comments/{datatype}/{id}

**List comments on a record**

`operationId: CommentsController_list`

Comments on a record. `parent` fetches replies to a specific comment rather than the top level, and `includeHidden` shows moderated comments — a moderator view, since hidden comments are hidden for a reason.

#### Signature

```http
GET /comments/{datatype}/{id} (datatype: string, id: string, p?: integer, ps?: integer, sort?: string, parent?: string, includeHidden?: boolean) -> Comments
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- `includeHidden` exposes moderated content.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /comments/{commentId}/replies`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `datatype` | path | string | yes | DataType of the record. |
| `id` | path | string | yes | Record id. |
| `sort` | query | string | — |  |
| `parent` | query | string | — | Fetch replies to this comment. |
| `includeHidden` | query | boolean | — | Include moderated comments. |
| `p` | query | integer | — | Page number. |
| `ps` | query | integer | — | Page size. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Comments |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /comments/{datatype}/{id}

**Add a comment**

`operationId: CommentsController_create`

Comments on any record. `parentComment` makes it a reply; `rating` attaches a score, which is how a comment doubles as a review.

The author is the calling customer or user — comments cannot be posted on someone else's behalf.

#### Signature

```http
POST /comments/{datatype}/{id} (datatype: string, id: string, body) -> The comment
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /comments/{datatype}/{id}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `datatype` | path | string | yes | DataType of the record. |
| `id` | path | string | yes | Record id. |

### Request body

The comment.

```json
{
  "message": "Arrived quickly and well packed.",
  "rating": 5
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The comment |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /comments/{commentId}

**Edit a comment**

`operationId: CommentsController_update`

Edits a comment. Restricted to its author — someone else's comment is moderated, not edited.

#### Signature

```http
PUT /comments/{commentId} (commentId: string, body) -> The updated comment
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /comments/{commentId}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `commentId` | path | string | yes | Comment id. |

### Request body

Fields to change.

```json
{
  "message": "Arrived quickly and well packed. Updated: the lid was cracked."
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated comment |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /comments/{commentId}

**Delete a comment**

`operationId: CommentsController_remove`

Removes a comment. Replies to it may be orphaned — setting its status to hidden preserves the thread structure, which is usually the better moderation action.

#### Signature

```http
DELETE /comments/{commentId} (commentId: string) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Prefer hiding when the comment has replies.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /comments/{commentId}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `commentId` | path | string | yes | Comment id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /comments/single/{commentId}

**Get one comment**

`operationId: CommentsController_getOne`

A single comment by id. The path segment `single` disambiguates it from the `{datatype}/{id}` list route.

#### Signature

```http
GET /comments/single/{commentId} (commentId: string) -> The comment
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `PUT /comments/{commentId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `commentId` | path | string | yes | Comment id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The comment |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /comments/{commentId}/replies

**List replies to a comment**

`operationId: CommentsController_replies`

The replies under one comment.

#### Signature

```http
GET /comments/{commentId}/replies (commentId: string, p?: integer, ps?: integer, sort?: string) -> Replies
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /comments/{datatype}/{id}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `commentId` | path | string | yes | Comment id. |
| `sort` | query | string | — |  |
| `p` | query | integer | — | Page number. |
| `ps` | query | integer | — | Page size. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Replies |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /comments/{commentId}/pin

**Pin a comment**

`operationId: CommentsController_pin`

Pins a comment to the top of its thread. `pinned: false` unpins — omitting the body pins, since it defaults to true.

#### Signature

```http
POST /comments/{commentId}/pin (commentId: string, body) -> The comment
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /comments/{commentId}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `commentId` | path | string | yes | Comment id. |

### Request body

Whether to pin. Defaults to pinning.

```json
{
  "pinned": true
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The comment |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /comments/{commentId}/status

**Set a comment's status**

`operationId: CommentsController_status`

Moderates a comment — approving, hiding or flagging it. This is what controls whether the public sees it, so it is the moderation action rather than deletion.

#### Signature

```http
POST /comments/{commentId}/status (commentId: string, body) -> The comment
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `400` | INVALID_STATUS | invalid status | The status is missing or not a recognised value. | Send a valid comment status. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

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

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `commentId` | path | string | yes | Comment id. |

### Request body

The new status.

```json
{
  "status": "hidden"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The comment |
| `400` | invalid status — The status is missing or not a recognised value. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /comments/{commentId}/report

**Report a comment**

`operationId: CommentsController_report`

Flags a comment for moderator attention. Reporting does not hide it — a moderator decides.

#### Signature

```http
POST /comments/{commentId}/report (commentId: string, body) -> The result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /comments/{commentId}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `commentId` | path | string | yes | Comment id. |

### Request body

Why it is being reported.

```json
{
  "reason": "spam",
  "details": "Repeated promotional links."
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /comments/by-author/{author}

**List an author's comments**

`operationId: CommentsController_byAuthor`

Everything one author has commented, across records — useful when moderating a pattern rather than a single comment.

#### Signature

```http
GET /comments/by-author/{author} (author: string, p?: integer, ps?: integer) -> Comments
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /comments/{commentId}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `author` | path | string | yes | Author identifier, typically an email. |
| `p` | query | integer | — | Page number. |
| `ps` | query | integer | — | Page size. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Comments |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

