Comments

Threaded post comments — a comment belongs to a post and an author, with optional reply_to_id for threading and is_public visibility control.

Service: blog.comments

Post comment with optional threading. A comment belongs to a post and an author (user); reply_to_id references a parent comment for threaded replies (null for top-level). Visibility is controlled by is_public.

Fields

Field Type Required Description
id string Primary key. Read-only, auto-generated
post_id string Post this comment belongs to
author_id string Author of the comment (user id)
reply_to_id string? Parent comment id for threaded replies. null for top-level comments
content string Comment body
is_public boolean Whether this comment is publicly visible. Default false
created_at string ISO 8601 creation timestamp. Read-only
updated_at string ISO 8601 last update timestamp. Read-only

Filterable: post_id · author_id · is_public

find

List comments with filtering, sorting, and pagination. Filter by post_id to fetch a comment thread, and by is_public to scope to published comments.

HTTP

Request

GET /v1/blog/comments?filter=%5B%5B%22post_id%22%2C%22%24eq%22%2C%221920438291750%22%5D%2C%5B%22is_public%22%2C%22%24eq%22%2Ctrue%5D%5D&sort=created_at&fields=id,post_id,author_id,reply_to_id,content,is_public,created_at,updated_at&limit=100
Authorization: Bearer <token>

Response

{
  "items": [
    {
      "id": "1920438291900",
      "post_id": "1920438291750",
      "author_id": "42",
      "reply_to_id": null,
      "content": "Great write-up — the threat model section finally made it click.",
      "is_public": true,
      "created_at": "2026-05-14T09:12:00Z",
      "updated_at": "2026-05-14T09:12:00Z"
    },
    {
      "id": "1920438291901",
      "post_id": "1920438291750",
      "author_id": "77",
      "reply_to_id": "1920438291900",
      "content": "Same here. The key-wrapping diagram helped a lot.",
      "is_public": true,
      "created_at": "2026-05-14T10:05:00Z",
      "updated_at": "2026-05-14T10:05:00Z"
    }
  ],
  "total": 2
}

WebSocket

Request

{
  "jsonrpc": "2.0",
  "method": "blog.comments.find",
  "params": {
    "filter": {
      "post_id": { "$eq": "1920438291750" },
      "is_public": { "$eq": true }
    },
    "sort": [{ "field": "created_at", "dir": "asc" }],
    "fields": ["id", "post_id", "author_id", "reply_to_id", "content", "is_public", "created_at", "updated_at"],
    "limit": 100
  },
  "id": 30
}

Response

{
  "jsonrpc": "2.0",
  "result": {
    "items": [
      {
        "id": "1920438291900",
        "post_id": "1920438291750",
        "author_id": "42",
        "reply_to_id": null,
        "content": "Great write-up — the threat model section finally made it click.",
        "is_public": true,
        "created_at": "2026-05-14T09:12:00Z",
        "updated_at": "2026-05-14T09:12:00Z"
      },
      {
        "id": "1920438291901",
        "post_id": "1920438291750",
        "author_id": "77",
        "reply_to_id": "1920438291900",
        "content": "Same here. The key-wrapping diagram helped a lot.",
        "is_public": true,
        "created_at": "2026-05-14T10:05:00Z",
        "updated_at": "2026-05-14T10:05:00Z"
      }
    ],
    "total": 2
  },
  "id": 30
}

findOneById

Fetch a single comment by id.

HTTP

Request

GET /v1/blog/comments/1920438291900?fields=id,post_id,author_id,reply_to_id,content,is_public,created_at,updated_at
Authorization: Bearer <token>

Response

{
  "id": "1920438291900",
  "post_id": "1920438291750",
  "author_id": "42",
  "reply_to_id": null,
  "content": "Great write-up — the threat model section finally made it click.",
  "is_public": true,
  "created_at": "2026-05-14T09:12:00Z",
  "updated_at": "2026-05-14T09:12:00Z"
}

WebSocket

Request

{
  "jsonrpc": "2.0",
  "method": "blog.comments.findOneById",
  "params": {
    "id": "1920438291900",
    "fields": ["id", "post_id", "author_id", "reply_to_id", "content", "is_public", "created_at", "updated_at"]
  },
  "id": 31
}

Response

{
  "jsonrpc": "2.0",
  "result": {
    "id": "1920438291900",
    "post_id": "1920438291750",
    "author_id": "42",
    "reply_to_id": null,
    "content": "Great write-up — the threat model section finally made it click.",
    "is_public": true,
    "created_at": "2026-05-14T09:12:00Z",
    "updated_at": "2026-05-14T09:12:00Z"
  },
  "id": 31
}

create

Create a new comment. The server assigns id, created_at, and updated_at. Set reply_to_id to a parent comment id to post a threaded reply; omit it (or send null) for a top-level comment.

HTTP

Request

POST /v1/blog/comments
Authorization: Bearer <token>
Content-Type: application/json

{
  "post_id": "1920438291750",
  "author_id": "77",
  "reply_to_id": "1920438291900",
  "content": "Same here. The key-wrapping diagram helped a lot.",
  "is_public": true
}

Response

{
  "id": "1920438291901",
  "post_id": "1920438291750",
  "reply_to_id": "1920438291900",
  "is_public": true,
  "created_at": "2026-05-14T10:05:00Z"
}

WebSocket

Request

