Comments API Threading, mentions, reactions, and reference anchoring for workspace and share entities.

Base URL: https://api.fast.io/current/ Auth: Bearer {jwt_token} Content-Type: application/json Format: JSON

Comments use JSON request bodies (Content-Type: application/json), unlike most other Fast.io endpoints which use application/x-www-form-urlencoded.


Endpoint Summary

MethodEndpointDescription
GET /current/comments/{entity_type}/{parent_id}/ List comments for an entity
GET /current/comments/{entity_type}/{parent_id}/{node_id}/ List comments for a specific node
POST /current/comments/{entity_type}/{parent_id}/ Create or update a comment on an entity
POST /current/comments/{entity_type}/{parent_id}/{node_id}/ Create or update a comment on a node
GET /current/comments/{comment_id}/details/ Get a single comment's details
DELETE /current/comments/{comment_id}/delete/ Soft-delete a comment and its replies
POST /current/comments/bulk/delete/ Bulk soft-delete multiple comments
POST /current/comments/{comment_id}/reactions/ Add or change an emoji reaction
DELETE /current/comments/{comment_id}/reactions/ Remove an emoji reaction

Path Parameters

Comments are scoped to an entity (workspace or share) and optionally to a specific node (file or folder).

ParameterTypeFormatDescription
{entity_type} string "workspace" or "share" Entity type discriminator
{parent_id} string 20-digit numeric Workspace or share profile ID
{node_id} string Alphanumeric opaque ID File or folder ID within the entity (optional)
{comment_id} string Alphanumeric opaque ID Comment identifier

Comment Object

Every comment returned by the API has this structure:

FieldTypeDescription
id string Alphanumeric opaque ID of the comment
entity_id string Opaque ID of the entity (workspace, share, or node)
profile_id string 20-digit numeric ID of the comment author
parent_id string|null Opaque ID of the parent comment (for replies), or null for top-level
body string Comment text content (may include mention markup)
properties object Metadata properties (includes mentions, content_filtered if applicable)
reference object|null Anchoring reference to a position in a file (see Reference Anchoring)
reactions object Map of emoji character to total reaction count (e.g., {"👍": 3})
user_reaction string|null The current authenticated user's emoji reaction, or null
created string ISO 8601 creation timestamp
updated string ISO 8601 last-updated timestamp
deleted string|null ISO 8601 deletion timestamp, or null if active

List Comments

GET /current/comments/{entity_type}/{parent_id}/

List comments for an entity.

GET /current/comments/{entity_type}/{parent_id}/{node_id}/

List comments for a specific node within an entity.

Auth: Required (JWT). Rate limited.

Query Parameters

ParameterTypeRequiredDefaultConstraintsDescription
sort string No asc "asc" or "desc" Sort order by creation time
limit integer No Min: 2, Max: 200 Number of comments to return
offset integer No 0 Min: 0 Number of comments to skip
page integer No Min: 1 Page number (alternative to offset-based pagination)
include_deleted boolean No false Include soft-deleted comments in results
reference_type string No Filter by reference anchor type (e.g., "page", "timestamp")
include_total boolean No false Include total count and pagination metadata in response

Request Example

curl -X GET "https://api.fast.io/current/comments/workspace/1234567890123456789/?limit=50&include_total=true" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "comments": [
      {
        "id": "abc123opaqueid",
        "entity_id": "xyz789opaqueid",
        "profile_id": "1234567890123456789",
        "parent_id": null,
        "body": "This looks great!",
        "properties": {},
        "reference": null,
        "reactions": {"👍": 2, "❤️": 1},
        "user_reaction": "👍",
        "created": "2025-01-15T10:30:00+00:00",
        "updated": "2025-01-15T10:30:00+00:00",
        "deleted": null
      }
    ],
    "count": 1,
    "allowed": true,
    "remaining": 95,
    "total": 5,
    "limit": 50,
    "offset": 0
  },
  "current_api_version": "1.0"
}

Response Fields

FieldTypeDescription
response.comments array Array of comment objects
response.count int Number of comments in this response
response.allowed bool Whether the current user can post new comments (based on plan limits)
response.remaining int Remaining comments allowed under plan limit (only present if plan has a limit)
response.total int Total number of comments (only if include_total=true)
response.limit int Limit used in query (only if include_total=true)
response.offset int Offset used in query (only if include_total=true)

Access Levels

RoleAccess
Workspace Owner/MemberFull access — sees all comments
Share OwnerFull access — sees all comments
Share GuestFiltered — sees own comments; visibility of owner and other guest comments depends on share permissions

Error Responses

