Authentication
Every request must include your personal API token as a Bearer token in the Authorization header. There are no other authentication methods.
1 - Get your token
Log in to Todo4you, go to Profile - API Access , and click Generate token . Your token is a 64-character hex string. Copy it immediately - it is only displayed once.
Profile → API Access
2 - Include the header
Copy Authorization: Bearer YOUR_64_CHAR_TOKEN
3 - Test your token
Paste your token below to verify it works and preview your project list:
Errors
All errors return JSON with an error field describing the problem. Successful responses never include an error field.
Copy // 422 example
{ "error" : "title is required." }
Status Meaning
401 Missing or invalid API token
403 Token valid but role insufficient for this action (viewer trying to create/move)
404 Project or ticket not found, or not accessible with your token
422 Validation failed - read the error message for the exact field
Projects
List projects
Returns all projects the authenticated user owns or is a member of, sorted alphabetically. Use the id field for all subsequent requests that need a project ID. The role field is the calling user's role on the project (manager, editor, contributor or viewer) and docs_enabled indicates whether the documentation area is turned on for the project.
Response
200 OK 200
Copy {
"projects" : [
{
"id" : 12 ,
"name" : "My Project" ,
"prefix" : "TDL" ,
"description" : "Main development board" ,
"role" : "manager" ,
"docs_enabled" : true
}
]
}
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/projects \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch('https://api.todo4you.com/api/v1/projects' , {
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
const { projects } = await res.json();
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$projects = $data['projects' ];
Copy import requests
data = requests.get(
'https://api.todo4you.com/api/v1/projects' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
Create project
Creates a new project. You will automatically become the project owner with manager role.
Request body (JSON)
Field Type Description
name
string
required
Project name (min 2 characters)
prefix
string
optional
Ticket prefix, e.g. TDL. Alphanumeric only, auto-uppercased
description
string
optional
Short project description
Response
201 Created 201
Copy {
"project" : {
"id" : 25 ,
"name" : "My New Project" ,
"prefix" : "MNP" ,
"description" : "A fresh project"
}
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"My New Project","prefix":"MNP","description":"A fresh project"}'
Copy const { project } = await (await fetch(
'https://api.todo4you.com/api/v1/projects' ,
{
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ name: 'My New Project' , prefix: 'MNP' } ),
} ,
)).json();
Copy $payload = json_encode (['name' => 'My New Project' , 'prefix' => 'MNP' ]);
$ch = curl_init ('https://api.todo4you.com/api/v1/projects' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$project = $data['project' ];
Copy import requests
resp = requests.post(
'https://api.todo4you.com/api/v1/projects' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'name' : 'My New Project' , 'prefix' : 'MNP' } ,
)
project = resp.json()['project' ]
Project stats
Returns the number of open tickets in a project (all statuses except done). Useful for condition checks and dashboards.
Path parameters
Response
200 OK 200
Copy { "open_tickets" : 14 }
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/projects/12/stats \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const { open_tickets } = await (await fetch(
'https://api.todo4you.com/api/v1/projects/12/stats' ,
{ headers: { Authorization : `Bearer ${TOKEN}` } } ,
)).json();
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/stats' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$openTickets = $data['open_tickets' ];
Copy import requests
data = requests.get(
'https://api.todo4you.com/api/v1/projects/12/stats' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
open_tickets = data['open_tickets' ]
Project statuses
Returns the valid status values for a project. Pass one of these to Move ticket .
Path parameters
Param Type Description
id integer Project ID
Response
200 OK 200
Copy {
"statuses" : [
{ "slug" : "backlog" , "label" : "Backlog" , "color" : "#6c757d" , "icon" : "fa-inbox" , "category" : "backlog" } ,
{ "slug" : "todo" , "label" : "To Do" , "color" : "#0dcaf0" , "icon" : "fa-list-ul" , "category" : "todo" } ,
{ "slug" : "in_progress" , "label" : "In Progress" , "color" : "#ffc107" , "icon" : "fa-tasks" , "category" : "active" } ,
{ "slug" : "review" , "label" : "Review" , "color" : "#0d6efd" , "icon" : "fa-eye" , "category" : "review" } ,
{ "slug" : "done" , "label" : "Done" , "color" : "#198754" , "icon" : "fa-check-circle" , "category" : "done" }
]
}
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/projects/12/statuses \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const { statuses } = await (await fetch(
'https://api.todo4you.com/api/v1/projects/12/statuses' ,
{ headers: { Authorization : `Bearer ${TOKEN}` } } ,
)).json();
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/statuses' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$statuses = $data['statuses' ];
Copy import requests
data = requests.get(
'https://api.todo4you.com/api/v1/projects/12/statuses' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
statuses = data['statuses' ]
List members
Returns all members of a project with their roles. Use the id values when assigning tickets via Assign member .
Path parameters
Param Type Description
id integer Project ID
Response
200 OK 200
Copy {
"members" : [
{ "id" : 3 , "name" : "Alice" , "avatar" : null , "role" : "manager" } ,
{ "id" : 8 , "name" : "Bob" , "avatar" : null , "role" : "developer" }
]
}
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/projects/12/members \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const { members } = await (await fetch(
'https://api.todo4you.com/api/v1/projects/12/members' ,
{ headers: { Authorization : `Bearer ${TOKEN}` } } ,
)).json();
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/members' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$members = $data['members' ];
Copy import requests
data = requests.get(
'https://api.todo4you.com/api/v1/projects/12/members' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
members = data['members' ]
Tickets
List tickets
Returns all non-archived tickets in a project. Optionally filter by status column. Each ticket includes its tags and a prefix_ref field (e.g. TDL-47).
Path parameters
Param Type Description
id integer Project ID
Query parameters
Param Type Description
status
string
optional
Filter by status slug (use GET /projects/{id}/statuses to get valid slugs)
Response
200 OK 200
Copy {
"tickets" : [
{
"id" : 301 ,
"project_ticket_number" : 47 ,
"prefix_ref" : "TDL-47" ,
"title" : "Fix login bug" ,
"status" : "in_progress" ,
"type" : "bug" ,
"priority" : "high" ,
"deadline" : "2026-03-15" ,
"tags" : [
{ "id" : 5 , "name" : "frontend" , "color" : "#e74c3c" }
] ,
"created_at" : "2026-03-01 14:22:00"
}
]
}
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/projects/12/tickets?status=in_progress \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const { tickets } = await (await fetch(
'https://api.todo4you.com/api/v1/projects/12/tickets?status=in_progress' ,
{ headers: { Authorization : `Bearer ${TOKEN}` } } ,
)).json();
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets?status=in_progress' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$tickets = $data['tickets' ];
Copy import requests
data = requests.get(
'https://api.todo4you.com/api/v1/projects/12/tickets' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
params={ 'status' : 'in_progress' } ,
).json()
tickets = data['tickets' ]
Get ticket
Returns full ticket details including comments, checklist items, tags, assignees, and creator. The number is the per-project ticket number - the numeric part of a ref like TDL-47.
Path parameters
Param Type Description
id integer Project ID
number integer Ticket number within the project (e.g. 47 for TDL-47)
Response
200 OK 200
Copy {
"ticket" : {
"id" : 301 ,
"prefix_ref" : "TDL-47" ,
"title" : "Fix login bug" ,
"status" : "in_progress" ,
"type" : "bug" ,
"priority" : "high" ,
"deadline" : "2026-03-15" ,
"tags" : [
{ "id" : 5 , "name" : "frontend" , "color" : "#e74c3c" }
] ,
"comments" : [
{
"id" : 291 ,
"message" : "Found the root cause" ,
"user_id" : 8 ,
"user_name" : "Alice" ,
"created_at" : "2026-03-02 09:15:00"
}
] ,
"checklist" : [
{ "id" : 10 , "text" : "Write tests" , "done" : 0 } ,
{ "id" : 11 , "text" : "Update docs" , "done" : 1 }
] ,
"assignees" : [
{ "id" : 8 , "name" : "Alice" }
] ,
"creator" : { "id" : 3 , "name" : "Bob" }
}
}
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/projects/12/tickets/47 \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const { ticket } = await (await fetch(
'https://api.todo4you.com/api/v1/projects/12/tickets/47' ,
{ headers: { Authorization : `Bearer ${TOKEN}` } } ,
)).json();
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets/47' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$ticket = $data['ticket' ];
Copy import requests
data = requests.get(
'https://api.todo4you.com/api/v1/projects/12/tickets/47' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
ticket = data['ticket' ]
Search tickets
Searches non-archived tickets by keyword. Matches against the ticket title and description (case-insensitive). Returns results ordered by most recently updated first.
Path parameters
Param Type Description
id integer Project ID
Query parameters
Param Type Description
q
string
required
Search keyword(s) to match against title and description
Response
200 OK 200
Copy {
"tickets" : [
{
"id" : 301 ,
"project_ticket_number" : 47 ,
"prefix_ref" : "TDL-47" ,
"title" : "Fix login bug" ,
"status" : "in_progress" ,
"type" : "bug" ,
"tags" : [
{ "id" : 5 , "name" : "frontend" , "color" : "#e74c3c" }
]
}
]
}
Example
cURL
JavaScript
PHP
Python
Copy curl "https://api.todo4you.com/api/v1/projects/12/tickets/search?q=login" \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const { tickets } = await (await fetch(
`https://api.todo4you.com/api/v1/projects/12/tickets/search?q=${encodeURIComponent('login')}` ,
{ headers: { Authorization : `Bearer ${TOKEN}` } } ,
)).json();
Copy $q = urlencode ('login' );
$ch = curl_init ("https://api.todo4you.com/api/v1/projects/12/tickets/search?q={$q}" );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$tickets = $data['tickets' ];
Copy import requests
data = requests.get(
'https://api.todo4you.com/api/v1/projects/12/tickets/search' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
params={ 'q' : 'login' } ,
).json()
tickets = data['tickets' ]
Tickets
Create ticket
Creates a new ticket in a project and returns its reference (e.g. TDL-47). Defaults to the backlog column unless a status is specified. Requires editor or manager role on the project.
Path parameters
Param Type Description
id integer Project ID
Request body (JSON)
Field Type Description
title
string
required
Ticket title
type
string
optional
bug - feature - releaseDefault: feature
priority
string
optional
urgent - high - medium - lowDefault: none
status
string
optional
Status slug (use Project statuses to get valid slugs)Default: first status in project
deadline
string
optional
Date in YYYY-MM-DD format
story_points
integer
optional
0 - 3. Only accepted when the project uses story points estimation
estimated_hours
number
optional
Estimated hours (e.g. 4.5). Only accepted when the project uses hours estimation
checklist
string[]
optional
Array of checklist item texts, e.g. ["Write tests", "Update docs"]
tags
integer[]
optional
Array of tag IDs from List tags
Response
201 Created 201
Copy { "ticket_ref" : "TDL-47" }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tickets \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Fix login bug",
"type": "bug",
"priority": "high",
"status": "todo",
"deadline": "2026-03-15",
"checklist": ["Write tests", "Update docs"],
"tags": [5, 12]
}'
Copy const { ticket_ref } = await (await fetch(
'https://api.todo4you.com/api/v1/projects/12/tickets' ,
{
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({
title: 'Fix login bug' ,
type: 'bug' ,
priority: 'high' ,
status: 'todo' ,
deadline: '2026-03-15' ,
checklist: ['Write tests' , 'Update docs' ],
tags: [5 , 12 ],
} ),
} ,
)).json();
// ticket_ref -> "TDL-47"
Copy $payload = json_encode ([
'title' => 'Fix login bug' ,
'type' => 'bug' ,
'priority' => 'high' ,
'status' => 'todo' ,
'deadline' => '2026-03-15' ,
'checklist' => ['Write tests' , 'Update docs' ],
'tags' => [5 , 12 ],
]);
$ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$ticketRef = $data['ticket_ref' ]; // "TDL-47"
Copy import requests
resp = requests.post(
'https://api.todo4you.com/api/v1/projects/12/tickets' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={
'title' : 'Fix login bug' ,
'type' : 'bug' ,
'priority' : 'high' ,
'status' : 'todo' ,
'deadline' : '2026-03-15' ,
'checklist' : ['Write tests' , 'Update docs' ],
'tags' : [5 , 12 ],
} ,
)
ticket_ref = resp.json()['ticket_ref' ] # "TDL-47"
Update ticket
Updates one or more fields on a ticket. Only send the fields you want to change. Requires editor or manager role. To change the status column, use Move ticket instead.
Path parameters
Param Type Description
id integer Project ID
number integer Ticket number within the project
Request body (JSON)
Field Type Description
title string optional New title (cannot be empty)
description string optional New description (empty string to clear)
type string optional bug - feature - release
priority string|null optional urgent - high - medium - low - null to clear
deadline string|null optional YYYY-MM-DD or null to clear
story_points integer|null optional 0-3 or null to clear (story points mode only)
estimated_hours number|null optional Hours or null to clear (hours mode only)
tags integer[] optional Replace all tags with this list of tag IDs
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tickets/47/update \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Updated title","priority":"urgent","tags":[5,12]}'
Copy await fetch('https://api.todo4you.com/api/v1/projects/12/tickets/47/update' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ title: 'Updated title' , priority: 'urgent' , tags: [5 , 12 ] } ),
} );
Copy $payload = json_encode (['title' => 'Updated title' , 'priority' => 'urgent' ]);
$ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets/47/update' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
requests.post(
'https://api.todo4you.com/api/v1/projects/12/tickets/47/update' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'title' : 'Updated title' , 'priority' : 'urgent' } ,
)
Move ticket
Moves a ticket to a different status column. Triggers a real-time board update for all active viewers. Requires editor or manager role.
Path parameters
Param Type Description
id integer Project ID
number integer Ticket number within the project
Request body (JSON)
Field Type Description
status
string
required
Status slug (use Project statuses to get valid slugs)
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tickets/47/move \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status":"done"}'
Copy await fetch('https://api.todo4you.com/api/v1/projects/12/tickets/47/move' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ status: 'done' } ),
} );
Copy $payload = json_encode (['status' => 'done' ]);
$ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets/47/move' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true ); // ['ok' => true]
curl_close ($ch);
Copy import requests
requests.post(
'https://api.todo4you.com/api/v1/projects/12/tickets/47/move' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'status' : 'done' } ,
)
Archive ticket
Archives a ticket, removing it from the active board. Archived tickets can be restored from the project archive page. Requires editor or manager role.
Path parameters
Param Type Description
id integer Project ID
number integer Ticket number within the project
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tickets/47/archive \
-H "Authorization: Bearer YOUR_TOKEN"
Copy await fetch('https://api.todo4you.com/api/v1/projects/12/tickets/47/archive' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets/47/archive' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true ); // ['ok' => true]
curl_close ($ch);
Copy import requests
requests.post(
'https://api.todo4you.com/api/v1/projects/12/tickets/47/archive' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
)
Unarchive ticket
Restores a previously archived ticket back onto the board. Returns the full ticket payload (with creator, assignees, tags and checklist counts) so the client can re-render immediately. Requires manager role.
Path parameters
Param Type Description
id integer Project ID
number integer Ticket number within the project
Response
200 OK 200
Copy {
"ok" : true ,
"ticket" : {
"id" : 312 ,
"project_ticket_number" : 47 ,
"prefix_ref" : "TDL-47" ,
"title" : "Set up CI" ,
"status" : "in_progress" ,
"archived_at" : null
}
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tickets/47/unarchive \
-H "Authorization: Bearer YOUR_TOKEN"
Copy await fetch('https://api.todo4you.com/api/v1/projects/12/tickets/47/unarchive' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets/47/unarchive' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
requests.post(
'https://api.todo4you.com/api/v1/projects/12/tickets/47/unarchive' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
)
List archived tickets
Returns up to 100 most-recently archived tickets in a project, newest first. Optionally filter by title with the q query parameter (minimum 2 characters). The response also includes the calling user's role on the project so a client can decide whether to expose Restore (managers) and Delete (managers or ticket creator). Requires viewer role.
Path parameters
Param Type Description
id integer Project ID
Query parameters
Param Type Description
q string Optional title search, case-insensitive. Minimum 2 characters.
Response
200 OK 200
Copy {
"success" : true ,
"role" : "manager" ,
"tickets" : [
{
"id" : 312 ,
"project_id" : 12 ,
"project_ticket_number" : 47 ,
"prefix_ref" : "TDL-47" ,
"title" : "Set up CI" ,
"type" : "feature" ,
"status" : "done" ,
"priority" : "medium" ,
"deadline" : null ,
"story_points" : 2 ,
"estimated_hours" : null ,
"sort_order" : 0 ,
"archived_at" : "2026-04-19 14:32:11" ,
"created_by" : 7
}
]
}
Example
cURL
JavaScript
PHP
Python
Copy curl "https://api.todo4you.com/api/v1/projects/12/archived-tickets?q=ci" \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch('https://api.todo4you.com/api/v1/projects/12/archived-tickets?q=ci' , {
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
const { tickets, role } = await res.json();
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/archived-tickets?q=ci' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
res = requests.get(
'https://api.todo4you.com/api/v1/projects/12/archived-tickets' ,
params={ 'q' : 'ci' } ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
)
data = res.json()
Delete ticket
Permanently deletes a ticket (soft delete). The ticket creator can delete their own tickets; otherwise manager role is required.
Path parameters
Param Type Description
id integer Project ID
number integer Ticket number within the project
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tickets/47/delete \
-H "Authorization: Bearer YOUR_TOKEN"
Copy await fetch('https://api.todo4you.com/api/v1/projects/12/tickets/47/delete' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets/47/delete' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
requests.post(
'https://api.todo4you.com/api/v1/projects/12/tickets/47/delete' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
)
Assign member
Assigns a project member to a ticket. The user must be a member of the project. Use List members to find valid user IDs. Requires editor or manager role.
Path parameters
Param Type Description
id integer Project ID
number integer Ticket number within the project
Request body (JSON)
Field Type Description
user_id integer required The project member's user ID
Response
201 Created 201
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tickets/47/assign \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"user_id":8}'
Copy await fetch('https://api.todo4you.com/api/v1/projects/12/tickets/47/assign' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ user_id: 8 } ),
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets/47/assign' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => json_encode (['user_id' => 8 ]),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
requests.post(
'https://api.todo4you.com/api/v1/projects/12/tickets/47/assign' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'user_id' : 8 } ,
)
Unassign member
Removes a member from a ticket's assignee list. Requires editor or manager role.
Path parameters
Param Type Description
id integer Project ID
number integer Ticket number within the project
Request body (JSON)
Field Type Description
user_id integer required The user ID to unassign
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tickets/47/unassign \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"user_id":8}'
Copy await fetch('https://api.todo4you.com/api/v1/projects/12/tickets/47/unassign' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ user_id: 8 } ),
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets/47/unassign' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => json_encode (['user_id' => 8 ]),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
requests.post(
'https://api.todo4you.com/api/v1/projects/12/tickets/47/unassign' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'user_id' : 8 } ,
)
Board
Board data
Returns the full kanban board for a project in a single request: all columns with their tickets, project tags, members, velocity (tickets done in the last 7 days), and the authenticated user's role. Each ticket includes tags, assignee list, reaction count, checklist progress, and creator info.
Path parameters
Param Type Description
id integer Project ID
Response
200 OK 200
Copy {
"project" : {
"id" : 12 , "name" : "My Project" , "prefix" : "TDL" ,
"estimation_mode" : "story_points" , "role" : "manager" ,
"docs_enabled" : true
} ,
"columns" : [
{
"status" : "backlog" ,
"hidden" : false ,
"tickets" : [
{
"id" : 101 , "title" : "Fix bug" , "prefix_ref" : "TDL-1" ,
"tags" : [... ], "assignees" : [... ], "creator" : {...} ,
"reaction_count" : 3 , "checklist_total" : 5 , "checklist_done" : 2
}
]
} ,
...
] ,
"tags" : [... ],
"members" : [... ],
"velocity" : 8
}
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/projects/12/board \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const board = await (await fetch(
'https://api.todo4you.com/api/v1/projects/12/board' ,
{ headers: { Authorization : `Bearer ${TOKEN}` } } ,
)).json();
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/board' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$board = $data;
Copy import requests
board = requests.get(
'https://api.todo4you.com/api/v1/projects/12/board' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
Sort tickets
Reorders tickets within a column. Pass the status and the full ordered list of ticket IDs. Requires contributor role or higher.
Path parameters
Param Type Description
id integer Project ID
Request body (JSON)
Field Type Description
status string required Column status being reordered
ticket_ids integer[] required Ordered array of ticket IDs
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tickets/sort \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status":"todo","ticket_ids":[45,12,78]}'
Copy await fetch('https://api.todo4you.com/api/v1/projects/12/tickets/sort' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ status: 'todo' , ticket_ids: [45 , 12 , 78 ] } ),
} );
Copy $payload = json_encode (['status' => 'todo' , 'ticket_ids' => [45 , 12 , 78 ]]);
$ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tickets/sort' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
data = requests.post(
'https://api.todo4you.com/api/v1/projects/12/tickets/sort' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'status' : 'todo' , 'ticket_ids' : [45 , 12 , 78 ]} ,
).json()
Checklist
Add checklist item
Adds a checklist item to a ticket. The item starts unchecked and is appended at the end. Requires editor or manager role.
Path parameters
Param Type Description
ticketId integer Ticket ID (not the project ticket number)
Request body (JSON)
Field Type Description
text string required Item text (max 500 characters)
Response
201 Created 201
Copy {
"ok" : true ,
"item" : {
"id" : 42 , "ticket_id" : 101 ,
"text" : "Write tests" , "done" : 0 , "sort_order" : 3
}
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/tickets/101/checklist \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"Write tests"}'
Copy await fetch('https://api.todo4you.com/api/v1/tickets/101/checklist' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ text: 'Write tests' } ),
} );
Copy $payload = json_encode (['text' => 'Write tests' ]);
$ch = curl_init ('https://api.todo4you.com/api/v1/tickets/101/checklist' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$item = $data['item' ];
Copy import requests
data = requests.post(
'https://api.todo4you.com/api/v1/tickets/101/checklist' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'text' : 'Write tests' } ,
).json()
item = data['item' ]
Toggle checklist item
Toggles a checklist item between done and not done. Requires editor or manager role.
Path parameters
Param Type Description
itemId integer Checklist item ID
Response
200 OK 200
Copy { "ok" : true , "done" : 1 }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/checklist/42/toggle \
-H "Authorization: Bearer YOUR_TOKEN"
Copy await fetch('https://api.todo4you.com/api/v1/checklist/42/toggle' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/checklist/42/toggle' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
data = requests.post(
'https://api.todo4you.com/api/v1/checklist/42/toggle' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
Update checklist item
Updates the text of a checklist item. Requires editor or manager role.
Path parameters
Param Type Description
itemId integer Checklist item ID
Request body (JSON)
Field Type Description
text string required New item text (max 500 characters)
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/checklist/42/update \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"Write integration tests"}'
Copy await fetch('https://api.todo4you.com/api/v1/checklist/42/update' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ text: 'Write integration tests' } ),
} );
Copy $payload = json_encode (['text' => 'Write integration tests' ]);
$ch = curl_init ('https://api.todo4you.com/api/v1/checklist/42/update' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
data = requests.post(
'https://api.todo4you.com/api/v1/checklist/42/update' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'text' : 'Write integration tests' } ,
).json()
Delete checklist item
Removes a checklist item from a ticket. Requires editor or manager role.
Path parameters
Param Type Description
itemId integer Checklist item ID
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/checklist/42/delete \
-H "Authorization: Bearer YOUR_TOKEN"
Copy await fetch('https://api.todo4you.com/api/v1/checklist/42/delete' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/checklist/42/delete' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
data = requests.post(
'https://api.todo4you.com/api/v1/checklist/42/delete' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
Sort checklist items
Reorders all checklist items for a ticket. Pass the full ordered list of item IDs. Requires editor or manager role.
Path parameters
Param Type Description
ticketId integer Ticket ID
Request body (JSON)
Field Type Description
item_ids integer[] required Ordered array of checklist item IDs
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/tickets/101/checklist/sort \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"item_ids":[42,43,41]}'
Copy await fetch('https://api.todo4you.com/api/v1/tickets/101/checklist/sort' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ item_ids: [42 , 43 , 41 ] } ),
} );
Copy $payload = json_encode (['item_ids' => [42 , 43 , 41 ]]);
$ch = curl_init ('https://api.todo4you.com/api/v1/tickets/101/checklist/sort' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
data = requests.post(
'https://api.todo4you.com/api/v1/tickets/101/checklist/sort' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'item_ids' : [42 , 43 , 41 ]} ,
).json()
Blockers
Add blocker
Marks another ticket in the same project as a blocker for this ticket. A ticket cannot block itself. Requires editor or manager role.
Path parameters
Param Type Description
ticketId integer Ticket ID of the blocked ticket
Request body (JSON)
Field Type Description
blocker_ticket_id integer required Ticket ID of the blocking ticket (must be in the same project)
Response
201 Created 201
Copy {
"ok" : true ,
"blockers" : [
{ "id" : 55 , "title" : "Setup database" , "status" : "in_progress" , "project_ticket_number" : 3 }
]
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/tickets/101/blockers \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"blocker_ticket_id":55}'
Copy await fetch('https://api.todo4you.com/api/v1/tickets/101/blockers' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ blocker_ticket_id: 55 } ),
} );
Copy $payload = json_encode (['blocker_ticket_id' => 55 ]);
$ch = curl_init ('https://api.todo4you.com/api/v1/tickets/101/blockers' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
data = requests.post(
'https://api.todo4you.com/api/v1/tickets/101/blockers' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'blocker_ticket_id' : 55 } ,
).json()
Remove blocker
Removes a blocker relationship from a ticket. Returns the updated blocker list. Requires editor or manager role.
Path parameters
Param Type Description
ticketId integer Ticket ID of the blocked ticket
blockerTicketId integer Ticket ID of the blocker to remove
Response
200 OK 200
Copy { "ok" : true , "blockers" : [] }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/tickets/101/blockers/55/delete \
-H "Authorization: Bearer YOUR_TOKEN"
Copy await fetch('https://api.todo4you.com/api/v1/tickets/101/blockers/55/delete' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/tickets/101/blockers/55/delete' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
data = requests.post(
'https://api.todo4you.com/api/v1/tickets/101/blockers/55/delete' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
Attachments
Upload files
Uploads one or more files to a ticket. Send as multipart/form-data with files in the files[] field. Maximum file size is 10 MB per file. Accepted types: images, PDF, Office documents, CSV, plain text, and archives. Requires editor or manager role.
Path parameters
Param Type Description
ticketId integer Ticket ID
Request body (multipart/form-data)
Field Type Description
files[] file required One or more files to upload
Response
200 OK 200
Copy {
"ok" : true ,
"attachments" : [
{
"id" : 7 , "ticket_id" : 101 ,
"original_name" : "screenshot.png" ,
"filesize" : 48210 , "mime_type" : "image/png"
}
]
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/tickets/101/attachments \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "files[]=@screenshot.png" \
-F "files[]=@report.pdf"
Copy const form = new FormData();
form.append('files[]' , fileInput.files[0 ]);
await fetch('https://api.todo4you.com/api/v1/tickets/101/attachments' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` } ,
body: form,
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/tickets/101/attachments' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => [
'files[0]' => new \CURLFile('screenshot.png' ),
'files[1]' => new \CURLFile('report.pdf' ),
],
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
data = requests.post(
'https://api.todo4you.com/api/v1/tickets/101/attachments' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
files=[
('files[]' , open ('screenshot.png' , 'rb' )),
('files[]' , open ('report.pdf' , 'rb' )),
],
).json()
Get file
Downloads or displays an attachment. Images and PDFs are returned inline; other file types trigger a download. The user must have at least viewer access to the project.
Path parameters
Param Type Description
id integer Attachment ID
Response
Returns the file binary with the appropriate Content-Type and Content-Disposition headers.
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/attachments/7 \
-H "Authorization: Bearer YOUR_TOKEN" \
--output screenshot.png
Copy const res = await fetch('https://api.todo4you.com/api/v1/attachments/7' , {
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
const blob = await res.blob();
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/attachments/7' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$fileData = curl_exec ($ch);
curl_close ($ch);
file_put_contents ('screenshot.png' , $fileData);
Copy import requests
resp = requests.get(
'https://api.todo4you.com/api/v1/attachments/7' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
)
with open ('screenshot.png' , 'wb' ) as f:
f.write(resp.content)
Delete file
Deletes an attachment. You can delete files you uploaded, files on tickets you created, or any file if you are a manager .
Path parameters
Param Type Description
id integer Attachment ID
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/attachments/7/delete \
-H "Authorization: Bearer YOUR_TOKEN"
Copy await fetch('https://api.todo4you.com/api/v1/attachments/7/delete' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/attachments/7/delete' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
data = requests.post(
'https://api.todo4you.com/api/v1/attachments/7/delete' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
Create tag
Creates a new tag in a project. Requires manager role.
Path parameters
Param Type Description
id integer Project ID
Request body (JSON)
Field Type Description
name string required Tag name (max 100 characters)
color string optional Hex color, e.g. #e74c3cDefault: #6c757d
Response
201 Created 201
Copy {
"tag" : {
"id" : 18 ,
"name" : "frontend" ,
"color" : "#e74c3c" ,
"sort_order" : 3
}
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tags \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"frontend","color":"#e74c3c"}'
Copy const { tag } = await (await fetch(
'https://api.todo4you.com/api/v1/projects/12/tags' ,
{
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` , 'Content-Type' : 'application/json' } ,
body: JSON.stringify({ name: 'frontend' , color: '#e74c3c' } ),
} ,
)).json();
Copy $payload = json_encode (['name' => 'frontend' , 'color' => '#e74c3c' ]);
$ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tags' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_TOKEN' ,
'Content-Type: application/json' ,
],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
$tag = $data['tag' ];
Copy import requests
resp = requests.post(
'https://api.todo4you.com/api/v1/projects/12/tags' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
json={ 'name' : 'frontend' , 'color' : '#e74c3c' } ,
)
tag = resp.json()['tag' ]
Delete tag
Deletes a tag from a project. The tag is automatically removed from all tickets that use it. Requires manager role.
Path parameters
Param Type Description
id integer Project ID
tagId integer Tag ID from List tags
Response
200 OK 200
Copy { "ok" : true }
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/tags/5/delete \
-H "Authorization: Bearer YOUR_TOKEN"
Copy await fetch('https://api.todo4you.com/api/v1/projects/12/tags/5/delete' , {
method: 'POST' ,
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/tags/5/delete' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
requests.post(
'https://api.todo4you.com/api/v1/projects/12/tags/5/delete' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
)
Time Tracking
List time entries
Returns all time entries for a ticket.
Path parameters
Param Type Description
ticketId integer The ticket ID
Response
200 OK 200
Copy {
"success" : true ,
"entries" : [
{
"id" : 1 ,
"ticket_id" : 42 ,
"user_id" : 3 ,
"project_id" : 5 ,
"minutes" : 30 ,
"is_running" : 0 ,
"started_at" : "2025-01-15 09:00:00" ,
"stopped_at" : "2025-01-15 09:30:00" ,
"user_name" : "Alice" ,
"user_avatar" : "avatar.jpg"
}
] ,
"total_minutes" : 45
}
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/tickets/42/time-entries \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch ("https://api.todo4you.com/api/v1/tickets/42/time-entries" , {
headers: { "Authorization" : "Bearer YOUR_TOKEN" }
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/tickets/42/time-entries" );
curl_setopt ($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_TOKEN" ]);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.get ("https://api.todo4you.com/api/v1/tickets/42/time-entries" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" })
data = res.json ()
Add manual entry
Adds a manual time entry (not a running timer).
Path parameters
Param Type Description
ticketId integer The ticket ID
Request body (JSON)
Field Type Description
minutes integer required Duration in minutes (min 1)
Response
200 OK 200
Copy {
"success" : true ,
"entry" : {
"id" : 2 ,
"ticket_id" : 42 ,
"minutes" : 30 ,
"is_running" : 0 ,
"started_at" : null ,
"stopped_at" : null
}
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/tickets/42/time-entries \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"minutes": 30}'
Copy const res = await fetch ("https://api.todo4you.com/api/v1/tickets/42/time-entries" , {
method: "POST" ,
headers: {
"Authorization" : "Bearer YOUR_TOKEN" ,
"Content-Type" : "application/json"
} ,
body: JSON.stringify ({ minutes: 30 } )
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/tickets/42/time-entries" );
curl_setopt ($ch, CURLOPT_POST, true );
curl_setopt ($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer YOUR_TOKEN" ,
"Content-Type: application/json"
]);
curl_setopt ($ch, CURLOPT_POSTFIELDS, json_encode ([
"minutes" => 30 ,
]));
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.post ("https://api.todo4you.com/api/v1/tickets/42/time-entries" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
json={"minutes" : 30 })
data = res.json ()
Start timer
Starts a running timer on a ticket. Only one timer can run per user at a time.
Path parameters
Param Type Description
ticketId integer The ticket ID
Response
200 OK 200
Copy {
"success" : true ,
"entry" : {
"id" : 3 ,
"ticket_id" : 42 ,
"minutes" : 0 ,
"is_running" : 1 ,
"started_at" : "2025-01-15 09:00:00" ,
"stopped_at" : null ,
"ticket_title" : "Fix login bug" ,
"project_name" : "My App" ,
"ticket_ref" : "APP-42"
}
}
422 Unprocessable Entity 422
Copy {
"error" : "You already have a running timer." ,
"running_ticket_id" : 55
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/tickets/42/time-entries/start \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch ("https://api.todo4you.com/api/v1/tickets/42/time-entries/start" , {
method: "POST" ,
headers: { "Authorization" : "Bearer YOUR_TOKEN" }
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/tickets/42/time-entries/start" );
curl_setopt ($ch, CURLOPT_POST, true );
curl_setopt ($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_TOKEN" ]);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.post ("https://api.todo4you.com/api/v1/tickets/42/time-entries/start" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" })
data = res.json ()
Stop timer
Stops a running or paused timer and calculates the final duration.
Path parameters
Param Type Description
entryId integer The time entry ID
Response
200 OK 200
Copy {
"success" : true ,
"entry" : {
"id" : 3 ,
"ticket_id" : 42 ,
"minutes" : 45 ,
"is_running" : 0 ,
"started_at" : "2025-01-15 09:00:00" ,
"stopped_at" : "2025-01-15 09:45:00" ,
"ticket_title" : "Fix login bug" ,
"project_name" : "My App" ,
"ticket_ref" : "APP-42"
}
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/time-entries/3/stop \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch ("https://api.todo4you.com/api/v1/time-entries/3/stop" , {
method: "POST" ,
headers: { "Authorization" : "Bearer YOUR_TOKEN" }
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/time-entries/3/stop" );
curl_setopt ($ch, CURLOPT_POST, true );
curl_setopt ($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_TOKEN" ]);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.post ("https://api.todo4you.com/api/v1/time-entries/3/stop" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" })
data = res.json ()
Pause timer
Pauses a running timer. Accumulated time is preserved in the minutes field.
Path parameters
Param Type Description
entryId integer The time entry ID
Response
200 OK 200
Copy {
"success" : true ,
"entry" : {
"id" : 3 ,
"ticket_id" : 42 ,
"minutes" : 15 ,
"is_running" : 2 ,
"started_at" : "2025-01-15 09:00:00" ,
"stopped_at" : null ,
"ticket_title" : "Fix login bug" ,
"project_name" : "My App" ,
"ticket_ref" : "APP-42"
}
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/time-entries/3/pause \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch ("https://api.todo4you.com/api/v1/time-entries/3/pause" , {
method: "POST" ,
headers: { "Authorization" : "Bearer YOUR_TOKEN" }
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/time-entries/3/pause" );
curl_setopt ($ch, CURLOPT_POST, true );
curl_setopt ($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_TOKEN" ]);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.post ("https://api.todo4you.com/api/v1/time-entries/3/pause" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" })
data = res.json ()
Resume timer
Resumes a paused timer. Cannot resume if another timer is already running.
Path parameters
Param Type Description
entryId integer The time entry ID
Response
200 OK 200
Copy {
"success" : true ,
"entry" : {
"id" : 3 ,
"ticket_id" : 42 ,
"minutes" : 15 ,
"is_running" : 1 ,
"started_at" : "2025-01-15 10:00:00" ,
"stopped_at" : null ,
"ticket_title" : "Fix login bug" ,
"project_name" : "My App" ,
"ticket_ref" : "APP-42"
}
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/time-entries/3/resume \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch ("https://api.todo4you.com/api/v1/time-entries/3/resume" , {
method: "POST" ,
headers: { "Authorization" : "Bearer YOUR_TOKEN" }
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/time-entries/3/resume" );
curl_setopt ($ch, CURLOPT_POST, true );
curl_setopt ($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_TOKEN" ]);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.post ("https://api.todo4you.com/api/v1/time-entries/3/resume" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" })
data = res.json ()
Update entry
Updates the minutes of a stopped time entry. Owner or project manager can update.
Path parameters
Param Type Description
entryId integer The time entry ID
Request body (JSON)
Field Type Description
minutes integer required New duration in minutes (min 1)
Response
200 OK 200
Copy {
"success" : true ,
"entry" : {
"id" : 3 ,
"ticket_id" : 42 ,
"minutes" : 60 ,
"is_running" : 0 ,
"started_at" : "2025-01-15 09:00:00" ,
"stopped_at" : "2025-01-15 09:45:00"
}
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/time-entries/3/update \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"minutes": 60}'
Copy const res = await fetch ("https://api.todo4you.com/api/v1/time-entries/3/update" , {
method: "POST" ,
headers: {
"Authorization" : "Bearer YOUR_TOKEN" ,
"Content-Type" : "application/json"
} ,
body: JSON.stringify ({ minutes: 60 } )
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/time-entries/3/update" );
curl_setopt ($ch, CURLOPT_POST, true );
curl_setopt ($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer YOUR_TOKEN" ,
"Content-Type: application/json"
]);
curl_setopt ($ch, CURLOPT_POSTFIELDS, json_encode (["minutes" => 60 ]));
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.post ("https://api.todo4you.com/api/v1/time-entries/3/update" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
json={"minutes" : 60 })
data = res.json ()
Delete entry
Deletes a time entry. Owner or project manager can delete.
Path parameters
Param Type Description
entryId integer The time entry ID
Response
200 OK 200
Copy {
"success" : true
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/time-entries/3/delete \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch ("https://api.todo4you.com/api/v1/time-entries/3/delete" , {
method: "POST" ,
headers: { "Authorization" : "Bearer YOUR_TOKEN" }
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/time-entries/3/delete" );
curl_setopt ($ch, CURLOPT_POST, true );
curl_setopt ($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_TOKEN" ]);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.post ("https://api.todo4you.com/api/v1/time-entries/3/delete" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" })
data = res.json ()
Running timer
Returns the currently running or paused timer for the authenticated user, with ticket and project details.
Response
200 OK 200
Copy {
"success" : true ,
"entry" : {
"id" : 1 ,
"ticket_id" : 42 ,
"minutes" : 15 ,
"is_running" : 1 ,
"started_at" : "2025-01-15 09:00:00" ,
"ticket_title" : "Fix login bug" ,
"project_name" : "My App" ,
"ticket_ref" : "APP-5"
}
}
When no timer is running, entry is null.
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/time-entries/running \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch ("https://api.todo4you.com/api/v1/time-entries/running" , {
headers: { "Authorization" : "Bearer YOUR_TOKEN" }
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/time-entries/running" );
curl_setopt ($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_TOKEN" ]);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.get ("https://api.todo4you.com/api/v1/time-entries/running" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" })
data = res.json ()
Active timers
Returns all running and paused timers for the authenticated user, with ticket and project details. Unlike /time-entries/running which returns only one entry, this endpoint returns all active timers.
Response
200 OK 200
Copy {
"success" : true ,
"entries" : [
{
"id" : 1 ,
"ticket_id" : 42 ,
"minutes" : 15 ,
"is_running" : 1 ,
"started_at" : "2025-01-15 09:00:00" ,
"ticket_title" : "Fix login bug" ,
"project_name" : "My App" ,
"ticket_ref" : "APP-5"
} ,
{
"id" : 2 ,
"ticket_id" : 18 ,
"minutes" : 45 ,
"is_running" : 2 ,
"started_at" : "2025-01-15 08:00:00" ,
"ticket_title" : "Update dashboard" ,
"project_name" : "My App" ,
"ticket_ref" : "APP-18"
}
]
}
When no timers are active, entries is an empty array. is_running is 1 for running and 2 for paused.
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/time-entries/active \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch ("https://api.todo4you.com/api/v1/time-entries/active" , {
headers: { "Authorization" : "Bearer YOUR_TOKEN" }
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/time-entries/active" );
curl_setopt ($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_TOKEN" ]);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.get ("https://api.todo4you.com/api/v1/time-entries/active" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" })
data = res.json ()
Notifications
List notifications
Returns the last 20 notifications and marks all as read.
Response
200 OK 200
Copy {
"notifications" : [
{
"id" : 1 ,
"type" : "reaction" ,
"message" : "commented on APP-5: Fix login bug" ,
"ticket_id" : 42 ,
"project_id" : 5 ,
"read_at" : null ,
"created_at" : "2025-01-15 10:00:00"
}
]
}
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/notifications \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch ("https://api.todo4you.com/api/v1/notifications" , {
headers: { "Authorization" : "Bearer YOUR_TOKEN" }
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/notifications" );
curl_setopt ($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_TOKEN" ]);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.get ("https://api.todo4you.com/api/v1/notifications" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" })
data = res.json ()
Unread count
Returns the count of unread notifications.
Response
200 OK 200
Copy {
"count" : 3
}
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/notifications/unread-count \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch ("https://api.todo4you.com/api/v1/notifications/unread-count" , {
headers: { "Authorization" : "Bearer YOUR_TOKEN" }
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/notifications/unread-count" );
curl_setopt ($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_TOKEN" ]);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.get ("https://api.todo4you.com/api/v1/notifications/unread-count" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" })
data = res.json ()
Mark read for ticket
Marks all unread notifications for a specific ticket as read.
Request body (JSON)
Field Type Description
ticket_id integer required The ticket ID to mark notifications as read for
Response
200 OK 200
Copy {
"success" : true ,
"unread_count" : 3
}
Example
cURL
JavaScript
PHP
Python
Copy curl -X POST https://api.todo4you.com/api/v1/notifications/mark-read-for-ticket \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"ticket_id": 42}'
Copy const res = await fetch ("https://api.todo4you.com/api/v1/notifications/mark-read-for-ticket" , {
method: "POST" ,
headers: {
"Authorization" : "Bearer YOUR_TOKEN" ,
"Content-Type" : "application/json"
} ,
body: JSON.stringify ({ ticket_id: 42 } )
} );
const data = await res.json ();
Copy $ch = curl_init ("https://api.todo4you.com/api/v1/notifications/mark-read-for-ticket" );
curl_setopt ($ch, CURLOPT_POST, true );
curl_setopt ($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer YOUR_TOKEN" ,
"Content-Type: application/json"
]);
curl_setopt ($ch, CURLOPT_POSTFIELDS, json_encode (["ticket_id" => 42 ]));
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true );
$res = json_decode (curl_exec ($ch), true );
Copy import requests
res = requests.post ("https://api.todo4you.com/api/v1/notifications/mark-read-for-ticket" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
json={"ticket_id" : 42 })
data = res.json ()
Documentation
List documentation root
Returns folders and articles at the documentation root of a project. The response also includes the calling user's role, so a client can decide whether to expose write actions. Returns 404 if the project does not have documentation enabled (docs_enabled is false on the project payload). All documentation endpoints share this guard.
Response
200 OK 200
Copy {
"success" : true ,
"role" : "manager" ,
"current_folder" : null ,
"breadcrumbs" : [],
"folders" : [
{ "id" : 3 , "project_id" : 12 , "parent_id" : null ,
"title" : "Onboarding" , "slug" : "onboarding" , "sort_order" : 0 }
],
"articles" : [
{ "id" : 7 , "project_id" : 12 , "folder_id" : null ,
"title" : "Welcome" , "slug" : "welcome" ,
"content" : "# Welcome\n\nGetting started..." , "sort_order" : 0 }
]
}
Example
cURL
JavaScript
PHP
Python
Copy curl https://api.todo4you.com/api/v1/projects/12/docs \
-H "Authorization: Bearer YOUR_TOKEN"
Copy const res = await fetch('https://api.todo4you.com/api/v1/projects/12/docs' , {
headers: { Authorization : `Bearer ${TOKEN}` } ,
} );
const { folders, articles, role } = await res.json();
Copy $ch = curl_init ('https://api.todo4you.com/api/v1/projects/12/docs' );
curl_setopt_array ($ch, [
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN' ],
]);
$data = json_decode (curl_exec ($ch), true );
curl_close ($ch);
Copy import requests
data = requests.get(
'https://api.todo4you.com/api/v1/projects/12/docs' ,
headers={ 'Authorization' : f'Bearer {TOKEN}' } ,
).json()
List folder contents
Same shape as the root listing, but scoped to the contents of a single folder. The response includes a current_folder object and the full breadcrumbs ancestor chain from the root down to this folder.
Example
Copy curl https://api.todo4you.com/api/v1/projects/12/docs/folders/3 \
-H "Authorization: Bearer YOUR_TOKEN"
Create folder
Creates a new folder. Requires contributor role or higher.
Request body (JSON)
Field Type Description
title string required Folder name
parent_id integer optional Parent folder id, or null/omitted to create at the root
Example
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/docs/folders \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Onboarding","parent_id":null}'
Update folder
Renames or moves a folder. Send only the fields you want to change. Requires contributor role or higher.
Request body (JSON)
Field Type Description
title string optional New title
parent_id integer | null optional Move to this parent. Pass null to move to the root. Omit to keep the parent unchanged. A folder cannot be its own parent.
Example
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/docs/folders/3 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Onboarding (renamed)"}'
Delete folder
Soft-deletes a folder. Any child folders and articles are reparented to this folder's parent rather than deleted, so nothing is lost. Requires contributor role or higher. The response includes parent_id so the client can refresh that view.
Example
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/docs/folders/3/delete \
-H "Authorization: Bearer YOUR_TOKEN"
Get article
Returns the article's markdown content along with attachments, comments (with author info), breadcrumbs, the calling user's role, and current_user_id so the client knows whether to show "edit" / "delete" affordances on individual comments.
Response
200 OK 200
Copy {
"success" : true ,
"role" : "manager" ,
"current_user_id" : 42 ,
"article" : {
"id" : 7 , "project_id" : 12 , "folder_id" : null ,
"title" : "Welcome" , "slug" : "welcome" ,
"content" : "# Welcome\n\nMarkdown body." ,
"created_by" : 42 , "updated_by" : null
} ,
"breadcrumbs" : [],
"attachments" : [
{ "id" : 11 , "original_name" : "diagram.png" ,
"filesize" : 12345 , "mime_type" : "image/png" }
],
"comments" : [
{ "id" : 5 , "user_id" : 42 ,
"user_name" : "Jorden" , "message" : "Looks good" }
]
}
Example
Copy curl https://api.todo4you.com/api/v1/projects/12/docs/articles/7 \
-H "Authorization: Bearer YOUR_TOKEN"
Create article
Creates a new article. Markdown is supported in content. Requires contributor role or higher.
Request body (JSON)
Field Type Description
title string required Article title
content string optional Markdown content. Defaults to empty string
folder_id integer optional Folder to place the article in. Omit for root
Example
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/docs/articles \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"How we deploy","content":"## Steps\n1. Push to main","folder_id":3}'
Update article
Updates an article. Send only the fields you want to change. The server stamps updated_by with the calling user. Requires contributor role or higher.
Request body (JSON)
Field Type Description
title string optional New title
content string optional New markdown content
folder_id integer | null optional Move to this folder. Pass null to move to root. Omit to leave unchanged.
Example
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/docs/articles/7 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content":"Updated body."}'
Delete article
Soft-deletes an article. Requires contributor role or higher.
Example
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/docs/articles/7/delete \
-H "Authorization: Bearer YOUR_TOKEN"
Copy article
Duplicates an article in the same folder. The new article gets the suffix (copy) on its title and is owned by the calling user. Requires contributor role or higher.
Example
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/docs/articles/7/copy \
-H "Authorization: Bearer YOUR_TOKEN"
Upload attachments
Uploads one or more files to a documentation article. Send as multipart/form-data with files in the files[] field. Maximum 10 MB per file. Same allowed types as ticket attachments (images, PDF, Office docs, CSV, plain text, archives). Requires contributor role or higher.
Example
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/docs/articles/7/attachments \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "files[]=@./diagram.png" \
-F "files[]=@./spec.pdf"
Get attachment
Streams the file back. Images and PDFs are served inline; other types as a download. The endpoint sets Content-Type, Content-Disposition, and a private Cache-Control header.
Example
Copy curl -OJ https://api.todo4you.com/api/v1/projects/12/docs/attachments/11 \
-H "Authorization: Bearer YOUR_TOKEN"
Delete attachment
Deletes an attachment from disk and from the database. Requires contributor role or higher.
Example
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/docs/attachments/11/delete \
-H "Authorization: Bearer YOUR_TOKEN"
Sort folders and articles
Sets the sort_order for folders and/or articles based on the order in the request arrays. The position in each array becomes the new sort_order. Requires contributor role or higher.
Request body (JSON)
Field Type Description
folders int[] optional Folder ids in the desired order
articles int[] optional Article ids in the desired order
Example
Copy curl -X POST https://api.todo4you.com/api/v1/projects/12/docs/sort \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"folders":[3,1,2],"articles":[12,10,11]}'