Skip to Content

Threads

Threads are the comment pins placed on a markup. Use these endpoints to list, read, create, resolve, reopen, and delete threads, reposition a thread’s pin, and manage the screenshot attached to a thread. Authenticate with an exchange token (embedded feedback) or a workspace- or organization-scoped API key (server-to-server) — see the Authentication overview.

List threads

GET /api/v2/threads

List the threads on a markup. Filter and paginate with the query parameters.

GET /api/v2/threads
curl "https://api.markup.io/api/v2/threads?markupId=7d929fc0-6b33-4c3e-94f7-8ba5aaca4811" \ -X GET \ -H "Authorization: Bearer <API-KEY-SECRET>" \ -H "Markup-API-Version: 2023-02-22" \ -H "Content-Type: application/json"
200 OK
{ "data": { "threads": [ {} ], "query": { "resolved": true }, "offset": 123, "total": 123, "cursorId": "some cursorId" } }

Response Body ProjectThreadsResponse

OptionType
threads
query
offset number
total number
cursorId string

Request Query Params ListThreadsQuery

OptionType
markupId string
cursorId optionalstring
limit optionalnumber
withThreadOrMessageId optionalstring
resolved optionalboolean
order optional
viewMode optional
q optionalstring
offset optionalnumber

Get thread

GET /api/v2/threads/:id

Get a single thread by ID, including its messages.

GET /api/v2/threads/:id
curl "https://api.markup.io/api/v2/threads/d65ddb14-b32e-49ec-b001-0634eba290a7" \ -X GET \ -H "Authorization: Bearer <API-KEY-SECRET>" \ -H "Markup-API-Version: 2023-02-22" \ -H "Content-Type: application/json"
200 OK
{ "data": { "id": "some id", "createdAt": {}, "modifiedAt": {}, "scopes": [ "some string" ], "assignedRoleSlugs": [ "some string" ], "user": { "id": "some id", "createdAt": {}, "modifiedAt": {}, "name": "some name", "guest": true }, "number": 123, "resolved": true, "messages": [ { "id": "some id", "createdAt": {}, "modifiedAt": {}, "scopes": [ "some string" ], "assignedRoleSlugs": [ "some string" ], "threadId": "some threadId", "message": "some message", "messageJson": {}, "user": { "id": "some id", "createdAt": {}, "modifiedAt": {}, "name": "some name", "guest": true }, "userMetaData": {}, "attachments": [ { "id": "some id", "createdAt": {}, "modifiedAt": {}, "messageId": "some messageId", "url": "some url", "etag": "some etag", "mimeType": "some mimeType", "originalFilename": "some originalFilename", "filesize": 123 } ], "loomVideos": [ { "id": "some id", "createdAt": {}, "modifiedAt": {}, "messageId": "some messageId", "title": "some title", "sharedUrl": "some sharedUrl", "width": 123, "height": 123 } ] } ], "userMetaData": {}, "projectId": "some projectId", "proxyUrl": "some proxyUrl", "originalUrl": "some originalUrl", "canonicalUrl": "some canonicalUrl", "elements": [ { "id": "some id", "createdAt": {}, "modifiedAt": {}, "threadId": "some threadId", "path": "some path", "offsetXPercentage": 123, "offsetYPercentage": 123 } ], "parents": [ { "id": "some id", "createdAt": {}, "modifiedAt": {}, "path": "some path", "depth": 123, "proxyUrl": "some proxyUrl", "originalUrl": "some originalUrl", "canonicalUrl": "some canonicalUrl" } ], "viewModeId": "some viewModeId" } }

Response Body - ThreadResponse

Request Path Params IdRequestParam

OptionType
id string

Create thread

POST /api/v2/threads

Create a new thread (comment pin) on a markup.