Error CodeHTTP StatusMessageCause
APP_ERROR_INPUT_INVALID400Invalid API format...Missing entity type or parent ID
APP_ERROR_INPUT_INVALID400Entity type must be "workspace" or "share"Invalid entity type
APP_DENIED403Invalid entity or insufficient permissionsUser lacks access
APP_ERROR_NOT_FOUND404Invalid entity or insufficient permissionsEntity not found
APP_ERROR_GENERAL500Failed to retrieve commentsInternal error

Create or Update Comment

POST /current/comments/{entity_type}/{parent_id}/

Create a new comment or update an existing one on an entity.

POST /current/comments/{entity_type}/{parent_id}/{node_id}/

Create a new comment or update an existing one on a specific node.

Auth: Required (JWT). Rate limited.

Content-Type: application/json

Request Body

FieldTypeRequiredConstraintsDescription
body string Required 1–8192 chars (raw); display text excluding mentions max 500 chars Comment text content
comment_id string No Valid opaque ID Include to update an existing comment; omit to create new
parent_id string No Valid opaque ID Parent comment ID for threaded reply (single-level only)
properties object No Arbitrary key-value metadata to attach
reference object No See Reference Anchoring Anchoring reference to a position in a file

Request Example — Create a new comment

curl -X POST "https://api.fast.io/current/comments/workspace/1234567890123456789/" \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Great work on this document!"
  }'

Request Example — Reply to a comment

curl -X POST "https://api.fast.io/current/comments/workspace/1234567890123456789/" \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Thanks for the feedback!",
    "parent_id": "abc123opaqueid"
  }'

Request Example — Comment with mention and page reference

curl -X POST "https://api.fast.io/current/comments/workspace/1234567890123456789/" \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hey @[user:9876543210987654321:Jane Smith], can you review page 3?",
    "reference": {"type": "page", "page": 3}
  }'

Request Example — Update an existing comment

curl -X POST "https://api.fast.io/current/comments/workspace/1234567890123456789/" \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "comment_id": "def456opaqueid",
    "body": "Updated: This looks great after the revision."
  }'

Response

{
  "result": "yes",
  "response": {
    "comment": {
      "id": "abc123opaqueid",
      "entity_id": "xyz789opaqueid",
      "profile_id": "1234567890123456789",
      "parent_id": null,
      "body": "Great work on this document!",
      "properties": {},
      "reference": null,
      "reactions": {},
      "user_reaction": null,
      "created": "2025-01-15T10:30:00+00:00",
      "updated": "2025-01-15T10:30:00+00:00",
      "deleted": null
    }
  },
  "current_api_version": "1.0"
}

Response Fields

FieldTypeDescription
response.comment object The created or updated comment object (full schema above)

Access Levels

RoleAccess
Workspace Owner/MemberCan create and edit own comments
Share OwnerCan create and edit own comments
Share GuestCan only post if comments are enabled on the share

Error Responses

Error CodeHTTP StatusMessageCause
APP_DENIED403Authentication required to post commentsUser not authenticated
APP_ERROR_INPUT_INVALID400Invalid JSON in request bodyMalformed JSON
APP_ERROR_INPUT_INVALID400Comment body must be between 1 and 8192 charactersBody length out of range
APP_ERROR_INPUT_INVALID400Comment text (excluding mentions) must not exceed 500 charactersDisplay text too long
APP_ERROR_INPUT_INVALID400Your comment appears to contain spam content...Spam detected
APP_ERROR_INPUT_INVALID400Invalid parent comment ID formatMalformed parent_id
APP_ERROR_NOT_FOUND404Parent comment not foundReferenced parent does not exist
APP_ERROR_INPUT_INVALID400Parent comment belongs to different entityParent is on a different entity
APP_ERROR_INPUT_INVALID400Invalid reference data: ...Reference failed validation
APP_ERROR_INPUT_INVALID400Comment limit exceeded for your planPlan comment limit reached
APP_ERROR_NOT_FOUND404Comment not foundComment ID for update not found
APP_DENIED403You do not have permission to edit this commentUser is not the comment author
APP_ERROR_GENERAL500Failed to save commentInternal error

Notes


Get Comment Details

GET /current/comments/{comment_id}/details/

Get a single comment's full details.

Auth: Required (JWT). Rate limited.

Request Example

curl -X GET "https://api.fast.io/current/comments/abc123opaqueid/details/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "comment": {
      "id": "abc123opaqueid",
      "entity_id": "xyz789opaqueid",
      "profile_id": "1234567890123456789",
      "parent_id": null,
      "body": "This looks great!",
      "properties": {},
      "reference": null,
      "reactions": {},
      "user_reaction": null,
      "created": "2025-01-15T10:30:00+00:00",
      "updated": "2025-01-15T10:30:00+00:00",
      "deleted": null
    }
  },
  "current_api_version": "1.0"
}

Error Responses

