REST API · v1

API Reference

The Vortask REST API gives you programmatic access to all your projects, tasks, members, and webhooks. Use personal API tokens for CI/CD or build custom integrations.

MCP Server

AI Agents

Vortask exposes a hosted Model Context Protocol (MCP) server at https://mcp.vortask.app. AI assistants (Claude, Cursor, etc.) can connect to it and manage your tasks and projects using natural language — no custom code required.

🤖
Machine-readable instructions for LLMs are available at https://vortask.app/llms.txt. AI crawlers and agents can fetch this file to understand how to access Vortask programmatically.

Connect from Claude.ai

Claude.ai supports remote MCP servers directly. No installation needed.

  1. 1Go to Settings → Integrations → Add MCP Server
  2. 2Enter URL: https://mcp.vortask.app
  3. 3When prompted, paste your vt_ API token

Connect from Claude Desktop

Add this to your claude_desktop_config.json:

claude_desktop_config.jsonjson
{
  "mcpServers": {
    "vortask": {
      "command": "npx",
      "args": ["-y", "vortask-mcp"],
      "env": {
        "VORTASK_API_URL": "https://api.vortask.app/api",
        "VORTASK_TOKEN": "vt_your_token_here"
      }
    }
  }
}

Authentication

For direct HTTP access, pass your API token as a Bearer token. The server uses the Streamable HTTP transport (JSON-RPC + SSE).

Initialize sessionhttp
POST https://mcp.vortask.app
Authorization: Bearer vt_your_token
Content-Type: application/json
Accept: application/json, text/event-stream

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
  "protocolVersion":"2024-11-05",
  "capabilities":{},
  "clientInfo":{"name":"my-agent","version":"1.0"}
}}

The response includes an mcp-session-id header. Pass it on all subsequent requests.

Available Tools

The MCP server exposes 14 tools. Call tools/list on the server to retrieve the full schema at any time.

get_context

Full workspace snapshot — profile, all projects, and the 20 most recent tasks in each. Call this first to orient yourself.

READ
list_projects

List all projects the user belongs to, with their role (Admin / Member / Viewer) and task count.

READ
list_tasks

List tasks in a project. Filters: status, priority, assigneeId, label, dueBefore, dueAfter.

READ
get_task

Full task details including all assignees and tags.

READ
get_task_history

Audit trail — who changed what and when.

READ
create_task

Create a task. Required: projectId, title. Optional: description, priority, dueDate, tags, assigneeIds.

WRITE
bulk_create_tasks

Create up to 100 tasks at once. Useful for seeding a project from a plan.

WRITE
update_task

Partial patch — only include the fields you want to change. Supports status, priority, title, description, dueDate, tags, assigneeIds.

WRITE
delete_task

Permanently delete a task. Requires Admin role in the project.

DELETE
list_members

List project members and pending invitations.

READ
create_project

Create a new project. The authenticated user becomes its Admin.

WRITE
list_comments

List all comments on a task, oldest-first.

READ
add_comment

Add a comment to a task. Supports plain text or HTML.

WRITE
delete_comment

Delete a comment. Only your own comments, unless you are a project Admin.

DELETE

Agent Workflow

Recommended sequence for an AI agent accessing Vortask for the first time:

1
Orientget_context

Call get_context to load the user's profile, all project IDs and names, and recent tasks. This gives you everything needed to proceed without additional round-trips.

2
Find worklist_tasks

Call list_tasks with status=Active or status=New to surface the current backlog. Use priority or assigneeId filters to narrow results.

3
Actupdate_task / create_task

Use update_task to change status, reassign, or set due dates. Use create_task or bulk_create_tasks to add new items from a plan.

4
Communicateadd_comment

Leave an add_comment to explain changes or ask for clarification — visible to the whole team.

Token Scopes

Create scoped tokens to limit what an agent can do. Tokens with no scopes have full access (bounded by project role).

ScopePermits
tasks:readRead tasks and task history
tasks:writeCreate and update tasks
tasks:deleteDelete tasks
projects:readRead projects and members
projects:writeManage projects and members

Authentication

All API requests authenticate with a Personal API token created from your account dashboard. Tokens have a vt_ prefix. Pass the token in the Authorization header on every request.

