HackMD Comments API
Operations for reading and resolving note comments.
Operations for reading and resolving note comments.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/hackmd:hackmd-comments-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: HackMD Open Comments API
version: 1.0.0
description: HackMD OpenAPI
license:
name: UNLICENSED
contact:
name: HackMD Team
email: support@hackmd.io
servers:
- url: /v1
description: API Server
tags:
- name: Comments
description: Operations for reading and resolving note comments.
paths:
/notes/{noteId}/comments:
get:
operationId: ListNoteComments
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/GetNoteComments'
'400':
description: Invalid request
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ApiCommentError'
- $ref: '#/components/schemas/ApiRequestErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ApiErrorResponse'
'403':
description: Comments not readable
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentError'
'404':
description: Note not found
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentError'
'429':
description: Rate limit or workspace quota exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/ApiRateLimitErrorResponse'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ApiServerErrorResponse'
description: List comments and replies visible on a note.
tags:
- Comments
security:
- token: []
parameters:
- in: path
name: noteId
required: true
schema:
type: string
- in: query
name: page
required: false
schema:
$ref: '#/components/schemas/ApiCommentPage'
- in: query
name: limit
required: false
schema:
$ref: '#/components/schemas/ApiCommentLimit'
- in: query
name: sort
required: false
schema:
default: asc
type: string
enum:
- asc
- desc
- in: query
name: threadId
required: false
schema:
$ref: '#/components/schemas/ApiCommentThreadId'
- in: query
name: commentStatus
required: false
schema:
$ref: '#/components/schemas/ApiCommentStatus'
- in: query
name: threadStatus
required: false
schema:
$ref: '#/components/schemas/ApiCommentStatus'
- in: query
name: isThreadHead
required: false
schema:
type: boolean
enum:
- true
summary: List note comments
x-summary-source: derived
/notes/{noteId}/comments/{commentId}:
get:
operationId: GetNoteComment
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentDetail'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ApiRequestErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ApiErrorResponse'
'403':
description: Comments not readable
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentError'
'404':
description: Not found
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentError'
'429':
description: Rate limit or workspace quota exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/ApiRateLimitErrorResponse'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ApiServerErrorResponse'
description: Get one comment or reply from a note.
tags:
- Comments
security:
- token: []
parameters:
- in: path
name: noteId
required: true
schema:
type: string
- in: path
name: commentId
required: true
schema:
$ref: '#/components/schemas/ApiCommentId'
summary: Get note comment
x-summary-source: derived
/notes/{noteId}/comments/{commentId}/resolution:
put:
operationId: ResolveNoteComment
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentResolutionResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ApiRequestErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ApiErrorResponse'
'403':
description: Comment resolution forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentError'
'404':
description: Not found
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentError'
'409':
description: Comment resolution conflict
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentResolutionConflictError'
'429':
description: Rate limit or workspace quota exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/ApiRateLimitErrorResponse'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ApiServerErrorResponse'
description: Resolve a comment or thread.
tags:
- Comments
security:
- token: []
parameters:
- in: path
name: noteId
required: true
schema:
type: string
- in: path
name: commentId
required: true
schema:
$ref: '#/components/schemas/ApiCommentId'
summary: Resolve note comment
x-summary-source: derived
delete:
operationId: UnresolveNoteComment
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentResolutionResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ApiRequestErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ApiErrorResponse'
'403':
description: Comment resolution forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentError'
'404':
description: Not found
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentError'
'409':
description: Comment resolution conflict
content:
application/json:
schema:
$ref: '#/components/schemas/ApiCommentResolutionConflictError'
'429':
description: Rate limit or workspace quota exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/ApiRateLimitErrorResponse'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ApiServerErrorResponse'
description: Unresolve a comment or thread.
tags:
- Comments
security:
- token: []
parameters:
- in: path
name: noteId
required: true
schema:
type: string
- in: path
name: commentId
required: true
schema:
$ref: '#/components/schemas/ApiCommentId'
summary: Unresolve note comment
x-summary-source: derived
components:
schemas:
ApiCommentReactionShortcode:
type: string
enum:
- '+1'
- '-1'
- joy
- tada
- thinking_face
- heart
- rocket
- eyes
ApiCommentStateReason:
type:
- string
- 'null'
enum:
- resolved
- spam
- abuse
- off_topic
- null
ApiCommentActor:
anyOf:
- $ref: '#/components/schemas/ApiCommentUserActor'
- $ref: '#/components/schemas/ApiCommentGuestActor'
- $ref: '#/components/schemas/ApiCommentTeamActor'
- $ref: '#/components/schemas/ApiCommentDeletedUserActor'
ApiCommentTeamActor:
properties:
kind:
type: string
enum:
- team
teamId:
type: string
format: uuid
displayName:
type: string
required:
- kind
- teamId
- displayName
type: object
additionalProperties: false
ApiCommentPage:
type: integer
format: int32
default: 1
minimum: 1
ApiCommentListReply:
properties:
id:
type: string
format: uuid
threadId:
type: string
format: uuid
actor:
$ref: '#/components/schemas/ApiCommentActor'
body:
type: string
contentType:
type: string
enum:
- plain_text
commentState:
$ref: '#/components/schemas/ApiCommentState'
isPinned:
type: boolean
anchor:
allOf:
- $ref: '#/components/schemas/ApiCommentAnchor'
currentAnchor:
allOf:
- $ref: '#/components/schemas/ApiCommentAnchor'
excerpt:
type:
- string
- 'null'
reactions:
items:
$ref: '#/components/schemas/ApiCommentReactionSummary'
type: array
createdAt:
type: number
format: double
description: Unix timestamp in milliseconds.
updatedAt:
type: number
format: double
description: Unix timestamp in milliseconds.
isThreadHead:
type: boolean
enum:
- false
required:
- id
- threadId
- actor
- body
- contentType
- commentState
- isPinned
- anchor
- currentAnchor
- excerpt
- reactions
- createdAt
- updatedAt
- isThreadHead
type: object
additionalProperties: false
ApiCommentStatus:
type: string
enum:
- open
- hidden
ApiServerErrorResponse:
anyOf:
- $ref: '#/components/schemas/ApiErrorResponse'
- $ref: '#/components/schemas/ApiRequestErrorResponse'
ApiCommentDeletedUserActor:
properties:
kind:
type: string
enum:
- deleted_user
required:
- kind
type: object
additionalProperties: false
ApiCommentThreadId:
type: string
format: uuid
ApiErrorResponse:
properties:
error:
type: string
required:
- error
type: object
additionalProperties: false
ApiRateLimitErrorResponse:
anyOf:
- $ref: '#/components/schemas/ApiErrorResponse'
- $ref: '#/components/schemas/ApiQuotaErrorResponse'
ApiCommentAnchor:
properties:
offset:
type: integer
format: int32
minimum: 0
length:
type: integer
format: int32
minimum: 0
required:
- offset
- length
type: object
additionalProperties: false
ApiCommentStateDeletedUserActor:
properties:
kind:
type: string
enum:
- deleted_user
required:
- kind
type: object
additionalProperties: false
ApiComment:
anyOf:
- $ref: '#/components/schemas/ApiCommentHead'
- $ref: '#/components/schemas/ApiCommentListReply'
ApiCommentResolutionResponse:
properties:
comment:
$ref: '#/components/schemas/ApiCommentDetail'
cascade:
allOf:
- $ref: '#/components/schemas/ApiCommentResolutionCascade'
required:
- comment
- cascade
type: object
additionalProperties: false
ApiCommentUserActor:
properties:
kind:
type: string
enum:
- user
userId:
type: string
format: uuid
displayName:
type: string
required:
- kind
- userId
- displayName
type: object
additionalProperties: false
ApiCommentError:
properties:
errorCode:
type: string
message:
type: string
required:
- errorCode
- message
type: object
additionalProperties: false
ApiRequestErrorResponse:
properties:
message:
type: string
required:
- message
type: object
additionalProperties: false
ApiCommentDetail:
anyOf:
- $ref: '#/components/schemas/ApiCommentHead'
- $ref: '#/components/schemas/ApiCommentDetailReply'
ApiCommentId:
type: string
format: uuid
GetNoteComments:
properties:
comments:
items:
$ref: '#/components/schemas/ApiComment'
type: array
pagination:
$ref: '#/components/schemas/ApiCommentPagination'
required:
- comments
- pagination
type: object
additionalProperties: false
ApiQuotaErrorResponse:
properties:
error:
properties:
upgradeUrl:
type: string
helpUrl:
type: string
message:
type: string
code:
type: string
enum:
- quota_exceeded
required:
- upgradeUrl
- helpUrl
- message
- code
type: object
required:
- error
type: object
additionalProperties: false
ApiCommentDetailReply:
properties:
id:
type: string
format: uuid
threadId:
type: string
format: uuid
actor:
$ref: '#/components/schemas/ApiCommentActor'
body:
type: string
contentType:
type: string
enum:
- plain_text
commentState:
$ref: '#/components/schemas/ApiCommentState'
isPinned:
type: boolean
anchor:
allOf:
- $ref: '#/components/schemas/ApiCommentAnchor'
currentAnchor:
allOf:
- $ref: '#/components/schemas/ApiCommentAnchor'
excerpt:
type:
- string
- 'null'
reactions:
items:
$ref: '#/components/schemas/ApiCommentReactionSummary'
type: array
createdAt:
type: number
format: double
description: Unix timestamp in milliseconds.
updatedAt:
type: number
format: double
description: Unix timestamp in milliseconds.
isThreadHead:
type: boolean
enum:
- false
threadState:
$ref: '#/components/schemas/ApiCommentThreadState'
required:
- id
- threadId
- actor
- body
- contentType
- commentState
- isPinned
- anchor
- currentAnchor
- excerpt
- reactions
- createdAt
- updatedAt
- isThreadHead
- threadState
type: object
additionalProperties: false
ApiCommentReactionSummary:
properties:
shortcode:
$ref: '#/components/schemas/ApiCommentReactionShortcode'
count:
type: integer
format: int32
minimum: 1
required:
- shortcode
- count
type: object
additionalProperties: false
ApiCommentPagination:
properties:
page:
type: integer
format: int32
minimum: 1
limit:
type: integer
format: int32
minimum: 1
maximum: 100
hasNext:
type: boolean
required:
- page
- limit
- hasNext
type: object
additionalProperties: false
ApiCommentStateUserActor:
properties:
kind:
type: string
enum:
- user
userId:
type: string
format: uuid
displayName:
type: string
required:
- kind
- userId
- displayName
type: object
additionalProperties: false
ApiCommentResolutionCascade:
properties:
threadId:
type: string
format: uuid
required:
- threadId
type: object
additionalProperties: false
ApiCommentLimit:
type: integer
format: int32
default: 50
minimum: 1
maximum: 100
ApiCommentGuestActor:
properties:
kind:
type: string
enum:
- guest
displayName:
type: string
required:
- kind
- displayName
type: object
additionalProperties: false
ApiCommentResolutionConflictError:
properties:
errorCode:
type: string
message:
type: string
commentState:
$ref: '#/components/schemas/ApiCommentState'
required:
- errorCode
- message
- commentState
type: object
additionalProperties: false
ApiCommentHead:
properties:
id:
type: string
format: uuid
threadId:
type: string
format: uuid
actor:
$ref: '#/components/schemas/ApiCommentActor'
body:
type: string
contentType:
type: string
enum:
- plain_text
commentState:
$ref: '#/components/schemas/ApiCommentState'
isPinned:
type: boolean
anchor:
allOf:
- $ref: '#/components/schemas/ApiCommentAnchor'
currentAnchor:
allOf:
- $ref: '#/components/schemas/ApiCommentAnchor'
excerpt:
type:
- string
- 'null'
reactions:
items:
$ref: '#/components/schemas/ApiCommentReactionSummary'
type: array
createdAt:
type: number
format: double
description: Unix timestamp in milliseconds.
updatedAt:
type: number
format: double
description: Unix timestamp in milliseconds.
isThreadHead:
type: boolean
enum:
- true
replyCount:
type: integer
format: int32
minimum: 0
threadState:
$ref: '#/components/schemas/ApiCommentThreadState'
required:
- id
- threadId
- actor
- body
- contentType
- commentState
- isPinned
- anchor
- currentAnchor
- excerpt
- reactions
- createdAt
- updatedAt
- isThreadHead
- replyCount
- threadState
type: object
additionalProperties: false
ApiCommentStateActor:
anyOf:
- $ref: '#/components/schemas/ApiCommentStateUserActor'
- $ref: '#/components/schemas/ApiCommentStateDeletedUserActor'
ApiCommentState:
properties:
status:
$ref: '#/components/schemas/ApiCommentStatus'
reason:
$ref: '#/components/schemas/ApiCommentStateReason'
actedBy:
allOf:
- $ref: '#/components/schemas/ApiCommentStateActor'
actedAt:
type:
- number
- 'null'
format: double
description: Unix timestamp in milliseconds.
required:
- status
- reason
- actedBy
- actedAt
type: object
additionalProperties: false
ApiCommentThreadState:
properties:
status:
$ref: '#/components/schemas/ApiCommentStatus'
reason:
$ref: '#/components/schemas/ApiCommentStateReason'
actedBy:
allOf:
- $ref: '#/components/schemas/ApiCommentStateActor'
actedAt:
type:
- number
- 'null'
format: double
description: Unix timestamp in milliseconds.
sourceCommentId:
type: string
format: uuid
required:
- status
- reason
- actedBy
- actedAt
- sourceCommentId
type: object
additionalProperties: false
securitySchemes:
token:
type: http
scheme: bearer
x-provenance:
method: harvested
publisher: HackMD
source: https://api.hackmd.io/v1/docs/swagger.json
note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
stamped by stamp-openapi-provenance.py (roadmap#793)