POST /api/v2/threads
curl "https://api.markup.io/api/v2/threads" \ -X POST \ -H "Authorization: Bearer <API-KEY-SECRET>" \ -H "Markup-API-Version: 2023-02-22" \ -H "Content-Type: application/json" \ --data '{ "isImageThread": true, "url": "some url", "canonicalUrl": "some canonicalUrl", "elements": [ { "elementPath": "some elementPath", "offsetXPercentage": 123, "offsetYPercentage": 123 } ], "offsetXPercentage": 123, "offsetYPercentage": 123, "message": {}, "browserContext": {}, "elementParents": [ { "url": "some url", "canonicalUrl": "some canonicalUrl", "path": "some path", "depth": 123 } ], "viewModeId": "ede0e7da-ec02-4659-b6f9-ae2f5afcf7cb" }'
200 OK
{ "data": { "id": "some id", "createdAt": {}, "modifiedAt": {}, "scopes": [ "some string" ], "assignedRoleSlugs": [ "some string" ], "user": { "id": "some id", "createdAt": {}, "modifiedAt": {}, "name": "some name", "guest": true }, "number": 123, "resolved": true, "messages": [ { "id": "some id", "createdAt": {}, "modifiedAt": {}, "scopes": [ "some string" ], "assignedRoleSlugs": [ "some string" ], "threadId": "some threadId", "message": "some message", "messageJson": {}, "user": { "id": "some id", "createdAt": {}, "modifiedAt": {}, "name": "some name", "guest": true }, "userMetaData": {}, "attachments": [ { "id": "some id", "createdAt": {}, "modifiedAt": {}, "messageId": "some messageId", "url": "some url", "etag": "some etag", "mimeType": "some mimeType", "originalFilename": "some originalFilename", "filesize": 123 } ], "loomVideos": [ { "id": "some id", "createdAt": {}, "modifiedAt": {}, "messageId": "some messageId", "title": "some title", "sharedUrl": "some sharedUrl", "width": 123, "height": 123 } ] } ], "userMetaData": {}, "projectId": "some projectId", "proxyUrl": "some proxyUrl", "originalUrl": "some originalUrl", "canonicalUrl": "some canonicalUrl", "elements": [ { "id": "some id", "createdAt": {}, "modifiedAt": {}, "threadId": "some threadId", "path": "some path", "offsetXPercentage": 123, "offsetYPercentage": 123 } ], "parents": [ { "id": "some id", "createdAt": {}, "modifiedAt": {}, "path": "some path", "depth": 123, "proxyUrl": "some proxyUrl", "originalUrl": "some originalUrl", "canonicalUrl": "some canonicalUrl" } ], "viewModeId": "some viewModeId" } }

Response Body - ThreadResponse

Request Body CreateThreadRequest

OptionType
isImageThread boolean
projectId optionalstring
projectImageId optionalstring
url string
canonicalUrl string
elements CreateThreadRequestElement[]
offsetXPercentage number
offsetYPercentage number
startTime optionalnumber
endTime optionalnumber
message Delta
browserContext
elementParents ThreadElementParentRequest[]
viewModeId string
attachments optionalMessageRequestAttachment[]
loomVideos optionalLoomVideoRequest[]
width optionalnumber
height optionalnumber
annotations optional
textHighlight optional
pageNumber optionalnumber
requireDimensionsOverride optionalboolean
priority optionalnumber

Resolve thread

POST /api/v2/threads/:id/resolve

Mark a thread as resolved.

POST /api/v2/threads/:id/resolve
curl "https://api.markup.io/api/v2/threads/dbb16ea2-4551-418b-9531-35def9238928/resolve" \ -X POST \ -H "Authorization: Bearer <API-KEY-SECRET>" \ -H "Markup-API-Version: 2023-02-22" \ -H "Content-Type: application/json"
200 OK
{ "data": { "threadId": "some threadId", "modifiedAt": 123 } }

Response Body ThreadResolvedResponse

OptionType
threadId string
modifiedAt number

Request Path Params IdRequestParam

OptionType
id string

Unresolve thread

POST /api/v2/threads/:id/unresolve

Reopen a previously resolved thread.

POST /api/v2/threads/:id/unresolve
curl "https://api.markup.io/api/v2/threads/0bbd3bf4-f66a-4a9d-ac9d-8807747e1842/unresolve" \ -X POST \ -H "Authorization: Bearer <API-KEY-SECRET>" \ -H "Markup-API-Version: 2023-02-22" \ -H "Content-Type: application/json"
200 OK
{ "data": { "threadId": "some threadId" } }

Response Body ThreadUnresolvedResponse

OptionType
threadId string

Request Path Params IdRequestParam

OptionType
id string

Delete thread

DELETE /api/v2/threads/:id