Authorization header
Authorization: Bearer vt_<your_token>
Note: API tokens do not expire by default unless you set an expiry date when creating them. Revoked or expired tokens return 401 Unauthorized.

Base URL & Headers

Base URL
https://your-domain.com/api

All requests must include the following headers:

HeaderValueRequired
Content-Typeapplication/jsonFor POST/PUT
AuthorizationBearer <token>Required

Errors

The API uses standard HTTP status codes. Error responses include a JSON body:

StatusMeaning
200OK
201Created
400Bad Request — validation failed
401Unauthorized — missing or invalid token
403Forbidden — insufficient role
404Not Found
Error response body
{
  "errors": ["Title is required."],
  "message": "Validation failed"
}

Profile

GET/profile

Get the authenticated user's profile.

Response 200
{
  "id": "uuid",
  "email": "alice@example.com",
  "displayName": "Alice",
  "avatarUrl": null,
  "createdAt": "2026-03-17T12:00:00Z"
}
PUT/profile

Update display name or avatar URL.

Request body (all optional)
{
  "displayName": "Alice Smith",
  "avatarUrl": "https://example.com/avatar.jpg"
}
DELETE/profile

Permanently delete the authenticated user's account. Returns 204 No Content.

Projects

GET/projects

List all projects the authenticated user is a member of.

Response 200
[
  {
    "id": 1,
    "name": "My Project",
    "description": "...",
    "taskCount": 12,
    "myRole": "Admin",
    "createdAt": "2026-03-01T10:00:00Z"
  }
]
GET/projects/:id

Get a single project by ID. Returns the same shape as the list item above.

POST/projects

Create a new project. The caller becomes the project Admin.

Request body
{
  "name": "My Project",       // required
  "description": "Optional desc"
}
PUT/projects/:idMember+

Update project name or description.

Request body (all optional)
{
  "name": "New Name",
  "description": "Updated desc"
}
DELETE/projects/:idAdmin only

Delete a project and all its tasks. Returns 204 No Content.

Members

Manage who has access to a project. Roles: Admin · Member · Viewer

GET/projects/:id/members

List all members of a project.

Response 200
[{
  "id": 1,
  "userId": "uuid",
  "email": "bob@example.com",
  "displayName": "Bob",
  "role": "Member",
  "joinedAt": "2026-03-10T08:00:00Z"
}]
POST/projects/:id/membersAdmin only

Invite a user to the project by email.

Request body
{
  "email": "bob@example.com",
  "role": "Member"  // Admin | Member | Viewer
}
PUT/projects/:id/members/:memberIdAdmin only

Change a member's role.

Request body
{ "role": "Viewer" }
DELETE/projects/:id/members/:memberIdAdmin only

Remove a member from the project.

DELETE/projects/:id/invitations/:invitationIdAdmin only

Cancel a pending invitation. Returns 204 No Content.

Tasks

GET/projects/:id/tasks

List tasks for a project. Supports multiple query filters:

Query paramTypeValues
statusstringNew · Active · Blocked · Closed
prioritystringLow · Medium · High
assigneeIdstring (UUID)Filter by assigned user ID
labelstringPartial match on tags
dueBeforeISO 8601e.g. 2026-04-01
dueAfterISO 8601e.g. 2026-03-01
Example request
GET /api/projects/1/tasks?status=Active&priority=High
GET/projects/:id/tasks/:taskId

Get a single task with full detail.

Response 200
{
  "id": 42,
  "title": "Implement login",
  "description": "...",
  "status": "Active",
  "priority": "High",
  "dueDate": "2026-03-20T00:00:00Z",
  "tags": ["backend", "auth"],
  "assignees": [{
    "userId": "uuid",
    "email": "alice@example.com",
    "displayName": "Alice"
  }],
  "createdAt": "2026-03-01T09:00:00Z",
  "updatedAt": "2026-03-15T14:22:00Z"
}
POST/projects/:id/tasksMember+

Create a new task. New tasks start with status New.