Error CodeHTTP StatusMessageCause
APP_ERROR_INPUT_INVALID400Comment ID is requiredMissing comment ID
APP_ERROR_INPUT_INVALID400Invalid comment ID formatMalformed opaque ID
APP_ERROR_NOT_FOUND404Comment not foundComment does not exist
APP_DENIED403You do not have permission to view this commentUser lacks access to the entity

Delete Comment

DELETE /current/comments/{comment_id}/delete/

Soft-delete a comment. Recursive — also deletes all replies to this comment.

Auth: Required (JWT). Rate limited.

Request Example

curl -X DELETE "https://api.fast.io/current/comments/abc123opaqueid/delete/" \
  -H "Authorization: Bearer {jwt_token}"

Response

{
  "result": "yes",
  "response": {
    "message": "Comment deleted successfully",
    "comment": {
      "id": "abc123opaqueid",
      "entity_id": "xyz789opaqueid",
      "profile_id": "1234567890123456789",
      "parent_id": null,
      "body": "This looks great!",
      "properties": {},
      "reference": null,
      "reactions": {},
      "user_reaction": null,
      "created": "2025-01-15T10:30:00+00:00",
      "updated": "2025-01-15T10:30:00+00:00",
      "deleted": "2025-01-16T08:00:00+00:00"
    }
  },
  "current_api_version": "1.0"
}

Access Levels

RoleAccess
Comment AuthorCan delete own comments
Entity OwnerCan delete any comment on their entity
Other UsersDenied

Error Responses

Error CodeHTTP StatusMessageCause
APP_ERROR_INPUT_INVALID400Comment ID is requiredMissing comment ID
APP_ERROR_INPUT_INVALID400Invalid comment ID formatMalformed opaque ID
APP_ERROR_NOT_FOUND404Comment not foundComment does not exist
APP_ERROR_INPUT_INVALID400Comment is already deletedComment was previously deleted
APP_DENIED403You do not have permission to delete this commentNot author or entity owner
APP_ERROR_GENERAL500Failed to delete commentInternal error

Bulk Delete Comments

POST /current/comments/bulk/delete/

Bulk soft-delete multiple comments. Each comment is processed independently — partial success is possible. NOT recursive — does not delete replies.

Auth: Required (JWT). Rate limited.

Content-Type: application/json

Request Body

FieldTypeRequiredConstraintsDescription
comment_ids array<string> Required Max 100 items Array of comment opaque IDs to delete

Request Example

curl -X POST "https://api.fast.io/current/comments/bulk/delete/" \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{"comment_ids": ["abc123opaqueid", "def456opaqueid", "ghi789opaqueid"]}'

Response

{
  "result": "yes",
  "response": {
    "success": true,
    "deleted_count": 3,
    "failed_count": 0,
    "total_count": 3,
    "results": {
      "abc123opaqueid": {"id": "abc123opaqueid", "success": true, "error": null},
      "def456opaqueid": {"id": "def456opaqueid", "success": true, "error": null},
      "ghi789opaqueid": {"id": "ghi789opaqueid", "success": true, "error": null}
    }
  },
  "current_api_version": "1.0"
}

Response Fields

FieldTypeDescription
response.success bool true only if all comments were deleted (failed_count === 0)
response.deleted_count int Number of successfully deleted comments
response.failed_count int Number that failed to delete
response.total_count int Total number of IDs provided
response.results object Per-comment results keyed by comment ID
response.results.{id}.success bool Whether this comment was deleted
response.results.{id}.error string|null Error message if failed, null on success

Per-Comment Error Messages

ErrorCause
Invalid comment ID formatNot a valid opaque ID
Comment not foundNo comment with this ID
Comment already deletedPreviously soft-deleted
Permission deniedUser is not author or entity owner
Failed to delete commentInternal error

Request-Level Error Responses

Error CodeHTTP StatusMessageCause
APP_ERROR_INPUT_INVALID400Invalid JSON request bodyMalformed JSON
APP_ERROR_INPUT_INVALID400comment_ids array is requiredMissing or non-array field
APP_ERROR_INPUT_INVALID400comment_ids array cannot be emptyEmpty array
APP_ERROR_INPUT_INVALID400Maximum 100 comments can be deleted at onceExceeds bulk limit

Important: Unlike single delete, bulk delete does not recursively delete replies.


Add or Change Reaction

POST /current/comments/{comment_id}/reactions/

Add an emoji reaction to a comment. One reaction per user per comment — sending a new reaction replaces any previous one.

Auth: Required (JWT). Rate limited.

Content-Type: application/json

Request Body

FieldTypeRequiredConstraintsDescription
emoji string Required Single emoji character; max 2 UTF-8 characters; must match Unicode emoji ranges Emoji to react with

Request Example

curl -X POST "https://api.fast.io/current/comments/abc123opaqueid/reactions/" \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{"emoji": "👍"}'