Delete a thread and all of its messages.

DELETE /api/v2/threads/:id
curl "https://api.markup.io/api/v2/threads/60c4590d-207a-40d5-9ba5-50639516609e" \ -X DELETE \ -H "Authorization: Bearer <API-KEY-SECRET>" \ -H "Markup-API-Version: 2023-02-22" \ -H "Content-Type: application/json"
Response
204 No Content

Request Path Params IdRequestParam

OptionType
id string

Move thread pin

PATCH /api/v2/threads/:id/move-pin

Reposition a thread’s pin on the markup.

PATCH /api/v2/threads/:id/move-pin
curl "https://api.markup.io/api/v2/threads/420e05d7-a96f-4d04-a164-93d0551d0179/move-pin" \ -X PATCH \ -H "Authorization: Bearer <API-KEY-SECRET>" \ -H "Markup-API-Version: 2023-02-22" \ -H "Content-Type: application/json" \ --data '{ "url": "some url", "canonicalUrl": "some canonicalUrl", "elements": [ { "elementPath": "some elementPath", "offsetXPercentage": 123, "offsetYPercentage": 123 } ], "browserContext": {}, "elementParents": [ { "url": "some url", "canonicalUrl": "some canonicalUrl", "path": "some path", "depth": 123 } ], "viewportXPercentage": 123, "viewportYPercentage": 123 }'
200 OK
{ "data": { "id": "some id", "userId": "some userId", "projectId": "some projectId", "number": 123, "resolved": true, "proxyHostId": "some proxyHostId", "urlPath": "some urlPath", "canonicalUrl": "some canonicalUrl", "viewModeId": "some viewModeId" } }

Response Body - Thread

Request Path Params IdRequestParam

OptionType
id string

Request Body MoveThreadPinBody

OptionType
url string
canonicalUrl string
elements CreateThreadRequestElement[]
browserContext
elementParents ThreadElementParentRequest[]
viewportXPercentage number
viewportYPercentage number

Get screenshot upload policy

GET /api/v2/threads/:id/screenshot-upload-policy

Get a pre-signed S3 upload policy for attaching a screenshot to a thread. Upload the file to S3 with the returned policy, then call PUT /threads/:id/screenshot to attach it.

GET /api/v2/threads/:id/screenshot-upload-policy
curl "https://api.markup.io/api/v2/threads/6d8cbfe0-d69f-4bd1-84f7-5002e9dc22df/screenshot-upload-policy?fileId=b90e3fa9-0d2e-48ca-9aae-c39a4c617ee8&filesize=123&filename=some+filename&mimeType=some+mimeType" \ -X GET \ -H "Authorization: Bearer <API-KEY-SECRET>" \ -H "Markup-API-Version: 2023-02-22" \ -H "Content-Type: application/json"
200 OK
{ "data": { "key": "some key", "policy": {}, "bucket": "some bucket" } }

Response Body S3UploadPolicyResponse

OptionType
key string
policy PresignedPost
bucket string
metadata Record

Request Path Params IdRequestParam

OptionType
id string

Request Query Params ScreenshotUploadPolicyRequestQuery

OptionType
fileId string
filesize number
filename string
mimeType string

Set thread screenshot

PUT /api/v2/threads/:id/screenshot

Attach (or replace) the screenshot for a thread after uploading the file with the upload policy.

PUT /api/v2/threads/:id/screenshot
curl "https://api.markup.io/api/v2/threads/05f05198-cd52-407a-a532-67253a6dfb80/screenshot" \ -X PUT \ -H "Authorization: Bearer <API-KEY-SECRET>" \ -H "Markup-API-Version: 2023-02-22" \ -H "Content-Type: application/json" \ --data '{ "key": "some key", "etag": "some etag", "mimeType": "some mimeType", "width": 123, "height": 123, "filesize": 123, "fileId": "1e732b30-b313-401c-bdb6-ba1835aae1fc" }'
200 OK
{ "data": { "id": "some id", "createdAt": {}, "modifiedAt": {}, "mimeType": "some mimeType", "width": 123, "height": 123, "filesize": 123, "type": "extension", "isProcessing": true } }

Response Body - ScreenshotResponse

Request Path Params IdRequestParam

OptionType
id string

Request Body CreateScreenshotRequest

