TaskNotes HTTP API
The TaskNotes HTTP API provides local HTTP access to tasks, time tracking, pomodoro, calendars, webhooks, and NLP parsing.
Availability
- Desktop only
- Disabled by default
- Started when Obsidian starts and TaskNotes API is enabled
- Not available on mobile
Enable it in Settings -> TaskNotes -> Integrations -> HTTP API.
Base URL
http://localhost:{PORT}
Default port is 8080.
Authentication
Authentication is optional.
- If
apiAuthTokenis empty, all API requests are accepted. - If
apiAuthTokenis set, sendAuthorization: Bearer <token>.
Example:
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8080/api/health
Response Format
Success:
{
"success": true,
"data": {}
}
Error:
{
"success": false,
"error": "Error message"
}
Endpoint Index
System
GET /api/healthGET /api/docsGET /api/docs/uiPOST /api/nlp/parsePOST /api/nlp/create
Tasks
GET /api/tasksPOST /api/tasksGET /api/tasks/:idPUT /api/tasks/:idDELETE /api/tasks/:idPOST /api/tasks/:id/toggle-statusPOST /api/tasks/:id/archivePOST /api/tasks/:id/complete-instancePOST /api/tasks/queryGET /api/filter-optionsGET /api/stats
Time Tracking
POST /api/tasks/:id/time/startPOST /api/tasks/:id/time/start-with-descriptionPOST /api/tasks/:id/time/stopGET /api/tasks/:id/timeGET /api/time/activeGET /api/time/summary
Pomodoro
POST /api/pomodoro/startPOST /api/pomodoro/stopPOST /api/pomodoro/pausePOST /api/pomodoro/resumeGET /api/pomodoro/statusGET /api/pomodoro/sessionsGET /api/pomodoro/stats
Calendars
GET /api/calendarsGET /api/calendars/googleGET /api/calendars/microsoftGET /api/calendars/subscriptionsGET /api/calendars/events
Webhooks
POST /api/webhooksGET /api/webhooksDELETE /api/webhooks/:idGET /api/webhooks/deliveries
See docs/webhooks.md for event and transform details.
Route Details
Health
GET /api/health
Returns service state plus vault metadata.
curl http://localhost:8080/api/health
Tasks
GET /api/tasks
Basic task listing with pagination only.
Query params:
limit(default50, max200)offset(default0)
Important:
- Filtering params such as
status,priority,tag,project,due_before,due_after,overdue,completed,archived, andsortare rejected on this endpoint with HTTP400. - Use
POST /api/tasks/queryfor filtering.
Example:
curl "http://localhost:8080/api/tasks?limit=25&offset=0"
Response fields:
data.tasksdata.paginationwithtotal,offset,limit,hasMoredata.vaultdata.note
POST /api/tasks
Create one task.
Required:
title
Common optional fields:
details,status,priority,due,scheduledtags,contexts,projectsrecurrence,timeEstimate
curl -X POST http://localhost:8080/api/tasks \
-H "Content-Type: application/json" \
-d '{"title":"Review docs","priority":"high"}'
Returns HTTP 201 with created task data.
GET /api/tasks/:id
Get one task by path id.
:idmust be URL-encoded task path.
curl "http://localhost:8080/api/tasks/TaskNotes%2FTasks%2FReview%20docs.md"
PUT /api/tasks/:id
Update task with partial payload.
curl -X PUT "http://localhost:8080/api/tasks/TaskNotes%2FTasks%2FReview%20docs.md" \
-H "Content-Type: application/json" \
-d '{"status":"in-progress"}'
DELETE /api/tasks/:id
Delete task file.
POST /api/tasks/:id/toggle-status
Toggle task status via configured workflow.
POST /api/tasks/:id/archive
Toggle archive state.
POST /api/tasks/:id/complete-instance
Complete recurring instance.
Request body:
- Optional
date(ISO string). If omitted, uses current date context.
POST /api/tasks/query
Advanced filtering.
Request body is a FilterQuery object. Root object is a group with:
type: "group"idconjunction: "and" | "or"children(conditions or groups)
Optional top-level query options:
sortKey,sortDirectiongroupKey,subgroupKey
Example:
{
"type": "group",
"id": "root",
"conjunction": "and",
"children": [
{
"type": "condition",
"id": "c1",
"property": "status",
"operator": "is",
"value": "open"
}
],
"sortKey": "due",
"sortDirection": "asc"
}
Response:
data.tasksdata.totaldata.filtereddata.vault
GET /api/filter-options
Returns filter options for UI builders.
GET /api/stats
Returns summary counts:
total,completed,active,overdue,archived,withTimeTracking
Time Tracking
POST /api/tasks/:id/time/start
Starts a new active time entry for that task.
POST /api/tasks/:id/time/start-with-description
Starts time tracking and writes description on the new active entry.
Request body:
{
"description": "Implementation"
}
POST /api/tasks/:id/time/stop
Stops active time entry for that task.
GET /api/tasks/:id/time
Returns per-task time summary and entries.
GET /api/time/active
Returns currently active sessions across tasks.
Important:
- Multiple active sessions can exist across different tasks.
GET /api/time/summary
Returns aggregate time summary.
Query params:
period(for exampletoday,week,month,all)from(ISO date)to(ISO date)
Example:
curl "http://localhost:8080/api/time/summary?period=week"
Pomodoro
POST /api/pomodoro/start
Starts a session.
Optional request fields:
taskId(URL path of task)duration(number)
POST /api/pomodoro/stop
Stops and resets current session.
POST /api/pomodoro/pause
Pauses running session.
POST /api/pomodoro/resume
Resumes paused session.
GET /api/pomodoro/status
Returns current state plus computed totals (totalPomodoros, currentStreak, totalMinutesToday).
GET /api/pomodoro/sessions
Returns history.
Query params:
limitdate(YYYY-MM-DD)
GET /api/pomodoro/stats
Returns stats for today or provided date.
Query params:
date(YYYY-MM-DD)
Calendars
GET /api/calendars
Returns provider connectivity overview and subscription counts.
GET /api/calendars/google
Returns Google provider details.
- If disconnected, returns
{ "connected": false }.
GET /api/calendars/microsoft
Returns Microsoft provider details.
- If disconnected, returns
{ "connected": false }.
GET /api/calendars/subscriptions
Returns ICS subscriptions with runtime fields such as lastFetched and lastError.
GET /api/calendars/events
Returns merged event list from connected providers and ICS subscriptions.
Query params:
start(ISO date/datetime)end(ISO date/datetime)
Response includes:
eventstotalsources(counts by provider)
Webhooks
POST /api/webhooks
Registers webhook.
Required fields:
urlevents(non-empty array)
Optional fields:
idsecretactivetransformFilecorsHeaders
GET /api/webhooks
Lists registered webhooks. Stored secrets are not returned.
DELETE /api/webhooks/:id
Deletes webhook.
GET /api/webhooks/deliveries
Returns last 100 delivery records.
OpenAPI Docs
GET /api/docs
Returns OpenAPI JSON generated from registered controllers.
GET /api/docs/ui
Returns Swagger UI.
Errors
Common status codes:
400invalid request or invalid state401missing/invalid bearer token (when auth token is configured)404missing task/webhook/resource500internal error
Security Notes
Current behavior:
- CORS allows all origins (
*). - Transport is HTTP only (no TLS).
- Node server is started with
server.listen(port)and does not explicitly bind to127.0.0.1.
Practical guidance:
- Set an auth token.
- Treat API port as sensitive and keep it firewalled.
- If you expose this port outside localhost, route through a trusted reverse proxy and TLS.
Troubleshooting
API unavailable
- Confirm API is enabled in settings.
- Confirm Obsidian is running.
- Confirm selected port is free.
- Reload plugin or restart Obsidian after changing API enable/port.
401 Authentication required
- Check token value.
- Check
Bearerprefix. - Remove whitespace around token.
Unexpected task list behavior
If you pass filters to GET /api/tasks, the endpoint returns 400 by design. Use POST /api/tasks/query.