API Reference
Complete reference for the Todoify REST API. All endpoints return JSON and follow consistent error conventions.
Quick Start
Get up and running in two steps:
- Go to your Profile page and click Create API Key. Copy the key (shown only once).
- Use it as a Bearer token in your requests:
export TOKEN="tdf_your_key_here"
# List boards
curl -s -H "Authorization: Bearer $TOKEN" https://yourapp.com/api/boards | jq
# Create a todo
curl -s -X POST https://yourapp.com/api/boards/BOARD_ID/todos \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Buy groceries","priority":"high","column":"todo"}' | jqAuthentication
Bearer Token
Most endpoints accept a Bearer token. Create one from your Profile page under API Keys, then include it in the Authorization header:
Authorization: Bearer tdf_abc123...Cookie Auth
API key management endpoints (/api/api-keys) require cookie-based session authentication from the browser. Bearer tokens cannot be used to create or revoke API keys.
Errors
All errors follow a consistent format:
{
"error": {
"code": "NOT_FOUND",
"message": "Board not found"
}
}UNAUTHORIZED401 — Missing or invalid authenticationBAD_REQUEST400 — Invalid or missing request parametersNOT_FOUND404 — Resource does not exist or is not owned by youINTERNAL_ERROR500 — Unexpected server errorBoards
GET/api/boards
List all boards for the authenticated user. Includes a todo count for each board.
Response
[
{
"id": "board-uuid",
"name": "Work Tasks",
"description": "Sprint backlog",
"userId": "user-uuid",
"todoCount": 12,
"createdAt": "2026-03-01T00:00:00.000Z",
"updatedAt": "2026-03-30T00:00:00.000Z"
}
]curl
curl -H "Authorization: Bearer $TOKEN" \
https://yourapp.com/api/boardsPOST/api/boards
Create a new board.
Request Body
{
"name": "Work Tasks",
"description": "Optional description"
}Response
{
"id": "board-uuid",
"name": "Work Tasks",
"description": "Optional description",
"userId": "user-uuid",
"createdAt": "2026-04-01T00:00:00.000Z",
"updatedAt": "2026-04-01T00:00:00.000Z"
}curl
curl -X POST https://yourapp.com/api/boards \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Work Tasks","description":"Sprint backlog"}'PATCH/api/boards/:boardId
Update a board. Include only the fields you want to change.
Request Body
{
"name": "Renamed Board",
"description": "Updated description"
}Response
{
"id": "board-uuid",
"name": "Renamed Board",
"description": "Sprint backlog",
"userId": "user-uuid",
"createdAt": "2026-03-01T00:00:00.000Z",
"updatedAt": "2026-04-01T00:00:00.000Z"
}curl
curl -X PATCH https://yourapp.com/api/boards/BOARD_ID \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Renamed Board","description":"Updated description"}'DELETE/api/boards/:boardId
Delete a board and all its todos (cascade).
Response
{ "success": true }curl
curl -X DELETE https://yourapp.com/api/boards/BOARD_ID \
-H "Authorization: Bearer $TOKEN"Todos
GET/api/boards/:boardId/todos
List all todos for a board. Supports optional query filters.
Query Parameters
columnFilter by column. Comma-separated: todo,in-progress,pending,completedpriorityFilter by priority: high, medium, or lowcategoryFilter by category: work, personal, health, finance, or othersearchCase-insensitive search across title and descriptionResponse
{
"board": {
"id": "board-uuid",
"name": "Work Tasks",
"description": "Sprint backlog",
"userId": "user-uuid",
"createdAt": "2026-03-01T00:00:00.000Z",
"updatedAt": "2026-03-30T00:00:00.000Z"
},
"todos": [
{
"id": "todo-uuid",
"title": "Buy groceries",
"description": "",
"priority": "high",
"category": "personal",
"tags": ["errands"],
"column": "todo",
"order": 1,
"humanNotes": "",
"aiNotes": "",
"actionDay": "2026-04-02",
"color": null,
"boardId": "board-uuid",
"createdAt": "2026-04-01T00:00:00.000Z",
"updatedAt": "2026-04-01T00:00:00.000Z"
}
]
}curl
# All todos
curl -H "Authorization: Bearer $TOKEN" \
https://yourapp.com/api/boards/BOARD_ID/todos
# With filters
curl -H "Authorization: Bearer $TOKEN" \
"https://yourapp.com/api/boards/BOARD_ID/todos?column=todo,in-progress&priority=high"POST/api/boards/:boardId/todos
Create a new todo on a board.
Request Body
{
"title": "Buy groceries", // required
"description": "Milk, eggs, bread", // optional, default ""
"priority": "high", // optional: high | medium | low
"category": "personal", // optional: work | personal | health | finance | other
"tags": ["errands"], // optional, default []
"column": "todo", // optional: todo | in-progress | pending | completed
"actionDay": "2026-04-02" // optional, ISO date string
}Response
{
"id": "todo-uuid",
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"priority": "high",
"category": "personal",
"tags": ["errands"],
"column": "todo",
"order": 5,
"humanNotes": "",
"aiNotes": "",
"actionDay": "2026-04-02",
"color": null,
"boardId": "board-uuid",
"createdAt": "2026-04-01T00:00:00.000Z",
"updatedAt": "2026-04-01T00:00:00.000Z"
}curl
curl -X POST https://yourapp.com/api/boards/BOARD_ID/todos \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Buy groceries","priority":"high","column":"todo"}'PATCH/api/boards/:boardId/todos/:todoId
Update any fields on a todo. Only include the fields you want to change.
Request Body
{
"title": "Updated title",
"column": "completed",
"priority": "low"
}Response
Returns the full updated todo object.
curl
curl -X PATCH https://yourapp.com/api/boards/BOARD_ID/todos/TODO_ID \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"column":"completed"}'DELETE/api/boards/:boardId/todos/:todoId
Delete a todo.
Response
{ "success": true }curl
curl -X DELETE https://yourapp.com/api/boards/BOARD_ID/todos/TODO_ID \
-H "Authorization: Bearer $TOKEN"PATCH/api/boards/:boardId/todos/reorder
Reorder todos within a board by providing new order values.
Request Body
{
"updates": [
{ "id": "todo-uuid-1", "order": 1 },
{ "id": "todo-uuid-2", "order": 2 },
{ "id": "todo-uuid-3", "order": 3 }
]
}Response
{ "success": true }curl
curl -X PATCH https://yourapp.com/api/boards/BOARD_ID/todos/reorder \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"updates":[{"id":"todo-1","order":1},{"id":"todo-2","order":2}]}'AI Suggestions
POST/api/ai/suggestions
Get AI-powered suggestions for a todo. Requires the OpenRouter integration to be configured on the server.
Request Body
{
"title": "Build landing page", // required
"description": "For the new product", // optional
"humanNotes": "Keep it minimal", // optional
"existingNotes": "..." // optional, avoids repeating prior suggestions
}Response
{
"suggestions": "- Start with wireframes\n- Choose a color scheme\n- Implement responsive design"
}curl
curl -X POST https://yourapp.com/api/ai/suggestions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Build landing page","description":"For the new product"}'API Keys
These endpoints require cookie-based session authentication (browser login). Bearer tokens cannot be used to manage API keys.
GET/api/api-keys
List all API keys for the authenticated user. Never returns the raw key or its hash.
Response
[
{
"id": "key-uuid",
"name": "CLI Session",
"keyPrefix": "tdf_a1b2",
"lastUsedAt": "2026-03-30T12:00:00.000Z",
"expiresAt": null,
"createdAt": "2026-03-01T00:00:00.000Z"
}
]POST/api/api-keys
Create a new API key. The raw key is returned only once in the response.
Request Body
{
"name": "My CLI Key"
}Response
{
"id": "key-uuid",
"name": "My CLI Key",
"key": "tdf_a1b2c3d4e5f6...",
"keyPrefix": "tdf_a1b2",
"createdAt": "2026-04-01T00:00:00.000Z"
}DELETE/api/api-keys/:keyId
Revoke an API key. The key will immediately stop working for authentication.
Response
{ "success": true }