Comments

A comment is a note your team leaves on a record: a contact, organization, deal, thread, file, calendar event, or space. Comments are internal; the people and companies they discuss never see them. Use this resource to read and write comments, reply to them, and react to them with a short piece of text such as an emoji.

A comment is visible to anyone who can see the record it belongs to. Only its author can edit or delete it. Mention a colleague in a comment and Carom notifies them; mention Carom itself on a contact, organization, thread, or deal, and Carom’s assistant answers with a reply of its own.

#The comment object

Returned by every comment endpoint except the reaction endpoints. Comments your team writes carry their content in html_content and json_content; Carom displays html_content. Replies written by Carom’s assistant carry their content in text and blocks instead.

Attributes

  • idstring · uuid

    Unique identifier for the comment.

  • html_contentstring · nullable

    The comment as HTML, sanitized by Carom when it was saved. This is the version Carom displays.

  • json_contentstring · nullable

    The same comment as a serialized TipTap document. Carom reads mentions from it.

  • textstring · nullable

    Plain text of a reply from Carom’s assistant. Null on comments your team writes.

  • parent_comment_idstring · uuid · nullable

    The comment this one replies to. Null for a top-level comment, including a reply whose parent was deleted.

  • user_idstring · uuid · nullable

    The author. On a reply from Carom’s assistant, the user who asked the question.

  • contact_id, organization_id, deal_id, thread_id, file_id, calendar_event_id, space_idstring · uuid · nullable

    The record the comment belongs to. Exactly one is set; the others are null.

  • agentstring · nullable

    assistant on a reply from Carom’s assistant. Null on comments your team writes.

  • statusstring

    Comments your team writes are always complete. A reply from Carom’s assistant is pending while the assistant works, then complete or failed. A failed reply’s text says why.

    pendingcompletefailed
  • blocksarray of objects

    Structured content of a reply from Carom’s assistant, in order. Empty on comments your team writes. Each block has a type.

    Show 4 block typesHide block types
    • textblock

      A passage of prose in text.

    • proposalblock

      A change the assistant proposes, by proposal_id, with its action_type, status, record_type and record_id, applied_record_type and applied_record_id, display, resolution_reason, and the actions you can take on it (accept, reject, undo). A tag.apply or tag.remove block also has tag_id, which is null while a proposed new tag doesn’t exist yet. See Proposals. When your key can’t see the proposal, status is unavailable and only proposal_id is given.

    • cardsblock

      A list of records, by ids, of one card_type: Contact, Organization, Thread, Deal, or Task. Has an optional title.

    • tableblock

      A table with an optional title, columns, and rows. Each column has a key, a label, and an optional kind: money, date, number, or text. Money and number cells are numbers, or a string when the value couldn’t be read as a number; date cells are strings. Each row has cells keyed by column, with null for an empty cell, and may have a ref to the record it describes.

  • refsarray of objects

    Records a reply from Carom’s assistant refers to, each with a snake-case type, an id, and a label: the record’s name as your key’s user sees it, such as a contact’s name, a thread’s subject, or a task’s assignment. label is null when your key’s user can’t see the record. Empty on comments your team writes.

  • mentionsarray of objects

    Users mentioned in the comment.

    Show 2 child attributesHide child attributes
    • idstring · uuid
    • user_idstring · uuid · nullable

      The mentioned user.

  • reactionsarray of objects

    Reactions to the comment. Add a reaction also returns each reaction’s created_at.

    Show 3 child attributesHide child attributes
    • idstring · uuid
    • textstring · nullable

      The reaction, usually an emoji.

    • user_idstring · uuid · nullable

      The user who reacted.

  • created_atstring · date-time · nullable
  • updated_atstring · date-time · nullable

    When the author last edited the comment. Null until the first edit.