OptionType
key string
etag string
mimeType string
width number
height number
filesize number
originalFilename optionalstring
fileId string

Get thread screenshot

GET /api/v2/threads/:id/screenshot

Get the screenshot attached to a thread.

GET /api/v2/threads/:id/screenshot
curl "https://api.markup.io/api/v2/threads/641d9ba2-fe50-4e3e-a79c-f590093dad96/screenshot" \ -X GET \ -H "Authorization: Bearer <API-KEY-SECRET>" \ -H "Markup-API-Version: 2023-02-22" \ -H "Content-Type: application/json"
200 OK
{ "data": { "id": "some id", "createdAt": {}, "modifiedAt": {}, "mimeType": "some mimeType", "width": 123, "height": 123, "filesize": 123, "type": "extension", "isProcessing": true } }

Response Body - ScreenshotResponse

Request Path Params IdRequestParam

OptionType
id string

ScreenshotResponse

OptionType
id string
createdAt Unix_Timestamp_Utc_Milliseconds
modifiedAt Unix_Timestamp_Utc_Milliseconds
mimeType string
width number
height number
filesize number
type
isProcessing boolean

ThreadOrder

OptionType
ThreadOrder `page` | `pin_asc` | `pin_desc` | `activity` | `timestamp` | `priority_asc` | `priority_desc`

ViewModeCategory

OptionType
ViewModeCategory `desktop` | `tablet` | `mobile`

ThreadElementParentRequest

OptionType
url string
canonicalUrl string
path string
depth number

BrowserContextRequest

OptionType
browserName string
browserVersion string
os string
osVersion string
osVersionName string
platform string
screenWidth number
screenHeight number
viewportWidth number
viewportHeight number

CanvasThreadAnnotationRequest

OptionType
version string
scale number
originalWidth number
originalHeight number

ThreadTextHighlightRequest

OptionType
startKey string
endKey string
startOffset number
startIndex number
endOffset number
endIndex number
text string

IProjectThreadQuery

OptionType
resolved boolean

ThreadResponse

WebpageThreadResponse

OptionType
id string
createdAt Unix_Timestamp_Utc_Milliseconds
modifiedAt Unix_Timestamp_Utc_Milliseconds
scopes string[]
assignedRoleSlugs string[]
user AuthorUserResponse
number number
resolved boolean
messages MessageResponse[]
userMetaData IUserResourceMetaData
lastActivityAt number
annotations AnnotationsResponse
projectId string
proxyUrl string
originalUrl string
canonicalUrl string
elements ThreadElementResponse[]
parents ThreadElementParentResponse[]
browserContext IBrowserContext
viewModeId string

ImageThreadResponse

OptionType
id string
createdAt Unix_Timestamp_Utc_Milliseconds
modifiedAt Unix_Timestamp_Utc_Milliseconds
scopes string[]
assignedRoleSlugs string[]
user AuthorUserResponse
number number
resolved boolean
messages MessageResponse[]
userMetaData IUserResourceMetaData
lastActivityAt number
annotations AnnotationsResponse
projectImageId string
offsetXPercentage number
offsetYPercentage number
startTime number
endTime number

PdfThreadResponse

OptionType
id string
createdAt Unix_Timestamp_Utc_Milliseconds
modifiedAt Unix_Timestamp_Utc_Milliseconds
scopes string[]
assignedRoleSlugs string[]
user AuthorUserResponse
number number
resolved boolean
messages MessageResponse[]
userMetaData IUserResourceMetaData
lastActivityAt number
annotations AnnotationsResponse
projectImageId string
offsetXPercentage number
offsetYPercentage number
pageNumber number
textHighlight TextHighlightResponse

Thread

OptionType
Thread

WebpageThread

OptionType
id string
userId string
projectId string
number number
resolved boolean
proxyHostId string
urlPath string
canonicalUrl string
viewModeId string

ImageThread

OptionType
id string
userId string
projectId string
number number
resolved boolean
projectImageId string
offsetXPercentage number
offsetYPercentage number
startTime number
endTime number

PdfThread

OptionType
id string
userId string
projectId string
number number
resolved boolean
pageNumber number
pageRelativeX number
pageRelativeY number

ScreenshotType

OptionType
ScreenshotType `extension` | `native` | `static`
Last updated on