Response

{
  "result": "yes",
  "response": {
    "reactions": {"👍": 3, "❤️": 1},
    "user_reaction": "👍"
  },
  "current_api_version": "1.0"
}

Response Fields

FieldTypeDescription
response.reactions object Map of emoji to total reaction count across all users
response.user_reaction string|null The current user's active reaction emoji

Error Responses

Error CodeHTTP StatusMessageCause
APP_ERROR_INPUT_INVALID400Comment ID is requiredMissing comment ID
APP_ERROR_INPUT_INVALID400Invalid comment ID formatMalformed opaque ID
APP_ERROR_NOT_FOUND404Comment not foundComment does not exist or is deleted
APP_DENIED403You do not have permission to react to this commentUser lacks entity access
APP_ERROR_INPUT_INVALID400emoji parameter is requiredMissing or non-string emoji
APP_ERROR_INPUT_INVALID400Invalid emoji characterDoes not match Unicode emoji pattern
APP_ERROR_INPUT_INVALID400Only single emoji allowedString exceeds 2 UTF-8 characters
APP_ERROR_GENERAL500Failed to save reactionInternal error

Remove Reaction

DELETE /current/comments/{comment_id}/reactions/

Remove an emoji reaction from a comment.

Auth: Required (JWT). Rate limited.

Content-Type: application/json

Request Body

FieldTypeRequiredConstraintsDescription
emoji string No Must match Unicode emoji ranges if provided Specific emoji to remove. Omit to remove any reaction by the current user

Request Example — Remove specific emoji

curl -X DELETE "https://api.fast.io/current/comments/abc123opaqueid/reactions/" \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{"emoji": "👍"}'

Request Example — Remove any reaction

curl -X DELETE "https://api.fast.io/current/comments/abc123opaqueid/reactions/" \
  -H "Authorization: Bearer {jwt_token}" \
  -H "Content-Type: application/json" \
  -d '{}'

Response

{
  "result": "yes",
  "response": {
    "reactions": {"❤️": 1},
    "user_reaction": null
  },
  "current_api_version": "1.0"
}

Response Fields

FieldTypeDescription
response.reactions object Updated map of emoji to total reaction count
response.user_reaction string|null Current user's reaction after removal (null if removed)

Error Responses

Error CodeHTTP StatusMessageCause
APP_ERROR_INPUT_INVALID400Comment ID is requiredMissing comment ID
APP_ERROR_INPUT_INVALID400Invalid comment ID formatMalformed opaque ID
APP_ERROR_NOT_FOUND404Comment not foundComment does not exist or is deleted
APP_DENIED403You do not have permission to react to this commentUser lacks entity access
APP_ERROR_INPUT_INVALID400emoji must be a stringNon-string emoji parameter
APP_ERROR_INPUT_INVALID400Invalid emoji characterDoes not match Unicode emoji pattern
APP_ERROR_GENERAL500Failed to remove reactionInternal error

Notes: Removing a reaction that does not exist returns success (idempotent). A "removed" event is triggered only when a reaction was actually removed.


Threading

Comments support single-level threading only.

Comment A (top-level)
├── Comment B (reply to A)
├── Comment C (reply to B → auto-flattened to reply to A)
└── Comment D (reply to A)

Mentions

Use mention markup in the body field to tag other users:

@[user:USER_ID:Display Name]
ComponentDescription
userLiteral prefix (always user)
USER_IDThe user's 20-digit numeric profile ID
Display NameDisplay name to show in the UI

Character limit details

Example body with mentions

Hey @[user:1234567890123456789:Jane Smith] and @[user:9876543210987654321:Bob Jones], please review this file.

Reference Anchoring

Comments can be anchored to specific positions within a file using the reference object.

Reference object fields

FieldTypeDescription
type string Required. The anchor type: "page", "timestamp", "region", "text"
timestamp number For video/audio — position in seconds
page integer For documents — page number
region object For images — coordinates {x, y, width, height} defining a rectangular area
text_snippet string For text files — the referenced text passage

Example — Video timestamp

{
  "body": "The transition at this point needs work.",
  "reference": {"type": "timestamp", "timestamp": 42.5}
}

Example — Document page

{
  "body": "Typo in the second paragraph.",
  "reference": {"type": "page", "page": 7}
}

Example — Image region

{
  "body": "This area needs higher contrast.",
  "reference": {"type": "region", "region": {"x": 120, "y": 80, "width": 200, "height": 150}}
}

Example — Text snippet

{
  "body": "This sentence should be rephrased.",
  "reference": {"type": "text", "text_snippet": "The quick brown fox jumps over the lazy dog."}
}

Content Filtering

Comment bodies undergo automatic filtering:

↑ Back to top