The comment object
{
  "id": "a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d",
  "html_content": "<p>@Jordan Reyes can you send Priya the renewal numbers before the 15th?</p>",
  "json_content": "{\"type\":\"doc\",\"content\":[{\"type\":\"paragraph\",\"content\":[{\"type\":\"mention\",\"attrs\":{\"id\":\"4e7a2c1b-8d3f-4a6e-9b5c-7f1d0e2a3b84\",\"label\":\"Jordan Reyes\"}},{\"type\":\"text\",\"text\":\" can you send Priya the renewal numbers before the 15th?\"}]}]}",
  "text": null,
  "parent_comment_id": null,
  "user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
  "contact_id": "1f3c9a52-7b0e-4d4a-9c1e-2a6f0d8b3e41",
  "organization_id": null,
  "deal_id": null,
  "thread_id": null,
  "file_id": null,
  "calendar_event_id": null,
  "space_id": null,
  "agent": null,
  "status": "complete",
  "blocks": [],
  "refs": [],
  "mentions": [
    {
      "id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
      "user_id": "4e7a2c1b-8d3f-4a6e-9b5c-7f1d0e2a3b84"
    }
  ],
  "reactions": [
    {
      "id": "d7e8f9a0-b1c2-4d3e-9f4a-5b6c7d8e9f01",
      "text": "👍",
      "user_id": "4e7a2c1b-8d3f-4a6e-9b5c-7f1d0e2a3b84"
    }
  ],
  "created_at": "2026-09-03T18:44:12.806Z",
  "updated_at": null
}
get/{record_type}/{record_id}/comments Read key

#List comments

Returns every comment on a record, oldest first, including replies and replies from Carom’s assistant, in one response; the list isn’t paginated. Rebuild threads of replies from parent_comment_id.

Path parameters

  • record_typestringrequired

    The plural resource name, one of:

    contactsorganizationsdealsthreadsfilescalendar_eventsspaces
  • record_idstring · uuidrequired

    The id of that record. In the OpenAPI spec each route names it after its type, for example contact_id.

    Show 7 pathsHide paths
    • /contacts/{contact_id}/comments
    • /organizations/{organization_id}/comments
    • /deals/{deal_id}/comments
    • /threads/{thread_id}/comments
    • /files/{file_id}/comments
    • /calendar_events/{calendar_event_id}/comments
    • /spaces/{space_id}/comments

Returns

  • commentsarray of comments

    All comments on the record, oldest first.

Errors

  • 404record_not_foundNo record of that type with that id is visible to your key.
get/contacts/{contact_id}/comments
curl https://api.carom.io/contacts/1f3c9a52-7b0e-4d4a-9c1e-2a6f0d8b3e41/comments \
  -H "Authorization: Bearer $CAROM_API_KEY"
Response200
{
  "comments": [
    {
      "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
      "html_content": "<p>@Carom when did we last send Priya pricing?</p>",
      "parent_comment_id": null,
      "user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
      "contact_id": "1f3c9a52-7b0e-4d4a-9c1e-2a6f0d8b3e41",
      "agent": null,
      "status": "complete",
      "created_at": "2026-09-08T15:20:04.117Z",
      …
    },
    {
      "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
      "html_content": null,
      "text": "You sent Priya the 2027 pricing sheet on August 28. She hasn't replied yet.",
      "parent_comment_id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
      "user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
      "contact_id": "1f3c9a52-7b0e-4d4a-9c1e-2a6f0d8b3e41",
      "agent": "assistant",
      "status": "complete",
      "blocks": [
        {
          "type": "text",
          "text": "You sent Priya the 2027 pricing sheet on August 28. She hasn't replied yet."
        }
      ],
      "created_at": "2026-09-08T15:20:05.942Z",
      …
    }
  ]
}
post/{record_type}/{record_id}/comments Write key

#Create a comment

Adds a comment to a record, written by your key’s user. To mention a colleague, include a mention node in json_content whose attrs.id is their user id. Carom notifies up to 25 mentioned users per comment, and skips anyone who can’t see the record, and the author.

