Comments
Threaded comments + edit/delete lifecycle.
Unpin a comment
Clears the `is_pinned` flag. Requires admin API key or admin JWT with the `moderate_content` capability. Emits a `comment_unpinned` SSE event on the discussion channel.
Pin a comment to the top of its thread
Moderator action — pins the comment so it sorts first within its discussion. Unlimited pins per discussion. Requires admin API key or an admin JWT with the `moderate_content` capability. Emits a `comment_pinned` SSE event on the discussion channel.
Admin-delete a comment (hard moderation)
Moderator removal — requires an admin API key or admin JWT. The comment status moves to `deleted` and is recorded as a moderation action. Dual-auth mounted at `/api/v1/comments/:id/remove` and `/api/v1/admin/comments/:id/remove`.
List comments by publisher external id
Same payload as the UUID route but keyed on the tenant-scoped `external_id` (publisher article/page identifier). Returns 404 when no discussion exists for that external id — the widget renders its empty state without Edgar ever having written. Dual-auth: available under `/api/v1/discussions/by-external/...` (API-key) and `/api/v1/admin/discussions/by-external/...` (admin JWT).
List comments for a discussion (paginated)
Returns comments in cursor-paginated order. Supports filtering by `parent_id` (pass `null` for top-level only), `sort`, and a `viewer_id` that enriches each row with the viewer's own reactions. Dual-auth: available under `/api/v1/discussions/...` (API-key) and `/api/v1/admin/discussions/...` (admin JWT).
Soft-delete own comment
Authors soft-delete their own comment; the row is retained (status `deleted`) so reply threads stay coherent. Emits a `comment_deleted` SSE event.
Edit own comment within edit window
Authors edit their own comment body within the tenant-configured edit window. Fails with 422 if the window has closed. Emits a `comment_edited` SSE event on success.
Unpin a comment
Clears the `is_pinned` flag. Requires admin API key or admin JWT with the `moderate_content` capability. Emits a `comment_unpinned` SSE event on the discussion channel.
Pin a comment to the top of its thread
Moderator action — pins the comment so it sorts first within its discussion. Unlimited pins per discussion. Requires admin API key or an admin JWT with the `moderate_content` capability. Emits a `comment_pinned` SSE event on the discussion channel.
Admin-delete a comment (hard moderation)
Moderator removal — requires an admin API key or admin JWT. The comment status moves to `deleted` and is recorded as a moderation action. Dual-auth mounted at `/api/v1/comments/:id/remove` and `/api/v1/admin/comments/:id/remove`.
Report a comment for moderation
End-users flag a comment for moderator review. One report per (reporter, comment) pair is enforced; duplicates fail with 422.
List comments by publisher external id
Same payload as the UUID route but keyed on the tenant-scoped `external_id` (publisher article/page identifier). Returns 404 when no discussion exists for that external id — the widget renders its empty state without Edgar ever having written. Dual-auth: available under `/api/v1/discussions/by-external/...` (API-key) and `/api/v1/admin/discussions/by-external/...` (admin JWT).
Create a comment keyed on publisher external id (lazy-creates discussion)
Creates a comment against the discussion identified by the tenant-scoped `external_id`. If no discussion exists for that id, one is materialised in the same request (title defaults to `external_id`; a later POST /api/v1/discussions can set a real title without being overwritten). Emits `comment_created` SSE. Idempotent — pass `Idempotency-Key: <uuid>` to safely retry.
List comments for a discussion (paginated)
Returns comments in cursor-paginated order. Supports filtering by `parent_id` (pass `null` for top-level only), `sort`, and a `viewer_id` that enriches each row with the viewer's own reactions. Dual-auth: available under `/api/v1/discussions/...` (API-key) and `/api/v1/admin/discussions/...` (admin JWT).
Create a top-level or reply comment
Publisher end-users create a comment against a discussion. Replies set `parent_id`. `user_id` is the external SDK identity, resolved to the tenant-scoped internal user. Emits a `comment_created` SSE event. Idempotent — pass `Idempotency-Key: <uuid>` to safely retry.