Comments service (gRPC)#

Comments service manages conversations about resources.

Endpoints#

Add reaction#

gRPC /nominal.comments.v1.CommentsService/AddReaction

Create a reaction on a comment

Request: AddReactionRequest

comment_rid string

The RID of comment to delete

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

Response: AddReactionResponse

comment Comment

​

Fields of Comment
rid string

Unique resource identifier for the comment

parent CommentParent

The parent of the comment. It can be a resource or another comment.

Fields of CommentParent
one of resource, comment

​

resource CommentParentResource

​

Fields of CommentParentResource
resource_type ResourceType

The type of resource that the comment is associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

comment CommentParentComment

​

Fields of CommentParentComment
comment_rid string

The resource identifier for the comment that the comment is replying to

author_rid string

The user who authored the comment

created_at string (date-time)

The time the comment was created

edited_at string (date-time)

The time the comment was edited. Empty if the comment has not been edited.

deleted_at string (date-time)

The time the comment was deleted. Empty if the comment has not been deleted.

content string

The markdown content of the comment.

pinned_by string

The user who pinned the comment. Empty if the comment is not pinned.

pinned_at string (date-time)

The time the comment was pinned. Empty if the comment is not pinned.

reactions array of Reaction

The reactions on the comment

Fields of Reaction
rid string

Unique resource identifier for the reaction

user_rid string

The user who authored the reaction

created_at string (date-time)

The time the reaction was created

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

attachments array of string

The comment’s attachments

Request

