Skip to content

REST API

Hypertask’s public REST API is available at https://app.hypertask.ai/api/v1. Use it to list projects, create and update tasks, manage comments, assign users, read inbox notifications, and manage task drafts.

Send an API key in the Authorization header:

Terminal window
Authorization: Bearer htk_...

Create API keys in the Hypertask app with Ctrl+K -> REST API. Each user can have up to 10 active keys. The full key is shown once when it is created, and keys can be revoked from the same modal.

Terminal window
export HT_API_KEY=htk_...
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/user/context"

Error responses use this general shape:

{
"success": false,
"error": "Validation error",
"message": "project_id must be a positive integer",
"details": {
"field": "project_id",
"code": "invalid_type"
}
}

Previously, several public API routes accepted an unsigned nookies_user cookie as the authenticated user identity. This has been tightened to prevent account takeover via forged cookies:

  • Routes that set nookies_user.id now require a valid, matching signed ht_session cookie with the same id value to succeed.

  • The following route families are affected:

    • Auth routes (e.g., /api/auth/*)
    • MCP routes (/api/mcp/*)
    • Other 64 public sub-paths previously relying on unsigned nookies_user
    • All associated webhook and logged-out call sites

Verified live on production: forging nookies_user={"id":6} now returns 401 instead of 200+ full data, and forging {"id":1} for any other user also returns 401.

Compatibility: The consensus across the auth, MCP, public, webhook, logged-out, and Bearer-auth request families is that this change does not affect existing integrations or tools:

  • Auth requests with standard Authorization: Bearer $HT_API_KEY continue to work.
  • MCP tools retain their same param schema.
  • Public integrations that already manage ht_session via the app workload continue untouched.
  • Work that previously shipped nookies_user directly (e.g., via server-to-server calls) should now explicitly sign or add ht_session with the same id, but it is a rare pattern in practice.

If your pattern relies on unsigned nookies_user outside these call sites, see /api/session/verify to validate the signed session instead.


The Hypertask CLI is a thin wrapper around the REST API. Every CLI command ultimately calls a route under https://app.hypertask.ai/api/mcp/*. You can call those same routes directly with curl or any HTTP client, bypassing the Node.js process startup cost.

Measured from a VPS, the difference is substantial:

MethodTypical latency
curl direct to REST API~0.21 s
hypertask CLI~0.84 – 1.06 s

The gap is almost entirely Node.js cold-start time. For agents that issue many sequential calls, this adds up quickly.

How the routes map:

  • The api/v1 routes documented on this page are the public, versioned REST API — use these for integrations and scripts.
  • The api/mcp/* routes are the same operations that the CLI and MCP server use internally. They accept the same authentication header (Authorization: Bearer htk_...).

For agent workloads that currently shell out to the CLI, switching to direct curl calls against either the api/v1 or api/mcp/* routes is a straightforward way to cut per-operation latency by ~4×.

Routes that operate on a specific task usually accept exactly one task identifier:

Use the internal task ID:

{ "task_id": 789 }

Return the authenticated user, accessible teams, projects, and agents.

Endpoint: GET /api/v1/user/context

Parameters: None

Example request:

Terminal window
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/user/context"

Response shape:

{
"success": true,
"user": {
"id": 6,
"email": "valentin@example.com",
"displayName": "Valentin"
},
"connected_agent": null,
"teams": [
{ "id": "team_uuid", "title": "Product" }
],
"projects": [
{ "id": 123, "title": "Engineering", "labels": [], "sections": [] }
],
"all_agents": [
{ "id": "agent_uuid", "displayName": "Release Agent" }
]
}

List projects the API key owner can access.

Endpoint: GET /api/v1/projects

Query parameters:

ParameterTypeRequiredDefaultDescription
statusstringNoNormalFilter by Normal, Archive, or Deleted
searchstringNoSearch project title, name, or description
limitnumberNo50Max results, capped at 100
offsetnumberNo0Pagination offset
sort_bystringNotitletitle, createdAt, or updatedAt
sort_orderstringNoascasc or desc

Example request:

Terminal window
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/projects?status=Normal&limit=20"

Response shape:

{
"success": true,
"projects": [
{
"id": 123,
"title": "Engineering",
"description": "Product engineering work",
"memberCount": 5,
"taskCount": 42,
"sections": [
{ "id": 456, "section_title": "Todo" }
],
"labels": [
{ "id": "label_uuid", "name": "Customer" }
],
"status": "Normal",
"createdAt": "2026-03-10T12:00:00.000Z"
}
],
"total": 1,
"limit": 20,
"offset": 0
}

List sections for a project board.

Endpoint: GET /api/v1/projects/{projectId}/sections

Path parameters:

ParameterTypeRequiredDescription
projectIdnumberYesProject ID

Query parameters:

ParameterTypeRequiredDefaultDescription
include_hiddenbooleanNofalseInclude hidden sections

Example request:

Terminal window
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/projects/123/sections?include_hidden=false"

Response shape:

{
"success": true,
"sections": [
{
"id": 456,
"section_title": "Todo",
"projectId": 123,
"visibility": true,
"deleted": false,
"ranking": "a0",
"taskCount": 12
}
],
"projectId": 123
}

Create a section in a project.

Endpoint: POST /api/v1/projects/{projectId}/sections

Path parameters:

ParameterTypeRequiredDescription
projectIdnumberYesProject ID

Body parameters:

ParameterTypeRequiredDescription
titlestringYesSection name, 1 to 200 characters
after_section_idnumberNoInsert the new section after this section ID

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"QA","after_section_id":456}' \
"https://app.hypertask.ai/api/v1/projects/123/sections"

Response shape:

{
"success": true,
"section": {
"id": 457,
"section_title": "QA",
"projectId": 123,
"taskCount": 0
},
"message": "Section created successfully"
}

Rename or reorder a section.

Endpoint: PATCH /api/v1/projects/{projectId}/sections/{sectionId}

Path parameters:

ParameterTypeRequiredDescription
projectIdnumberYesProject ID
sectionIdnumberYesSection ID

Body parameters:

ParameterTypeRequiredDescription
titlestringNoNew section name
move_after_section_idnumberNoMove the section after this section ID

Provide at least one body parameter.

Example request:

Terminal window
curl -s -X PATCH -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Ready for QA"}' \
"https://app.hypertask.ai/api/v1/projects/123/sections/456"

Response shape:

{
"success": true,
"section": {
"id": 456,
"section_title": "Ready for QA",
"projectId": 123,
"taskCount": 4
},
"message": "Section updated successfully"
}

Delete a section and move its tasks to the first remaining section.

Endpoint: DELETE /api/v1/projects/{projectId}/sections/{sectionId}

Path parameters:

ParameterTypeRequiredDescription
projectIdnumberYesProject ID
sectionIdnumberYesSection ID

Example request:

Terminal window
curl -s -X DELETE -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/projects/123/sections/456"

Response shape:

{
"success": true,
"message": "Section deleted successfully"
}

Create a label in a project.

Endpoint: POST /api/v1/projects/{projectId}/labels

Path parameters:

ParameterTypeRequiredDescription
projectIdnumberYesProject ID

Body parameters:

ParameterTypeRequiredDescription
namestringYesLabel name, 1 to 100 characters. Must be unique in the project.

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Customer"}' \
"https://app.hypertask.ai/api/v1/projects/123/labels"

Response shape:

{
"success": true,
"label": {
"id": "label_uuid",
"name": "Customer"
},
"message": "Label \"Customer\" created successfully"
}

List project members for mentions and assignment.

Endpoint: GET /api/v1/projects/{projectId}/members

Path parameters:

ParameterTypeRequiredDescription
projectIdnumberYesProject ID

Example request:

Terminal window
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/projects/123/members"

Response shape:

{
"success": true,
"members": [
{
"id": 6,
"email": "valentin@example.com",
"displayName": "Valentin"
}
],
"projectId": 123
}

Invite or add a project member by email or user ID.

Endpoint: POST /api/v1/projects/{projectId}/members

Path parameters:

ParameterTypeRequiredDescription
projectIdnumberYesProject ID

Body parameters:

ParameterTypeRequiredDescription
userToAddstring or numberYesEmail address or positive integer user ID

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"userToAdd":"teammate@example.com"}' \
"https://app.hypertask.ai/api/v1/projects/123/members"

Response shape:

{
"success": true,
"projectId": 123
}

Create a board under a team from a structured manifest. Find team IDs with GET /api/v1/user/context.

Endpoint: POST /api/v1/teams/{teamId}/boards

Path parameters:

ParameterTypeRequiredDescription
teamIdstringYesTeam UUID

Headers:

HeaderRequiredDescription
Idempotency-KeyNoReplays with the same key and same body return the cached successful response for 24 hours

Body parameters:

ParameterTypeRequiredDescription
titlestringYesBoard title, 1 to 200 characters
descriptionstringNoBoard description
sectionsobject[]Yes1 to 50 sections. Each item: { "title": string }
labelsobject[]NoUp to 100 labels. Each item: { "name": string, "color"?: string }. color is accepted but not persisted.
tasksobject[]NoUp to 500 starter tasks
tasks[].titlestringYesTask title, 1 to 500 characters
tasks[].descriptionstringNoHTML task description
tasks[].section_indexnumberConditionalZero-based section index. Provide this or section_title, not both.
tasks[].section_titlestringConditionalSection title. Provide this or section_index, not both.
tasks[].label_namesstring[]NoLabel names defined in the same manifest
tasks[].prioritynumberNo0 No Priority, 1 Urgent, 2 High, 3 Medium, 4 Low
tasks[].estimatenumberNo0 none, 2 XS, 3 S, 4 M, 5 L, 6 XL
tasks[].due_datestringNoISO 8601 date or datetime

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: board-import-001" \
-d '{
"title": "Launch",
"sections": [
{ "title": "Todo" },
{ "title": "Done" }
],
"labels": [
{ "name": "Docs" }
],
"tasks": [
{
"title": "Draft launch plan",
"section_index": 0,
"label_names": ["Docs"],
"priority": 2
}
]
}' \
"https://app.hypertask.ai/api/v1/teams/team_uuid/boards"

Response shape:

{
"success": true,
"team_id": "team_uuid",
"board": {
"id": 123,
"title": "Launch"
},
"sections": [
{ "id": 456, "title": "Todo" }
],
"labels": [
{ "id": "label_uuid", "name": "Docs" }
],
"tasks": [
{ "id": 789, "ticketNumber": "ENG-42", "title": "Draft launch plan" }
],
"message": "Board created successfully"
}

List tasks with filters, or fetch tasks by identifier.

Endpoint: GET /api/v1/tasks

Query parameters:

ParameterTypeRequiredDefaultDescription
task_idnumber or CSVNoGet one or more tasks by internal ID
ticket_numberstring or CSVNoGet one or more tasks by ticket number
unique_indexnumberNoGet a task by project-scoped index. Requires project_id.
project_idnumberNoFilter by project, or scope ticket_number and unique_index lookup
board_idnumberNoAlias for project filtering
sectionstringNoFilter by section title
assigned_tostringNome, unassigned, or comma-separated user IDs
prioritystringNoPriority value, such as High
has_due_datebooleanNoFilter by due date presence
due_date_beforestringNoISO 8601 date or datetime
due_date_afterstringNoISO 8601 date or datetime
statusstringNoNormalNormal, Archive, or Deleted
labelsstringNoRepeat this parameter for label IDs or label names
created_bynumberNoCreator user ID
updated_sincestringNoISO 8601 datetime
created_sincestringNoISO 8601 datetime
has_commentsbooleanNoFilter tasks with or without comments
has_attachmentsbooleanNoFilter tasks with or without attachments
searchstringNoSearch title, description, or ticket number
limitnumberNo50Max results, capped at 100
offsetnumberNo0Pagination offset
sort_bystringNoupdatedAtcreatedAt, updatedAt, dueDate, priority, or title
sort_orderstringNodescasc or desc

Example request:

Terminal window
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/tasks?project_id=123&status=Normal&limit=20"

Response shape:

{
"success": true,
"tasks": [
{
"id": 789,
"ticketNumber": "ENG-42",
"title": "Ship API docs",
"description": "<p>Publish REST API docs.</p>",
"section": "Todo",
"sectionId": 456,
"boardId": 123,
"boardTitle": "Engineering",
"projectId": 123,
"status": "Normal",
"priority": "High",
"dueDate": "2026-03-10T00:00:00.000Z",
"assigneeCount": 1,
"labelCount": 1,
"commentCount": 2,
"createdAt": "2026-03-01T12:00:00.000Z",
"updatedAt": "2026-03-02T12:00:00.000Z"
}
],
"total": 1,
"limit": 20,
"offset": 0,
"metadata": {
"projectCount": 1,
"sectionCount": 1
}
}

Single-task lookups return either { "success": true, "tasks": [...] } or, for a legacy single ticket_number lookup, { "success": true, "task": {...} }.

Create a task in a project.

Endpoint: POST /api/v1/tasks/create

Body parameters:

ParameterTypeRequiredDescription
project_idnumberYesProject ID
titlestringYesTask title, 1 to 500 characters
descriptionstringNoHTML description
section_idnumberNoSection ID. Defaults to the project’s first section.
prioritynumberNo0 No Priority, 1 Urgent, 2 High, 3 Medium, 4 Low
estimatenumberNo0 none, 2 XS, 3 S, 4 M, 5 L, 6 XL
due_datestringNoISO 8601 date or datetime
imagesstring[]NoHTTP or HTTPS image URLs to attach
labelsstring[] or number[]NoLabel IDs to assign
parent_task_idnumberNoParent task ID
assigneenumber[]NoPositive integer user IDs to assign

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"project_id": 123,
"title": "Ship API docs",
"description": "<p>Publish the REST API reference.</p>",
"section_id": 456,
"priority": 2
}' \
"https://app.hypertask.ai/api/v1/tasks/create"

Response shape:

{
"success": true,
"task": {
"id": 789,
"ticketNumber": "ENG-42",
"title": "Ship API docs",
"description": "<p>Publish the REST API reference.</p>",
"section": "Todo",
"sectionId": 456,
"boardId": 123,
"projectId": 123,
"priority": {
"priority_index": 2,
"Priority_Value": "High"
},
"labels": [],
"assignees": [],
"totalComments": 0,
"createdAt": "2026-03-01T12:00:00.000Z",
"updatedAt": "2026-03-01T12:00:00.000Z"
},
"message": "Task created successfully"
}

Update one or more tasks.

Endpoint: POST /api/v1/tasks/update

Body parameters:

ParameterTypeRequiredDescription
task_idnumber or number[]ConditionalIdentify task or tasks by internal ID
ticket_numberstring or string[]ConditionalIdentify task or tasks by ticket number
unique_indexnumberConditionalIdentify a task by project-scoped index. Requires project_id.
project_idnumberConditionalRequired with unique_index; optional scope for ticket_number
titlestringNoNew task title
descriptionstringNoNew HTML description
prioritynumberNo0 No Priority, 1 Urgent, 2 High, 3 Medium, 4 Low
estimatenumberNo0 none, 2 XS, 3 S, 4 M, 5 L, 6 XL
sectionIdnumberNoMove to a section in the same project
statusstringNoNormal, Archive, or Deleted
labelsstring[] or number[]NoReplace all labels with these label IDs
due_datestring or nullNoISO 8601 date or datetime, or null to clear
assigneenumber[]NoPositive integer user IDs to assign
parent_task_idnumberNoParent task ID

Provide exactly one task identification method and at least one field to update.

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ticket_number":"ENG-42","project_id":123,"status":"Archive"}' \
"https://app.hypertask.ai/api/v1/tasks/update"

Response shape:

{
"success": true,
"tasks": [
{
"id": 789,
"ticketNumber": "ENG-42",
"title": "Ship API docs",
"status": "Archive",
"section": "Todo",
"boardId": 123,
"projectId": 123,
"updatedAt": "2026-03-02T12:00:00.000Z"
}
],
"task": {
"id": 789,
"ticketNumber": "ENG-42",
"status": "Archive"
},
"message": "1 task(s) updated successfully"
}

Move a task to another project or section.

Endpoint: POST /api/v1/tasks/move

Body parameters:

ParameterTypeRequiredDescription
task_idnumberConditionalIdentify task by internal ID
ticket_numberstringConditionalIdentify task by ticket number
project_idnumberConditionalRequired with unique_index
unique_indexnumberConditionalIdentify task by project-scoped index
target_project_idnumberYesDestination project ID
target_section_idnumberNoDestination section ID. Defaults to the first section in the destination project.

Provide exactly one task identification method.

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"task_id":789,"target_project_id":124,"target_section_id":501}' \
"https://app.hypertask.ai/api/v1/tasks/move"

Response shape:

{
"success": true,
"task": {
"id": 789,
"ticketNumber": "ENG-42",
"boardId": 124,
"projectId": 124,
"sectionId": 501,
"section": "Backlog"
},
"message": "Task moved successfully"
}

Search tasks by title, description, or ticket number.

Endpoint: GET /api/v1/tasks/search

Query parameters:

ParameterTypeRequiredDefaultDescription
qstringYesSearch query, max 200 characters
board_idnumberNoLimit to a board
project_idnumberNoLimit to a project
assigned_tostringNome, unassigned, or a user ID
prioritystringNoPriority value, such as High
sectionstringNoSection title
has_due_datebooleanNoFilter by due date presence
statusstringNoNormalNormal or Archive
limitnumberNo10Max results, capped at 50

Example request:

Terminal window
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/tasks/search?q=docs&project_id=123&limit=10"

Response shape:

{
"success": true,
"tasks": [
{
"id": 789,
"ticketNumber": "ENG-42",
"title": "Ship API docs",
"description": "<p>Publish REST API docs.</p>",
"boardId": 123,
"boardTitle": "Engineering",
"projectId": 123,
"section": "Todo",
"createdAt": "2026-03-01T12:00:00.000Z"
}
],
"total": 1,
"boardId": 123
}

Return a task’s family tree from the topmost parent.

Endpoint: GET /api/v1/tasks/tree

Query parameters:

ParameterTypeRequiredDefaultDescription
task_idnumberConditionalIdentify task by internal ID
ticket_numberstringConditionalIdentify task by ticket number
depthnumberNoFull subtreeNumber of descendant levels to include. 0 returns the root only.

Provide exactly one of task_id or ticket_number.

Example request:

Terminal window
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/tasks/tree?ticket_number=ENG-42&depth=2"

Response shape:

{
"success": true,
"tree": {
"id": 700,
"ticketNumber": "ENG-1",
"title": "Launch project",
"uniqueIndex": 1,
"children": [
{
"id": 789,
"ticketNumber": "ENG-42",
"title": "Ship API docs",
"uniqueIndex": 42,
"children": []
}
]
}
}

Upload attachments to a task description, or to a comment when comment_id is provided.

Endpoint: POST /api/v1/tasks/attachments

Body parameters:

ParameterTypeRequiredDescription
task_idnumberConditionalIdentify task by internal ID
ticket_numberstringConditionalIdentify task by ticket number
comment_idnumberNoAttach to this comment instead of the task description
filesobject[]Yes1 to 10 files
files[].filenamestringYesFilename, max 255 characters. Must not include path segments.
files[].content_typestringYesOne of image/png, image/jpeg, image/webp, image/gif, application/pdf, text/markdown, text/plain
files[].datastringConditionalRaw base64 file data
files[].urlstringConditionalHTTP or HTTPS URL to fetch

Each file must provide exactly one of data or url. Decoded or fetched file size is limited to 15 MB.

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"task_id": 789,
"files": [
{
"filename": "brief.txt",
"content_type": "text/plain",
"data": "SGVsbG8="
}
]
}' \
"https://app.hypertask.ai/api/v1/tasks/attachments"

Response shape:

{
"success": true,
"attachments": [
{
"id": 9001,
"fileName": "brief.txt",
"fileType": "text/plain",
"fileSize": 5,
"url": "https://..."
}
]
}

List user comments for a task. Activity log entries are excluded.

Endpoint: GET /api/v1/comments

Query parameters:

ParameterTypeRequiredDefaultDescription
task_idnumberConditionalIdentify task by internal ID
ticket_numberstringConditionalIdentify task by ticket number
unique_indexnumberConditionalIdentify task by project-scoped index. Requires project_id.
project_idnumberConditionalRequired with unique_index; optional scope for ticket_number
limitnumberNo50Max results, capped at 100
offsetnumberNo0Pagination offset
sort_orderstringNodescasc or desc

Example request:

Terminal window
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/comments?ticket_number=ENG-42&project_id=123"

Response shape:

{
"success": true,
"comments": [
{
"id": 321,
"text": "<p>Looks good.</p>",
"commentText": "<p>Looks good.</p>",
"createdAt": "2026-03-02T12:00:00.000Z",
"creatorId": 6,
"creator": {
"id": 6,
"email": "valentin@example.com",
"displayName": "Valentin"
},
"attachments": [],
"reactions": []
}
],
"total": 1,
"limit": 50,
"offset": 0
}

Add a comment to a task. Comment text is HTML.

Endpoint: POST /api/v1/comments

Body parameters:

ParameterTypeRequiredDescription
task_idnumberConditionalIdentify task by internal ID
ticket_numberstringConditionalIdentify task by ticket number
unique_indexnumberConditionalIdentify task by project-scoped index. Requires project_id.
project_idnumberConditionalRequired with unique_index; optional scope for ticket_number
textstringYesHTML comment text, max 5000 characters
imagesstring[]NoHTTP or HTTPS image URLs
mentionsobject[]NoOptional mention metadata. Each item: { "user_id": number, "display_name": string }

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"task_id":789,"text":"<p>Looks good.</p>"}' \
"https://app.hypertask.ai/api/v1/comments"

Response shape:

{
"success": true,
"comment": {
"id": 321,
"text": "<p>Looks good.</p>",
"createdAt": "2026-03-02T12:00:00.000Z",
"creatorId": 6,
"attachments": []
}
}

Update your own comment.

Endpoint: PATCH /api/v1/comments/{comment_id}

Path parameters:

ParameterTypeRequiredDescription
comment_idnumberYesComment ID

Body parameters:

ParameterTypeRequiredDescription
textstringYesHTML comment text, max 5000 characters
mentionsobject[]NoOptional mention metadata. Each item: { "user_id": number, "display_name": string }

Example request:

Terminal window
curl -s -X PATCH -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"<p>Updated comment.</p>"}' \
"https://app.hypertask.ai/api/v1/comments/321"

Response shape:

{
"success": true,
"comment": {
"id": 321,
"text": "<p>Updated comment.</p>",
"createdAt": "2026-03-02T12:00:00.000Z",
"creatorId": 6
}
}

Delete your own comment.

Endpoint: DELETE /api/v1/comments/{comment_id}

Path parameters:

ParameterTypeRequiredDescription
comment_idnumberYesComment ID

Example request:

Terminal window
curl -s -X DELETE -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/comments/321"

Response shape:

{
"success": true,
"message": "Comment deleted"
}

Assign or unassign one or more project members on a task.

Endpoint: POST /api/v1/assignees/assign

Body parameters:

ParameterTypeRequiredDescription
task_idnumberConditionalIdentify task by internal ID
ticket_numberstringConditionalIdentify task by ticket number
project_idnumberConditionalRequired with unique_index; optional scope for ticket_number
unique_indexnumberConditionalIdentify task by project-scoped index
user_idnumberConditionalSingle user to assign or unassign
user_idsnumber[]ConditionalMultiple users. Requires mode: "multiple".
modestringConditionalUse multiple with user_ids
intentstringNoassign or unassign. Defaults to assign.

Provide exactly one task identifier and either user_id or user_ids.

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"task_id":789,"user_ids":[12,34],"mode":"multiple","intent":"assign"}' \
"https://app.hypertask.ai/api/v1/assignees/assign"

Response shape:

{
"success": true,
"assignees": [
{ "userId": 12 },
{ "userId": 34 }
],
"assignStatus": "Assigned"
}

Return inbox notifications for the user and, when the token is agent-bound, the connected agent.

Endpoint: GET /api/v1/inbox/list

Parameters: None

Example request:

Terminal window
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/inbox/list"

Response shape:

{
"success": true,
"user_notifications": [
{
"id": 1001,
"status": "Normal",
"taskId": 789
}
],
"agent_notifications": []
}

For user-only API keys, agent_notifications may be omitted.

Archive inbox notifications by ID.

Endpoint: POST /api/v1/inbox/archive

Body parameters:

ParameterTypeRequiredDescription
notification_idsnumber[]YesNon-empty array of notification IDs

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"notification_ids":[1001,1002]}' \
"https://app.hypertask.ai/api/v1/inbox/archive"

Response shape:

{
"success": true,
"archived_count": 2
}

List drafts for a task.

Endpoint: GET /api/v1/drafts

Query parameters:

ParameterTypeRequiredDefaultDescription
task_idnumberConditionalIdentify task by internal ID
ticket_numberstringConditionalIdentify task by ticket number
unique_indexnumberConditionalIdentify task by project-scoped index. Requires project_id.
project_idnumberConditionalRequired with unique_index; optional scope for ticket_number

Example request:

Terminal window
curl -s -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/drafts?task_id=789"

Response shape:

{
"success": true,
"drafts": [
{
"id": 555,
"taskId": 789,
"ticketNumber": "ENG-42",
"draftType": "comment",
"text": "<p>Draft response.</p>",
"status": "Draft",
"updatedAt": "2026-03-02T12:00:00.000Z",
"createdBy": {
"id": 6,
"email": "valentin@example.com",
"displayName": "Valentin"
}
}
]
}

Create or replace a description or comment draft for a task.

Endpoint: POST /api/v1/drafts

Body parameters:

ParameterTypeRequiredDescription
task_idnumberConditionalIdentify task by internal ID
ticket_numberstringConditionalIdentify task by ticket number
unique_indexnumberConditionalIdentify task by project-scoped index. Requires project_id.
project_idnumberConditionalRequired with unique_index; optional scope for ticket_number
draft_typestringYesdescription or comment
textstringYesHTML draft content

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"task_id":789,"draft_type":"comment","text":"<p>Draft response.</p>"}' \
"https://app.hypertask.ai/api/v1/drafts"

Response shape:

{
"success": true,
"draft": {
"id": 555,
"taskId": 789,
"ticketNumber": "ENG-42",
"draftType": "comment",
"text": "<p>Draft response.</p>",
"status": "Draft",
"updatedAt": "2026-03-02T12:00:00.000Z"
},
"message": "Draft created successfully"
}

Update your own draft text.

Endpoint: PATCH /api/v1/drafts/{draft_id}

Path parameters:

ParameterTypeRequiredDescription
draft_idnumberYesDraft ID

Body parameters:

ParameterTypeRequiredDescription
textstringYesHTML draft content

Example request:

Terminal window
curl -s -X PATCH -H "Authorization: Bearer $HT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"<p>Updated draft.</p>"}' \
"https://app.hypertask.ai/api/v1/drafts/555"

Response shape:

{
"success": true,
"draft": {
"id": 555,
"taskId": 789,
"ticketNumber": "ENG-42",
"draftType": "comment",
"text": "<p>Updated draft.</p>",
"status": "Draft",
"updatedAt": "2026-03-02T12:05:00.000Z"
},
"message": "Draft updated successfully"
}

Delete your own draft.

Endpoint: DELETE /api/v1/drafts/{draft_id}

Path parameters:

ParameterTypeRequiredDescription
draft_idnumberYesDraft ID

Example request:

Terminal window
curl -s -X DELETE -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/drafts/555"

Response shape:

{
"success": true,
"message": "Draft deleted successfully"
}

Publish a draft into a task description or comments, depending on the draft type.

Endpoint: POST /api/v1/drafts/{draft_id}/publish

Path parameters:

ParameterTypeRequiredDescription
draft_idnumberYesDraft ID

Example request:

Terminal window
curl -s -X POST -H "Authorization: Bearer $HT_API_KEY" \
"https://app.hypertask.ai/api/v1/drafts/555/publish"

Response shape:

{
"success": true,
"message": "Draft published - comment added to ENG-42"
}