mirror of
https://github.com/callumalpass/tasknotes.git
synced 2026-07-22 12:50:26 +00:00
## OpenAPI Specification - Add decorator-based OpenAPI system with @OpenAPIController and @OpenAPI decorators - Generate machine-readable OpenAPI 3.0 spec at /api/docs - Serve interactive Swagger UI documentation at /api/docs/ui - Complete schema definitions for all API types and responses - Enable TypeScript experimental decorators support ## Pomodoro API Endpoints - POST /api/pomodoro/start - Start new pomodoro session with optional task - POST /api/pomodoro/stop - Stop current session - POST /api/pomodoro/pause - Pause running session - POST /api/pomodoro/resume - Resume paused session - GET /api/pomodoro/status - Get current session status and statistics - GET /api/pomodoro/sessions - Get session history with filtering - GET /api/pomodoro/stats - Get daily/date-specific statistics ## Documentation Updates - Add comprehensive HTTP API documentation with pomodoro examples - Include JavaScript PomodoroController integration example - Update feature documentation with view types and settings - Improve navigation structure across documentation files ## Dependencies - Add reflect-metadata for decorator metadata support - Remove unused express dependency - Update TypeScript configuration for decorator support All endpoints include proper error handling, OpenAPI documentation, and support for recurring task integration.
575 lines
11 KiB
Markdown
575 lines
11 KiB
Markdown
# TaskNotes HTTP API
|
|
|
|
The TaskNotes HTTP API allows external applications to interact with your TaskNotes data. This enables powerful integrations with browsers, automation tools, mobile apps, and custom scripts.
|
|
|
|
## Quick Start
|
|
|
|
1. **Enable API**: Go to TaskNotes Settings → HTTP API tab (desktop only)
|
|
2. **Configure**: Set port (default 8080) and optional auth token
|
|
3. **Restart**: Restart Obsidian to start the server
|
|
4. **Test**: `curl http://localhost:8080/api/health`
|
|
5. **Explore**: Visit `http://localhost:8080/api/docs/ui` for interactive documentation
|
|
|
|
## Interactive Documentation
|
|
|
|
TaskNotes provides comprehensive API documentation through Swagger UI:
|
|
|
|
- **OpenAPI Specification**: `GET /api/docs` - Machine-readable API spec in OpenAPI 3.0 format
|
|
- **Interactive Docs**: `GET /api/docs/ui` - Swagger UI for exploring and testing endpoints
|
|
|
|
The interactive documentation includes:
|
|
- Complete endpoint documentation with examples
|
|
- Request/response schemas
|
|
- Try-it-out functionality for testing endpoints
|
|
- Authentication setup for protected endpoints
|
|
|
|
## Authentication
|
|
|
|
### Optional Bearer Token
|
|
```bash
|
|
# Set token in settings, then use in requests:
|
|
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8080/api/tasks
|
|
```
|
|
|
|
### No Authentication
|
|
If no token is configured, all requests are allowed from localhost.
|
|
|
|
## Base URL
|
|
```
|
|
http://localhost:{PORT}/api
|
|
```
|
|
Default port is 8080 (configurable in settings).
|
|
|
|
## Response Format
|
|
|
|
All endpoints return JSON in this format:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": { /* response data */ },
|
|
"message": "optional success message"
|
|
}
|
|
```
|
|
|
|
Error responses:
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": "Error description"
|
|
}
|
|
```
|
|
|
|
## Endpoints
|
|
|
|
### Health Check
|
|
```
|
|
GET /api/health
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"status": "ok",
|
|
"timestamp": "2025-08-12T10:30:00.000Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Tasks
|
|
|
|
#### List Tasks
|
|
```
|
|
GET /api/tasks
|
|
```
|
|
|
|
**Query Parameters:**
|
|
|
|
- `status` - Filter by status (e.g., "open", "completed")
|
|
- `priority` - Filter by priority (e.g., "High", "Normal")
|
|
- `project` - Filter by project name (partial match)
|
|
- `tag` - Filter by tag (partial match)
|
|
- `overdue` - "true" for overdue tasks only
|
|
- `completed` - "true" or "false"
|
|
- `archived` - "true" or "false"
|
|
- `due_before` - ISO date (e.g., "2025-08-15")
|
|
- `due_after` - ISO date
|
|
- `sort` - Field to sort by (e.g., "due:asc", "priority:desc")
|
|
- `limit` - Max number of results
|
|
- `offset` - Skip this many results
|
|
|
|
**Examples:**
|
|
```bash
|
|
# All active tasks
|
|
curl "http://localhost:8080/api/tasks?completed=false&archived=false"
|
|
|
|
# High priority overdue tasks
|
|
curl "http://localhost:8080/api/tasks?priority=High&overdue=true"
|
|
|
|
# Tasks due this week, sorted by due date
|
|
curl "http://localhost:8080/api/tasks?due_before=2025-08-19&sort=due:asc"
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"tasks": [
|
|
{
|
|
"path": "TaskNotes/Tasks/sample-task.md",
|
|
"title": "Review quarterly budget",
|
|
"status": "open",
|
|
"priority": "High",
|
|
"due": "2025-08-15",
|
|
"scheduled": "2025-08-14",
|
|
"tags": ["work", "finance"],
|
|
"projects": ["[[Q3 Planning]]"],
|
|
"contexts": ["@office"],
|
|
"dateCreated": "2025-08-10T09:00:00.000Z",
|
|
"dateModified": "2025-08-10T09:00:00.000Z"
|
|
}
|
|
],
|
|
"total": 150,
|
|
"filtered": 1
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Create Task
|
|
|
|
```
|
|
POST /api/tasks
|
|
```
|
|
|
|
**Request Body:**
|
|
|
|
```json
|
|
{
|
|
"title": "New task title",
|
|
"priority": "High",
|
|
"status": "open",
|
|
"due": "2025-08-15",
|
|
"scheduled": "2025-08-14",
|
|
"tags": ["email", "urgent"],
|
|
"projects": ["[[Work Project]]"],
|
|
"contexts": ["@computer"],
|
|
"details": "Additional task description",
|
|
"timeEstimate": 60
|
|
}
|
|
```
|
|
|
|
**Required Fields:**
|
|
|
|
- `title` - Task title (max 200 characters)
|
|
|
|
**Optional Fields:**
|
|
|
|
- `priority` - Task priority
|
|
- `status` - Task status
|
|
- `due` - Due date (ISO format)
|
|
- `scheduled` - Scheduled date (ISO format)
|
|
- `tags` - Array of tag strings
|
|
- `projects` - Array of project links
|
|
- `contexts` - Array of context strings
|
|
- `details` - Task description/details
|
|
- `timeEstimate` - Estimated time in minutes
|
|
|
|
#### Get Single Task
|
|
|
|
```
|
|
GET /api/tasks/{id}
|
|
```
|
|
|
|
Where `{id}` is the task file path (URL-encoded).
|
|
|
|
#### Update Task
|
|
|
|
```
|
|
PUT /api/tasks/{id}
|
|
```
|
|
|
|
**Request Body:** Same format as create task, with partial updates supported.
|
|
|
|
#### Delete Task
|
|
|
|
```
|
|
DELETE /api/tasks/{id}
|
|
```
|
|
|
|
### Time Tracking
|
|
|
|
#### Start Time Tracking
|
|
|
|
```
|
|
POST /api/tasks/{id}/time/start
|
|
```
|
|
|
|
#### Stop Time Tracking
|
|
|
|
```
|
|
POST /api/tasks/{id}/time/stop
|
|
```
|
|
|
|
### Task Actions
|
|
|
|
#### Toggle Status
|
|
|
|
```
|
|
POST /api/tasks/{id}/toggle-status
|
|
```
|
|
|
|
Toggles between open/completed status.
|
|
|
|
#### Toggle Archive
|
|
|
|
```
|
|
POST /api/tasks/{id}/archive
|
|
```
|
|
|
|
Archives or unarchives the task.
|
|
|
|
#### Complete Recurring Instance
|
|
|
|
```
|
|
POST /api/tasks/{id}/complete-instance
|
|
```
|
|
|
|
|
|
**Request Body:**
|
|
|
|
```json
|
|
{
|
|
"date": "2025-08-12"
|
|
}
|
|
```
|
|
|
|
### Advanced Queries
|
|
|
|
#### Query Tasks
|
|
|
|
```
|
|
POST /api/tasks/query
|
|
```
|
|
|
|
|
|
**Request Body:** Advanced FilterQuery object (see TaskNotes FilterQuery documentation).
|
|
|
|
#### Get Filter Options
|
|
|
|
```
|
|
GET /api/filter-options
|
|
```
|
|
|
|
Returns available tags, projects, statuses, and priorities for building filter UIs.
|
|
|
|
### Statistics
|
|
|
|
#### Get Task Statistics
|
|
|
|
```
|
|
GET /api/stats
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"total": 245,
|
|
"completed": 189,
|
|
"active": 45,
|
|
"overdue": 8,
|
|
"archived": 11,
|
|
"withTimeTracking": 67
|
|
}
|
|
}
|
|
```
|
|
|
|
### Pomodoro
|
|
|
|
Control pomodoro sessions programmatically through the API.
|
|
|
|
#### Start Pomodoro Session
|
|
|
|
```
|
|
POST /api/pomodoro/start
|
|
```
|
|
|
|
**Request Body (Optional):**
|
|
|
|
```json
|
|
{
|
|
"taskId": "path/to/task.md"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"session": {
|
|
"id": "pomo_123",
|
|
"type": "work",
|
|
"duration": 1500,
|
|
"startTime": "2025-08-13T10:00:00.000Z"
|
|
},
|
|
"task": {
|
|
"id": "path/to/task.md",
|
|
"title": "Work on API integration"
|
|
},
|
|
"message": "Pomodoro session started"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Stop Pomodoro Session
|
|
|
|
```
|
|
POST /api/pomodoro/stop
|
|
```
|
|
|
|
#### Pause Pomodoro Session
|
|
|
|
```
|
|
POST /api/pomodoro/pause
|
|
```
|
|
|
|
#### Resume Pomodoro Session
|
|
|
|
```
|
|
POST /api/pomodoro/resume
|
|
```
|
|
|
|
#### Get Pomodoro Status
|
|
|
|
```
|
|
GET /api/pomodoro/status
|
|
```
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"isRunning": true,
|
|
"timeRemaining": 900,
|
|
"currentSession": {
|
|
"id": "pomo_123",
|
|
"type": "work",
|
|
"duration": 1500,
|
|
"startTime": "2025-08-13T10:00:00.000Z"
|
|
},
|
|
"totalPomodoros": 42,
|
|
"currentStreak": 3,
|
|
"totalMinutesToday": 180
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Get Pomodoro Session History
|
|
|
|
```
|
|
GET /api/pomodoro/sessions
|
|
```
|
|
|
|
**Query Parameters:**
|
|
|
|
- `limit` - Maximum number of sessions to return
|
|
- `date` - Filter sessions by date (YYYY-MM-DD)
|
|
|
|
**Examples:**
|
|
|
|
```bash
|
|
# Get last 10 sessions
|
|
curl "http://localhost:8080/api/pomodoro/sessions?limit=10"
|
|
|
|
# Get sessions for specific date
|
|
curl "http://localhost:8080/api/pomodoro/sessions?date=2025-08-13"
|
|
```
|
|
|
|
#### Get Pomodoro Statistics
|
|
|
|
```
|
|
GET /api/pomodoro/stats
|
|
```
|
|
|
|
**Query Parameters:**
|
|
|
|
- `date` - Get stats for specific date (YYYY-MM-DD), defaults to today
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"totalSessions": 15,
|
|
"completedSessions": 12,
|
|
"interruptedSessions": 3,
|
|
"totalFocusTime": 300,
|
|
"workSessions": 10,
|
|
"breakSessions": 5,
|
|
"longestStreak": 8,
|
|
"averageSessionLength": 24.5
|
|
}
|
|
}
|
|
```
|
|
|
|
## Integration Examples
|
|
|
|
### Browser Bookmarklet
|
|
|
|
```javascript
|
|
javascript:(function(){
|
|
const title = document.title;
|
|
const url = window.location.href;
|
|
|
|
fetch('http://localhost:8080/api/tasks', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({
|
|
title: `Review: ${title}`,
|
|
tags: ['web'],
|
|
details: `Source: ${url}`
|
|
})
|
|
}).then(r => r.json()).then(d => {
|
|
alert(d.success ? 'Task created!' : 'Error: ' + d.error);
|
|
});
|
|
})();
|
|
```
|
|
|
|
### Python Script
|
|
|
|
```python
|
|
import requests
|
|
|
|
def create_task(title, **kwargs):
|
|
response = requests.post('http://localhost:8080/api/tasks',
|
|
json={'title': title, **kwargs})
|
|
return response.json()
|
|
|
|
# Create task from command line
|
|
task = create_task("Call dentist", priority="High", due="2025-08-15")
|
|
print(f"Created task: {task['data']['title']}")
|
|
```
|
|
|
|
### Automation (Zapier/IFTTT)
|
|
|
|
```bash
|
|
# Webhook URL for automation services
|
|
curl -X POST http://localhost:8080/api/tasks \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"title":"{{trigger.subject}}", "tags":["email"], "details":"{{trigger.body}}"}'
|
|
```
|
|
|
|
### Pomodoro Timer Integration
|
|
|
|
```javascript
|
|
// Simple Pomodoro timer controller
|
|
class PomodoroController {
|
|
constructor(apiUrl = 'http://localhost:8080') {
|
|
this.apiUrl = apiUrl;
|
|
}
|
|
|
|
async startSession(taskId = null) {
|
|
const body = taskId ? { taskId } : {};
|
|
const response = await fetch(`${this.apiUrl}/api/pomodoro/start`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body)
|
|
});
|
|
return response.json();
|
|
}
|
|
|
|
async getStatus() {
|
|
const response = await fetch(`${this.apiUrl}/api/pomodoro/status`);
|
|
return response.json();
|
|
}
|
|
|
|
async pause() {
|
|
const response = await fetch(`${this.apiUrl}/api/pomodoro/pause`, {
|
|
method: 'POST'
|
|
});
|
|
return response.json();
|
|
}
|
|
|
|
async resume() {
|
|
const response = await fetch(`${this.apiUrl}/api/pomodoro/resume`, {
|
|
method: 'POST'
|
|
});
|
|
return response.json();
|
|
}
|
|
|
|
async stop() {
|
|
const response = await fetch(`${this.apiUrl}/api/pomodoro/stop`, {
|
|
method: 'POST'
|
|
});
|
|
return response.json();
|
|
}
|
|
}
|
|
|
|
// Usage
|
|
const pomodoro = new PomodoroController();
|
|
|
|
// Start a session for a specific task
|
|
await pomodoro.startSession('Projects/MyProject.md');
|
|
|
|
// Check current status
|
|
const status = await pomodoro.getStatus();
|
|
console.log(`Time remaining: ${Math.floor(status.data.timeRemaining / 60)} minutes`);
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
### Common Errors
|
|
|
|
- `400 Bad Request` - Invalid request data
|
|
- `401 Unauthorized` - Invalid or missing auth token
|
|
- `404 Not Found` - Task not found
|
|
- `500 Internal Server Error` - Server error
|
|
|
|
### Rate Limiting
|
|
|
|
No rate limiting currently implemented. Use responsibly.
|
|
|
|
### CORS
|
|
|
|
CORS is enabled for all origins (`*`). API is intended for localhost use only.
|
|
|
|
## Security Notes
|
|
|
|
- **Localhost Only**: API server only accepts connections from localhost
|
|
- **Desktop Only**: API is not available on mobile platforms
|
|
- **Optional Auth**: Bearer token authentication is optional but recommended
|
|
- **No HTTPS**: Traffic is unencrypted (localhost only)
|
|
|
|
## Troubleshooting
|
|
|
|
### API Not Starting
|
|
|
|
1. Check that API is enabled in settings
|
|
2. Ensure port is not in use by another application
|
|
3. Try different port (1024-65535)
|
|
4. Check Obsidian console for errors
|
|
|
|
### Connection Refused
|
|
|
|
1. Verify API is enabled and Obsidian is running
|
|
2. Check correct port number
|
|
3. Ensure using `http://` not `https://`
|
|
4. Try `127.0.0.1` instead of `localhost`
|
|
|
|
### Authentication Errors
|
|
|
|
1. Verify token matches exactly (case-sensitive)
|
|
2. Include `Bearer ` prefix in Authorization header
|
|
3. Check for trailing spaces in token
|
|
|
|
|