{
  "jsonrpc": "2.0",
  "method": "blog.comments.create",
  "params": {
    "document": {
      "post_id": "1920438291750",
      "author_id": "77",
      "reply_to_id": "1920438291900",
      "content": "Same here. The key-wrapping diagram helped a lot.",
      "is_public": true
    }
  },
  "id": 32
}

Response

{
  "jsonrpc": "2.0",
  "result": {
    "id": "1920438291901",
    "post_id": "1920438291750",
    "reply_to_id": "1920438291900",
    "is_public": true,
    "created_at": "2026-05-14T10:05:00Z"
  },
  "id": 32
}

updateOneById

Partial update — only specified fields change; omitted fields are untouched.

HTTP

Request

PATCH /v1/blog/comments/1920438291901
Authorization: Bearer <token>
Content-Type: application/json

{ "is_public": false }

Response

{
  "id": "1920438291901",
  "is_public": false,
  "updated_at": "2026-05-14T10:30:00Z"
}

WebSocket

Request

{
  "jsonrpc": "2.0",
  "method": "blog.comments.updateOneById",
  "params": {
    "id": "1920438291901",
    "document": { "is_public": false }
  },
  "id": 33
}

Response

{
  "jsonrpc": "2.0",
  "result": {
    "id": "1920438291901",
    "is_public": false,
    "updated_at": "2026-05-14T10:30:00Z"
  },
  "id": 33
}

replaceOneById

Full replacement — all writable fields must be provided. Unlike updateOneById, omitted fields are reset to defaults.

HTTP

Request

PUT /v1/blog/comments/1920438291901
Authorization: Bearer <token>
Content-Type: application/json

{
  "post_id": "1920438291750",
  "author_id": "77",
  "reply_to_id": "1920438291900",
  "content": "Same here. The key-wrapping diagram helped a lot.",
  "is_public": true
}

Response

{
  "id": "1920438291901",
  "post_id": "1920438291750",
  "author_id": "77",
  "reply_to_id": "1920438291900",
  "is_public": true,
  "updated_at": "2026-05-14T10:35:00Z"
}

WebSocket

Request

{
  "jsonrpc": "2.0",
  "method": "blog.comments.replaceOneById",
  "params": {
    "id": "1920438291901",
    "document": {
      "post_id": "1920438291750",
      "author_id": "77",
      "reply_to_id": "1920438291900",
      "content": "Same here. The key-wrapping diagram helped a lot.",
      "is_public": true
    }
  },
  "id": 34
}

Response

{
  "jsonrpc": "2.0",
  "result": {
    "id": "1920438291901",
    "post_id": "1920438291750",
    "author_id": "77",
    "reply_to_id": "1920438291900",
    "is_public": true,
    "updated_at": "2026-05-14T10:35:00Z"
  },
  "id": 34
}

update

Batch update multiple comments in a single transaction (all-or-nothing). See Batch operations.

HTTP

Request

PATCH /v1/blog/comments
Authorization: Bearer <token>
Content-Type: application/json

{
  "items": [
    { "id": "1920438291900", "document": { "is_public": true } },
    { "id": "1920438291901", "document": { "is_public": true } }
  ]
}

Response

{
  "affected": 2,
  "items": [
    { "id": "1920438291900", "is_public": true },
    { "id": "1920438291901", "is_public": true }
  ]
}

WebSocket

Request

{
  "jsonrpc": "2.0",
  "method": "blog.comments.update",
  "params": {
    "items": [
      { "id": "1920438291900", "document": { "is_public": true } },
      { "id": "1920438291901", "document": { "is_public": true } }
    ]
  },
  "id": 35
}

Response

{
  "jsonrpc": "2.0",
  "result": {
    "affected": 2,
    "items": [
      { "id": "1920438291900", "is_public": true },
      { "id": "1920438291901", "is_public": true }
    ]
  },
  "id": 35
}

deleteOneById

Delete a comment. Replies that pointed to this comment survive — their reply_to_id is reset to null (they become top-level).

HTTP

Request

DELETE /v1/blog/comments/1920438291900
Authorization: Bearer <token>

Response

{ "id": "1920438291900", "content": "Great write-up — the threat model section finally made it click." }

WebSocket

Request

{
  "jsonrpc": "2.0",
  "method": "blog.comments.deleteOneById",
  "params": { "id": "1920438291900" },
  "id": 36
}

Response

{
  "jsonrpc": "2.0",
  "result": { "id": "1920438291900", "content": "Great write-up — the threat model section finally made it click." },
  "id": 36
}

delete

Batch delete comments in a single transaction (all-or-nothing). See Batch operations.

HTTP

Request

DELETE /v1/blog/comments
Authorization: Bearer <token>
Content-Type: application/json

{
  "items": [
    { "id": "1920438291900" },
    { "id": "1920438291901" }
  ]
}

Response

{
  "affected": 2,
  "items": [
    { "id": "1920438291900" },
    { "id": "1920438291901" }
  ]
}

WebSocket

Request

{
  "jsonrpc": "2.0",
  "method": "blog.comments.delete",
  "params": {
    "items": [
      { "id": "1920438291900" },
      { "id": "1920438291901" }
    ]
  },
  "id": 37
}

Response

{
  "jsonrpc": "2.0",
  "result": {
    "affected": 2,
    "items": [
      { "id": "1920438291900" },
      { "id": "1920438291901" }
    ]
  },
  "id": 37
}