To ask Carom’s assistant a question, mention it with the id carom. The text after that mention is the question. The assistant answers only on contacts, organizations, threads, and deals, only when Ask Carom is turned on for the account, and only when the author hasn’t opted out of it; otherwise the mention gets no reply. capabilities.ask_carom on Retrieve your key’s user tells you whether the assistant will answer. The reply appears in List comments as a reply to your comment, with agent set to assistant and status set to pending until the answer is ready.

Path parameters

Request body application/json

  • commentobjectrequired
    Show 3 child attributesHide child attributes
    • html_contentstringrequired

      The comment as HTML. Carom removes scripts, event handlers, javascript: links, and iframes, and keeps formatting such as bold text, links, and lists.

    • json_contentstring · nullable

      The same comment as a serialized TipTap document. Required for mentions: Carom reads them only from here.

    • parent_comment_idstring · uuid

      Reply to this comment. It must belong to the same record.

Returns

The new comment object, wrapped in comment, with status 201.

Errors

  • 400invalid_requesthtml_content is missing, or a field is malformed.
  • 404record_not_foundThe record isn’t visible to your key, or parent_comment_id isn’t a comment on it.
post/contacts/{contact_id}/comments
curl https://api.carom.io/contacts/1f3c9a52-7b0e-4d4a-9c1e-2a6f0d8b3e41/comments \
  -H "Authorization: Bearer $CAROM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "comment": {
      "html_content": "<p>@Jordan Reyes can you send Priya the renewal numbers before the 15th?</p>",
      "json_content": "{\"type\":\"doc\",\"content\":[{\"type\":\"paragraph\",\"content\":[{\"type\":\"mention\",\"attrs\":{\"id\":\"4e7a2c1b-8d3f-4a6e-9b5c-7f1d0e2a3b84\",\"label\":\"Jordan Reyes\"}},{\"type\":\"text\",\"text\":\" can you send Priya the renewal numbers before the 15th?\"}]}]}"
    }
  }'
Response201
{
  "comment": {
    "id": "a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d",
    "html_content": "<p>@Jordan Reyes can you send Priya the renewal numbers before the 15th?</p>",
    "parent_comment_id": null,
    "user_id": "9c41d2e8-3f6a-4b7c-8d1e-5a2f7b9c0d3e",
    "contact_id": "1f3c9a52-7b0e-4d4a-9c1e-2a6f0d8b3e41",
    "status": "complete",
    "mentions": [
      {
        "id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
        "user_id": "4e7a2c1b-8d3f-4a6e-9b5c-7f1d0e2a3b84"
      }
    ],
    "reactions": [],
    "created_at": "2026-09-03T18:44:12.806Z",
    …
  }
}
patch/comments/{id} Write key

#Update a comment

Replaces the content of a comment your key’s user wrote and sets updated_at. Replies from Carom’s assistant can’t be edited.

When you send json_content, Carom reads the mentions again: newly mentioned users are notified, and users no longer mentioned are removed from mentions. An edit without json_content keeps the previous json_content and mentions, so send both fields whenever the text changes.

Path parameters

  • idstring · uuidrequired

    The comment’s id.

Request body application/json

  • commentobjectrequired
    Show 2 child attributesHide child attributes
    • html_contentstringrequired

      The new content as HTML. Must not be empty. Sanitized as on Create a comment.

    • json_contentstring · nullable

      The new content as a serialized TipTap document.

Returns

The updated comment object, wrapped in comment.

Errors

  • 400invalid_requesthtml_content is missing or empty.
  • 404record_not_foundNo comment with that id was written by your key’s user on a record visible to your key, or the comment is a reply from Carom’s assistant.
patch/comments/{id}
curl -X PATCH https://api.carom.io/comments/a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d \
  -H "Authorization: Bearer $CAROM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "comment": {
      "html_content": "<p>Priya needs the renewal numbers before the 12th, not the 15th.</p>"
    }
  }'