import grpc
from nominal.protos.comments.v1 import comments_pb2, comments_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
comments_service = comments_pb2_grpc.CommentsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = comments_pb2.AddReactionRequest(comment_rid="<comment rid>", type="LIKE")
response = comments_service.AddReaction(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	commentsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/comments/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	commentsService := commentsv1.NewCommentsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &commentsv1.AddReactionRequest{
		CommentRid: "<comment rid>",
		Type:       commentsv1.ReactionType_LIKE,
	}
	response, err := commentsService.AddReaction(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "comment": {
    "rid": "<rid>",
    "parent": {
      "resource": {
        "resource_type": "RUN",
        "resource_rid": "<resource rid>"
      }
    },
    "author_rid": "<author rid>",
    "created_at": "2026-01-01T00:00:00Z",
    "edited_at": "2026-01-01T00:00:00Z",
    "deleted_at": "2026-01-01T00:00:00Z",
    "content": "<content>",
    "pinned_by": "<pinned by>",
    "pinned_at": "2026-01-01T00:00:00Z",
    "reactions": [
      {
        "rid": "<rid>",
        "user_rid": "<user rid>",
        "created_at": "2026-01-01T00:00:00Z",
        "type": "LIKE"
      }
    ],
    "attachments": [
      "<attachments>"
    ]
  }
}

Create comment#

gRPC /nominal.comments.v1.CommentsService/CreateComment

Create a comment on a resource

Request: CreateCommentRequest

parent CommentParent

​

Fields of CommentParent
one of resource, comment required

​

resource CommentParentResource

​

Fields of CommentParentResource
resource_type ResourceType

The type of resource that the comment is associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

comment CommentParentComment

​

Fields of CommentParentComment
comment_rid string

The resource identifier for the comment that the comment is replying to

content string

The content of the comment. Markdown supported.

attachments array of string

Attachments to the comment.

Response: CreateCommentResponse

comment Comment

​

Fields of Comment
rid string

Unique resource identifier for the comment

parent CommentParent

The parent of the comment. It can be a resource or another comment.

Fields of CommentParent
one of resource, comment

​

resource CommentParentResource

​

Fields of CommentParentResource
resource_type ResourceType

The type of resource that the comment is associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

comment CommentParentComment

​

Fields of CommentParentComment
comment_rid string

The resource identifier for the comment that the comment is replying to

author_rid string

The user who authored the comment

created_at string (date-time)

The time the comment was created

edited_at string (date-time)

The time the comment was edited. Empty if the comment has not been edited.

deleted_at string (date-time)

The time the comment was deleted. Empty if the comment has not been deleted.

content string

The markdown content of the comment.

pinned_by string

The user who pinned the comment. Empty if the comment is not pinned.

pinned_at string (date-time)

The time the comment was pinned. Empty if the comment is not pinned.

reactions array of Reaction

The reactions on the comment

Fields of Reaction
rid string

Unique resource identifier for the reaction

user_rid string

The user who authored the reaction

created_at string (date-time)

The time the reaction was created

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

attachments array of string

The comment’s attachments

Request

import grpc
from nominal.protos.comments.v1 import comments_pb2, comments_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
comments_service = comments_pb2_grpc.CommentsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = comments_pb2.CreateCommentRequest(
    parent={"resource": {"resource_type": "RUN", "resource_rid": "<resource rid>"}},
    content="<content>",
    attachments=["<attachments>"],
)
response = comments_service.CreateComment(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	commentsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/comments/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	commentsService := commentsv1.NewCommentsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &commentsv1.CreateCommentRequest{
		Parent: &commentsv1.CommentParent{
			CommentParent: &commentsv1.CommentParent_Resource{Resource: &commentsv1.CommentParentResource{
				ResourceType: commentsv1.ResourceType_RUN,
				ResourceRid:  "<resource rid>",
			}},
		},
		Content: "<content>",
		Attachments: []string{
			"<attachments>",
		},
	}
	response, err := commentsService.CreateComment(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "comment": {
    "rid": "<rid>",
    "parent": {
      "resource": {
        "resource_type": "RUN",
        "resource_rid": "<resource rid>"
      }
    },
    "author_rid": "<author rid>",
    "created_at": "2026-01-01T00:00:00Z",
    "edited_at": "2026-01-01T00:00:00Z",
    "deleted_at": "2026-01-01T00:00:00Z",
    "content": "<content>",
    "pinned_by": "<pinned by>",
    "pinned_at": "2026-01-01T00:00:00Z",
    "reactions": [
      {
        "rid": "<rid>",
        "user_rid": "<user rid>",
        "created_at": "2026-01-01T00:00:00Z",
        "type": "LIKE"
      }
    ],
    "attachments": [
      "<attachments>"
    ]
  }
}

Delete comment#

gRPC /nominal.comments.v1.CommentsService/DeleteComment

Delete an existing comment

Request: DeleteCommentRequest

comment_rid string

The RID of comment to delete

Response: DeleteCommentResponse

comment Comment

​

Fields of Comment
rid string

Unique resource identifier for the comment

parent CommentParent

The parent of the comment. It can be a resource or another comment.

Fields of CommentParent
one of resource, comment

​

resource CommentParentResource

​

Fields of CommentParentResource
resource_type ResourceType

The type of resource that the comment is associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

comment CommentParentComment

​

Fields of CommentParentComment
comment_rid string

The resource identifier for the comment that the comment is replying to

author_rid string

The user who authored the comment

created_at string (date-time)

The time the comment was created

edited_at string (date-time)

The time the comment was edited. Empty if the comment has not been edited.

deleted_at string (date-time)

The time the comment was deleted. Empty if the comment has not been deleted.

content string

The markdown content of the comment.

pinned_by string

The user who pinned the comment. Empty if the comment is not pinned.

pinned_at string (date-time)

The time the comment was pinned. Empty if the comment is not pinned.

reactions array of Reaction

The reactions on the comment

Fields of Reaction
rid string

Unique resource identifier for the reaction

user_rid string

The user who authored the reaction

created_at string (date-time)

The time the reaction was created

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

attachments array of string

The comment’s attachments

Request

import grpc
from nominal.protos.comments.v1 import comments_pb2, comments_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
comments_service = comments_pb2_grpc.CommentsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = comments_pb2.DeleteCommentRequest(comment_rid="<comment rid>")
response = comments_service.DeleteComment(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	commentsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/comments/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	commentsService := commentsv1.NewCommentsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &commentsv1.DeleteCommentRequest{
		CommentRid: "<comment rid>",
	}
	response, err := commentsService.DeleteComment(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "comment": {
    "rid": "<rid>",
    "parent": {
      "resource": {
        "resource_type": "RUN",
        "resource_rid": "<resource rid>"
      }
    },
    "author_rid": "<author rid>",
    "created_at": "2026-01-01T00:00:00Z",
    "edited_at": "2026-01-01T00:00:00Z",
    "deleted_at": "2026-01-01T00:00:00Z",
    "content": "<content>",
    "pinned_by": "<pinned by>",
    "pinned_at": "2026-01-01T00:00:00Z",
    "reactions": [
      {
        "rid": "<rid>",
        "user_rid": "<user rid>",
        "created_at": "2026-01-01T00:00:00Z",
        "type": "LIKE"
      }
    ],
    "attachments": [
      "<attachments>"
    ]
  }
}

Edit comment#

gRPC /nominal.comments.v1.CommentsService/EditComment

Edit an existing comment

Request: EditCommentRequestWrapper

comment_rid string

The RID of comment to edit

request EditCommentRequest

​

Fields of EditCommentRequest
content string

The content of the comment. Markdown supported.

attachments array of string

Attachments to the comment.

Response: EditCommentResponse

comment Comment

​

Fields of Comment
rid string

Unique resource identifier for the comment

parent CommentParent

The parent of the comment. It can be a resource or another comment.

Fields of CommentParent
one of resource, comment

​

resource CommentParentResource

​

Fields of CommentParentResource
resource_type ResourceType

The type of resource that the comment is associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

comment CommentParentComment

​

Fields of CommentParentComment
comment_rid string

The resource identifier for the comment that the comment is replying to

author_rid string

The user who authored the comment

created_at string (date-time)

The time the comment was created

edited_at string (date-time)

The time the comment was edited. Empty if the comment has not been edited.

deleted_at string (date-time)

The time the comment was deleted. Empty if the comment has not been deleted.

content string

The markdown content of the comment.

pinned_by string

The user who pinned the comment. Empty if the comment is not pinned.

pinned_at string (date-time)

The time the comment was pinned. Empty if the comment is not pinned.

reactions array of Reaction

The reactions on the comment

Fields of Reaction
rid string

Unique resource identifier for the reaction

user_rid string

The user who authored the reaction

created_at string (date-time)

The time the reaction was created

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

attachments array of string

The comment’s attachments

Request

import grpc
from nominal.protos.comments.v1 import comments_pb2, comments_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
comments_service = comments_pb2_grpc.CommentsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = comments_pb2.EditCommentRequestWrapper(
    comment_rid="<comment rid>",
    request={"content": "<content>", "attachments": ["<attachments>"]},
)
response = comments_service.EditComment(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	commentsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/comments/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	commentsService := commentsv1.NewCommentsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &commentsv1.EditCommentRequestWrapper{
		CommentRid: "<comment rid>",
		Request: &commentsv1.EditCommentRequest{
			Content: "<content>",
			Attachments: []string{
				"<attachments>",
			},
		},
	}
	response, err := commentsService.EditComment(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "comment": {
    "rid": "<rid>",
    "parent": {
      "resource": {
        "resource_type": "RUN",
        "resource_rid": "<resource rid>"
      }
    },
    "author_rid": "<author rid>",
    "created_at": "2026-01-01T00:00:00Z",
    "edited_at": "2026-01-01T00:00:00Z",
    "deleted_at": "2026-01-01T00:00:00Z",
    "content": "<content>",
    "pinned_by": "<pinned by>",
    "pinned_at": "2026-01-01T00:00:00Z",
    "reactions": [
      {
        "rid": "<rid>",
        "user_rid": "<user rid>",
        "created_at": "2026-01-01T00:00:00Z",
        "type": "LIKE"
      }
    ],
    "attachments": [
      "<attachments>"
    ]
  }
}

Get comment#

gRPC /nominal.comments.v1.CommentsService/GetComment

Get a comment identified by its RID

Request: GetCommentRequest

comment_rid string

The RID of comment to fetch

Response: GetCommentResponse

comment Comment

​

Fields of Comment
rid string

Unique resource identifier for the comment

parent CommentParent

The parent of the comment. It can be a resource or another comment.

Fields of CommentParent
one of resource, comment

​

resource CommentParentResource

​

Fields of CommentParentResource
resource_type ResourceType

The type of resource that the comment is associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

comment CommentParentComment

​

Fields of CommentParentComment
comment_rid string

The resource identifier for the comment that the comment is replying to

author_rid string

The user who authored the comment

created_at string (date-time)

The time the comment was created

edited_at string (date-time)

The time the comment was edited. Empty if the comment has not been edited.

deleted_at string (date-time)

The time the comment was deleted. Empty if the comment has not been deleted.

content string

The markdown content of the comment.

pinned_by string

The user who pinned the comment. Empty if the comment is not pinned.

pinned_at string (date-time)

The time the comment was pinned. Empty if the comment is not pinned.

reactions array of Reaction

The reactions on the comment

Fields of Reaction
rid string

Unique resource identifier for the reaction

user_rid string

The user who authored the reaction

created_at string (date-time)

The time the reaction was created

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

attachments array of string

The comment’s attachments

Request

import grpc
from nominal.protos.comments.v1 import comments_pb2, comments_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
comments_service = comments_pb2_grpc.CommentsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = comments_pb2.GetCommentRequest(comment_rid="<comment rid>")
response = comments_service.GetComment(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	commentsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/comments/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	commentsService := commentsv1.NewCommentsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &commentsv1.GetCommentRequest{
		CommentRid: "<comment rid>",
	}
	response, err := commentsService.GetComment(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "comment": {
    "rid": "<rid>",
    "parent": {
      "resource": {
        "resource_type": "RUN",
        "resource_rid": "<resource rid>"
      }
    },
    "author_rid": "<author rid>",
    "created_at": "2026-01-01T00:00:00Z",
    "edited_at": "2026-01-01T00:00:00Z",
    "deleted_at": "2026-01-01T00:00:00Z",
    "content": "<content>",
    "pinned_by": "<pinned by>",
    "pinned_at": "2026-01-01T00:00:00Z",
    "reactions": [
      {
        "rid": "<rid>",
        "user_rid": "<user rid>",
        "created_at": "2026-01-01T00:00:00Z",
        "type": "LIKE"
      }
    ],
    "attachments": [
      "<attachments>"
    ]
  }
}

Get conversation#

gRPC /nominal.comments.v1.CommentsService/GetConversation

A conversation is a fully resolved comment tree. It includes all comments for the given resource and all the nested comments/replies to those comments.

Request: GetConversationRequest

resource_type ResourceType

The type of resource that the comments are associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The RID of resource that the comments are associated with

Response: GetConversationResponse

conversation Conversation

​

Fields of Conversation
resource_rid string

RID for the resource that the conversation is associated with.

resource_type ResourceType

The type of the resource that the conversation is associated with.

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

comments array of ConversationNode

The comments on the conversation ordered by creation time. Empty if the comment has no replies.

Fields of ConversationNode
comment Comment

The comment

Fields of Comment
rid string

Unique resource identifier for the comment

parent CommentParent

The parent of the comment. It can be a resource or another comment.

Fields of CommentParent
one of resource, comment

​

resource CommentParentResource

​

Fields of CommentParentResource
resource_type ResourceType

The type of resource that the comment is associated with

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

comment CommentParentComment

​

Fields of CommentParentComment
comment_rid string

The resource identifier for the comment that the comment is replying to

author_rid string

The user who authored the comment

created_at string (date-time)

The time the comment was created

edited_at string (date-time)

The time the comment was edited. Empty if the comment has not been edited.

deleted_at string (date-time)

The time the comment was deleted. Empty if the comment has not been deleted.

content string

The markdown content of the comment.

pinned_by string

The user who pinned the comment. Empty if the comment is not pinned.

pinned_at string (date-time)

The time the comment was pinned. Empty if the comment is not pinned.

reactions array of Reaction

The reactions on the comment

Fields of Reaction
rid string

Unique resource identifier for the reaction

user_rid string

The user who authored the reaction

created_at string (date-time)

The time the reaction was created

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

attachments array of string

The comment’s attachments

replies array of ConversationNode

The comments on (aka replies to) the comment ordered by creation time. Empty if the comment has no replies.

Request

import grpc
from nominal.protos.comments.v1 import comments_pb2, comments_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
comments_service = comments_pb2_grpc.CommentsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = comments_pb2.GetConversationRequest(
    resource_type="RUN",
    resource_rid="<resource rid>",
)
response = comments_service.GetConversation(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	commentsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/comments/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	commentsService := commentsv1.NewCommentsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &commentsv1.GetConversationRequest{
		ResourceType: commentsv1.ResourceType_RUN,
		ResourceRid:  "<resource rid>",
	}
	response, err := commentsService.GetConversation(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "conversation": {
    "resource_rid": "<resource rid>",
    "resource_type": "RUN",
    "comments": [
      {
        "comment": {
          "rid": "<rid>",
          "parent": {
            "resource": {
              "resource_type": "RUN",
              "resource_rid": "<resource rid>"
            }
          },
          "author_rid": "<author rid>",
          "created_at": "2026-01-01T00:00:00Z",
          "edited_at": "2026-01-01T00:00:00Z",
          "deleted_at": "2026-01-01T00:00:00Z",
          "content": "<content>",
          "pinned_by": "<pinned by>",
          "pinned_at": "2026-01-01T00:00:00Z",
          "reactions": [
            {
              "rid": "<rid>",
              "user_rid": "<user rid>",
              "created_at": "2026-01-01T00:00:00Z",
              "type": "LIKE"
            }
          ],
          "attachments": [
            "<attachments>"
          ]
        },
        "replies": []
      }
    ]
  }
}

Get conversation count#

gRPC /nominal.comments.v1.CommentsService/GetConversationCount

Returns the number of comments in a conversation.

Request: GetConversationCountRequest

resource_type ResourceType

The type of resource that the comments are associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The RID of resource that the comments are associated with

include_deleted boolean

Whether to include deleted comments in the count

Response: GetConversationCountResponse

count integer

​

Request

import grpc
from nominal.protos.comments.v1 import comments_pb2, comments_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
comments_service = comments_pb2_grpc.CommentsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = comments_pb2.GetConversationCountRequest(
    resource_type="RUN",
    resource_rid="<resource rid>",
    include_deleted=True,
)
response = comments_service.GetConversationCount(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	commentsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/comments/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
	"google.golang.org/protobuf/proto"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	commentsService := commentsv1.NewCommentsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &commentsv1.GetConversationCountRequest{
		ResourceType:   commentsv1.ResourceType_RUN,
		ResourceRid:    "<resource rid>",
		IncludeDeleted: proto.Bool(true),
	}
	response, err := commentsService.GetConversationCount(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "count": 1
}

Pin comment#

gRPC /nominal.comments.v1.CommentsService/PinComment

Pin a comment to the top of the conversation

Request: PinCommentRequest

comment_rid string

The RID of comment to pin

Response: PinCommentResponse

comment Comment

​

Fields of Comment
rid string

Unique resource identifier for the comment

parent CommentParent

The parent of the comment. It can be a resource or another comment.

Fields of CommentParent
one of resource, comment

​

resource CommentParentResource

​

Fields of CommentParentResource
resource_type ResourceType

The type of resource that the comment is associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

comment CommentParentComment

​

Fields of CommentParentComment
comment_rid string

The resource identifier for the comment that the comment is replying to

author_rid string

The user who authored the comment

created_at string (date-time)

The time the comment was created

edited_at string (date-time)

The time the comment was edited. Empty if the comment has not been edited.

deleted_at string (date-time)

The time the comment was deleted. Empty if the comment has not been deleted.

content string

The markdown content of the comment.

pinned_by string

The user who pinned the comment. Empty if the comment is not pinned.

pinned_at string (date-time)

The time the comment was pinned. Empty if the comment is not pinned.

reactions array of Reaction

The reactions on the comment

Fields of Reaction
rid string

Unique resource identifier for the reaction

user_rid string

The user who authored the reaction

created_at string (date-time)

The time the reaction was created

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

attachments array of string

The comment’s attachments

Request

import grpc
from nominal.protos.comments.v1 import comments_pb2, comments_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
comments_service = comments_pb2_grpc.CommentsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = comments_pb2.PinCommentRequest(comment_rid="<comment rid>")
response = comments_service.PinComment(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	commentsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/comments/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	commentsService := commentsv1.NewCommentsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &commentsv1.PinCommentRequest{
		CommentRid: "<comment rid>",
	}
	response, err := commentsService.PinComment(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "comment": {
    "rid": "<rid>",
    "parent": {
      "resource": {
        "resource_type": "RUN",
        "resource_rid": "<resource rid>"
      }
    },
    "author_rid": "<author rid>",
    "created_at": "2026-01-01T00:00:00Z",
    "edited_at": "2026-01-01T00:00:00Z",
    "deleted_at": "2026-01-01T00:00:00Z",
    "content": "<content>",
    "pinned_by": "<pinned by>",
    "pinned_at": "2026-01-01T00:00:00Z",
    "reactions": [
      {
        "rid": "<rid>",
        "user_rid": "<user rid>",
        "created_at": "2026-01-01T00:00:00Z",
        "type": "LIKE"
      }
    ],
    "attachments": [
      "<attachments>"
    ]
  }
}

Remove reaction#

gRPC /nominal.comments.v1.CommentsService/RemoveReaction

Create a reaction on a comment

Request: RemoveReactionRequest

comment_rid string

The RID of comment to delete

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

Response: RemoveReactionResponse

comment Comment

​

Fields of Comment
rid string

Unique resource identifier for the comment

parent CommentParent

The parent of the comment. It can be a resource or another comment.

Fields of CommentParent
one of resource, comment

​

resource CommentParentResource

​

Fields of CommentParentResource
resource_type ResourceType

The type of resource that the comment is associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

comment CommentParentComment

​

Fields of CommentParentComment
comment_rid string

The resource identifier for the comment that the comment is replying to

author_rid string

The user who authored the comment

created_at string (date-time)

The time the comment was created

edited_at string (date-time)

The time the comment was edited. Empty if the comment has not been edited.

deleted_at string (date-time)

The time the comment was deleted. Empty if the comment has not been deleted.

content string

The markdown content of the comment.

pinned_by string

The user who pinned the comment. Empty if the comment is not pinned.

pinned_at string (date-time)

The time the comment was pinned. Empty if the comment is not pinned.

reactions array of Reaction

The reactions on the comment

Fields of Reaction
rid string

Unique resource identifier for the reaction

user_rid string

The user who authored the reaction

created_at string (date-time)

The time the reaction was created

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

attachments array of string

The comment’s attachments

Request

import grpc
from nominal.protos.comments.v1 import comments_pb2, comments_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
comments_service = comments_pb2_grpc.CommentsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = comments_pb2.RemoveReactionRequest(comment_rid="<comment rid>", type="LIKE")
response = comments_service.RemoveReaction(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	commentsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/comments/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	commentsService := commentsv1.NewCommentsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &commentsv1.RemoveReactionRequest{
		CommentRid: "<comment rid>",
		Type:       commentsv1.ReactionType_LIKE,
	}
	response, err := commentsService.RemoveReaction(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "comment": {
    "rid": "<rid>",
    "parent": {
      "resource": {
        "resource_type": "RUN",
        "resource_rid": "<resource rid>"
      }
    },
    "author_rid": "<author rid>",
    "created_at": "2026-01-01T00:00:00Z",
    "edited_at": "2026-01-01T00:00:00Z",
    "deleted_at": "2026-01-01T00:00:00Z",
    "content": "<content>",
    "pinned_by": "<pinned by>",
    "pinned_at": "2026-01-01T00:00:00Z",
    "reactions": [
      {
        "rid": "<rid>",
        "user_rid": "<user rid>",
        "created_at": "2026-01-01T00:00:00Z",
        "type": "LIKE"
      }
    ],
    "attachments": [
      "<attachments>"
    ]
  }
}

Unpin comment#

gRPC /nominal.comments.v1.CommentsService/UnpinComment

Unpin a comment from the top of the conversation

Request: UnpinCommentRequest

comment_rid string

The RID of comment to unpin

Response: UnpinCommentResponse

comment Comment

​

Fields of Comment
rid string

Unique resource identifier for the comment

parent CommentParent

The parent of the comment. It can be a resource or another comment.

Fields of CommentParent
one of resource, comment

​

resource CommentParentResource

​

Fields of CommentParentResource
resource_type ResourceType

The type of resource that the comment is associated with

Values of ResourceType
RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

comment CommentParentComment

​

Fields of CommentParentComment
comment_rid string

The resource identifier for the comment that the comment is replying to

author_rid string

The user who authored the comment

created_at string (date-time)

The time the comment was created

edited_at string (date-time)

The time the comment was edited. Empty if the comment has not been edited.

deleted_at string (date-time)

The time the comment was deleted. Empty if the comment has not been deleted.

content string

The markdown content of the comment.

pinned_by string

The user who pinned the comment. Empty if the comment is not pinned.

pinned_at string (date-time)

The time the comment was pinned. Empty if the comment is not pinned.

reactions array of Reaction

The reactions on the comment

Fields of Reaction
rid string

Unique resource identifier for the reaction

user_rid string

The user who authored the reaction

created_at string (date-time)

The time the reaction was created

type ReactionType

The type of reaction

Values of ReactionType
REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

attachments array of string

The comment’s attachments

Request

import grpc
from nominal.protos.comments.v1 import comments_pb2, comments_pb2_grpc

channel = grpc.secure_channel("api.gov.nominal.io:443", grpc.ssl_channel_credentials())
comments_service = comments_pb2_grpc.CommentsServiceStub(channel)
auth = [("authorization", "Bearer <api key>")]

request = comments_pb2.UnpinCommentRequest(comment_rid="<comment rid>")
response = comments_service.UnpinComment(request, metadata=auth)
print(response)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"log"

	commentsv1 "github.com/nominal-io/nominal-api-protos-go/nominal/protos/comments/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/metadata"
)

func main() {
	conn, err := grpc.NewClient("api.gov.nominal.io:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	commentsService := commentsv1.NewCommentsServiceClient(conn)
	ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <api key>")

	request := &commentsv1.UnpinCommentRequest{
		CommentRid: "<comment rid>",
	}
	response, err := commentsService.UnpinComment(ctx, request)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}

Response

{
  "comment": {
    "rid": "<rid>",
    "parent": {
      "resource": {
        "resource_type": "RUN",
        "resource_rid": "<resource rid>"
      }
    },
    "author_rid": "<author rid>",
    "created_at": "2026-01-01T00:00:00Z",
    "edited_at": "2026-01-01T00:00:00Z",
    "deleted_at": "2026-01-01T00:00:00Z",
    "content": "<content>",
    "pinned_by": "<pinned by>",
    "pinned_at": "2026-01-01T00:00:00Z",
    "reactions": [
      {
        "rid": "<rid>",
        "user_rid": "<user rid>",
        "created_at": "2026-01-01T00:00:00Z",
        "type": "LIKE"
      }
    ],
    "attachments": [
      "<attachments>"
    ]
  }
}

Errors#

Errors shows how these errors are sent.

Code

Reason

Message

INVALID_ARGUMENT

COMMENTS_ERROR_CONTENT_TOO_LONG

ContentTooLong

INVALID_ARGUMENT

COMMENTS_ERROR_EMPTY_COMMENT_CONTENT

EmptyCommentContent

INVALID_ARGUMENT

COMMENTS_ERROR_INVALID_ARGUMENT

InvalidArgument

INVALID_ARGUMENT

COMMENTS_ERROR_INVALID_ATTACHMENT

InvalidAttachment

INVALID_ARGUMENT

COMMENTS_ERROR_MAX_NESTING_DEPTH_EXCEEDED

MaxNestingDepthExceeded

NOT_FOUND

COMMENTS_ERROR_COMMENT_NOT_FOUND

CommentNotFound

PERMISSION_DENIED

COMMENTS_ERROR_UNAUTHORIZED

Unauthorized

Types#

Comment#

rid string

Unique resource identifier for the comment

parent CommentParent

The parent of the comment. It can be a resource or another comment.

author_rid string

The user who authored the comment

created_at string (date-time)

The time the comment was created

edited_at string (date-time)

The time the comment was edited. Empty if the comment has not been edited.

deleted_at string (date-time)

The time the comment was deleted. Empty if the comment has not been deleted.

content string

The markdown content of the comment.

pinned_by string

The user who pinned the comment. Empty if the comment is not pinned.

pinned_at string (date-time)

The time the comment was pinned. Empty if the comment is not pinned.

reactions array of Reaction

The reactions on the comment

attachments array of string

The comment’s attachments

CommentParent#

The parent of a comment. It can be a resource or another comment in the case of a reply.

Set exactly one of the fields below.

one of resource, comment required

​

resource CommentParentResource

​

CommentParentComment#

comment_rid string

The resource identifier for the comment that the comment is replying to

CommentParentResource#

resource_type ResourceType

The type of resource that the comment is associated with

resource_rid string

The resource identifier for the resource that the comment is associated with. For example, a run or a workbook.

Conversation#

resource_rid string

RID for the resource that the conversation is associated with.

resource_type ResourceType

The type of the resource that the conversation is associated with.

comments array of ConversationNode

The comments on the conversation ordered by creation time. Empty if the comment has no replies.

ConversationNode#

comment Comment

The comment

replies array of ConversationNode

The comments on (aka replies to) the comment ordered by creation time. Empty if the comment has no replies.

EditCommentRequest#

content string

The content of the comment. Markdown supported.

attachments array of string

Attachments to the comment.

Reaction#

rid string

Unique resource identifier for the reaction

user_rid string

The user who authored the reaction

created_at string (date-time)

The time the reaction was created

type ReactionType

The type of reaction

ReactionType#

REACTION_TYPE_UNSPECIFIED

​

LIKE

​

DISLIKE

​

HEART

​

HOORAY

​

ROCKET

​

EYES

​

ResourceType#

RESOURCE_TYPE_UNSPECIFIED

​

RUN

​

EVENT

​

Page design based on Scalar, MIT License.