API Reference
A stateless, API-key authenticated REST API to read and write your Tascer projects, boards and tasks. The base route is a self-describing discovery document, so an automated client can learn the whole surface from a single call.
Quickstart
Call the base route first with your key. It returns the full, machine-readable map of every endpoint, its parameters and body schema — enough for a client (or an AI agent) to operate the API without any other documentation.
Recommended flow
- GET
/me— confirm which user this key belongs to. - GET
/projects— list the projects you can see. - GET
/boards?project_id=<id>— list boards in a project. - GET
/boards/<id>— fetch a board with its statuses, types, priorities and members. Use these ids when creating or updating tasks. - GET
/boards/<id>/tasks— list tasks (paginated, filterable). - POST
/boards/<id>/tasks— create a task (onlytitleis required). - PATCH / DELETE
/tasks/<id>— update or remove. Delete cascades comments and files.
curl -H "Authorization: Bearer tsk_your_key" \
https://your-host/apis/index.php
Authentication
Every request needs a valid Tascer API key. Generate one in the web app under API Keys — keys are shown once, scoped to your user, and can be revoked or given an expiry. A key inherits exactly the access of the user it belongs to.
Supply the key in one of three ways
| Method | Example | Recommended |
|---|---|---|
| Bearer header | Authorization: Bearer <API_KEY> | Yes |
| Custom header | X-API-Key: <API_KEY> | Yes |
| Query parameter | ?api_key=<API_KEY> | Avoid — leaks into logs |
Conventions
Consistent envelopes and rules across the whole API.
Response envelopes
Successful responses wrap the payload in data; paginated lists add meta. Errors always use a single error object.
{ "data": { /* object or array */ }, "meta": { "page": 1, "limit": 50, "total": 128 } }
{ "error": { "code": "validation_error", "message": "Status does not belong to this board.",
"details": { "field": "task_status_id" } } }
Rules
- Content type:
application/json; charset=utf-8. - Dates: returned as
Y-m-d H:i:s; inputs are parsed leniently (ISO 8601 accepted). - Pagination: list endpoints accept
limit(max 200) andpage(1-based); the total is inmeta.total. - Authorization: you only see and modify projects/boards/tasks you own or are a member of (admins see everything). Board-scoped ids (
task_status_id,task_type_id,task_priority_id,user_id) are validated against the target board on write.
Discovery & session
Returns the full, self-describing API map: auth, conventions, every endpoint with parameters and body schema, examples and error codes. Call it first.
The user this API key belongs to.
{ "data": { "user_id": 1, "username": "admin", "is_admin": true } }Projects
Lists the projects visible to you.
{ "data": [
{ "id": 7, "name": "Website Relaunch", "status": "active",
"url": "https://example.com", "created_at": "2026-05-01 10:15:00",
"modified_at": "2026-05-30 12:11:22", "created_by": 3 }
] }A single project. Returns 403 no_access if you are not a member, 404 not_found if it does not exist.
Boards
Lists boards visible to you.
| Query | Type | Required | Description |
|---|---|---|---|
project_id | integer | no | Restrict to one project. |
A board together with everything needed to create or update its tasks — statuses, types, priorities and members in one call.
{ "data": {
"id": 3, "title": "Testboard", "status": "1", "project_id": 3,
"statuses": [ { "id": 9, "title": "Todo", "color": "red", "last_step": 0 }, ... ],
"types": [ { "id": 5, "title": "task", "color": "", "icon": "" }, ... ],
"priorities": [ { "id": 3, "title": "normal", "color": "", "level_number": 1 } ],
"members": [ { "id": 2, "username": "Testuser" } ]
} }The individual lists, if you only need one of them. members are the valid task assignees for the board.
Lists tasks on a board, newest change first.
| Query | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | Page size, max 200. |
page | integer | 1 | 1-based page number. |
status_id | integer | — | Filter by task_status_id. |
updated_after | datetime | — | Only tasks modified at/after this time. |
fields | csv | all | Subset of task fields to return. |
{ "data": [ { /* task */ } ], "meta": { "page": 1, "limit": 50, "total": 12 } }Creates a task. Only title is required; board-scoped ids must belong to the board and user_id must be a board member.
| Field | Type | Required |
|---|---|---|
title | string | yes |
description | string | no |
deadline | datetime | null | no |
estimated_time · taken_time | number | no |
task_status_id · task_type_id · task_priority_id | integer (board-scoped) | no |
user_id | integer (board member; defaults to you) | no |
{ "title": "Landingpage QA", "description": "Check mobile spacing",
"task_status_id": 9, "task_priority_id": 3, "user_id": 2 }{ "data": {
"id": 42, "title": "Landingpage QA", "description": "Check mobile spacing",
"estimated_time": 0, "taken_time": 0, "deadline": null,
"created_at": "2026-07-12 20:07:39", "modified_at": "2026-07-12 20:07:39",
"task_status_id": 9, "task_type_id": 5, "task_priority_id": 3,
"user_id": 2, "board_id": 3 } }Tasks
A single task with all fields.
Partial update — send only the fields to change. Board-scoped ids are validated against the task's board. Returns the full updated task.
{ "task_status_id": 12, "taken_time": 1.75 }Deletes the task and cascades its comments, attached files (also removed from disk) and view records.
{ "data": { "deleted": true, "id": 42 } }Comments
Comments on a task, oldest first.
{ "data": [ { "id": 8, "comment": "hello from API",
"created_at": "2026-07-12 20:07:39", "user_id": 1, "username": "admin" } ] }Adds a comment. Body: { "comment": "text" }. Returns the created comment (201).
Errors
Every error uses the error envelope with a stable machine code.
| Status | Code | Meaning |
|---|---|---|
| 401 | missing_api_key | No key supplied. |
| 401 | invalid_api_key | Key unknown, revoked or expired. |
| 403 | no_access | Not allowed to access this object. |
| 404 | not_found | Object or route does not exist. |
| 405 | method_not_allowed | Route exists, but not for this HTTP method. |
| 422 | validation_error | Payload failed validation (see details). |
| 400 | invalid_json | Request body was not valid JSON. |
| 500 | server_error | Unexpected failure. |
Live explorer
Send a real request against this instance. Your key is used only in your browser to make the call — it is never stored.