Response200
{
  "comment": {
    "id": "a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d",
    "html_content": "<p>Priya needs the renewal numbers before the 12th, not the 15th.</p>",
    "created_at": "2026-09-03T18:44:12.806Z",
    "updated_at": "2026-09-04T09:02:37.251Z",
    …
  }
}
delete/comments/{id} Write key

#Delete a comment

Permanently deletes a comment your key’s user wrote, including a reply from Carom’s assistant to a question they asked. The comment’s reactions and mentions are deleted with it. Replies to it are kept and become top-level comments.

Path parameters

  • idstring · uuidrequired

    The comment’s id.

Returns

An empty response with status 204.

Errors

  • 404record_not_foundNo comment with that id was written by your key’s user on a record visible to your key.
delete/comments/{id}
curl -X DELETE https://api.carom.io/comments/a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d \
  -H "Authorization: Bearer $CAROM_API_KEY"
Response204
No content
post/comments/{comment_id}/reactions Write key

#Add a reaction

Adds a reaction from your key’s user to a comment. A reaction is usually a single emoji, but any non-empty text is accepted. Each call adds a new reaction, even if the same user already reacted with the same text.

Path parameters

  • comment_idstring · uuidrequired

    The comment to react to.

Request body application/json

  • reactionobjectrequired
    Show 1 child attributeHide child attributes
    • textstringrequired

      The reaction. Must not be empty.

Returns

The new reaction, with status 201.

  • reactionobject
    Show 4 child attributesHide child attributes
    • idstring · uuid
    • user_idstring · uuid · nullable

      The user who reacted.

    • textstring · nullable
    • created_atstring · date-time · nullable

Errors

  • 400invalid_requestreaction.text is missing or empty.
  • 404record_not_foundNo comment with that id is visible to your key.
post/comments/{comment_id}/reactions
curl https://api.carom.io/comments/a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d/reactions \
  -H "Authorization: Bearer $CAROM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "reaction": { "text": "👍" } }'
Response201
{
  "reaction": {
    "id": "d7e8f9a0-b1c2-4d3e-9f4a-5b6c7d8e9f01",
    "user_id": "4e7a2c1b-8d3f-4a6e-9b5c-7f1d0e2a3b84",
    "text": "👍",
    "created_at": "2026-09-03T19:02:51.630Z"
  }
}
patch/comments/{comment_id}/reactions/{id} Write key

#Update a reaction

Changes the text of a reaction your key’s user added.

Path parameters

  • comment_idstring · uuidrequired

    The comment the reaction belongs to.

  • idstring · uuidrequired

    The reaction’s id.

Request body application/json

Returns

The updated reaction, wrapped in reaction, as on Add a reaction.

Errors

  • 400invalid_requestreaction.text is missing or empty.
  • 404record_not_foundThe comment isn’t visible to your key, or it has no reaction with that id from your key’s user.
patch/comments/{comment_id}/reactions/{id}
curl -X PATCH https://api.carom.io/comments/a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d/reactions/d7e8f9a0-b1c2-4d3e-9f4a-5b6c7d8e9f01 \
  -H "Authorization: Bearer $CAROM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "reaction": { "text": "✅" } }'
Response200
{
  "reaction": {
    "id": "d7e8f9a0-b1c2-4d3e-9f4a-5b6c7d8e9f01",
    "user_id": "4e7a2c1b-8d3f-4a6e-9b5c-7f1d0e2a3b84",
    "text": "✅",
    "created_at": "2026-09-03T19:02:51.630Z"
  }
}
delete/comments/{comment_id}/reactions/{id} Write key

#Remove a reaction

Deletes a reaction your key’s user added.

Path parameters

Returns

An empty response with status 204.

Errors

  • 404record_not_foundThe comment isn’t visible to your key, or it has no reaction with that id from your key’s user.
delete/comments/{comment_id}/reactions/{id}
curl -X DELETE https://api.carom.io/comments/a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d/reactions/d7e8f9a0-b1c2-4d3e-9f4a-5b6c7d8e9f01 \
  -H "Authorization: Bearer $CAROM_API_KEY"
Response204
No content