Request body
{
  "title": "Add dark mode",       // required
  "description": "Support system theme",
  "priority": "Medium",            // required
  "dueDate": "2026-04-01",
  "tags": ["frontend", "ui"],
  "assigneeIds": ["uuid1", "uuid2"]
}
PUT/projects/:id/tasks/:taskIdMember+

Update any task field. All fields are optional — only send what you want to change.

Request body (all optional)
{
  "title": "Updated title",
  "description": "New description",
  "status": "Closed",
  "priority": "High",
  "dueDate": "2026-05-01",
  "tags": ["backend"],
  "assigneeIds": ["uuid1"]
}
DELETE/projects/:id/tasks/:taskIdAdmin only

Delete a task permanently. Returns 204 No Content.

Task History

GET/projects/:id/tasks/:taskId/history

Returns an audit log of all changes to a task, newest first.

Response 200
[{
  "id": 7,
  "actorId": "uuid",
  "actorName": "Alice",
  "action": "StatusChanged",
  "detail": "New → Active",
  "createdAt": "2026-03-15T14:22:00Z"
}]

Invitations

When a project Admin invites a user by email, an invitation token is sent. These endpoints let you preview and accept that invitation.

GET/invitations/preview?token=<token>No auth required

Preview an invitation before accepting it. Useful for showing the user what project they are being invited to.

Response 200
{
  "projectName": "My Project",
  "email": "bob@example.com",
  "role": "Member",
  "expiresAt": "2026-04-01T00:00:00Z"
}
POST/invitations/accept?token=<token>

Accept an invitation. The authenticated user's email must match the invitation email. Returns the project the user was added to.

Response 200
{
  "projectId": 1,
  "projectName": "My Project"
}

API Tokens

Personal API tokens let you authenticate without a session. Tokens have a vt_ prefix and act as the authenticated user on all requests.

GET/apitokens

List your API tokens. The full token value is never returned after creation.

Response 200
[{
  "id": "uuid",
  "name": "CI Deploy",
  "tokenPrefix": "vt_abc123de",
  "isActive": true,
  "createdAt": "2026-03-01T12:00:00Z",
  "expiresAt": null
}]
POST/apitokens

Create a new token. Copy the token value immediately — it is only shown once.

Request body
{
  "name": "CI Deploy",       // required
  "expiresAt": "2027-01-01"  // optional
}
Response 201
{
  "id": "uuid",
  "name": "CI Deploy",
  "token": "vt_abc123...",  // full value, once only
  "createdAt": "2026-03-17T..."
}
DELETE/apitokens/:id

Revoke (delete) a token immediately. Any requests using that token will return 401.

Webhooks

Webhooks fire a POST request to your URL when task events occur. Requires Admin role.

GET/projects/:id/webhooks

List all webhooks registered for a project.

POST/projects/:id/webhooksAdmin only

Register a new webhook endpoint.

Request body
{
  "callbackUrl": "https://your-server.com/hook",
  "secret": "optional_hmac_secret"
}
PUT/projects/:id/webhooks/:webhookIdAdmin only

Update the URL or toggle a webhook on/off.

Request body (all optional)
{
  "callbackUrl": "https://new-url.com/hook",
  "isActive": false
}
DELETE/projects/:id/webhooks/:webhookIdAdmin only

Remove a webhook registration.

Data Models

TaskStatus
"New" | "Active" | "Blocked" | "Closed"
TaskPriority
"Low" | "Medium" | "High"
ProjectRole
"Admin" | "Member" | "Viewer"
Dates
ISO 8601 strings
e.g. "2026-03-17T12:00:00Z"
or   "2026-03-17" (date only)

Webhook Events

When an event fires, Vortask sends a POST to your registered URL with this payload. If you provided a secret, an X-Vortask-Signature header is included (HMAC-SHA256 of the body).

EventFired when
task.createdA new task is created
task.updatedAny task field is updated
task.deletedA task is deleted
Webhook POST payload
{
  "event": "task.updated",
  "projectId": 1,
  "task": {
    "id": 42,
    "title": "Deploy to production",
    "status": "Closed",
    "priority": "High",
    "assignees": [{ "email": "alice@example.com" }],
    "tags": ["backend"],
    "updatedAt": "2026-03-17T14:00:00Z"
  }
}